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 ExprResolveString(ExprDef * expr,
662 ExprResult * val_rtrn)
664 ExprResult leftRtrn, rightRtrn;
672 if (expr->type != TypeString)
674 ERROR("Found constant of type %s, expected a string\n",
675 exprTypeText(expr->type));
678 val_rtrn->str = XkbcAtomGetString(expr->value.str);
679 if (val_rtrn->str == NULL)
680 val_rtrn->str = strdup("");
683 ERROR("Identifier \"%s\" of type string not found\n",
684 XkbcAtomText(expr->value.str));
687 ERROR("Default \"%s.%s\" of type string not found\n",
688 XkbcAtomText(expr->value.field.element),
689 XkbcAtomText(expr->value.field.field));
692 left = expr->value.binary.left;
693 right = expr->value.binary.right;
694 if (ExprResolveString(left, &leftRtrn) &&
695 ExprResolveString(right, &rightRtrn))
699 len = strlen(leftRtrn.str) + strlen(rightRtrn.str) + 1;
700 new = (char *) malloc(len);
702 { sprintf(new, "%s%s", leftRtrn.str, rightRtrn.str);
714 bogus = "Subtraction";
717 bogus = "Multiplication";
723 bogus = "Assignment";
729 bogus = "Bitwise complement";
730 ERROR("%s of string values not permitted\n", bogus);
733 ERROR("The ! operator cannot be applied to a string\n");
736 ERROR("The + operator cannot be applied to a string\n");
739 WSGO("Unknown operator %d in ResolveString\n", expr->op);
746 ExprResolveKeyName(ExprDef * expr,
747 ExprResult * val_rtrn)
754 if (expr->type != TypeKeyName)
756 ERROR("Found constant of type %s, expected a key name\n",
757 exprTypeText(expr->type));
760 memcpy(val_rtrn->keyName.name, expr->value.keyName, XkbKeyNameLength);
763 ERROR("Identifier \"%s\" of type string not found\n",
764 XkbcAtomText(expr->value.str));
767 ERROR("Default \"%s.%s\" of type key name not found\n",
768 XkbcAtomText(expr->value.field.element),
769 XkbcAtomText(expr->value.field.field));
776 bogus = "Subtraction";
779 bogus = "Multiplication";
785 bogus = "Assignment";
791 bogus = "Bitwise complement";
792 ERROR("%s of key name values not permitted\n", bogus);
795 ERROR("The ! operator cannot be applied to a key name\n");
798 ERROR("The + operator cannot be applied to a key name\n");
801 WSGO("Unknown operator %d in ResolveKeyName\n", expr->op);
807 /***====================================================================***/
810 ExprResolveEnum(ExprDef * expr, ExprResult * val_rtrn, LookupEntry * values)
812 if (expr->op != ExprIdent)
814 ERROR("Found a %s where an enumerated value was expected\n",
815 exprOpText(expr->op));
818 if (!SimpleLookup((char *) values, (uint32_t) None, expr->value.str,
819 (unsigned) TypeInt, val_rtrn))
822 ERROR("Illegal identifier %s (expected one of: ",
823 XkbcAtomText(expr->value.str));
824 while (values && values->name)
827 INFO(", %s", values->name);
829 INFO("%s", values->name);
840 ExprResolveMask(ExprDef * expr,
841 ExprResult * val_rtrn,
842 IdentLookupFunc lookup, char * lookupPriv)
845 ExprResult leftRtrn, rightRtrn;
846 ExprDef *left, *right;
852 if (expr->type != TypeInt)
855 ("Found constant of type %s where a mask was expected\n",
856 exprTypeText(expr->type));
859 val_rtrn->ival = expr->value.ival;
864 ok = (*lookup) (lookupPriv,
865 None, expr->value.str, TypeInt, val_rtrn);
868 ERROR("Identifier \"%s\" of type int is unknown\n",
869 XkbcAtomText(expr->value.str));
874 ok = (*lookup) (lookupPriv,
875 expr->value.field.element,
876 expr->value.field.field, TypeInt, val_rtrn);
879 ERROR("Default \"%s.%s\" of type int is unknown\n",
880 XkbcAtomText(expr->value.field.element),
881 XkbcAtomText(expr->value.field.field));
884 bogus = "array reference";
887 bogus = "function use";
888 ERROR("Unexpected %s in mask expression\n", bogus);
889 ACTION("Expression ignored\n");
895 left = expr->value.binary.left;
896 right = expr->value.binary.right;
897 if (ExprResolveMask(left, &leftRtrn, lookup, lookupPriv) &&
898 ExprResolveMask(right, &rightRtrn, lookup, lookupPriv))
903 val_rtrn->ival = leftRtrn.ival | rightRtrn.ival;
906 val_rtrn->ival = leftRtrn.ival & (~rightRtrn.ival);
910 ERROR("Cannot %s masks\n",
911 expr->op == OpDivide ? "divide" : "multiply");
912 ACTION("Illegal operation ignored\n");
919 WSGO("Assignment operator not implemented yet\n");
922 left = expr->value.child;
923 if (ExprResolveInteger(left, &leftRtrn, lookup, lookupPriv))
925 val_rtrn->ival = ~leftRtrn.ival;
932 left = expr->value.child;
933 if (ExprResolveInteger(left, &leftRtrn, lookup, lookupPriv))
935 ERROR("The %s operator cannot be used with a mask\n",
936 (expr->op == OpNegate ? "-" : "!"));
940 WSGO("Unknown operator %d in ResolveMask\n", expr->op);
947 ExprResolveKeySym(ExprDef * expr,
948 ExprResult * val_rtrn)
953 if (expr->op == ExprIdent)
956 str = XkbcAtomText(expr->value.str);
957 if ((str != NULL) && ((sym = xkb_string_to_keysym(str)) != NoSymbol))
959 val_rtrn->uval = sym;
963 ok = ExprResolveInteger(expr, val_rtrn, NULL, NULL);
964 if ((ok) && (val_rtrn->uval < 10))
965 val_rtrn->uval += '0';