Bug Summary

File:Actions.c
Location:line 484, column 4
Description:Assigned value is garbage or undefined

Annotated Source Code

1/*
2 * Copyright (c) 1998 by The XFree86 Project, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
18 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
19 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 * SOFTWARE.
21 *
22 * Except as contained in this notice, the name of the XFree86 Project shall
23 * not be used in advertising or otherwise to promote the sale, use or other
24 * dealings in this Software without prior written authorization from the
25 * XFree86 Project.
26 */
27
28#ifdef HAVE_CONFIG_H1
29#include <config.h>
30#endif
31#include <ctype.h>
32#include <stdio.h>
33#include <stdlib.h>
34#include <string.h>
35#include <X11/Xmd.h>
36#include <X11/IntrinsicP.h>
37#include <X11/StringDefs.h>
38#include <X11/CoreP.h>
39#include <X11/Constraint.h>
40#include <X11/Xmu/CharSet.h>
41#include <X11/Xfuncs.h>
42#include "Private.h"
43
44#ifdef __UNIXOS2__
45static char dummy;
46#endif
47
48#ifndef OLDXAW
49
50/*
51 * Definitions
52 */
53#define ERROR-2 -2
54#define END-1 -1
55#define BOOLEAN0 0
56#define AND'&' '&'
57#define OR'|' '|'
58#define XOR'^' '^'
59#define NOT'~' '~'
60#define LP'(' '('
61#define RP')' ')'
62
63/*
64 * Types
65 */
66/* boolean expressions */
67typedef struct _XawEvalInfo {
68 Widget widget;
69 XawActionResList *rlist;
70 XawActionVarList *vlist;
71 XawParseBooleanProc parse_proc;
72 XEvent *event;
73 char *cp, *lp;
74 int token;
75 Boolint value;
76} XawEvalInfo;
77
78/* resources */
79typedef struct _XawActionRes {
80 XrmQuark qname;
81 XrmQuark qtype;
82 Cardinal size;
83} XawActionRes;
84
85struct _XawActionResList {
86 WidgetClass widget_class;
87 XawActionRes **resources;
88 Cardinal num_common_resources;
89 Cardinal num_constraint_resources;
90};
91
92/* variables */
93typedef struct _XawActionVar {
94 XrmQuark qname;
95 XrmQuark qvalue;
96} XawActionVar;
97
98struct _XawActionVarList {
99 Widget widget;
100 Cardinal num_variables;
101 XawActionVar **variables;
102};
103
104/*
105 * Private methods
106 */
107/* expressions */
108static int get_token(XawEvalInfo*);
109static Boolint expr(XawEvalInfo*);
110static Boolint and(XawEvalInfo*);
111static Boolint prim(XawEvalInfo*);
112
113/* resources */
114static String XawConvertActionRes(XawActionResList*, Widget w, String);
115
116static String _XawEscapeActionVarValue(String);
117static String _XawUnescapeActionVarValue(String);
118static XawActionResList *_XawCreateActionResList(WidgetClass);
119static XawActionResList *_XawFindActionResList(WidgetClass);
120static void _XawBindActionResList(XawActionResList*);
121static XawActionRes *_XawFindActionRes(XawActionResList*, Widget, String);
122static int qcmp_action_resource_list(_Xconstconst void*, _Xconstconst void*);
123static int bcmp_action_resource_list(_Xconstconst void*, _Xconstconst void*);
124static int qcmp_action_resource(_Xconstconst void*, _Xconstconst void*);
125static int bcmp_action_resource(_Xconstconst void*, _Xconstconst void*);
126
127/* variables */
128static String XawConvertActionVar(XawActionVarList*, String);
129static void XawDeclareActionVar(XawActionVarList*, String, String);
130
131static XawActionVarList *_XawCreateActionVarList(Widget);
132static XawActionVarList *_XawFindActionVarList(Widget);
133static XawActionVar *_XawCreateActionVar(XawActionVarList*, String);
134static XawActionVar *_XawFindActionVar(XawActionVarList*, String);
135static void _XawDestroyActionVarList(Widget, XtPointer, XtPointer);
136
137/*
138 * Initialization
139 */
140/* resources */
141static XawActionResList **resource_list;
142static Cardinal num_resource_list;
143
144/* variables */
145static XawActionVarList **variable_list;
146static Cardinal num_variable_list;
147
148/*
149 * Implementation
150 */
151/*
152 * Start of Boolean Expression Evaluation Implementation Code
153 */
154Boolint
155XawParseBoolean(Widget w, String param, XEvent *event, Boolint *succed)
156{
157 char *tmp = param;
158 int value;
159
160 if (!param)
161 return (False0);
162
163 value = (int)strtod(param, &tmp);
164 if (*tmp == '\0')
165 return (value);
166
167 if (XmuCompareISOLatin1(param, "true") == 0
168 || XmuCompareISOLatin1(param, "yes") == 0
169 || XmuCompareISOLatin1(param, "on") == 0
170 || XmuCompareISOLatin1(param, "in") == 0
171 || XmuCompareISOLatin1(param, "up") == 0)
172 return (True1);
173 else if (XmuCompareISOLatin1(param, "false") == 0
174 || XmuCompareISOLatin1(param, "no") == 0
175 || XmuCompareISOLatin1(param, "off") == 0
176 || XmuCompareISOLatin1(param, "out") == 0
177 || XmuCompareISOLatin1(param, "down") == 0)
178 ;
179 else if (XmuCompareISOLatin1(param, "my") == 0
180 || XmuCompareISOLatin1(param, "mine") == 0)
181 return (event->xany.window == XtWindow(w)((w)->core.window));
182 else if (XmuCompareISOLatin1(param, "faked") == 0)
183 return (event->xany.send_event != 0);
184 else
185 *succed = False0;
186
187 return (False0);
188}
189
190Boolint
191XawBooleanExpression(Widget w, String param, XEvent *event)
192{
193 XawEvalInfo info;
194 Boolint retval;
195
196 if (!param)
197 return (False0);
198
199 info.widget = w;
200
201 info.rlist = XawGetActionResList(XtClass(w)((w)->core.widget_class));
202 info.vlist = XawGetActionVarList(w);
203
204 /*
205 * Verify widget class, in case we will allow the parse proc procedure
206 * as a widget class element, or if we allow overriding the default
207 * parse boolean proc.
208 */
209 info.parse_proc = XawParseBoolean;
210
211 info.event = event;
212 info.cp = info.lp = param;
213
214#ifdef DIAGNOSTIC
215 fprintf(stderrstderr, "(*) Parsing expression \"%s\"\n", param);
216#endif
217
218 (void)get_token(&info);
219 if (info.token == ERROR-2)
220 return (False0);
221 retval = expr(&info);
222
223 return (info.token != ERROR-2 ? retval : False0);
224}
225
226static int
227get_token(XawEvalInfo *info)
228{
229 int ch;
230 char *p, name[256];
231
232 info->lp = info->cp;
233
234 /*COSTCOND*/
235 while (1) /* eat white spaces */
236 {
237 ch = *info->cp++;
238 if (isspace(ch)((*__ctype_b_loc ())[(int) ((ch))] & (unsigned short int)
_ISspace)
)
239 continue;
240 break;
241 }
242
243 switch (ch)
244 {
245 case AND'&': case OR'|': case XOR'^': case NOT'~': case LP'(': case RP')':
246 return (info->token = ch);
247 }
248
249 /* It's a symbol name, resolve it. */
250 if (ch == XAW_PRIV_VAR_PREFIX'$' || isalnum(ch)((*__ctype_b_loc ())[(int) ((ch))] & (unsigned short int)
_ISalnum)
|| ch == '_' || ch == '\\')
251 {
252 Boolint succed = True1;
253
254 p = info->cp - 1;
255
256 while ((ch = *info->cp) && (isalnum(ch)((*__ctype_b_loc ())[(int) ((ch))] & (unsigned short int)
_ISalnum)
|| ch == '_'))
257 ++info->cp;
258
259 strncpy(name, p, XawMin((int)sizeof(name) - 1,(((int)sizeof(name) - 1) < ((unsigned)(info->cp - p)) ?
((int)sizeof(name) - 1) : ((unsigned)(info->cp - p)))
260 (unsigned)(info->cp - p))(((int)sizeof(name) - 1) < ((unsigned)(info->cp - p)) ?
((int)sizeof(name) - 1) : ((unsigned)(info->cp - p)))
);
261 name[XawMin((int)sizeof(name) -1, info->cp - p)(((int)sizeof(name) -1) < (info->cp - p) ? ((int)sizeof
(name) -1) : (info->cp - p))
] = '\0';
262
263 if (name[0] == XAW_PRIV_VAR_PREFIX'$')
264 {
265 String value = XawConvertActionVar(info->vlist, name);
266
267 info->value = info->parse_proc(info->widget, value, info->event,
268 &succed) & 1;
269 }
270 else
271 {
272 info->value = info->parse_proc(info->widget, name, info->event,
273 &succed) & 1;
274 if (!succed)
275 {
276 String value =
277 XawConvertActionRes(info->rlist, info->widget,
278 name[0] == '\\' ? &name[1] : name);
279 /* '\\' may have been used to escape a resource name.
280 */
281
282 succed = True1;
283 info->value = info->parse_proc(info->widget, value, info->event,
284 &succed) & 1;
285 if (!succed)
286 {
287 /* not a numeric value or boolean string */
288 info->value = True1;
289 succed = True1;
290 }
291 }
292 }
293 if (succed)
294 return (info->token = BOOLEAN0);
295 }
296 else if (ch == '\0')
297 return (info->token = END-1);
298
299 {
300 char msg[256];
301
302 snprintf(msg, sizeof(msg), "evaluate(): bad token \"%c\" at \"%s\"",
303 ch, info->cp - 1);
304
305 XtAppWarning(XtWidgetToApplicationContext(info->widget), msg);
306 }
307
308 return (info->token = ERROR-2);
309}
310
311static Boolint
312expr(XawEvalInfo *info)
313{
314 Boolint left = and(info);
315
316 for (;;)
317 switch (info->token)
318 {
319 case OR'|':
320 (void)get_token(info);
321 left |= and(info);
322 break;
323 case XOR'^':
324 (void)get_token(info);
325 left ^= and(info);
326 break;
327 default:
328 return (left);
329 }
330 /* NOTREACHED */
331}
332
333static Boolint
334and(XawEvalInfo *info)
335{
336 Boolint left = prim(info);
337
338 for (;;)
339 switch (info->token)
340 {
341 case AND'&':
342 (void)get_token(info);
343 left &= prim(info);
344 break;
345 default:
346 return (left);
347 }
348 /* NOTREACHED */
349}
350
351static Boolint
352prim(XawEvalInfo *info)
353{
354 Boolint e;
355
356 switch (info->token)
357 {
358 case BOOLEAN0:
359 e = info->value;
360 (void)get_token(info);
361 return (e);
362 case NOT'~':
363 (void)get_token(info);
364 return (!prim(info));
365 case LP'(':
366 (void)get_token(info);
367 e = expr(info);
368 if (info->token != RP')')
369 {
370 char msg[256];
371
372 info->token = ERROR-2;
373 snprintf(msg, sizeof(msg), "evaluate(): expecting ), at \"%s\"",
374 info->lp);
375 XtAppWarning(XtWidgetToApplicationContext(info->widget), msg);
376 return (False0);
377 }
378 (void)get_token(info);
379 return (e);
380 case END-1:
381 return (True1);
382 default:
383 {
384 char msg[256];
385
386 info->token = ERROR-2;
387 snprintf(msg, sizeof(msg), "evaluate(): syntax error, at \"%s\"",
388 info->lp);
389 XtAppWarning(XtWidgetToApplicationContext(info->widget), msg);
390 } return (False0);
391 }
392 /* NOTREACHED */
393}
394
395/*
396 * Start of Resources Implementation Code
397 */
398void
399XawSetValuesAction(Widget w, XEvent *event,
400 String *params, Cardinal *num_params)
401{
402 Arg *arglist;
403 Cardinal num_args, count;
404 XawActionResList *rlist;
405 XawActionVarList *vlist;
406 XawActionRes *resource;
407 XrmValue from, to;
408 String value;
409 char c_1;
410 short c_2;
411 int c_4;
412#ifdef LONG64
413 long c_8;
414#endif
415
416 if (!(*num_params & 1))
1
Taking false branch
417 {
418 XawPrintActionErrorMsg("set-values", w, params, num_params);
419 return;
420 }
421
422 if (!XawBooleanExpression(w, params[0], event))
2
Taking false branch
423 return;
424
425 rlist = XawGetActionResList(XtClass(w)((w)->core.widget_class));
426 vlist = XawGetActionVarList(w);
427
428 num_args = 0;
429 arglist = (Arg *)XtMalloc(sizeof(Arg) * ((*num_params) >> 1));
430
431 for (count = 1; count < *num_params; count += 2)
3
Loop condition is true. Entering loop body
7
Loop condition is true. Entering loop body
432 {
433 if ((resource = _XawFindActionRes(rlist, w, params[count])) == NULL((void*)0))
4
Taking false branch
8
Taking false branch
434 {
435 char msg[256];
436
437 snprintf(msg, sizeof(msg), "set-values(): bad resource name \"%s\"",
438 params[count]);
439 XtAppWarning(XtWidgetToApplicationContext(w), msg);
440 continue;
441 }
442 value = XawConvertActionVar(vlist, params[count + 1]);
443 from.size = strlen(value) + 1;
444 from.addr = value;
445 to.size = resource->size;
446 switch (to.size)
5
Control jumps to the 'default' case at line 454
9
Control jumps to 'case 8:' at line 452
447 {
448 case 1: to.addr = (XPointer)&c_1; break;
449 case 2: to.addr = (XPointer)&c_2; break;
450 case 4: to.addr = (XPointer)&c_4; break;
451#ifdef LONG64
452 case 8: to.addr = (XPointer)&c_8; break;
10
Execution continues on line 465
453#endif
454 default:
455 {
456 char msg[256];
457
458 snprintf(msg, sizeof(msg),
459 "set-values(): bad resource size for \"%s\"",
460 params[count]);
461 XtAppWarning(XtWidgetToApplicationContext(w), msg);
462 } continue;
6
Execution continues on line 431
463 }
464
465 if (strcmp(XtRString((char*)&XtStrings[1797]), XrmQuarkToString(resource->qtype)) == 0)
11
Taking false branch
466#ifdef LONG64
467 c_8 = (long)from.addr;
468#else
469 c_4 = (int)from.addr;
470#endif
471 else if (!XtConvertAndStore(w, XtRString((char*)&XtStrings[1797]), &from,
12
Taking false branch
472 XrmQuarkToString(resource->qtype), &to))
473 continue;
474
475 switch (to.size)
13
Control jumps to 'case 4:' at line 483
476 {
477 case 1:
478 XtSetArg(arglist[num_args], XrmQuarkToString(resource->qname), c_1)((void)( (arglist[num_args]).name = (XrmQuarkToString(resource
->qname)), (arglist[num_args]).value = (XtArgVal)(c_1) ))
;
479 break;
480 case 2:
481 XtSetArg(arglist[num_args], XrmQuarkToString(resource->qname), c_2)((void)( (arglist[num_args]).name = (XrmQuarkToString(resource
->qname)), (arglist[num_args]).value = (XtArgVal)(c_2) ))
;
482 break;
483 case 4:
484 XtSetArg(arglist[num_args], XrmQuarkToString(resource->qname), c_4)((void)( (arglist[num_args]).name = (XrmQuarkToString(resource
->qname)), (arglist[num_args]).value = (XtArgVal)(c_4) ))
;
14
Within the expansion of the macro 'XtSetArg':
a
Assigned value is garbage or undefined
485 break;
486#ifdef LONG64
487 case 8:
488 XtSetArg(arglist[num_args], XrmQuarkToString(resource->qname), c_8)((void)( (arglist[num_args]).name = (XrmQuarkToString(resource
->qname)), (arglist[num_args]).value = (XtArgVal)(c_8) ))
;
489 break;
490#endif
491 }
492 ++num_args;
493 }
494
495 XtSetValues(w, arglist, num_args);
496 XtFree((char *)arglist);
497}
498
499void
500XawGetValuesAction(Widget w, XEvent *event,
501 String *params, Cardinal *num_params)
502{
503 XawActionResList *rlist;
504 XawActionVarList *vlist;
505 String value;
506 Cardinal count;
507
508 if (!(*num_params & 1))
509 {
510 XawPrintActionErrorMsg("get-values", w, params, num_params);
511 return;
512 }
513 if (!XawBooleanExpression(w, params[0], event))
514 return;
515
516 rlist = XawGetActionResList(XtClass(w)((w)->core.widget_class));
517 vlist = XawGetActionVarList(w);
518
519 for (count = 1; count < *num_params; count += 2)
520 {
521 if ((value = XawConvertActionRes(rlist, w, params[count + 1])) == NULL((void*)0))
522 continue;
523 XawDeclareActionVar(vlist, params[count], value);
524 }
525}
526
527void
528XawDeclareAction(Widget w, XEvent *event,
529 String *params, Cardinal *num_params)
530{
531 XawActionVarList *vlist;
532 Cardinal count;
533
534 if (!(*num_params & 1))
535 {
536 XawPrintActionErrorMsg("declare", w, params, num_params);
537 return;
538 }
539 if (!XawBooleanExpression(w, params[0], event))
540 return;
541
542 vlist = XawGetActionVarList(w);
543
544 for (count = 1; count < *num_params; count += 2)
545 XawDeclareActionVar(vlist, params[count], params[count + 1]);
546}
547
548void
549XawCallProcAction(Widget w, XEvent *event,
550 String *params, Cardinal *num_params)
551{
552 String *args;
553 Cardinal num_args;
554
555 if (*num_params < 2)
556 {
557 XawPrintActionErrorMsg("call-proc", w, params, num_params);
558 return;
559 }
560
561 if (*num_params && !XawBooleanExpression(w, params[0], event))
562 return;
563
564 if (*num_params > 2)
565 {
566 args = &params[2];
567 num_args = *num_params - 2;
568 }
569 else
570 {
571 args = NULL((void*)0);
572 num_args = 0;
573 }
574
575 XtCallActionProc(w, params[1], event, args, num_args);
576}
577
578static String
579XawConvertActionRes(XawActionResList *list, Widget w, String name)
580{
581 XawActionRes *resource;
582 XrmValue from, to;
583 Arg arg;
584 char c_1;
585 short c_2;
586 int c_4;
587#ifdef LONG64
588 long c_8;
589#endif
590
591 if ((resource = _XawFindActionRes(list, w, name)) == NULL((void*)0))
592 {
593 char msg[256];
594
595 snprintf(msg, sizeof(msg), "convert(): bad resource name \"%s\"",
596 name);
597 XtAppWarning(XtWidgetToApplicationContext(w), msg);
598 return (NULL((void*)0));
599 }
600
601 from.size = resource->size;
602 switch (from.size)
603 {
604 case 1:
605 XtSetArg(arg, XrmQuarkToString(resource->qname),((void)( (arg).name = (XrmQuarkToString(resource->qname)),
(arg).value = (XtArgVal)(from.addr = (XPointer)&c_1) ))
606 from.addr = (XPointer)&c_1)((void)( (arg).name = (XrmQuarkToString(resource->qname)),
(arg).value = (XtArgVal)(from.addr = (XPointer)&c_1) ))
;
607 break;
608 case 2:
609 XtSetArg(arg, XrmQuarkToString(resource->qname),((void)( (arg).name = (XrmQuarkToString(resource->qname)),
(arg).value = (XtArgVal)(from.addr = (XPointer)&c_2) ))
610 from.addr = (XPointer)&c_2)((void)( (arg).name = (XrmQuarkToString(resource->qname)),
(arg).value = (XtArgVal)(from.addr = (XPointer)&c_2) ))
;
611 break;
612 case 4:
613 XtSetArg(arg, XrmQuarkToString(resource->qname),((void)( (arg).name = (XrmQuarkToString(resource->qname)),
(arg).value = (XtArgVal)(from.addr = (XPointer)&c_4) ))
614 from.addr = (XPointer)&c_4)((void)( (arg).name = (XrmQuarkToString(resource->qname)),
(arg).value = (XtArgVal)(from.addr = (XPointer)&c_4) ))
;
615 break;
616#ifdef LONG64
617 case 8:
618 XtSetArg(arg, XrmQuarkToString(resource->qname),((void)( (arg).name = (XrmQuarkToString(resource->qname)),
(arg).value = (XtArgVal)(from.addr = (XPointer)&c_8) ))
619 from.addr = (XPointer)&c_8)((void)( (arg).name = (XrmQuarkToString(resource->qname)),
(arg).value = (XtArgVal)(from.addr = (XPointer)&c_8) ))
;
620 break;
621#endif
622 default:
623 {
624 char msg[256];
625
626 snprintf(msg, sizeof(msg), "convert(): bad resource size for \"%s\"",
627 name);
628 XtAppWarning(XtWidgetToApplicationContext(w), name);
629 } return (NULL((void*)0));
630 }
631
632 XtGetValues(w, &arg, 1);
633 to.size = sizeof(String);
634 to.addr = NULL((void*)0);
635
636 if (strcmp(XtRString((char*)&XtStrings[1797]), XrmQuarkToString(resource->qtype)) == 0)
637 to.addr = *(char **)from.addr;
638 else if (!XtConvertAndStore(w, XrmQuarkToString(resource->qtype),
639 &from, XtRString((char*)&XtStrings[1797]), &to))
640 return (NULL((void*)0));
641
642 return ((String)to.addr);
643}
644
645void
646XawPrintActionErrorMsg(String action_name, Widget w,
647 String *params, Cardinal *num_params)
648{
649 char msg[1024];
650 unsigned int size, idx;
651
652 size = snprintf(msg, sizeof(msg), "%s(): bad number of parameters.\n\t(",
653 action_name);
654
655 idx = 0;
656 while (idx < *num_params - 1 && size < sizeof(msg))
657 size += snprintf(&msg[size], sizeof(msg) - size, "%s, ",
658 params[idx++]);
659 if (*num_params)
660 snprintf(&msg[size], sizeof(msg) - size, "%s)", params[idx]);
661 else
662 snprintf(&msg[size], sizeof(msg) - size, ")");
663 XtAppWarning(XtWidgetToApplicationContext(w), msg);
664}
665
666XawActionResList *
667XawGetActionResList(WidgetClass wc)
668{
669 XawActionResList *list;
670
671 list = _XawFindActionResList(wc);
672
673 if (!list)
674 list = _XawCreateActionResList(wc);
675
676 return (list);
677}
678
679static int
680qcmp_action_resource_list(register _Xconstconst void *left,
681 register _Xconstconst void *right)
682{
683 return ((char *)((*(XawActionResList **)left)->widget_class) -
684 (char *)((*(XawActionResList **)right)->widget_class));
685}
686
687static XawActionResList *
688_XawCreateActionResList(WidgetClass wc)
689{
690 XawActionResList *list;
691
692 list = (XawActionResList *)XtMalloc(sizeof(XawActionResList));
693 list->widget_class = wc;
694 list->num_common_resources = list->num_constraint_resources = 0;
695 list->resources = NULL((void*)0);
696
697 if (!resource_list)
698 {
699 num_resource_list = 1;
700 resource_list = (XawActionResList **)XtMalloc(sizeof(XawActionResList*));
701 resource_list[0] = list;
702 }
703 else
704 {
705 ++num_resource_list;
706 resource_list = (XawActionResList **)XtRealloc((char *)resource_list,
707 sizeof(XawActionResList*)
708 * num_resource_list);
709 resource_list[num_resource_list - 1] = list;
710 qsort(resource_list, num_resource_list, sizeof(XawActionResList*),
711 qcmp_action_resource_list);
712 }
713
714 _XawBindActionResList(list);
715
716 return (list);
717}
718
719static int
720bcmp_action_resource_list(register _Xconstconst void *wc,
721 register _Xconstconst void *list)
722{
723 return ((char *)wc - (char *)((*(XawActionResList **)list)->widget_class));
724}
725
726static XawActionResList *
727_XawFindActionResList(WidgetClass wc)
728{
729 XawActionResList **list;
730
731 if (!resource_list)
732 return (NULL((void*)0));
733
734 list = (XawActionResList **)bsearch(wc, resource_list,
735 num_resource_list,
736 sizeof(XawActionResList*),
737 bcmp_action_resource_list);
738
739 return (list ? *list : NULL((void*)0));
740}
741
742static int
743qcmp_action_resource(register _Xconstconst void *left,
744 register _Xconstconst void *right)
745{
746 return (strcmp(XrmQuarkToString((*(XawActionRes **)left)->qname),
747 XrmQuarkToString((*(XawActionRes **)right)->qname)));
748}
749
750static void
751_XawBindActionResList(XawActionResList *list)
752{
753 XtResourceList xt_list, cons_list;
754 Cardinal i, num_xt, num_cons;
755
756#ifdef DIAGNOSTIC
757 fprintf(stderrstderr, "(*) Creating resource list for class \'%s\'\n---------\n",
758 list->widget_class->core_class.class_name);
759#endif
760
761 XtGetResourceList(list->widget_class, &xt_list, &num_xt);
762 XtGetConstraintResourceList(list->widget_class, &cons_list, &num_cons);
763 list->num_common_resources = num_xt;
764 list->num_constraint_resources = num_cons;
765
766 list->resources = (XawActionRes **)
767 XtMalloc(sizeof(XawActionRes*) * (num_xt + num_cons));
768
769#ifdef DIAGNOSTIC
770 fprintf(stderrstderr, "Common resources\n---\n");
771#endif
772
773 for (i = 0; i < num_xt; i++)
774 {
775 list->resources[i] = (XawActionRes *)XtMalloc(sizeof(XawActionRes));
776 list->resources[i]->qname =
777 XrmPermStringToQuark(xt_list[i].resource_name);
778 list->resources[i]->qtype =
779 XrmPermStringToQuark(xt_list[i].resource_type);
780 list->resources[i]->size = xt_list[i].resource_size;
781
782#ifdef DIAGNOSTIC
783 fprintf(stderrstderr, "%-20s\t%-20s\t(%d)\n",
784 xt_list[i].resource_name,
785 xt_list[i].resource_type,
786 xt_list[i].resource_size);
787#endif
788 }
789
790#ifdef DIAGNOSTIC
791 fprintf(stderrstderr, "---\nContraint resources\n---");
792#endif
793
794 for (; i < num_xt + num_cons; i++)
795 {
796 list->resources[i] = (XawActionRes *)XtMalloc(sizeof(XawActionRes));
797 list->resources[i]->qname =
798 XrmPermStringToQuark(cons_list[i - num_xt].resource_name);
799 list->resources[i]->qtype =
800 XrmPermStringToQuark(cons_list[i - num_xt].resource_type);
801 list->resources[i]->size = cons_list[i - num_xt].resource_size;
802
803#ifdef DIAGNOSTIC
804 fprintf(stderrstderr, "%-20s\t%-20s\t(%d)\n",
805 cons_list[i - num_xt].resource_name,
806 cons_list[i - num_xt].resource_type,
807 cons_list[i - num_xt].resource_size);
808#endif
809 }
810
811#ifdef DIAGNOSTIC
812 fprintf(stderrstderr, "---\n");
813#endif
814
815 XtFree((char *)xt_list);
816 if (cons_list)
817 XtFree((char *)cons_list);
818
819 qsort(list->resources, list->num_common_resources, sizeof(XawActionRes*),
820 qcmp_action_resource);
821 if (num_cons)
822 qsort(&list->resources[num_xt], list->num_constraint_resources,
823 sizeof(XawActionRes*), qcmp_action_resource);
824}
825
826static int
827bcmp_action_resource(register _Xconstconst void *string,
828 register _Xconstconst void *resource)
829{
830 return (strcmp((String)string,
831 XrmQuarkToString((*(XawActionRes **)resource)->qname)));
832}
833
834static XawActionRes *
835_XawFindActionRes(XawActionResList *list, Widget detail, String name)
836{
837 XawActionRes **res;
838
839 if (!list->resources)
840 return (NULL((void*)0));
841
842 res = (XawActionRes **)bsearch(name, list->resources,
843 list->num_common_resources,
844 sizeof(XawActionRes*), bcmp_action_resource);
845
846 if (!res && XtParent(detail)((detail)->core.parent)
847 && XtIsSubclass(XtParent(detail)((detail)->core.parent), constraintWidgetClass))
848 {
849 XawActionResList *cons = XawGetActionResList(XtClass(XtParent(detail))((((detail)->core.parent))->core.widget_class));
850
851 if (cons)
852 res = (XawActionRes **)
853 bsearch(name, &cons->resources[cons->num_common_resources],
854 cons->num_constraint_resources,
855 sizeof(XawActionRes*), bcmp_action_resource);
856 }
857
858 return (res ? *res : NULL((void*)0));
859}
860
861/*
862 * Start of Variables Implementation Code
863 */
864/* For speed, only does memory allocation when really required */
865static String
866_XawEscapeActionVarValue(String value)
867{
868 String escape;
869
870 if (value[0] == '$' || value[0] == '\\')
871 {
872 escape = XtMalloc(strlen(value) + 2);
873 escape[0] = '\\';
874 strcpy(escape + 1, value);
875 return (escape);
876 }
877 return (NULL((void*)0));
878}
879
880/* For speed, only does memory allocation when really required */
881static String
882_XawUnescapeActionVarValue(String value)
883{
884 String unescape;
885
886 if (value[0] == '\\')
887 {
888 unescape = XtMalloc(strlen(value));
889 strcpy(unescape, value + 1);
890 return (unescape);
891 }
892 return (NULL((void*)0));
893}
894
895static void
896XawDeclareActionVar(XawActionVarList *list, String name, String value)
897{
898 XawActionVar *variable;
899 String escape = NULL((void*)0);
900
901 if (name[0] != XAW_PRIV_VAR_PREFIX'$')
902 {
903 char msg[256];
904
905 snprintf(msg, sizeof(msg),
906 "declare(): variable name must begin with \'%c\', at %s = %s",
907 XAW_PRIV_VAR_PREFIX'$', name, value);
908 XtAppWarning(XtWidgetToApplicationContext(list->widget), msg);
909 return;
910 }
911 variable = _XawFindActionVar(list, name);
912 if (!variable)
913 variable = _XawCreateActionVar(list, name);
914 if (value)
915 escape = _XawEscapeActionVarValue(value);
916
917 if (variable->qvalue)
918 {
919 String val = escape ? escape : value;
920
921 if (strcmp(XrmQuarkToString(variable->qvalue), val) == 0)
922 {
923 if (escape)
924 XtFree(escape);
925 return;
926 }
927 }
928 variable->qvalue = (escape ? XrmStringToQuark(escape) :
929 (value ? XrmStringToQuark(value) : NULLQUARK((XrmQuark) 0)));
930 if (escape)
931 XtFree(escape);
932}
933
934static String
935XawConvertActionVar(XawActionVarList *list, String name)
936{
937 XawActionVar *variable;
938 String unescape;
939 XrmQuark quark;
940
941 if (name[0] != XAW_PRIV_VAR_PREFIX'$')
942 return (name);
943
944 variable = _XawFindActionVar(list, name);
945 if (!variable || variable->qvalue == NULLQUARK((XrmQuark) 0))
946 return (name);
947 unescape = _XawUnescapeActionVarValue(XrmQuarkToString(variable->qvalue));
948 if (unescape)
949 {
950 quark = XrmStringToQuark(unescape);
951 XtFree(unescape);
952 }
953 else
954 quark = variable->qvalue;
955
956 return (XrmQuarkToString(quark));
957}
958
959XawActionVarList *
960XawGetActionVarList(Widget w)
961{
962 XawActionVarList *list;
963
964 list = _XawFindActionVarList(w);
965 if (!list)
966 list = _XawCreateActionVarList(w);
967
968 return (list);
969}
970
971static int
972qcmp_action_variable_list(register _Xconstconst void *left,
973 register _Xconstconst void *right)
974{
975 return ((char *)((*(XawActionVarList **)left)->widget) -
976 (char *)((*(XawActionVarList **)right)->widget));
977}
978
979static XawActionVarList *
980_XawCreateActionVarList(Widget w)
981{
982 XawActionVarList *list;
983
984#ifdef DIAGNOSTIC
985 fprintf(stderrstderr, "(*) Creating action variable list for widget %s (%p)\n",
986 XtName(w), w);
987#endif
988
989 list = (XawActionVarList *)XtMalloc(sizeof(XawActionVarList));
990 list->widget = w;
991 list->num_variables = 0;
992 list->variables = NULL((void*)0);
993
994 if (!variable_list)
995 {
996 num_variable_list = 1;
997 variable_list = (XawActionVarList **)XtMalloc(sizeof(XawActionVarList*));
998 variable_list[0] = list;
999 }
1000 else
1001 {
1002 ++num_variable_list;
1003 variable_list = (XawActionVarList **)
1004 XtRealloc((char *)variable_list,
1005 sizeof(XawActionVarList *) * num_variable_list);
1006 variable_list[num_variable_list - 1] = list;
1007 qsort(variable_list, num_variable_list, sizeof(XawActionVarList*),
1008 qcmp_action_variable_list);
1009 }
1010
1011 XtAddCallback(w, XtNdestroyCallback((char*)&XtStrings[169]), _XawDestroyActionVarList,
1012 (XtPointer)list);
1013
1014 return (list);
1015}
1016
1017static int
1018bcmp_action_variable_list(register _Xconstconst void *widget,
1019 register _Xconstconst void *list)
1020{
1021 return ((char *)widget - (char *)((*(XawActionVarList **)list)->widget));
1022}
1023
1024static XawActionVarList *
1025_XawFindActionVarList(Widget w)
1026{
1027 XawActionVarList **list;
1028
1029 if (!num_variable_list)
1030 return (NULL((void*)0));
1031
1032 list = (XawActionVarList **)bsearch(w, variable_list, num_variable_list,
1033 sizeof(XawActionVarList*),
1034 bcmp_action_variable_list);
1035
1036 return (list ? *list : NULL((void*)0));
1037}
1038
1039static int
1040qcmp_action_variable(register _Xconstconst void *left,
1041 register _Xconstconst void *right)
1042{
1043 return (strcmp(XrmQuarkToString((*(XawActionVar **)left)->qname),
1044 XrmQuarkToString((*(XawActionVar **)right)->qname)));
1045}
1046
1047static XawActionVar *
1048_XawCreateActionVar(XawActionVarList *list, String name)
1049{
1050 XawActionVar *variable;
1051
1052#ifdef DIAGNOSTIC
1053 fprintf(stderrstderr, "(*) Creating action variable '%s' for widget %s (%p)\n",
1054 name, XtName(list->widget), list->widget);
1055#endif
1056
1057 variable = (XawActionVar *)XtMalloc(sizeof(XawActionVar));
1058 variable->qname = XrmStringToQuark(name);
1059 variable->qvalue = NULLQUARK((XrmQuark) 0);
1060
1061 if (!list->variables)
1062 {
1063 list->num_variables = 1;
1064 list->variables = (XawActionVar **)XtMalloc(sizeof(XawActionVar*));
1065 list->variables[0] = variable;
1066 }
1067 else
1068 {
1069 ++list->num_variables;
1070 list->variables = (XawActionVar **)XtRealloc((char *)list->variables,
1071 sizeof(XawActionVar *) *
1072 list->num_variables);
1073 list->variables[list->num_variables - 1] = variable;
1074 qsort(list->variables, list->num_variables, sizeof(XawActionVar*),
1075 qcmp_action_variable);
1076 }
1077 return (variable);
1078}
1079
1080static int
1081bcmp_action_variable(register _Xconstconst void *string,
1082 register _Xconstconst void *variable)
1083{
1084 return (strcmp((String)string,
1085 XrmQuarkToString((*(XawActionVar **)variable)->qname)));
1086}
1087
1088static XawActionVar *
1089_XawFindActionVar(XawActionVarList *list, String name)
1090{
1091 XawActionVar **var;
1092
1093 if (!list->variables)
1094 return (NULL((void*)0));
1095
1096 var = (XawActionVar **)bsearch(name, list->variables, list->num_variables,
1097 sizeof(XawActionVar*), bcmp_action_variable);
1098
1099 return (var ? *var : NULL((void*)0));
1100}
1101
1102/*ARGSUSED*/
1103static void
1104_XawDestroyActionVarList(Widget w, XtPointer client_data, XtPointer call_data)
1105{
1106 XawActionVarList *list = (XawActionVarList *)client_data;
1107 Cardinal i;
1108
1109 for (i = 0; i < num_variable_list; i++)
1110 if (variable_list[i] == list)
1111 break;
1112 if (i >= num_variable_list || list->widget != w
1113 || variable_list[i]->widget != w)
1114 {
1115 XtWarning("destroy-variable-list(): Bad widget argument.");
1116 return;
1117 }
1118 if (--num_variable_list > 0)
1119 {
1120 memmove(&variable_list[i], &variable_list[i + 1],
1121 (num_variable_list - i) * sizeof(XawActionVarList *));
1122 variable_list = (XawActionVarList **)
1123 XtRealloc((char *)variable_list, sizeof(XawActionVarList *) *
1124 num_variable_list);
1125 }
1126 else
1127 {
1128 XtFree((char *)variable_list);
1129 variable_list = NULL((void*)0);
1130 }
1131
1132 XtFree((char *)list->variables);
1133 XtFree((char *)list);
1134}
1135
1136#endif /* OLDXAW */