File: | Actions.c |
Location: | line 488, column 4 |
Description: | Assigned value is garbage or undefined |
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__ | ||||
45 | static 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 */ | ||||
67 | typedef 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 */ | ||||
79 | typedef struct _XawActionRes { | ||||
80 | XrmQuark qname; | ||||
81 | XrmQuark qtype; | ||||
82 | Cardinal size; | ||||
83 | } XawActionRes; | ||||
84 | |||||
85 | struct _XawActionResList { | ||||
86 | WidgetClass widget_class; | ||||
87 | XawActionRes **resources; | ||||
88 | Cardinal num_common_resources; | ||||
89 | Cardinal num_constraint_resources; | ||||
90 | }; | ||||
91 | |||||
92 | /* variables */ | ||||
93 | typedef struct _XawActionVar { | ||||
94 | XrmQuark qname; | ||||
95 | XrmQuark qvalue; | ||||
96 | } XawActionVar; | ||||
97 | |||||
98 | struct _XawActionVarList { | ||||
99 | Widget widget; | ||||
100 | Cardinal num_variables; | ||||
101 | XawActionVar **variables; | ||||
102 | }; | ||||
103 | |||||
104 | /* | ||||
105 | * Private methods | ||||
106 | */ | ||||
107 | /* expressions */ | ||||
108 | static int get_token(XawEvalInfo*); | ||||
109 | static Boolint expr(XawEvalInfo*); | ||||
110 | static Boolint and(XawEvalInfo*); | ||||
111 | static Boolint prim(XawEvalInfo*); | ||||
112 | |||||
113 | /* resources */ | ||||
114 | static String XawConvertActionRes(XawActionResList*, Widget w, String); | ||||
115 | |||||
116 | static String _XawEscapeActionVarValue(String); | ||||
117 | static String _XawUnescapeActionVarValue(String); | ||||
118 | static XawActionResList *_XawCreateActionResList(WidgetClass); | ||||
119 | static XawActionResList *_XawFindActionResList(WidgetClass); | ||||
120 | static void _XawBindActionResList(XawActionResList*); | ||||
121 | static XawActionRes *_XawFindActionRes(XawActionResList*, Widget, String); | ||||
122 | static int qcmp_action_resource_list(_Xconstconst void*, _Xconstconst void*); | ||||
123 | static int bcmp_action_resource_list(_Xconstconst void*, _Xconstconst void*); | ||||
124 | static int qcmp_action_resource(_Xconstconst void*, _Xconstconst void*); | ||||
125 | static int bcmp_action_resource(_Xconstconst void*, _Xconstconst void*); | ||||
126 | |||||
127 | /* variables */ | ||||
128 | static String XawConvertActionVar(XawActionVarList*, String); | ||||
129 | static void XawDeclareActionVar(XawActionVarList*, String, String); | ||||
130 | |||||
131 | static XawActionVarList *_XawCreateActionVarList(Widget); | ||||
132 | static XawActionVarList *_XawFindActionVarList(Widget); | ||||
133 | static XawActionVar *_XawCreateActionVar(XawActionVarList*, String); | ||||
134 | static XawActionVar *_XawFindActionVar(XawActionVarList*, String); | ||||
135 | static void _XawDestroyActionVarList(Widget, XtPointer, XtPointer); | ||||
136 | |||||
137 | /* | ||||
138 | * Initialization | ||||
139 | */ | ||||
140 | /* resources */ | ||||
141 | static XawActionResList **resource_list; | ||||
142 | static Cardinal num_resource_list; | ||||
143 | |||||
144 | /* variables */ | ||||
145 | static XawActionVarList **variable_list; | ||||
146 | static Cardinal num_variable_list; | ||||
147 | |||||
148 | /* | ||||
149 | * Implementation | ||||
150 | */ | ||||
151 | /* | ||||
152 | * Start of Boolean Expression Evaluation Implementation Code | ||||
153 | */ | ||||
154 | Boolint | ||||
155 | XawParseBoolean(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 | |||||
190 | Boolint | ||||
191 | XawBooleanExpression(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 | |||||
226 | static int | ||||
227 | get_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 | |||||
311 | static Boolint | ||||
312 | expr(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 | |||||
333 | static Boolint | ||||
334 | and(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 | |||||
351 | static Boolint | ||||
352 | prim(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 | */ | ||||
398 | void | ||||
399 | XawSetValuesAction(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)) | ||||
| |||||
417 | { | ||||
418 | XawPrintActionErrorMsg("set-values", w, params, num_params); | ||||
419 | return; | ||||
420 | } | ||||
421 | |||||
422 | if (!XawBooleanExpression(w, params[0], event)) | ||||
| |||||
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) | ||||
| |||||
| |||||
432 | { | ||||
433 | if ((resource = _XawFindActionRes(rlist, w, params[count])) == NULL((void*)0)) | ||||
| |||||
| |||||
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) | ||||
| |||||
| |||||
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; | ||||
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; | ||||
| |||||
463 | } | ||||
464 | |||||
465 | if (strcmp(XtRString((char*)&XtStrings[1797]), XrmQuarkToString(resource->qtype)) == 0) | ||||
| |||||
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, | ||||
| |||||
472 | XrmQuarkToString(resource->qtype), &to)) | ||||
473 | continue; | ||||
474 | |||||
475 | switch (to.size) | ||||
| |||||
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) )); | ||||
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 | |||||
499 | void | ||||
500 | XawGetValuesAction(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 | |||||
527 | void | ||||
528 | XawDeclareAction(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 | |||||
548 | void | ||||
549 | XawCallProcAction(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 = ¶ms[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 | |||||
578 | static String | ||||
579 | XawConvertActionRes(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 | |||||
645 | void | ||||
646 | XawPrintActionErrorMsg(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 | |||||
666 | XawActionResList * | ||||
667 | XawGetActionResList(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 | |||||
679 | static int | ||||
680 | qcmp_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 | |||||
687 | static 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 | |||||
719 | static int | ||||
720 | bcmp_action_resource_list(register _Xconstconst void *wc, | ||||
721 | register _Xconstconst void *list) | ||||
722 | { | ||||
723 | return ((char *)wc - (char *)((*(XawActionResList **)list)->widget_class)); | ||||
724 | } | ||||
725 | |||||
726 | static 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 | |||||
742 | static int | ||||
743 | qcmp_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 | |||||
750 | static 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 | |||||
826 | static int | ||||
827 | bcmp_action_resource(register _Xconstconst void *string, | ||||
828 | register _Xconstconst void *resource) | ||||
829 | { | ||||
830 | return (strcmp((String)string, | ||||
831 | XrmQuarkToString((*(XawActionRes **)resource)->qname))); | ||||
832 | } | ||||
833 | |||||
834 | static 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 */ | ||||
865 | static 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 */ | ||||
881 | static 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 | |||||
895 | static void | ||||
896 | XawDeclareActionVar(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 | |||||
934 | static String | ||||
935 | XawConvertActionVar(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 | |||||
959 | XawActionVarList * | ||||
960 | XawGetActionVarList(Widget w) | ||||
961 | { | ||||
962 | XawActionVarList *list; | ||||
963 | |||||
964 | list = _XawFindActionVarList(w); | ||||
965 | if (!list) | ||||
966 | list = _XawCreateActionVarList(w); | ||||
967 | |||||
968 | return (list); | ||||
969 | } | ||||
970 | |||||
971 | static int | ||||
972 | qcmp_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 | |||||
979 | static 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 | |||||
1017 | static int | ||||
1018 | bcmp_action_variable_list(register _Xconstconst void *widget, | ||||
1019 | register _Xconstconst void *list) | ||||
1020 | { | ||||
1021 | return ((char *)widget - (char *)((*(XawActionVarList **)list)->widget)); | ||||
1022 | } | ||||
1023 | |||||
1024 | static 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 | |||||
1039 | static int | ||||
1040 | qcmp_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 | |||||
1047 | static 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 | |||||
1080 | static int | ||||
1081 | bcmp_action_variable(register _Xconstconst void *string, | ||||
1082 | register _Xconstconst void *variable) | ||||
1083 | { | ||||
1084 | return (strcmp((String)string, | ||||
1085 | XrmQuarkToString((*(XawActionVar **)variable)->qname))); | ||||
1086 | } | ||||
1087 | |||||
1088 | static 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*/ | ||||
1103 | static 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 */ |