Bug Summary

File:src/ResConfig.c
Location:line 265, column 3
Description:Null pointer argument in call to string length function

Annotated Source Code

1/*
2
3Copyright 1987, 1988, 1998 The Open Group
4
5Permission to use, copy, modify, distribute, and sell this software and its
6documentation for any purpose is hereby granted without fee, provided that
7the above copyright notice appear in all copies and that both that
8copyright notice and this permission notice appear in supporting
9documentation.
10
11The above copyright notice and this permission notice shall be included in
12all copies or substantial portions of the Software.
13
14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
21Except as contained in this notice, the name of The Open Group shall not be
22used in advertising or otherwise to promote the sale, use or other dealings
23in this Software without prior written authorization from The Open Group.
24
25*/
26/*****************************************************************
27
28(C) COPYRIGHT International Business Machines Corp. 1992,1997
29 All Rights Reserved
30
31Permission is hereby granted, free of charge, to any person obtaining a copy
32of this software and associated documentation files (the "Software"), to deal
33in the Software without restriction, including without limitation the rights
34to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
35copies of the Software.
36
37The above copyright notice and this permission notice shall be included in
38all copies or substantial portions of the Software.
39
40THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
41IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
42FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
43THE IBM CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING,
44BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL DAMAGES, OR OTHER LIABILITY,
45WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
46IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
47
48Except as contained in this notice, the name of the IBM Corporation shall
49not be used in advertising or otherwise to promote the sale, use or other
50dealings in this Software without prior written authorization from the IBM
51Corporation.
52
53******************************************************************/
54
55#ifdef HAVE_CONFIG_H1
56#include <config.h>
57#endif
58#include "Intrinsic.h"
59#include "IntrinsicI.h"
60#include "Core.h"
61#include "CoreP.h"
62#include "ShellP.h"
63#include "StringDefs.h"
64#include "ResConfigP.h"
65#include <X11/Xatom.h>
66#include <stdio.h>
67#include <stdlib.h>
68
69#define MAX_BUFFER512 512
70
71static void _search_child(Widget, char *, char *, char *, char *, char, char *);
72static void _set_and_search(Widget, char *, char *, char *, char *, char , char *);
73static int _locate_children(Widget, Widget **);
74
75/*
76 * NAME: _set_resource_values
77 *
78 * FUNCTION:
79 * This function sets the value on the widget. It must first determine
80 * if the last part is a valid resource for that widget. (eg.
81 * labelString is a valid resource for label but not for bulletin board)
82 * It must also add the resource to the application's resource database
83 * and then query it out using specific resource strings that it builds
84 * from the widget information. This ensures that a customizing tool
85 * on-the-fly paradigm is followed: an application that is
86 * instantaneously updated should look the same as one that is restarted
87 * and uses the .Xdefaults file.
88 *
89 * PARAMETERS:
90 * w the widget to match
91 * resource the resource string to be matched
92 * value the value to be set
93 * last_part the last resource part (e.g. *background)
94 *
95 * RETURN VALUES: void
96 *
97 * ERRORS: none
98 */
99static void
100_set_resource_values (
101 Widget w,
102 char *resource,
103 char *value,
104 char *last_part)
105{
106 XrmDatabase db = NULL((void*)0);
107 char *resource_name = NULL((void*)0);
108 char *resource_class = NULL((void*)0);
109 char *return_type;
110 XrmValue return_value;
111 char *resource_value;
112 Widget cur = w;
113 char *temp;
114 XtResourceList resources_return = NULL((void*)0);
115 Cardinal num_resources_return = 0;
116 Cardinal res_index;
117 Boolean found_resource = False0;
118 Display *dpy;
119 XrmDatabase tmp_db;
120
121 if (!XtIsWidget (w)(((Object)(w))->object.widget_class->core_class.class_inited
& 0x04)
)
37
Taking false branch
122 dpy = XtDisplay (w->core.parent)(((w->core.parent)->core.screen)->display);
123 else
124 dpy = XtDisplay (w)(((w)->core.screen)->display);
125 tmp_db = XtDatabase(dpy);
126
127 /*
128 * get a list of all the valid resources for this widget
129 */
130 XtGetResourceList (w->core.widget_class,
131 &resources_return, &num_resources_return);
132
133 /*
134 * try to match the last_part of the resource string with
135 * a resource in this resource list
136 */
137 for (res_index=0; res_index<num_resources_return; res_index++) {
38
Assuming 'res_index' is < 'num_resources_return'
39
Loop condition is true. Entering loop body
138 if ((strcmp (last_part,
40
Taking true branch
139 resources_return[res_index].resource_name) == 0) ||
140 (strcmp (last_part,
141 resources_return[res_index].resource_class) == 0)) {
142 found_resource = True1;
143 break;
41
Execution continues on line 152
144 }
145 }
146
147 /*
148 * if resource is not a valid resource for this widget
149 * or the resource name or class are NULL
150 * then exit this function
151 */
152 if (!found_resource
42
Taking false branch
153 || !resources_return[res_index].resource_name
154 || !resources_return[res_index].resource_class) {
155 XtFree ((char *) resources_return);
156 return;
157 }
158
159 /*
160 * build the full resource name and class specifications so
161 * that you can query the resource database
162 * eg: .app.button1.foreground
163 * .App.XmPushButton.Foreground
164 */
165 while (cur != NULL((void*)0)) {
43
Loop condition is true. Entering loop body
48
Assuming 'cur' is equal to null
49
Loop condition is false. Execution continues on line 214
166 /*
167 * create resource name string
168 */
169 if (resource_name) {
44
Taking false branch
170 XtAsprintf (&temp, ".%s%s", cur->core.name, resource_name);
171 XtFree (resource_name);
172 } else if (!XtIsWidget (cur)(((Object)(cur))->object.widget_class->core_class.class_inited
& 0x04)
|| !cur->core.name) {
45
Taking false branch
173 cur = XtParent(cur)((cur)->core.parent);
174 continue;
175 } else {
176 XtAsprintf (&temp, ".%s", cur->core.name);
177 }
178 resource_name = temp;
179
180 /*
181 * create resource class string
182 */
183 if ((XtIsTopLevelShell (cur)(((Object)(cur))->object.widget_class->core_class.class_inited
& 0x80)
) && (XtParent (cur)((cur)->core.parent) == NULL((void*)0))) {
184 ApplicationShellWidget top =
185 (ApplicationShellWidget) (cur);
186
187 if (resource_class) {
188 XtAsprintf (&temp, ".%s%s",
189 top->application.class, resource_class);
190 } else {
191 XtAsprintf (&temp, ".%s",
192 top->application.class);
193 }
194 } else {
195 if (resource_class) {
46
Taking false branch
196 XtAsprintf (&temp, ".%s%s",
197 cur->core.widget_class->core_class.class_name,
198 resource_class);
199 } else {
200 XtAsprintf (&temp, ".%s",
201 cur->core.widget_class->core_class.class_name);
202 }
203 }
204 if (resource_class != NULL((void*)0))
47
Taking false branch
205 XtFree (resource_class);
206 resource_class = temp;
207
208 cur = XtParent(cur)((cur)->core.parent);
209 }
210
211 /*
212 * add the resource name to the end of the resource name string
213 */
214 XtAsprintf (&temp, "%s.%s", resource_name,
215 resources_return[res_index].resource_name);
216 if (resource_name != NULL((void*)0))
50
Assuming 'resource_name' is equal to null
51
Taking false branch
217 XtFree (resource_name);
218 resource_name = temp;
219
220 /*
221 * add the resource class to the end of the resource class string
222 */
223 XtAsprintf (&temp, "%s.%s", resource_class,
224 resources_return[res_index].resource_class);
225 if (resource_class != NULL((void*)0))
52
Assuming 'resource_class' is equal to null
53
Taking false branch
226 XtFree (resource_class);
227 resource_class = temp;
228
229#ifdef DEBUG
230 fprintf (stderr__stderrp, "resource_name = %s\n", resource_name);
231 fprintf (stderr__stderrp, "resource_class = %s\n", resource_class);
232#endif
233
234 /*
235 * put the resource and its value in a resource database and
236 * then query it back out again using the specific name and
237 * class resource strings that were built above. This is
238 * necessary to maintain a precedence similar to the .Xdefaults
239 * file
240 */
241 XrmPutStringResource (&db, resource, value);
242 XrmMergeDatabases (db, &tmp_db);
243 XrmGetResource (tmp_db, resource_name, resource_class,
244 &return_type, &return_value);
245 if (return_type)
54
Assuming 'return_type' is non-null
55
Taking true branch
246 resource_value = XtNewString (return_value.addr)((return_value.addr) != ((void*)0) ? (__builtin___strcpy_chk (
XtMalloc((unsigned)strlen(return_value.addr) + 1), return_value
.addr, __builtin_object_size (XtMalloc((unsigned)strlen(return_value
.addr) + 1), 2 > 1 ? 1 : 0))) : ((void*)0))
;
56
Null pointer value stored to 'resource_value'
247 else
248 resource_value = XtNewString (value)((value) != ((void*)0) ? (__builtin___strcpy_chk (XtMalloc((unsigned
)strlen(value) + 1), value, __builtin_object_size (XtMalloc((
unsigned)strlen(value) + 1), 2 > 1 ? 1 : 0))) : ((void*)0)
)
;
249
250#ifdef DEBUG
251 fprintf (stderr__stderrp,
252 "Apply:\n\twidget = %s\n\tlast_part = %s\n\tvalue = %s\n",
253 (w->core.name == NULL((void*)0)) ? "NULL" : w->core.name,
254 resources_return[res_index].resource_name,
255 resource_value);
256#endif
257 /*
258 * use XtVaSetValues with XtVaTypedArg to convert the value of
259 * type String the the same type as the resource (last_part).
260 * Then set the value.
261 */
262 XtVaSetValues (w,
263 XtVaTypedArg"XtVaTypedArg", resources_return[res_index].resource_name,
264 XtRString((char*)&XtStrings[1797]), resource_value,
265 strlen (resource_value) + 1,
57
Null pointer argument in call to string length function
266 NULL((void*)0));
267
268 XtFree ((char *) resources_return);
269 XtFree (resource_name);
270 XtFree (resource_class);
271 XtFree (resource_value);
272}
273
274/*
275 * NAME: _apply_values_to_children
276 *
277 * FUNCTION:
278 * Once the resource string matches the value must be applied to
279 * all children if applicable. (eg. App*Form.background must apply
280 * background to all children of the Form widget)
281 *
282 * PARAMETERS:
283 * w the widget to match
284 * remainder the part of the resource string left over
285 * resource the resource string to be matched
286 * value the value to be set
287 * last_token the last * or . before the final resoruce part
288 * last_part the last resource part (e.g. *background)
289 *
290 * RETURN VALUES: void
291 *
292 * ERRORS: none
293 */
294static void
295_apply_values_to_children (
296 Widget w,
297 char *remainder,
298 char *resource,
299 char *value,
300 char last_token,
301 char *last_part)
302{
303 int i;
304 int num_children;
305 Widget *children;
306
307 /*
308 * Recursively search through the children
309 */
310 num_children = _locate_children (w, &children);
311
312 for (i=0; i<num_children; i++) {
28
Assuming 'i' is < 'num_children'
29
Loop condition is true. Entering loop body
30
Assuming 'i' is < 'num_children'
31
Loop condition is true. Entering loop body
32
Assuming 'i' is < 'num_children'
33
Loop condition is true. Entering loop body
34
Assuming 'i' is < 'num_children'
35
Loop condition is true. Entering loop body
313
314#ifdef DEBUG
315 if (XtIsWidget (children[i])(((Object)(children[i]))->object.widget_class->core_class
.class_inited & 0x04)
&& XtIsWidget (w)(((Object)(w))->object.widget_class->core_class.class_inited
& 0x04)
)
316 fprintf (stderr__stderrp, "searching child %s of parent %s\n",
317 children[i]->core.name, w->core.name);
318 else
319 fprintf (stderr__stderrp,"searching child (NULL) of parent %s\n",
320 w->core.name);
321 if (!XtIsWidget (children[i])(((Object)(children[i]))->object.widget_class->core_class
.class_inited & 0x04)
)
322 fprintf (stderr__stderrp, "children[%d] is NOT a widget\n", i);
323 if (!XtIsWidget (w)(((Object)(w))->object.widget_class->core_class.class_inited
& 0x04)
)
324 fprintf (stderr__stderrp, "w is NOT a widget\n");
325#endif
326
327 _set_resource_values (children[i], resource, value, last_part);
36
Calling '_set_resource_values'
328 _apply_values_to_children (children[i], remainder,
329 resource, value, last_token, last_part);
330 }
331
332 XtFree ((char *)children);
333}
334
335/*
336 * NAME: _search_child
337 *
338 * FUNCTION:
339 * descends through each child of the tree
340 *
341 * PARAMETERS:
342 * w the widget whose children are to be searched
343 * indx index into the resource string
344 * remainder the remaining part of the resource string
345 * resource the resource string to be matched
346 * value the value to be applied
347 * last_token the last * or . before the final resoruce part
348 * last_part the last resource part (e.g. *background)
349 *
350 * RETURN VALUES: none
351 *
352 * ERRORS: none
353 */
354static void
355_search_child (
356 Widget w,
357 char *indx,
358 char *remainder,
359 char *resource,
360 char *value,
361 char last_token,
362 char *last_part)
363{
364 int i;
365 int num_children;
366 Widget *children;
367
368 /*
369 * Recursively search through the children
370 */
371 num_children = _locate_children (w, &children);
372 for (i=0; i<num_children; i++) {
373 _set_and_search (children[i], indx, remainder, resource,
374 value, last_token, last_part);
375 }
376
377 XtFree ((char *)children);
378}
379
380/*
381 * NAME: _get_part
382 *
383 * FUNCTION:
384 * This routine will return the token and following part of the resource
385 * when given the current index it will update the index accordingly
386 *
387 * PARAMETERS:
388 * remainder the part of the resource string left over
389 * indx the index into the resource string
390 * part the parsed off part of the resource string
391 *
392 * RETURN VALUES:
393 * char the token (* or . or ?) preceding the resource part
394 * indx the index into the resource string
395 * part the parsed off part of the resource string
396 *
397 * ERRORS: none
398 */
399/* ARGSUSED */
400static char
401_get_part (
402 char *remainder,
403 char **indx,
404 char **part)
405{
406 char buffer[MAX_BUFFER512];
407 char *buf_ptr;
408 char token = **indx;
409 int i = 0;
410
411 /*
412 * copy the remainder part into the buffer
413 */
414 buf_ptr = buffer;
415 (*indx)++; /* get rid of the token */
416 while (**indx && (**indx != '.') && (**indx != '*')) {
417 *buf_ptr++ = *(*indx)++;
418 if (++i >= MAX_BUFFER512 - 1)
419 break;
420 }
421 *buf_ptr = '\0';
422
423 *part = XtNewString (buffer)((buffer) != ((void*)0) ? (__builtin___strcpy_chk (XtMalloc((
unsigned)strlen(buffer) + 1), buffer, __builtin_object_size (
XtMalloc((unsigned)strlen(buffer) + 1), 2 > 1 ? 1 : 0))) :
((void*)0))
; /* return a new string to part */
424
425 if (strcmp (*indx, "") == 0)
426 *indx = NULL((void*)0);
427
428 return (token); /* return the token */
429}
430
431/*
432 * NAME: _match_resource_to_widget
433 *
434 * FUNCTION:
435 * This function matches the resource part to the widget name or class
436 *
437 * PARAMETERS:
438 * w the widget to match
439 * part the parsed off part of the resource string
440 *
441 * RETURN VALUES:
442 * Boolean true if a match occurs
443 *
444 * ERRORS: none
445 */
446static Boolean
447_match_resource_to_widget (
448 Widget w,
449 char *part)
450{
451 /*
452 * Match any widget at this level if the ? is used
453 */
454 if (strcmp (part, "?") == 0)
455 return (True1);
456
457 /*
458 * if the object is really a widget then its name can be matched
459 * otherwise only use its class. Note that if you try to reference
460 * a widget name when the object is not a widget, you may get a
461 * core dump from an invalid pointer reference.
462 */
463 if (XtIsWidget (w)(((Object)(w))->object.widget_class->core_class.class_inited
& 0x04)
) {
464 if ((strcmp (w->core.name, part) == 0) ||
465 (strcmp (w->core.widget_class->core_class.class_name,
466 part) == 0))
467 return (True1);
468 else
469 return (False0);
470 } else {
471 if ((strcmp (w->core.widget_class->core_class.class_name,
472 part) == 0))
473 return (True1);
474 else
475 return (False0);
476 }
477}
478
479/*
480 * NAME: _set_and_search
481 *
482 * FUNCTION:
483 * The algorithm to search the widget tree and apply a resource string
484 *
485 * PARAMETERS:
486 * w the widget to match
487 * indx the index into the resource string
488 * remainder the part of the resource string left over
489 * resource the resource string to be matched
490 * value the value to be set
491 * last_token the last * or . before the final resoruce part
492 * last_part the last resource part (e.g. *background)
493 *
494 * RETURN VALUES: none
495 *
496 * ERRORS: none
497 *
498 * ALGORITHM:
499 * loop (look at all children)
500 * if (resource segment and current widget match)
501 * if '.'
502 * if at end of resource string
503 * set values ( .=over all children
504 * *=this widget only)
505 * else
506 * descend the widget tree
507 * and parse off resource segment
508 * exit the loop
509 * if '*'
510 * if at end of resource string
511 * set values ( .=over all children
512 * *=this widget only)
513 * descend and parse
514 * else
515 * if '.'
516 * continue looping
517 * if '*'
518 * descend but don't parse
519 * continue looping
520 * end loop
521 *
522 * NOTE: the _set_resource_values routine will not allow a value to be
523 * set on a resource against the rules of the resource database manager
524 */
525static void
526_set_and_search (
527 Widget w,
528 char *indx,
529 char *remainder,
530 char *resource,
531 char *value,
532 char last_token,
533 char *last_part)
534{
535 char *part;
536 char *local_index = indx;
537 char token;
538
539 /*
540 * parse off one part, return token and the new index
541 */
542 token = _get_part (remainder, &local_index, &part);
543
544 if (_match_resource_to_widget (w, part)) {
21
Taking true branch
545 if (token == '.') {
22
Taking false branch
546 if (local_index == NULL((void*)0)) {
547 if (last_token == '.') {
548 _set_resource_values (w, resource,
549 value, last_part);
550 } else if (last_token == '*') {
551 _set_resource_values (w, resource,
552 value, last_part);
553 _apply_values_to_children (w,
554 remainder, resource, value,
555 last_token, last_part);
556 }
557 } else
558 _search_child (w, local_index, remainder,
559 resource, value, last_token, last_part);
560 return;
561 }
562 if (token == '*') {
23
Taking true branch
563 if (local_index == NULL((void*)0)) {
24
Taking true branch
564 if (last_token == '.') {
25
Taking false branch
565 _set_resource_values (w, resource,
566 value, last_part);
567 } else if (last_token == '*') {
26
Taking true branch
568 _set_resource_values (w, resource,
569 value, last_part);
570 _apply_values_to_children ( w,
27
Calling '_apply_values_to_children'
571 remainder, resource, value,
572 last_token, last_part);
573 }
574 } else
575 _search_child (w, local_index, remainder,
576 resource, value, last_token, last_part);
577 }
578 } else {/* if the widget name and class don't match the part */
579 /* if (token == '.') just continue looping */
580
581 if (token == '*') {
582 _search_child (w, indx, remainder, resource, value,
583 last_token, last_part);
584 }
585 }
586
587 XtFree (part);
588}
589
590/*
591 * NAME: _get_last_part
592 *
593 * FUNCTION:
594 * This routine will parse off the last segment of a resource string
595 * and its token and return them. the remainder of resource is also
596 * returned. strcoll is used to guarantee no problems with
597 * international strings.
598 *
599 * PARAMETERS:
600 * remainder the part of the resource string left over
601 * part the parsed off part of the resource string
602 *
603 * RETURN VALUES:
604 * char the token (* or . or ?) preceding the resource part
605 * remainder the part of the resource string left over
606 * part the parsed off part of the resource string
607 *
608 * ERRORS: none
609 */
610static char
611_get_last_part (
612 char *remainder,
613 char **part)
614{
615 char *loose, *tight;
616
617 loose = strrchr (remainder, '*');
618 tight = strrchr (remainder, '.');
619
620 if ((loose == NULL((void*)0)) && (tight == NULL((void*)0))) {
621 *part = XtNewString (remainder)((remainder) != ((void*)0) ? (__builtin___strcpy_chk (XtMalloc
((unsigned)strlen(remainder) + 1), remainder, __builtin_object_size
(XtMalloc((unsigned)strlen(remainder) + 1), 2 > 1 ? 1 : 0
))) : ((void*)0))
;
622 return ('.');
623 }
624 if ((loose == NULL((void*)0)) || (tight && (strcoll (loose, tight) < 0))) {
625 *tight++ = '\0'; /* shorten the remainder string */
626 *part = XtNewString (tight)((tight) != ((void*)0) ? (__builtin___strcpy_chk (XtMalloc((unsigned
)strlen(tight) + 1), tight, __builtin_object_size (XtMalloc((
unsigned)strlen(tight) + 1), 2 > 1 ? 1 : 0))) : ((void*)0)
)
;
627 return ('.');
628 }
629 if ((tight == NULL((void*)0)) || (loose && (strcoll (tight, loose) < 0))) {
630 *loose++ = '\0';
631 *part = XtNewString (loose)((loose) != ((void*)0) ? (__builtin___strcpy_chk (XtMalloc((unsigned
)strlen(loose) + 1), loose, __builtin_object_size (XtMalloc((
unsigned)strlen(loose) + 1), 2 > 1 ? 1 : 0))) : ((void*)0)
)
;
632 return ('*');
633 }
634 *part = NULL((void*)0);
635
636 return ('0'); /* error - return 0 */
637}
638
639/*
640 * NAME: _search_widget_tree
641 *
642 * FUNCTION:
643 * This function tries to match a resource string to the widgets
644 * it applies to. The functions it invokes to do this then set
645 * the value for that resource to each widget.
646 *
647 * The resource string has to be parsed into the following format:
648 * resource = App*Form*button1.background
649 * remainder = *Form*button1
650 * last_part = background last_token = .
651 * As the widget tree is recursively descended, these variables are
652 * passed. The remainder is parsed at each level in the widget
653 * tree as the _set_and_search function attempts to match
654 * the resource part (eg. part = Form token = *) to a widget. When
655 * the entire resource string has been matched, the _set_resource_values
656 * functions is called to apply the value to the widget or widgets.
657 *
658 * PARAMETERS:
659 * w a widget from whose toplevel shell ancestor
660 * the search will start
661 * resource the resource string to match
662 * value the value to apply
663 *
664 * RETURN VALUES: none
665 *
666 * ERRORS: none
667 */
668static void
669_search_widget_tree (
670 Widget w,
671 char *resource,
672 char *value)
673{
674 Widget parent = w;
675 char *last_part;
676 char *remainder = NULL((void*)0);
677 char last_token;
678 char *indx, *copy;
679 char *loose, *tight;
680 int loose_len, tight_len;
681
682 /*
683 * Find the root of the tree given any widget
684 */
685 while (XtParent(parent)((parent)->core.parent) != NULL((void*)0)) {
13
Loop condition is false. Execution continues on line 700
686 parent = XtParent(parent)((parent)->core.parent);
687 }
688#ifdef DEBUG
689 if (XtIsWidget (w)(((Object)(w))->object.widget_class->core_class.class_inited
& 0x04)
&& XtIsWidget (parent)(((Object)(parent))->object.widget_class->core_class.class_inited
& 0x04)
)
690 fprintf (stderr__stderrp, "widget = %s parent = %s\n",
691 w->core.name, parent->core.name);
692 else
693 fprintf (stderr__stderrp, "widget = NULL parent = NULL\n");
694#endif
695
696 /*
697 * parse off the Class name that was prepended to this string in
698 * a customizing tool
699 */
700 loose = strchr (resource, '*');
701 tight = strchr (resource, '.');
702 if ((loose == NULL((void*)0)) && (tight == NULL((void*)0)))
14
Assuming 'loose' is not equal to null
703 return;
704
705 loose_len = (loose) ? strlen (loose) : 0;
15
'?' condition is true
706 tight_len = (tight) ? strlen (tight) : 0;
16
Assuming 'tight' is null
17
'?' condition is false
707
708 if ((loose == NULL((void*)0)) || (tight_len > loose_len))
18
Taking false branch
709 remainder = XtNewString (tight)((tight) != ((void*)0) ? (__builtin___strcpy_chk (XtMalloc((unsigned
)strlen(tight) + 1), tight, __builtin_object_size (XtMalloc((
unsigned)strlen(tight) + 1), 2 > 1 ? 1 : 0))) : ((void*)0)
)
;
710 else if ((tight == NULL((void*)0)) || (loose_len > tight_len))
711 remainder = XtNewString (loose)((loose) != ((void*)0) ? (__builtin___strcpy_chk (XtMalloc((unsigned
)strlen(loose) + 1), loose, __builtin_object_size (XtMalloc((
unsigned)strlen(loose) + 1), 2 > 1 ? 1 : 0))) : ((void*)0)
)
;
712
713 /*
714 * Parse last segment off of resource string, (eg. background, font,
715 * etc.)
716 */
717 last_token = _get_last_part (remainder, &last_part);
718 /*
719 * this case covers resources of only one level (eg. *background)
720 */
721 if (remainder[0] == 0) {
19
Taking false branch
722 _set_resource_values (w, resource, value, last_part);
723 if (last_token == '*')
724 _apply_values_to_children (parent, remainder, resource,
725 value, last_token, last_part);
726 /*
727 * all other resource strings are recursively applied to the widget tree.
728 * Prepend a '.' to the remainder string if there is no leading token.
729 */
730 } else {
731 if (remainder[0] != '*' && remainder[0] != '.') {
732 XtAsprintf (&copy, ".%s", remainder);
733 XtFree (remainder);
734 remainder = copy;
735 }
736 indx = remainder;
737 _set_and_search (parent, indx, remainder, resource, value,
20
Calling '_set_and_search'
738 last_token, last_part);
739 }
740
741 XtFree (remainder);
742 XtFree (last_part);
743}
744
745/*
746 * NAME: _locate_children
747 *
748 * FUNCTION:
749 * returns a list of all of a widget's children
750 *
751 * PARAMETERS:
752 * w the parent to search for its children
753 * children the list of children that is created
754 * normal flag for normal children
755 * popup flag for popup children
756 *
757 * RETURN VALUES:
758 * int the number of children
759 * children the list of children found
760 *
761 * ERRORS: none
762 */
763static int
764_locate_children (
765 Widget parent,
766 Widget **children)
767{
768 CompositeWidget comp = (CompositeWidget) parent;
769 Cardinal i;
770 int num_children = 0;
771 int current = 0;
772
773 /*
774 * count the number of children
775 */
776 if (XtIsWidget (parent)(((Object)(parent))->object.widget_class->core_class.class_inited
& 0x04)
)
777 num_children += parent->core.num_popups;
778 if (XtIsComposite (parent)(((Object)(parent))->object.widget_class->core_class.class_inited
& 0x08)
)
779 num_children += comp->composite.num_children;
780 if (num_children == 0) {
781 *children = NULL((void*)0);
782 return (0);
783 }
784
785 *children = (Widget *)
786 XtMalloc ((Cardinal) sizeof(Widget) * num_children);
787
788 if (XtIsComposite (parent)(((Object)(parent))->object.widget_class->core_class.class_inited
& 0x08)
) {
789 for (i=0; i<comp->composite.num_children; i++) {
790 (*children)[current] = comp->composite.children[i];
791 current++;
792 }
793 }
794
795 if (XtIsWidget (parent)(((Object)(parent))->object.widget_class->core_class.class_inited
& 0x04)
) {
796 for (i=0; i<parent->core.num_popups; i++) {
797 (*children)[current] = comp->core.popup_list[i];
798 current++;
799 }
800 }
801
802 return (num_children);
803}
804
805#ifdef DEBUG
806/*
807 * NAME: dump_widget_tree
808 *
809 * FUNCTION:
810 * recursively printout entire widget tree
811 *
812 * PARAMETERS:
813 * w the widget to match
814 * indent the amount to indent each line
815 *
816 * RETURN VALUES: void
817 *
818 * ERRORS: none
819 */
820static void
821dump_widget_tree (
822 Widget w,
823 int indent)
824{
825 int i,j;
826 int num_children;
827 Widget *children;
828
829 /*
830 * Recursively search through the children
831 */
832 num_children = _locate_children (w, &children);
833 indent += 2;
834 for (i=0; i<num_children; i++) {
835 if (children[i] != NULL((void*)0)) {
836 for (j=0; j<indent; j++)
837 fprintf (stderr__stderrp, " ");
838 if (XtIsWidget (children[i])(((Object)(children[i]))->object.widget_class->core_class
.class_inited & 0x04)
) {
839 fprintf (stderr__stderrp, "(%s)\t",children[i]->core.name);
840 fprintf (stderr__stderrp, "(%s)\n",
841 children[i]->core.widget_class->core_class.class_name);
842 } else {
843 fprintf (stderr__stderrp, "(NULL)\t");
844 fprintf (stderr__stderrp, "(%s)\n",
845 children[i]->core.widget_class->core_class.class_name);
846 }
847 }
848 dump_widget_tree (children[i], indent);
849 }
850
851 XtFree ((char *)children);
852}
853#endif
854
855/*
856 * NAME: _XtResourceConfiguationEH
857 *
858 * FUNCTION:
859 * This function is the event handler for the on-the-fly communication
860 * with a resource customization tool. This event handler must be
861 * registered for the toplevel shell of each app. This is best done
862 * in the _XtCreatePopupShell and _XtAppCreateShell functions in Xt's
863 * Create.c source file.
864 *
865 * The property used to communicate with a customizing tool is
866 * placed on the toplevel shell window of the application. The
867 * customizing tool places a property on this window which causes
868 * this event handler to be invoked via the PropertyNotify event.
869 * This event handler reads the property and then deletes it from
870 * the server. The contents of the property are a resource string
871 * and value. The event handler then calls functions to walk the
872 * applications widget tree, determining which widgets are affected
873 * by the resource string, and then applying the value with XtSetValues.
874 *
875 * PARAMETERS:
876 * w the widget that invoked this event handler
877 * client_data not used
878 * event the event structure
879 *
880 * RETURN VALUES: none
881 *
882 * ERRORS: none
883 */
884/* ARGSUSED */
885void
886_XtResourceConfigurationEH (
887 Widget w,
888 XtPointer client_data,
889 XEvent *event)
890{
891 Atom actual_type;
892 int actual_format;
893 unsigned long nitems;
894 unsigned long leftover;
895 char *data = NULL((void*)0);
896 unsigned long resource_len;
897 char *data_ptr;
898 char *resource;
899 char *value;
900#ifdef DEBUG
901 int indent = 0;
902#endif
903 XtPerDisplay pd;
904
905#ifdef DEBUG
906 fprintf (stderr__stderrp, "in _XtResourceConfiguationEH atom = %d\n",event->xproperty.atom);
907 fprintf (stderr__stderrp, " window = %x\n", XtWindow (w)((w)->core.window));
908 if (XtIsWidget (w)(((Object)(w))->object.widget_class->core_class.class_inited
& 0x04)
)
909 fprintf (stderr__stderrp, " widget = %x name = %s\n", w, w->core.name);
910#endif
911
912 pd = _XtGetPerDisplay (XtDisplay (w)(((w)->core.screen)->display));
913
914 /*
915 * The window on which a customizing tool places the property
916 * is determined at this point. It should be the applications
917 * toplevel shell window.
918 *
919 * A customizing tool sends a "ping" to the application on
920 * the RCM_INIT property. The application answers the ping
921 * by deleting the property.
922 */
923 if (event->xproperty.atom == pd->rcm_init) {
1
Taking false branch
924 XDeleteProperty (XtDisplay(w)(((w)->core.screen)->display), XtWindow (w)((w)->core.window), pd->rcm_init);
925
926#ifdef DEBUG
927 if (XtIsWidget (w)(((Object)(w))->object.widget_class->core_class.class_inited
& 0x04)
)
928 fprintf (stderr__stderrp, "%s\n", w->core.name);
929 else
930 fprintf (stderr__stderrp, "NULL name\n");
931 dump_widget_tree(w, indent);
932
933 fprintf (stderr__stderrp, "answer ping\n");
934#endif
935 }
936
937 /*
938 * This event handler ignores any property notify events that
939 * are not RCM_INIT or RCM_DATA
940 */
941 if (event->xproperty.atom != pd->rcm_data)
2
Taking false branch
942 return;
943
944 /*
945 * Retrieve the data from the property
946 */
947#ifdef DEBUG
948 fprintf (stderr__stderrp, "receiving RCM_DATA property\n");
949#endif
950 if (XGetWindowProperty (XtDisplay(w)(((w)->core.screen)->display),
5
Taking true branch
951 XtWindow (w)((w)->core.window),
952 pd->rcm_data, 0L, 8192L,
953 TRUE1, XA_STRING((Atom) 31),
954 &actual_type, &actual_format, &nitems, &leftover,
955 (unsigned char **)&data ) == Success0 && actual_type == XA_STRING((Atom) 31)
3
Assuming 'actual_type' is equal to 31
956 && actual_format == 8) {
4
Assuming 'actual_format' is equal to 8
957 /*
958 * data format is:
959 *
960 * resource_length, resource, value
961 *
962 * convert the resource_length to a long, skip over it, put a
963 * zero byte at the end of the resource, and pick off the
964 * resource and value fields.
965 */
966 if (data) {
6
Assuming 'data' is non-null
7
Taking true branch
967 char *data_end = data + nitems;
968 char *data_value;
969
970 resource_len = strtoul (data, &data_ptr, 10);
971
972 if (data_ptr != (char *) data) {
8
Assuming 'data_ptr' is not equal to 'data'
9
Taking true branch
973 data_ptr++;
974 data_value = data_ptr + resource_len;
975 } else /* strtoul failed to convert a number */
976 data_ptr = data_value = NULL((void*)0);
977
978 if (data_value > data_ptr && data_value < data_end) {
10
Assuming 'data_value' is > 'data_ptr'
11
Taking true branch
979 *data_value++ = '\0';
980
981 resource = XtNewString (data_ptr)((data_ptr) != ((void*)0) ? (__builtin___strcpy_chk (XtMalloc
((unsigned)strlen(data_ptr) + 1), data_ptr, __builtin_object_size
(XtMalloc((unsigned)strlen(data_ptr) + 1), 2 > 1 ? 1 : 0)
)) : ((void*)0))
;
982 value = XtNewString (data_value)((data_value) != ((void*)0) ? (__builtin___strcpy_chk (XtMalloc
((unsigned)strlen(data_value) + 1), data_value, __builtin_object_size
(XtMalloc((unsigned)strlen(data_value) + 1), 2 > 1 ? 1 : 0
))) : ((void*)0))
;
983#ifdef DEBUG
984 fprintf (stderr__stderrp, "resource_len=%d\n",
985 resource_len);
986 fprintf (stderr__stderrp, "resource = %s\t value = %s\n",
987 resource, value);
988#endif
989 /*
990 * descend the application widget tree and
991 * apply the value to the appropriate widgets
992 */
993 _search_widget_tree (w, resource, value);
12
Calling '_search_widget_tree'
994
995 XtFree (resource);
996 XtFree (value);
997 }
998 }
999 }
1000
1001 if (data)
1002 XFree ((char *)data);
1003}