1 /************************************************************
2 Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
4 Permission to use, copy, modify, and distribute this
5 software and its documentation for any purpose and without
6 fee is hereby granted, provided that the above copyright
7 notice appear in all copies and that both that copyright
8 notice and this permission notice appear in supporting
9 documentation, and that the name of Silicon Graphics not be
10 used in advertising or publicity pertaining to distribution
11 of the software without specific prior written permission.
12 Silicon Graphics makes no representation about the suitability
13 of this software for any purpose. It is provided "as is"
14 without any express or implied warranty.
16 SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
17 SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
18 AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
19 GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
20 DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
21 DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
22 OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
23 THE USE OR PERFORMANCE OF THIS SOFTWARE.
25 ********************************************************/
35 /***====================================================================***/
38 exprOpText(unsigned type)
45 strcpy(buf, "literal");
48 strcpy(buf, "identifier");
51 strcpy(buf, "action declaration");
54 strcpy(buf, "field reference");
57 strcpy(buf, "array reference");
60 strcpy(buf, "list of keysyms");
63 strcpy(buf, "list of actions");
66 strcpy(buf, "addition");
69 strcpy(buf, "subtraction");
72 strcpy(buf, "multiplication");
75 strcpy(buf, "division");
78 strcpy(buf, "assignment");
81 strcpy(buf, "logical not");
84 strcpy(buf, "arithmetic negation");
87 strcpy(buf, "bitwise inversion");
90 strcpy(buf, "plus sign");
93 snprintf(buf, sizeof(buf), "illegal(%d)", type);
100 exprTypeText(unsigned type)
107 strcpy(buf, "unknown");
110 strcpy(buf, "boolean");
116 strcpy(buf, "string");
119 strcpy(buf, "action");
122 strcpy(buf, "keyname");
125 snprintf(buf, sizeof(buf), "illegal(%d)", type);
132 ExprResolveLhs(ExprDef * expr,
133 ExprResult * elem_rtrn,
134 ExprResult * field_rtrn, ExprDef ** index_rtrn)
139 elem_rtrn->str = NULL;
140 field_rtrn->str = XkbcAtomGetString(expr->value.str);
144 elem_rtrn->str = XkbcAtomGetString(expr->value.field.element);
145 field_rtrn->str = XkbcAtomGetString(expr->value.field.field);
149 elem_rtrn->str = XkbcAtomGetString(expr->value.array.element);
150 field_rtrn->str = XkbcAtomGetString(expr->value.array.field);
151 *index_rtrn = expr->value.array.entry;
154 WSGO("Unexpected operator %d in ResolveLhs\n", expr->op);
159 SimpleLookup(char * priv,
160 uint32_t elem, uint32_t field, unsigned type, ExprResult * val_rtrn)
165 if ((priv == NULL) ||
166 (field == None) || (elem != None) ||
167 ((type != TypeInt) && (type != TypeFloat)))
171 str = XkbcAtomText(field);
172 for (entry = (LookupEntry *) priv;
173 (entry != NULL) && (entry->name != NULL); entry++)
175 if (uStrCaseCmp(str, entry->name) == 0)
177 val_rtrn->uval = entry->result;
178 if (type == TypeFloat)
179 val_rtrn->uval *= XkbGeomPtsPerMM;
187 RadioLookup(char * priv,
188 uint32_t elem, uint32_t field, unsigned type, ExprResult * val_rtrn)
193 if ((field == None) || (elem != None) || (type != TypeInt))
195 str = XkbcAtomText(field);
198 if (uStrCasePrefix("group", str))
199 str += strlen("group");
200 else if (uStrCasePrefix("radiogroup", str))
201 str += strlen("radiogroup");
202 else if (uStrCasePrefix("rg", str))
204 else if (!isdigit(str[0]))
207 if ((!str) || (sscanf(str, "%i", &rg) < 1) || (rg < 1)
208 || (rg > XkbMaxRadioGroups))
214 static LookupEntry modIndexNames[] = {
215 {"shift", ShiftMapIndex},
216 {"control", ControlMapIndex},
217 {"lock", LockMapIndex},
218 {"mod1", Mod1MapIndex},
219 {"mod2", Mod2MapIndex},
220 {"mod3", Mod3MapIndex},
221 {"mod4", Mod4MapIndex},
222 {"mod5", Mod5MapIndex},
223 {"none", XkbNoModifier},
228 LookupModIndex(char * priv,
229 uint32_t elem, uint32_t field, unsigned type, ExprResult * val_rtrn)
231 return SimpleLookup((char *) modIndexNames, elem, field, type,
236 LookupModMask(char * priv,
237 uint32_t elem, uint32_t field, unsigned type, ExprResult * val_rtrn)
242 if ((elem != None) || (type != TypeInt))
244 str = XkbcAtomGetString(field);
247 if (uStrCaseCmp(str, "all") == 0)
248 val_rtrn->uval = 0xff;
249 else if (uStrCaseCmp(str, "none") == 0)
251 else if (LookupModIndex(priv, elem, field, type, val_rtrn))
252 val_rtrn->uval = (1 << val_rtrn->uval);
253 else if (priv != NULL)
255 LookupPriv *lpriv = (LookupPriv *) priv;
256 if ((lpriv->chain == NULL) ||
257 (!(*lpriv->chain) (lpriv->chainPriv, elem, field, type,
268 ExprResolveModMask(ExprDef * expr,
269 ExprResult * val_rtrn)
275 priv.chainPriv = NULL;
276 return ExprResolveMask(expr, val_rtrn, LookupModMask, (char *) & priv);
280 ExprResolveVModMask(ExprDef * expr,
281 ExprResult * val_rtrn,
282 struct xkb_desc *xkb)
287 priv.chain = LookupVModMask;
288 priv.chainPriv = (char *) xkb;
289 return ExprResolveMask(expr, val_rtrn, LookupModMask, (char *) & priv);
293 ExprResolveBoolean(ExprDef * expr,
294 ExprResult * val_rtrn)
297 const char *bogus = NULL;
302 if (expr->type != TypeBoolean)
305 ("Found constant of type %s where boolean was expected\n",
306 exprTypeText(expr->type));
309 val_rtrn->ival = expr->value.ival;
312 bogus = XkbcAtomText(expr->value.str);
315 if ((uStrCaseCmp(bogus, "true") == 0) ||
316 (uStrCaseCmp(bogus, "yes") == 0) ||
317 (uStrCaseCmp(bogus, "on") == 0))
322 else if ((uStrCaseCmp(bogus, "false") == 0) ||
323 (uStrCaseCmp(bogus, "no") == 0) ||
324 (uStrCaseCmp(bogus, "off") == 0))
330 ERROR("Identifier \"%s\" of type int is unknown\n",
331 XkbcAtomText(expr->value.str));
334 ERROR("Default \"%s.%s\" of type boolean is unknown\n",
335 XkbcAtomText(expr->value.field.element),
336 XkbcAtomText(expr->value.field.field));
340 ok = ExprResolveBoolean(expr, val_rtrn);
342 val_rtrn->uval = !val_rtrn->uval;
349 bogus = "Subtraction";
352 bogus = "Multiplication";
358 bogus = "Assignment";
362 ERROR("%s of boolean values not permitted\n", bogus);
365 ERROR("Unary \"+\" operator not permitted for boolean values\n");
368 WSGO("Unknown operator %d in ResolveBoolean\n", expr->op);
375 ExprResolveFloat(ExprDef * expr,
376 ExprResult * val_rtrn)
379 ExprResult leftRtrn, rightRtrn;
380 ExprDef *left, *right;
385 if (expr->type == TypeString)
388 str = XkbcAtomText(expr->value.str);
389 if ((str != NULL) && (strlen(str) == 1))
391 val_rtrn->uval = str[0] * XkbGeomPtsPerMM;
395 if ((expr->type != TypeInt) && (expr->type != TypeFloat))
397 ERROR("Found constant of type %s, expected a number\n",
398 exprTypeText(expr->type));
401 val_rtrn->ival = expr->value.ival;
402 if (expr->type == TypeInt)
403 val_rtrn->ival *= XkbGeomPtsPerMM;
406 ERROR("Numeric identifier \"%s\" unknown\n",
407 XkbcAtomText(expr->value.str));
410 ERROR("Numeric default \"%s.%s\" unknown\n",
411 XkbcAtomText(expr->value.field.element),
412 XkbcAtomText(expr->value.field.field));
418 left = expr->value.binary.left;
419 right = expr->value.binary.right;
420 if (ExprResolveFloat(left, &leftRtrn) &&
421 ExprResolveFloat(right, &rightRtrn))
426 val_rtrn->ival = leftRtrn.ival + rightRtrn.ival;
429 val_rtrn->ival = leftRtrn.ival - rightRtrn.ival;
432 val_rtrn->ival = leftRtrn.ival * rightRtrn.ival;
435 val_rtrn->ival = leftRtrn.ival / rightRtrn.ival;
442 WSGO("Assignment operator not implemented yet\n");
445 ERROR("The ! operator cannot be applied to a number\n");
449 left = expr->value.child;
450 if (ExprResolveFloat(left, &leftRtrn))
452 if (expr->op == OpNegate)
453 val_rtrn->ival = -leftRtrn.ival;
455 val_rtrn->ival = ~leftRtrn.ival;
460 left = expr->value.child;
461 return ExprResolveFloat(left, val_rtrn);
463 WSGO("Unknown operator %d in ResolveFloat\n", expr->op);
470 ExprResolveKeyCode(ExprDef * expr,
471 ExprResult * val_rtrn)
473 ExprResult leftRtrn, rightRtrn;
474 ExprDef *left, *right;
479 if (expr->type != TypeInt)
482 ("Found constant of type %s where an int was expected\n",
483 exprTypeText(expr->type));
486 val_rtrn->uval = expr->value.uval;
492 left = expr->value.binary.left;
493 right = expr->value.binary.right;
494 if (ExprResolveKeyCode(left, &leftRtrn) &&
495 ExprResolveKeyCode(right, &rightRtrn))
500 val_rtrn->uval = leftRtrn.uval + rightRtrn.uval;
503 val_rtrn->uval = leftRtrn.uval - rightRtrn.uval;
506 val_rtrn->uval = leftRtrn.uval * rightRtrn.uval;
509 val_rtrn->uval = leftRtrn.uval / rightRtrn.uval;
516 left = expr->value.child;
517 if (ExprResolveKeyCode(left, &leftRtrn))
519 val_rtrn->uval = ~leftRtrn.uval;
524 left = expr->value.child;
525 return ExprResolveKeyCode(left, val_rtrn);
527 WSGO("Unknown operator %d in ResolveInteger\n", expr->op);
533 ExprResolveInteger(ExprDef * expr,
534 ExprResult * val_rtrn,
535 IdentLookupFunc lookup, char * lookupPriv)
538 ExprResult leftRtrn, rightRtrn;
539 ExprDef *left, *right;
544 if (expr->type == TypeString)
547 str = XkbcAtomText(expr->value.str);
555 val_rtrn->uval = str[0];
561 if ((expr->type != TypeInt) && (expr->type != TypeFloat))
564 ("Found constant of type %s where an int was expected\n",
565 exprTypeText(expr->type));
568 val_rtrn->ival = expr->value.ival;
569 if (expr->type == TypeFloat)
570 val_rtrn->ival /= XkbGeomPtsPerMM;
575 ok = (*lookup) (lookupPriv,
576 None, expr->value.str, TypeInt, val_rtrn);
579 ERROR("Identifier \"%s\" of type int is unknown\n",
580 XkbcAtomText(expr->value.str));
585 ok = (*lookup) (lookupPriv,
586 expr->value.field.element,
587 expr->value.field.field, TypeInt, val_rtrn);
590 ERROR("Default \"%s.%s\" of type int is unknown\n",
591 XkbcAtomText(expr->value.field.element),
592 XkbcAtomText(expr->value.field.field));
598 left = expr->value.binary.left;
599 right = expr->value.binary.right;
600 if (ExprResolveInteger(left, &leftRtrn, lookup, lookupPriv) &&
601 ExprResolveInteger(right, &rightRtrn, lookup, lookupPriv))
606 val_rtrn->ival = leftRtrn.ival + rightRtrn.ival;
609 val_rtrn->ival = leftRtrn.ival - rightRtrn.ival;
612 val_rtrn->ival = leftRtrn.ival * rightRtrn.ival;
615 val_rtrn->ival = leftRtrn.ival / rightRtrn.ival;
622 WSGO("Assignment operator not implemented yet\n");
625 left = expr->value.child;
626 if (ExprResolveInteger(left, &leftRtrn, lookup, lookupPriv))
628 ERROR("The ! operator cannot be applied to an integer\n");
633 left = expr->value.child;
634 if (ExprResolveInteger(left, &leftRtrn, lookup, lookupPriv))
636 if (expr->op == OpNegate)
637 val_rtrn->ival = -leftRtrn.ival;
639 val_rtrn->ival = ~leftRtrn.ival;
644 left = expr->value.child;
645 return ExprResolveInteger(left, val_rtrn, lookup, lookupPriv);
647 WSGO("Unknown operator %d in ResolveInteger\n", expr->op);
654 ExprResolveRadioGroup(ExprDef * expr,
655 ExprResult * val_rtrn)
657 return ExprResolveInteger(expr, val_rtrn, RadioLookup, NULL);
661 ExprResolveGroup(ExprDef * expr,
662 ExprResult * val_rtrn)
664 static LookupEntry group_names[] = {
676 return ExprResolveInteger(expr, val_rtrn, SimpleLookup,
677 (char *) group_names);
681 ExprResolveLevel(ExprDef * expr,
682 ExprResult * val_rtrn)
684 static LookupEntry level_names[] = {
696 return ExprResolveInteger(expr, val_rtrn, SimpleLookup,
697 (char *) level_names);
701 ExprResolveButton(ExprDef * expr,
702 ExprResult * val_rtrn)
704 static LookupEntry button_names[] = {
714 return ExprResolveInteger(expr, val_rtrn, SimpleLookup,
715 (char *) button_names);
719 ExprResolveString(ExprDef * expr,
720 ExprResult * val_rtrn)
722 ExprResult leftRtrn, rightRtrn;
730 if (expr->type != TypeString)
732 ERROR("Found constant of type %s, expected a string\n",
733 exprTypeText(expr->type));
736 val_rtrn->str = XkbcAtomGetString(expr->value.str);
737 if (val_rtrn->str == NULL)
738 val_rtrn->str = strdup("");
741 ERROR("Identifier \"%s\" of type string not found\n",
742 XkbcAtomText(expr->value.str));
745 ERROR("Default \"%s.%s\" of type string not found\n",
746 XkbcAtomText(expr->value.field.element),
747 XkbcAtomText(expr->value.field.field));
750 left = expr->value.binary.left;
751 right = expr->value.binary.right;
752 if (ExprResolveString(left, &leftRtrn) &&
753 ExprResolveString(right, &rightRtrn))
757 len = strlen(leftRtrn.str) + strlen(rightRtrn.str) + 1;
758 new = (char *) malloc(len);
760 { sprintf(new, "%s%s", leftRtrn.str, rightRtrn.str);
772 bogus = "Subtraction";
775 bogus = "Multiplication";
781 bogus = "Assignment";
787 bogus = "Bitwise complement";
788 ERROR("%s of string values not permitted\n", bogus);
791 ERROR("The ! operator cannot be applied to a string\n");
794 ERROR("The + operator cannot be applied to a string\n");
797 WSGO("Unknown operator %d in ResolveString\n", expr->op);
804 ExprResolveKeyName(ExprDef * expr,
805 ExprResult * val_rtrn)
812 if (expr->type != TypeKeyName)
814 ERROR("Found constant of type %s, expected a key name\n",
815 exprTypeText(expr->type));
818 memcpy(val_rtrn->keyName.name, expr->value.keyName, XkbKeyNameLength);
821 ERROR("Identifier \"%s\" of type string not found\n",
822 XkbcAtomText(expr->value.str));
825 ERROR("Default \"%s.%s\" of type key name not found\n",
826 XkbcAtomText(expr->value.field.element),
827 XkbcAtomText(expr->value.field.field));
834 bogus = "Subtraction";
837 bogus = "Multiplication";
843 bogus = "Assignment";
849 bogus = "Bitwise complement";
850 ERROR("%s of key name values not permitted\n", bogus);
853 ERROR("The ! operator cannot be applied to a key name\n");
856 ERROR("The + operator cannot be applied to a key name\n");
859 WSGO("Unknown operator %d in ResolveKeyName\n", expr->op);
865 /***====================================================================***/
868 ExprResolveEnum(ExprDef * expr, ExprResult * val_rtrn, LookupEntry * values)
870 if (expr->op != ExprIdent)
872 ERROR("Found a %s where an enumerated value was expected\n",
873 exprOpText(expr->op));
876 if (!SimpleLookup((char *) values, (uint32_t) None, expr->value.str,
877 (unsigned) TypeInt, val_rtrn))
880 ERROR("Illegal identifier %s (expected one of: ",
881 XkbcAtomText(expr->value.str));
882 while (values && values->name)
885 INFO(", %s", values->name);
887 INFO("%s", values->name);
898 ExprResolveMask(ExprDef * expr,
899 ExprResult * val_rtrn,
900 IdentLookupFunc lookup, char * lookupPriv)
903 ExprResult leftRtrn, rightRtrn;
904 ExprDef *left, *right;
910 if (expr->type != TypeInt)
913 ("Found constant of type %s where a mask was expected\n",
914 exprTypeText(expr->type));
917 val_rtrn->ival = expr->value.ival;
922 ok = (*lookup) (lookupPriv,
923 None, expr->value.str, TypeInt, val_rtrn);
926 ERROR("Identifier \"%s\" of type int is unknown\n",
927 XkbcAtomText(expr->value.str));
932 ok = (*lookup) (lookupPriv,
933 expr->value.field.element,
934 expr->value.field.field, TypeInt, val_rtrn);
937 ERROR("Default \"%s.%s\" of type int is unknown\n",
938 XkbcAtomText(expr->value.field.element),
939 XkbcAtomText(expr->value.field.field));
942 bogus = "array reference";
945 bogus = "function use";
946 ERROR("Unexpected %s in mask expression\n", bogus);
947 ACTION("Expression ignored\n");
953 left = expr->value.binary.left;
954 right = expr->value.binary.right;
955 if (ExprResolveMask(left, &leftRtrn, lookup, lookupPriv) &&
956 ExprResolveMask(right, &rightRtrn, lookup, lookupPriv))
961 val_rtrn->ival = leftRtrn.ival | rightRtrn.ival;
964 val_rtrn->ival = leftRtrn.ival & (~rightRtrn.ival);
968 ERROR("Cannot %s masks\n",
969 expr->op == OpDivide ? "divide" : "multiply");
970 ACTION("Illegal operation ignored\n");
977 WSGO("Assignment operator not implemented yet\n");
980 left = expr->value.child;
981 if (ExprResolveInteger(left, &leftRtrn, lookup, lookupPriv))
983 val_rtrn->ival = ~leftRtrn.ival;
990 left = expr->value.child;
991 if (ExprResolveInteger(left, &leftRtrn, lookup, lookupPriv))
993 ERROR("The %s operator cannot be used with a mask\n",
994 (expr->op == OpNegate ? "-" : "!"));
998 WSGO("Unknown operator %d in ResolveMask\n", expr->op);
1005 ExprResolveKeySym(ExprDef * expr,
1006 ExprResult * val_rtrn)
1011 if (expr->op == ExprIdent)
1014 str = XkbcAtomText(expr->value.str);
1015 if ((str != NULL) && ((sym = xkb_string_to_keysym(str)) != NoSymbol))
1017 val_rtrn->uval = sym;
1021 ok = ExprResolveInteger(expr, val_rtrn, NULL, NULL);
1022 if ((ok) && (val_rtrn->uval < 10))
1023 val_rtrn->uval += '0';