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 ExprResolveLevel(ExprDef * expr,
662 ExprResult * val_rtrn)
664 static LookupEntry level_names[] = {
676 return ExprResolveInteger(expr, val_rtrn, SimpleLookup,
677 (char *) level_names);
681 ExprResolveButton(ExprDef * expr,
682 ExprResult * val_rtrn)
684 static LookupEntry button_names[] = {
694 return ExprResolveInteger(expr, val_rtrn, SimpleLookup,
695 (char *) button_names);
699 ExprResolveString(ExprDef * expr,
700 ExprResult * val_rtrn)
702 ExprResult leftRtrn, rightRtrn;
710 if (expr->type != TypeString)
712 ERROR("Found constant of type %s, expected a string\n",
713 exprTypeText(expr->type));
716 val_rtrn->str = XkbcAtomGetString(expr->value.str);
717 if (val_rtrn->str == NULL)
718 val_rtrn->str = strdup("");
721 ERROR("Identifier \"%s\" of type string not found\n",
722 XkbcAtomText(expr->value.str));
725 ERROR("Default \"%s.%s\" of type string not found\n",
726 XkbcAtomText(expr->value.field.element),
727 XkbcAtomText(expr->value.field.field));
730 left = expr->value.binary.left;
731 right = expr->value.binary.right;
732 if (ExprResolveString(left, &leftRtrn) &&
733 ExprResolveString(right, &rightRtrn))
737 len = strlen(leftRtrn.str) + strlen(rightRtrn.str) + 1;
738 new = (char *) malloc(len);
740 { sprintf(new, "%s%s", leftRtrn.str, rightRtrn.str);
752 bogus = "Subtraction";
755 bogus = "Multiplication";
761 bogus = "Assignment";
767 bogus = "Bitwise complement";
768 ERROR("%s of string values not permitted\n", bogus);
771 ERROR("The ! operator cannot be applied to a string\n");
774 ERROR("The + operator cannot be applied to a string\n");
777 WSGO("Unknown operator %d in ResolveString\n", expr->op);
784 ExprResolveKeyName(ExprDef * expr,
785 ExprResult * val_rtrn)
792 if (expr->type != TypeKeyName)
794 ERROR("Found constant of type %s, expected a key name\n",
795 exprTypeText(expr->type));
798 memcpy(val_rtrn->keyName.name, expr->value.keyName, XkbKeyNameLength);
801 ERROR("Identifier \"%s\" of type string not found\n",
802 XkbcAtomText(expr->value.str));
805 ERROR("Default \"%s.%s\" of type key name not found\n",
806 XkbcAtomText(expr->value.field.element),
807 XkbcAtomText(expr->value.field.field));
814 bogus = "Subtraction";
817 bogus = "Multiplication";
823 bogus = "Assignment";
829 bogus = "Bitwise complement";
830 ERROR("%s of key name values not permitted\n", bogus);
833 ERROR("The ! operator cannot be applied to a key name\n");
836 ERROR("The + operator cannot be applied to a key name\n");
839 WSGO("Unknown operator %d in ResolveKeyName\n", expr->op);
845 /***====================================================================***/
848 ExprResolveEnum(ExprDef * expr, ExprResult * val_rtrn, LookupEntry * values)
850 if (expr->op != ExprIdent)
852 ERROR("Found a %s where an enumerated value was expected\n",
853 exprOpText(expr->op));
856 if (!SimpleLookup((char *) values, (uint32_t) None, expr->value.str,
857 (unsigned) TypeInt, val_rtrn))
860 ERROR("Illegal identifier %s (expected one of: ",
861 XkbcAtomText(expr->value.str));
862 while (values && values->name)
865 INFO(", %s", values->name);
867 INFO("%s", values->name);
878 ExprResolveMask(ExprDef * expr,
879 ExprResult * val_rtrn,
880 IdentLookupFunc lookup, char * lookupPriv)
883 ExprResult leftRtrn, rightRtrn;
884 ExprDef *left, *right;
890 if (expr->type != TypeInt)
893 ("Found constant of type %s where a mask was expected\n",
894 exprTypeText(expr->type));
897 val_rtrn->ival = expr->value.ival;
902 ok = (*lookup) (lookupPriv,
903 None, expr->value.str, TypeInt, val_rtrn);
906 ERROR("Identifier \"%s\" of type int is unknown\n",
907 XkbcAtomText(expr->value.str));
912 ok = (*lookup) (lookupPriv,
913 expr->value.field.element,
914 expr->value.field.field, TypeInt, val_rtrn);
917 ERROR("Default \"%s.%s\" of type int is unknown\n",
918 XkbcAtomText(expr->value.field.element),
919 XkbcAtomText(expr->value.field.field));
922 bogus = "array reference";
925 bogus = "function use";
926 ERROR("Unexpected %s in mask expression\n", bogus);
927 ACTION("Expression ignored\n");
933 left = expr->value.binary.left;
934 right = expr->value.binary.right;
935 if (ExprResolveMask(left, &leftRtrn, lookup, lookupPriv) &&
936 ExprResolveMask(right, &rightRtrn, lookup, lookupPriv))
941 val_rtrn->ival = leftRtrn.ival | rightRtrn.ival;
944 val_rtrn->ival = leftRtrn.ival & (~rightRtrn.ival);
948 ERROR("Cannot %s masks\n",
949 expr->op == OpDivide ? "divide" : "multiply");
950 ACTION("Illegal operation ignored\n");
957 WSGO("Assignment operator not implemented yet\n");
960 left = expr->value.child;
961 if (ExprResolveInteger(left, &leftRtrn, lookup, lookupPriv))
963 val_rtrn->ival = ~leftRtrn.ival;
970 left = expr->value.child;
971 if (ExprResolveInteger(left, &leftRtrn, lookup, lookupPriv))
973 ERROR("The %s operator cannot be used with a mask\n",
974 (expr->op == OpNegate ? "-" : "!"));
978 WSGO("Unknown operator %d in ResolveMask\n", expr->op);
985 ExprResolveKeySym(ExprDef * expr,
986 ExprResult * val_rtrn)
991 if (expr->op == ExprIdent)
994 str = XkbcAtomText(expr->value.str);
995 if ((str != NULL) && ((sym = xkb_string_to_keysym(str)) != NoSymbol))
997 val_rtrn->uval = sym;
1001 ok = ExprResolveInteger(expr, val_rtrn, NULL, NULL);
1002 if ((ok) && (val_rtrn->uval < 10))
1003 val_rtrn->uval += '0';