comparison src/xrdb.c @ 4232:f533d585cfc8

Implement search for app-defaults directory and localized default databases, along with some other functionality provided by Xt. #include <stdio.h>, since we call sprintf. [emacs] (malloc, realloc, free): #define these to xmalloc, xrealloc, and xfree. (x_get_string_resource, file_p): Add forward declarations for these. (x_customization_string): New variable. (x_get_customization_string): New function. (gethomedir): Return malloc'ed space of the right size, instead of writing into a fixed-size buffer; this means that our callers do not impose an arbitrary limit on file name length. (magic_file_p): Rewrite of decode_magic; actually do the substitutions, instead of expanding all %-escapes to "". Support the customization string. Return 0 or the expanded file name, instead of just zero or one. Allocate the space for the expanded file name ourselves, instead of writing into a fixed-size buffer passed to us; this removes an arbitrary limit. (search_magic_path): Rewrite of magic_searchpath_decoder. Return 0 or the expanded file name, instead of just zero or one. Allocate the space for the expanded file name ourselves, instead of writing into a fixed-size buffer passed to us; this means that our callers do not impose an arbitrary limit on file name length. (get_system_app): Changed to work with search_magic_path. (get_user_app): Rewritten to work with search_magic_path, and not to assume that the values of XAPPLRESDIR is a single directory. (get_user_db): Properly use the new version of gethomedir. (get_environ_db): Remove arbitrary limit on length of host name. (x_load_resources): Take a new argument, myname. Call get_user_db early to obtain the customization string. Changes to stand-alone testing code.
author Jim Blandy <jimb@redhat.com>
date Thu, 22 Jul 1993 22:00:48 +0000
parents e67c6c10dd7c
children a4197ae1927d
comparison
equal deleted inserted replaced
4231:91a883c56382 4232:f533d585cfc8
18 /* Written by jla, 4/90 */ 18 /* Written by jla, 4/90 */
19 19
20 #ifdef emacs 20 #ifdef emacs
21 #include "config.h" 21 #include "config.h"
22 #endif 22 #endif
23
24 #include <stdio.h>
23 25
24 #if 1 /* I'd really appreciate it if this code could go away... -JimB */ 26 #if 1 /* I'd really appreciate it if this code could go away... -JimB */
25 /* this avoids lossage in the `dual-universe' headers on AT&T SysV X11 */ 27 /* this avoids lossage in the `dual-universe' headers on AT&T SysV X11 */
26 #ifdef USG5 28 #ifdef USG5
27 #define SYSV 29 #define SYSV
69 #else 71 #else
70 extern struct passwd *getpwuid (); 72 extern struct passwd *getpwuid ();
71 extern struct passwd *getpwnam (); 73 extern struct passwd *getpwnam ();
72 #endif 74 #endif
73 75
76 /* Make sure not to #include anything after these definitions. Let's
77 not step on anyone's prototypes. */
78 #ifdef emacs
79 #define malloc xmalloc
80 #define realloc xrealloc
81 #define free xfree
82 #endif
83
84 char *x_get_string_resource ();
85 static int file_p ();
86
87
88 /* X file search path processing. */
89
90
91 /* The string which gets substituted for the %C escape in XFILESEARCHPATH
92 and friends, or zero if none was specified. */
93 char *x_customization_string;
94
95
96 /* Return the value of the emacs.customization (Emacs.Customization)
97 resource, for later use in search path decoding. If we find no
98 such resource, return zero. */
99 char *
100 x_get_customization_string (db, name, class)
101 XrmDatabase db;
102 char *name, *class;
103 {
104 char *full_name
105 = (char *) alloca (strlen (name) + sizeof ("customization") + 3);
106 char *full_class
107 = (char *) alloca (strlen (class) + sizeof ("Customization") + 3);
108 char *result;
109
110 sprintf (full_name, "%s.%s", name, "customization");
111 sprintf (full_class, "%s.%s", class, "Customization");
112
113 result = x_get_string_resource (db, full_name, full_class);
114
115 if (result)
116 return strcpy ((char *) malloc (strlen (result) + 1), result);
117 else
118 return 0;
119 }
120
121
122 /* Expand all the Xt-style %-escapes in STRING, whose length is given
123 by STRING_LEN. Here are the escapes we're supposed to recognize:
124
125 %N The value of the application's class name
126 %T The value of the type parameter ("app-defaults" in this
127 context)
128 %S The value of the suffix parameter ("" in this context)
129 %L The language string associated with the specified display
130 (We use the "LANG" environment variable here, if it's set.)
131 %l The language part of the display's language string
132 (We treat this just like %L. If someone can tell us what
133 we're really supposed to do, dandy.)
134 %t The territory part of the display's language string
135 (This never gets used.)
136 %c The codeset part of the display's language string
137 (This never gets used either.)
138 %C The customization string retrieved from the resource
139 database associated with display.
140 (This is x_customization_string.)
141
142 Return the expanded file name if it exists and is readable, and
143 refers to %L only when the LANG environment variable is set, or
144 otherwise provided by X.
145
146 ESCAPED_SUFFIX and SUFFIX are postpended to STRING if they are
147 non-zero. %-escapes in ESCAPED_SUFFIX are expanded; STRING is left
148 alone.
149
150 Return NULL otherwise. */
151
74 static char * 152 static char *
75 gethomedir (dirname) 153 magic_file_p (string, string_len, class, escaped_suffix, suffix)
76 char *dirname; 154 char *string;
155 int string_len;
156 char *class, *escaped_suffix, *suffix;
157 {
158 char *lang = getenv ("LANG");
159
160 int path_size = 100;
161 char *path = (char *) malloc (path_size);
162 int path_len = 0;
163
164 char *p = string;
165
166 while (p < string + string_len)
167 {
168 /* The chunk we're about to stick on the end of result. */
169 char *next;
170 int next_len;
171
172 if (*p == '%')
173 {
174 p++;
175
176 if (p >= string + string_len)
177 next_len = 0;
178 else
179 switch (*p)
180 {
181 case '%':
182 next = "%";
183 next_len = 1;
184 break;
185
186 case 'C':
187 next = (x_customization_string
188 ? x_customization_string
189 : "");
190 next_len = strlen (next);
191 break;
192
193 case 'N':
194 next = class;
195 next_len = strlen (class);
196 break;
197
198 case 'T':
199 next = "app-defaults";
200 next_len = strlen (next);
201 break;
202
203 default:
204 case 'S':
205 next_len = 0;
206 break;
207
208 case 'L':
209 case 'l':
210 if (! lang)
211 {
212 free (path);
213 return NULL;
214 }
215
216 next = lang;
217 next_len = strlen (next);
218 break;
219
220 case 't':
221 case 'c':
222 free (path);
223 return NULL;
224 }
225 }
226 else
227 next = p, next_len = 1;
228
229 /* Do we have room for this component followed by a '\0' ? */
230 if (path_len + next_len + 1 > path_size)
231 {
232 path_size = (path_len + next_len + 1) * 2;
233 path = (char *) realloc (path, path_size);
234 }
235
236 bcopy (next, path + path_len, next_len);
237 path_len += next_len;
238
239 p++;
240
241 /* If we've reached the end of the string, append ESCAPED_SUFFIX. */
242 if (p >= string + string_len && escaped_suffix)
243 {
244 string = escaped_suffix;
245 string_len = strlen (string);
246 p = string;
247 escaped_suffix = NULL;
248 }
249 }
250
251 /* Perhaps we should add the SUFFIX now. */
252 if (suffix)
253 {
254 int suffix_len = strlen (suffix);
255
256 if (path_len + suffix_len + 1 > path_size)
257 {
258 path_size = (path_len + suffix_len + 1);
259 path = (char *) realloc (path, path_size);
260 }
261
262 bcopy (suffix, path + path_len, suffix_len);
263 path_len += suffix_len;
264 }
265
266 path[path_len] = '\0';
267
268 if (! file_p (path))
269 {
270 free (path);
271 return NULL;
272 }
273
274 return path;
275 }
276
277
278 static char *
279 gethomedir ()
77 { 280 {
78 int uid; 281 int uid;
79 struct passwd *pw; 282 struct passwd *pw;
80 char *ptr; 283 char *ptr;
284 char *copy;
81 285
82 if ((ptr = getenv ("HOME")) == NULL) 286 if ((ptr = getenv ("HOME")) == NULL)
83 { 287 {
84 if ((ptr = getenv ("USER")) != NULL) 288 if ((ptr = getenv ("USER")) != NULL)
85 pw = getpwnam (ptr); 289 pw = getpwnam (ptr);
86 else 290 else
87 { 291 {
88 uid = getuid (); 292 uid = getuid ();
89 pw = getpwuid (uid); 293 pw = getpwuid (uid);
90 } 294 }
295
91 if (pw) 296 if (pw)
92 ptr = pw->pw_dir; 297 ptr = pw->pw_dir;
93 else 298 }
94 { 299
95 ptr = NULL; 300 if (ptr == NULL)
96 *dirname = '\0'; 301 return "/";
97 } 302
98 } 303 copy = (char *) malloc (strlen (ptr) + 2);
99 304 strcpy (copy, ptr);
100 if (ptr != NULL) 305 strcat (copy, "/");
101 strcpy (dirname, ptr); 306
102 307 return copy;
103 dirname += strlen (dirname); 308 }
104 *dirname = '/'; 309
105 dirname++;
106 *dirname = '\0';
107
108 return dirname;
109 }
110 310
111 static int 311 static int
112 file_p (path) 312 file_p (path)
113 char *path; 313 char *path;
114 { 314 {
117 return (access (path, 4) == 0 /* exists and is readable */ 317 return (access (path, 4) == 0 /* exists and is readable */
118 && stat (path, &status) == 0 /* get the status */ 318 && stat (path, &status) == 0 /* get the status */
119 && (status.st_mode & S_IFDIR) == 0); /* not a directory */ 319 && (status.st_mode & S_IFDIR) == 0); /* not a directory */
120 } 320 }
121 321
122 #if 0 322
123 #define X_DEFAULT_SEARCH_PATH "/usr/lib/X11/" 323 /* Find the first element of SEARCH_PATH which exists and is readable,
124 #endif 324 after expanding the %-escapes. Return 0 if we didn't find any, and
125 325 the path name of the one we found otherwise. */
126 /* Isn't this just disgusting? */ 326
127 327 static char *
128 #define X_DEFAULT_SEARCH_PATH "/usr/lib/X11/%L/%T/%N%S:/usr/lib/X11/%l/%T/%N%S:/usr/lib/X11/%T/%N%S" 328 search_magic_path (search_path, class, escaped_suffix, suffix)
129 329 char *search_path, *class, *escaped_suffix, *suffix;
130 static int 330 {
131 decode_magic (string, file, return_path) 331 register char *s, *p;
132 char *string, *file, *return_path; 332
133 { 333 for (s = search_path; *s; s = p)
134 char *p = string; 334 {
135 char *t = return_path; 335 for (p = s; *p && *p != ':'; p++)
136 336 ;
137 while (*p) 337
138 {
139 if (*p == '%')
140 switch (*++p)
141 {
142 case '%':
143 *t++ = '%';
144 p++;
145 break;
146
147 case 'N':
148 case 'T':
149 case 'S':
150 case 'L':
151 case 'l':
152 case 't':
153 case 'c':
154 default:
155 p++;
156 if (*t == '/' && *p == '/')
157 p++;
158 break;
159 }
160 else
161 *t++ = *p++;
162 }
163 *t = '\0';
164 strcat (return_path, file);
165
166 if (file_p (return_path))
167 return 1;
168
169 return_path[0] = '\0';
170 return 0;
171 }
172
173 static int
174 magic_searchpath_decoder (incantation_string, file, return_path)
175 char *incantation_string, *return_path, *file;
176 {
177 register char *s = incantation_string;
178 register char *p;
179
180 /* Must be big enough for "%N%S". */
181 register int string_size = MAXPATHLEN;
182 register char *string = (char *) alloca (string_size * sizeof (*string));
183
184 while (*s)
185 {
186 p = s;
187
188 while (*p && *p != ':')
189 p++;
190
191 if (*p == ':' && *(p + 1) == ':') 338 if (*p == ':' && *(p + 1) == ':')
192 { 339 {
193 /* We know string is big enough for this. */ 340 char *path;
194 bcopy ("%N%S", string, 5); 341
195 if (decode_magic (string, file, return_path)) 342 s = "%N%S";
196 return 1; 343 path = magic_file_p (s, strlen (s), class, escaped_suffix, suffix);
344 if (path)
345 return path;
197 346
198 s = p + 1; 347 s = p + 1;
199 continue; 348 continue;
200 } 349 }
201 350
202 if (p > s) 351 if (p > s)
203 { 352 {
204 int len = p - s; 353 char *path = magic_file_p (s, p - s, class, escaped_suffix, suffix);
205 354 if (path)
206 if (string_size < len+1) 355 return path;
207 {
208 string_size = 2 * len;
209 string = (char *) alloca (string_size * sizeof (*string));
210 }
211 bcopy (s, string, len);
212 string[len] = '\0';
213 if (decode_magic (string, file, return_path))
214 return 1;
215 } 356 }
216 357
217 if (p && *p != 0) 358 if (*p == ':')
218 s = p + 1; 359 p++;
219 else
220 return 0;
221 } 360 }
222 361
223 return 0; 362 return 0;
224 } 363 }
225 364
365 /* Producing databases for individual sources. */
366
367 #define X_DEFAULT_SEARCH_PATH "/usr/lib/X11/%L/%T/%N%C%S:/usr/lib/X11/%l/%T/%N%C%S:/usr/lib/X11/%T/%N%C%S:/usr/lib/X11/%L/%T/%N%S:/usr/lib/X11/%l/%T/%N%S:/usr/lib/X11/%T/%N%S"
368
226 static XrmDatabase 369 static XrmDatabase
227 get_system_app (class) 370 get_system_app (class)
228 char *class; 371 char *class;
229 { 372 {
230 XrmDatabase db; 373 XrmDatabase db = NULL;
231 char path[MAXPATHLEN]; 374 char *path;
232 char *p; 375
233 376 path = getenv ("XFILESEARCHPATH");
234 if ((p = getenv ("XFILESEARCHPATH")) == NULL) 377 if (! path) path = X_DEFAULT_SEARCH_PATH;
235 p = X_DEFAULT_SEARCH_PATH; 378
236 379 path = search_magic_path (path, class, 0, 0);
237 if (! magic_searchpath_decoder (p, class, path)) 380 if (path)
238 return NULL; 381 {
239 382 db = XrmGetFileDatabase (path);
240 db = XrmGetFileDatabase (path); 383 free (path);
384 }
385
241 return db; 386 return db;
242 } 387 }
388
243 389
244 static XrmDatabase 390 static XrmDatabase
245 get_fallback (display) 391 get_fallback (display)
246 Display *display; 392 Display *display;
247 { 393 {
248 XrmDatabase db; 394 XrmDatabase db;
249 395
250 return NULL; 396 return NULL;
251 } 397 }
252 398
399
253 static XrmDatabase 400 static XrmDatabase
254 get_user_app (class) 401 get_user_app (class)
255 char *class; 402 char *class;
256 { 403 {
257 XrmDatabase db; 404 char *path;
258 char *magic_path; 405 char *file = 0;
259 char path[MAXPATHLEN]; 406
260 407 /* Check for XUSERFILESEARCHPATH. It is a path of complete file
261 if ((magic_path = getenv ("XUSERFILESEARCHPATH")) == NULL) 408 names, not directories. */
262 { 409 if (((path = getenv ("XUSERFILESEARCHPATH"))
263 char homedir[MAXPATHLEN]; 410 && (file = search_magic_path (path, class, 0, 0)))
264 char *default_magic; 411
265 char *p; 412 /* Check for APPLRESDIR; it is a path of directories. In each,
266 413 we have to search for LANG/CLASS and then CLASS. */
267 gethomedir (homedir); 414 || ((path = getenv ("XAPPLRESDIR"))
268 415 && ((file = search_magic_path (path, class, "/%L/%N", 0))
269 if ((p = getenv ("XAPPLRESDIR")) == NULL) 416 || (file = search_magic_path (path, class, "/%N", 0))))
270 { 417
271 default_magic = "%s/%%L/%%N:%s/%%l/%%N:%s/%%N"; 418 /* Check in the home directory. This is a bit of a hack; let's
272 magic_path = (char *) alloca ((3 * strlen (homedir)) 419 hope one's home directory doesn't contain any %-escapes. */
273 + strlen (default_magic)); 420 || (path = gethomedir (),
274 sprintf (magic_path, default_magic, homedir, homedir, homedir); 421 ((file = search_magic_path (path, class, "%L/%N", 0))
275 } 422 || (file = search_magic_path (path, class, "%N", 0)))))
276 else 423 {
277 { 424 XrmDatabase db = XrmGetFileDatabase (file);
278 default_magic = "%s/%%L/%%N:%s/%%l/%%N:%s/%%N:%s/%%N"; 425 free (file);
279 magic_path = (char *) alloca ((3 * strlen (p)) 426 return db;
280 + strlen (default_magic) 427 }
281 + strlen (homedir)); 428 else
282 sprintf (magic_path, default_magic, p, p, p, homedir);
283 }
284 }
285
286 if (! magic_searchpath_decoder (magic_path, class, path))
287 return NULL; 429 return NULL;
288 430 }
289 db = XrmGetFileDatabase (path); 431
290 return db;
291 }
292 432
293 static XrmDatabase 433 static XrmDatabase
294 get_user_db (display) 434 get_user_db (display)
295 Display *display; 435 Display *display;
296 { 436 {
305 445
306 if (xdefs != NULL) 446 if (xdefs != NULL)
307 db = XrmGetStringDatabase (xdefs); 447 db = XrmGetStringDatabase (xdefs);
308 else 448 else
309 { 449 {
310 char xdefault[MAXPATHLEN]; 450 char *home;
311 451 char *xdefault;
312 gethomedir (xdefault); 452
453 home = gethomedir ();
454 xdefault = (char *) malloc (strlen (home) + sizeof (".Xdefaults"));
455 strcpy (xdefault, home);
313 strcat (xdefault, ".Xdefaults"); 456 strcat (xdefault, ".Xdefaults");
314 db = XrmGetFileDatabase (xdefault); 457 db = XrmGetFileDatabase (xdefault);
458 free (home);
459 free (xdefault);
315 } 460 }
316 461
317 #ifdef XlibSpecificationRelease 462 #ifdef XlibSpecificationRelease
318 #if XlibSpecificationRelease >= 5 463 #if XlibSpecificationRelease >= 5
319 /* Get the screen-specific resources too. */ 464 /* Get the screen-specific resources too. */
332 static XrmDatabase 477 static XrmDatabase
333 get_environ_db () 478 get_environ_db ()
334 { 479 {
335 XrmDatabase db; 480 XrmDatabase db;
336 char *p; 481 char *p;
337 char path[MAXPATHLEN]; 482 char *path = 0, *home = 0, *host = 0;
338 483
339 if ((p = getenv ("XENVIRONMENT")) == NULL) 484 if ((p = getenv ("XENVIRONMENT")) == NULL)
340 { 485 {
341 gethomedir (path); 486 home = gethomedir ();
342 strcat (path, ".Xdefaults-"); 487
343 gethostname (path + strlen (path), MAXPATHLEN - strlen (path)); 488 {
489 int host_size = 100;
490 host = (char *) malloc (host_size);
491
492 for (;;)
493 {
494 host[host_size - 1] = '\0';
495 gethostname (host, host_size - 1);
496 if (strlen (host) < host_size - 1)
497 break;
498 host = (char *) realloc (host, host_size *= 2);
499 }
500 }
501
502 path = (char *) malloc (strlen (home)
503 + sizeof (".Xdefaults-")
504 + strlen (host));
505 sprintf (path, "%s%s%s", home, ".Xdefaults-", host);
344 p = path; 506 p = path;
345 } 507 }
346 508
347 db = XrmGetFileDatabase (p); 509 db = XrmGetFileDatabase (p);
510
511 if (path) free (path);
512 if (home) free (home);
513 if (host) free (host);
514
348 return db; 515 return db;
349 } 516 }
350 517
518 /* External interface. */
519
351 /* Types of values that we can find in a database */ 520 /* Types of values that we can find in a database */
352 521
353 #define XrmStringType "String" /* String representation */ 522 #define XrmStringType "String" /* String representation */
354 XrmRepresentation x_rm_string; /* Quark representation */ 523 XrmRepresentation x_rm_string; /* Quark representation */
355 524
356 /* Load X resources based on the display and a possible -xrm option. */ 525 /* Load X resources based on the display and a possible -xrm option. */
357 526
358 XrmDatabase 527 XrmDatabase
359 x_load_resources (display, xrm_string, myclass) 528 x_load_resources (display, xrm_string, myname, myclass)
360 Display *display; 529 Display *display;
361 char *xrm_string, *myclass; 530 char *xrm_string, *myname, *myclass;
362 { 531 {
363 char *xdefs; 532 char *xdefs;
533 XrmDatabase user_database;
364 XrmDatabase rdb; 534 XrmDatabase rdb;
365 XrmDatabase db; 535 XrmDatabase db;
366 536
367 x_rm_string = XrmStringToQuark (XrmStringType); 537 x_rm_string = XrmStringToQuark (XrmStringType);
368 XrmInitialize (); 538 XrmInitialize ();
369 rdb = XrmGetStringDatabase (""); 539 rdb = XrmGetStringDatabase ("");
540
541 user_database = get_user_db (display);
542
543 /* Figure out what the "customization string" is, so we can use it
544 to decode paths. */
545 if (x_customization_string)
546 free (x_customization_string);
547 x_customization_string
548 = x_get_customization_string (user_database, myname, myclass);
370 549
371 /* Get application system defaults */ 550 /* Get application system defaults */
372 db = get_system_app (myclass); 551 db = get_system_app (myclass);
373 if (db != NULL) 552 if (db != NULL)
374 XrmMergeDatabases (db, &rdb); 553 XrmMergeDatabases (db, &rdb);
382 db = get_user_app (myclass); 561 db = get_user_app (myclass);
383 if (db != NULL) 562 if (db != NULL)
384 XrmMergeDatabases (db, &rdb); 563 XrmMergeDatabases (db, &rdb);
385 564
386 /* get User defaults */ 565 /* get User defaults */
387 db = get_user_db (display); 566 if (user_database != NULL)
388 if (db != NULL) 567 XrmMergeDatabases (user_database, &rdb);
389 XrmMergeDatabases (db, &rdb);
390 568
391 /* Get Environment defaults. */ 569 /* Get Environment defaults. */
392 db = get_environ_db (); 570 db = get_environ_db ();
393 if (db != NULL) 571 if (db != NULL)
394 XrmMergeDatabases (db, &rdb); 572 XrmMergeDatabases (db, &rdb);
402 } 580 }
403 581
404 return rdb; 582 return rdb;
405 } 583 }
406 584
585
407 /* Retrieve the value of the resource specified by NAME with class CLASS 586 /* Retrieve the value of the resource specified by NAME with class CLASS
408 and of type TYPE from database RDB. The value is returned in RET_VALUE. */ 587 and of type TYPE from database RDB. The value is returned in RET_VALUE. */
409 588
410 int 589 int
411 x_get_resource (rdb, name, class, expected_type, ret_value) 590 x_get_resource (rdb, name, class, expected_type, ret_value)
450 return (char *) value.addr; 629 return (char *) value.addr;
451 630
452 return (char *) 0; 631 return (char *) 0;
453 } 632 }
454 633
634 /* Stand-alone test facilities. */
635
455 #ifdef TESTRM 636 #ifdef TESTRM
456 #include <stdio.h> 637
457 #include "arg-list.h" 638 typedef char **List;
639 #define arg_listify(len, list) (list)
640 #define car(list) (*(list))
641 #define cdr(list) (list + 1)
642 #define NIL(list) (! *(list))
643 #define free_arglist(list)
644
645 static List
646 member (elt, list)
647 char *elt;
648 List list;
649 {
650 List p;
651
652 for (p = list; ! NIL (p); p = cdr (p))
653 if (! strcmp (elt, car (p)))
654 return p;
655
656 return p;
657 }
458 658
459 static void 659 static void
460 fatal (msg, prog, x1, x2, x3, x4, x5) 660 fatal (msg, prog, x1, x2, x3, x4, x5)
461 char *msg, *prog; 661 char *msg, *prog;
462 int x1, x2, x3, x4, x5; 662 int x1, x2, x3, x4, x5;
473 main (argc, argv) 673 main (argc, argv)
474 int argc; 674 int argc;
475 char **argv; 675 char **argv;
476 { 676 {
477 Display *display; 677 Display *display;
478 char *displayname, *resource_string, *class; 678 char *displayname, *resource_string, *class, *name;
479 XrmDatabase xdb; 679 XrmDatabase xdb;
480 List *arg_list, *lp; 680 List arg_list, lp;
481 681
482 arg_list = arg_listify (argc, argv); 682 arg_list = arg_listify (argc, argv);
483 683
484 lp = member ("-d", arg_list); 684 lp = member ("-d", arg_list);
485 if (!NIL (lp)) 685 if (!NIL (lp))
497 if (! NIL (lp)) 697 if (! NIL (lp))
498 class = car (cdr (lp)); 698 class = car (cdr (lp));
499 else 699 else
500 class = "Emacs"; 700 class = "Emacs";
501 701
702 lp = member ("-n", arg_list);
703 if (! NIL (lp))
704 name = car (cdr (lp));
705 else
706 name = "emacs";
707
502 free_arglist (arg_list); 708 free_arglist (arg_list);
503
504
505 709
506 if (!(display = XOpenDisplay (displayname))) 710 if (!(display = XOpenDisplay (displayname)))
507 fatal ("Can't open display '%s'\n", XDisplayName (displayname)); 711 fatal ("Can't open display '%s'\n", XDisplayName (displayname));
508 712
509 xdb = x_load_resources (display, resource_string, class); 713 xdb = x_load_resources (display, resource_string, name, class);
510 714
511 #if 0
512 /* In a real program, you'd want to also do this: */ 715 /* In a real program, you'd want to also do this: */
513 display->db = xdb; 716 display->db = xdb;
514 #endif
515 717
516 while (1) 718 while (1)
517 { 719 {
518 char line[90]; 720 char query_name[90];
519 721 char query_class[90];
520 printf ("String: "); 722
521 gets (line); 723 printf ("Name: ");
522 if (strlen (line)) 724 gets (query_name);
725
726 if (strlen (query_name))
523 { 727 {
524 char *value = x_get_string_resource (xdb, line, class); 728 char *value;
729
730 printf ("Class: ");
731 gets (query_class);
732
733 value = x_get_string_resource (xdb, query_name, query_class);
525 734
526 if (value != NULL) 735 if (value != NULL)
527 printf ("\t%s: %s\n\n", line, value); 736 printf ("\t%s(%s): %s\n\n", query_name, query_class, value);
528 else 737 else
529 printf ("\tNo Value.\n\n"); 738 printf ("\tNo Value.\n\n");
530 } 739 }
531 else 740 else
532 break; 741 break;