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,
270 IdentLookupFunc lookup, char * lookupPriv)
276 priv.chainPriv = lookupPriv;
277 return ExprResolveMask(expr, val_rtrn, LookupModMask, (char *) & priv);
281 ExprResolveVModMask(ExprDef * expr,
282 ExprResult * val_rtrn,
283 struct xkb_desc *xkb)
288 priv.chain = LookupVModMask;
289 priv.chainPriv = (char *) xkb;
290 return ExprResolveMask(expr, val_rtrn, LookupModMask, (char *) & priv);
294 ExprResolveBoolean(ExprDef * expr,
295 ExprResult * val_rtrn,
296 IdentLookupFunc lookup, char * lookupPriv)
299 const char *bogus = NULL;
304 if (expr->type != TypeBoolean)
307 ("Found constant of type %s where boolean was expected\n",
308 exprTypeText(expr->type));
311 val_rtrn->ival = expr->value.ival;
314 bogus = XkbcAtomText(expr->value.str);
317 if ((uStrCaseCmp(bogus, "true") == 0) ||
318 (uStrCaseCmp(bogus, "yes") == 0) ||
319 (uStrCaseCmp(bogus, "on") == 0))
324 else if ((uStrCaseCmp(bogus, "false") == 0) ||
325 (uStrCaseCmp(bogus, "no") == 0) ||
326 (uStrCaseCmp(bogus, "off") == 0))
334 ok = (*lookup) (lookupPriv,
335 None, expr->value.str, TypeBoolean, val_rtrn);
338 ERROR("Identifier \"%s\" of type int is unknown\n",
339 XkbcAtomText(expr->value.str));
344 ok = (*lookup) (lookupPriv,
345 expr->value.field.element,
346 expr->value.field.field, TypeBoolean, val_rtrn);
349 ERROR("Default \"%s.%s\" of type boolean is unknown\n",
350 XkbcAtomText(expr->value.field.element),
351 XkbcAtomText(expr->value.field.field));
355 ok = ExprResolveBoolean(expr, val_rtrn, lookup, lookupPriv);
357 val_rtrn->uval = !val_rtrn->uval;
364 bogus = "Subtraction";
367 bogus = "Multiplication";
373 bogus = "Assignment";
377 ERROR("%s of boolean values not permitted\n", bogus);
380 ERROR("Unary \"+\" operator not permitted for boolean values\n");
383 WSGO("Unknown operator %d in ResolveBoolean\n", expr->op);
390 ExprResolveFloat(ExprDef * expr,
391 ExprResult * val_rtrn,
392 IdentLookupFunc lookup, char * lookupPriv)
395 ExprResult leftRtrn, rightRtrn;
396 ExprDef *left, *right;
401 if (expr->type == TypeString)
404 str = XkbcAtomText(expr->value.str);
405 if ((str != NULL) && (strlen(str) == 1))
407 val_rtrn->uval = str[0] * XkbGeomPtsPerMM;
411 if ((expr->type != TypeInt) && (expr->type != TypeFloat))
413 ERROR("Found constant of type %s, expected a number\n",
414 exprTypeText(expr->type));
417 val_rtrn->ival = expr->value.ival;
418 if (expr->type == TypeInt)
419 val_rtrn->ival *= XkbGeomPtsPerMM;
424 ok = (*lookup) (lookupPriv,
425 None, expr->value.str, TypeFloat, val_rtrn);
428 ERROR("Numeric identifier \"%s\" unknown\n",
429 XkbcAtomText(expr->value.str));
434 ok = (*lookup) (lookupPriv,
435 expr->value.field.element,
436 expr->value.field.field, TypeFloat, val_rtrn);
439 ERROR("Numeric default \"%s.%s\" unknown\n",
440 XkbcAtomText(expr->value.field.element),
441 XkbcAtomText(expr->value.field.field));
447 left = expr->value.binary.left;
448 right = expr->value.binary.right;
449 if (ExprResolveFloat(left, &leftRtrn, lookup, lookupPriv) &&
450 ExprResolveFloat(right, &rightRtrn, lookup, lookupPriv))
455 val_rtrn->ival = leftRtrn.ival + rightRtrn.ival;
458 val_rtrn->ival = leftRtrn.ival - rightRtrn.ival;
461 val_rtrn->ival = leftRtrn.ival * rightRtrn.ival;
464 val_rtrn->ival = leftRtrn.ival / rightRtrn.ival;
471 WSGO("Assignment operator not implemented yet\n");
474 left = expr->value.child;
475 if (ExprResolveFloat(left, &leftRtrn, lookup, lookupPriv))
477 ERROR("The ! operator cannot be applied to a number\n");
482 left = expr->value.child;
483 if (ExprResolveFloat(left, &leftRtrn, lookup, lookupPriv))
485 if (expr->op == OpNegate)
486 val_rtrn->ival = -leftRtrn.ival;
488 val_rtrn->ival = ~leftRtrn.ival;
493 left = expr->value.child;
494 return ExprResolveFloat(left, val_rtrn, lookup, lookupPriv);
496 WSGO("Unknown operator %d in ResolveFloat\n", expr->op);
503 ExprResolveKeyCode(ExprDef * expr,
504 ExprResult * val_rtrn)
506 ExprResult leftRtrn, rightRtrn;
507 ExprDef *left, *right;
512 if (expr->type != TypeInt)
515 ("Found constant of type %s where an int was expected\n",
516 exprTypeText(expr->type));
519 val_rtrn->uval = expr->value.uval;
525 left = expr->value.binary.left;
526 right = expr->value.binary.right;
527 if (ExprResolveKeyCode(left, &leftRtrn) &&
528 ExprResolveKeyCode(right, &rightRtrn))
533 val_rtrn->uval = leftRtrn.uval + rightRtrn.uval;
536 val_rtrn->uval = leftRtrn.uval - rightRtrn.uval;
539 val_rtrn->uval = leftRtrn.uval * rightRtrn.uval;
542 val_rtrn->uval = leftRtrn.uval / rightRtrn.uval;
549 left = expr->value.child;
550 if (ExprResolveKeyCode(left, &leftRtrn))
552 val_rtrn->uval = ~leftRtrn.uval;
557 left = expr->value.child;
558 return ExprResolveKeyCode(left, val_rtrn);
560 WSGO("Unknown operator %d in ResolveInteger\n", expr->op);
566 ExprResolveInteger(ExprDef * expr,
567 ExprResult * val_rtrn,
568 IdentLookupFunc lookup, char * lookupPriv)
571 ExprResult leftRtrn, rightRtrn;
572 ExprDef *left, *right;
577 if (expr->type == TypeString)
580 str = XkbcAtomText(expr->value.str);
588 val_rtrn->uval = str[0];
594 if ((expr->type != TypeInt) && (expr->type != TypeFloat))
597 ("Found constant of type %s where an int was expected\n",
598 exprTypeText(expr->type));
601 val_rtrn->ival = expr->value.ival;
602 if (expr->type == TypeFloat)
603 val_rtrn->ival /= XkbGeomPtsPerMM;
608 ok = (*lookup) (lookupPriv,
609 None, expr->value.str, TypeInt, val_rtrn);
612 ERROR("Identifier \"%s\" of type int is unknown\n",
613 XkbcAtomText(expr->value.str));
618 ok = (*lookup) (lookupPriv,
619 expr->value.field.element,
620 expr->value.field.field, TypeInt, val_rtrn);
623 ERROR("Default \"%s.%s\" of type int is unknown\n",
624 XkbcAtomText(expr->value.field.element),
625 XkbcAtomText(expr->value.field.field));
631 left = expr->value.binary.left;
632 right = expr->value.binary.right;
633 if (ExprResolveInteger(left, &leftRtrn, lookup, lookupPriv) &&
634 ExprResolveInteger(right, &rightRtrn, lookup, lookupPriv))
639 val_rtrn->ival = leftRtrn.ival + rightRtrn.ival;
642 val_rtrn->ival = leftRtrn.ival - rightRtrn.ival;
645 val_rtrn->ival = leftRtrn.ival * rightRtrn.ival;
648 val_rtrn->ival = leftRtrn.ival / rightRtrn.ival;
655 WSGO("Assignment operator not implemented yet\n");
658 left = expr->value.child;
659 if (ExprResolveInteger(left, &leftRtrn, lookup, lookupPriv))
661 ERROR("The ! operator cannot be applied to an integer\n");
666 left = expr->value.child;
667 if (ExprResolveInteger(left, &leftRtrn, lookup, lookupPriv))
669 if (expr->op == OpNegate)
670 val_rtrn->ival = -leftRtrn.ival;
672 val_rtrn->ival = ~leftRtrn.ival;
677 left = expr->value.child;
678 return ExprResolveInteger(left, val_rtrn, lookup, lookupPriv);
680 WSGO("Unknown operator %d in ResolveInteger\n", expr->op);
687 ExprResolveString(ExprDef * expr,
688 ExprResult * val_rtrn,
689 IdentLookupFunc lookup, char * lookupPriv)
692 ExprResult leftRtrn, rightRtrn;
700 if (expr->type != TypeString)
702 ERROR("Found constant of type %s, expected a string\n",
703 exprTypeText(expr->type));
706 val_rtrn->str = XkbcAtomGetString(expr->value.str);
707 if (val_rtrn->str == NULL)
708 val_rtrn->str = strdup("");
713 ok = (*lookup) (lookupPriv,
714 None, expr->value.str, TypeString, val_rtrn);
717 ERROR("Identifier \"%s\" of type string not found\n",
718 XkbcAtomText(expr->value.str));
723 ok = (*lookup) (lookupPriv,
724 expr->value.field.element,
725 expr->value.field.field, TypeString, val_rtrn);
728 ERROR("Default \"%s.%s\" of type string not found\n",
729 XkbcAtomText(expr->value.field.element),
730 XkbcAtomText(expr->value.field.field));
733 left = expr->value.binary.left;
734 right = expr->value.binary.right;
735 if (ExprResolveString(left, &leftRtrn, lookup, lookupPriv) &&
736 ExprResolveString(right, &rightRtrn, lookup, lookupPriv))
740 len = strlen(leftRtrn.str) + strlen(rightRtrn.str) + 1;
741 new = (char *) malloc(len);
744 sprintf(new, "%s%s", leftRtrn.str, rightRtrn.str);
756 bogus = "Subtraction";
759 bogus = "Multiplication";
765 bogus = "Assignment";
771 bogus = "Bitwise complement";
772 ERROR("%s of string values not permitted\n", bogus);
775 left = expr->value.child;
776 if (ExprResolveString(left, &leftRtrn, lookup, lookupPriv))
778 ERROR("The ! operator cannot be applied to a string\n");
782 left = expr->value.child;
783 if (ExprResolveString(left, &leftRtrn, lookup, lookupPriv))
785 ERROR("The + operator cannot be applied to a string\n");
789 WSGO("Unknown operator %d in ResolveString\n", expr->op);
796 ExprResolveKeyName(ExprDef * expr,
797 ExprResult * val_rtrn,
798 IdentLookupFunc lookup, char * lookupPriv)
808 if (expr->type != TypeKeyName)
810 ERROR("Found constant of type %s, expected a key name\n",
811 exprTypeText(expr->type));
814 memcpy(val_rtrn->keyName.name, expr->value.keyName, XkbKeyNameLength);
819 ok = (*lookup) (lookupPriv,
820 None, expr->value.str, TypeString, val_rtrn);
823 ERROR("Identifier \"%s\" of type string not found\n",
824 XkbcAtomText(expr->value.str));
829 ok = (*lookup) (lookupPriv,
830 expr->value.field.element,
831 expr->value.field.field, TypeString, val_rtrn);
834 ERROR("Default \"%s.%s\" of type key name not found\n",
835 XkbcAtomText(expr->value.field.element),
836 XkbcAtomText(expr->value.field.field));
843 bogus = "Subtraction";
846 bogus = "Multiplication";
852 bogus = "Assignment";
858 bogus = "Bitwise complement";
859 ERROR("%s of key name values not permitted\n", bogus);
862 left = expr->value.binary.left;
863 if (ExprResolveString(left, &leftRtrn, lookup, lookupPriv))
865 ERROR("The ! operator cannot be applied to a key name\n");
869 left = expr->value.binary.left;
870 if (ExprResolveString(left, &leftRtrn, lookup, lookupPriv))
872 ERROR("The + operator cannot be applied to a key name\n");
876 WSGO("Unknown operator %d in ResolveKeyName\n", expr->op);
882 /***====================================================================***/
885 ExprResolveEnum(ExprDef * expr, ExprResult * val_rtrn, LookupEntry * values)
887 if (expr->op != ExprIdent)
889 ERROR("Found a %s where an enumerated value was expected\n",
890 exprOpText(expr->op));
893 if (!SimpleLookup((char *) values, (uint32_t) None, expr->value.str,
894 (unsigned) TypeInt, val_rtrn))
897 ERROR("Illegal identifier %s (expected one of: ",
898 XkbcAtomText(expr->value.str));
899 while (values && values->name)
902 INFO(", %s", values->name);
904 INFO("%s", values->name);
915 ExprResolveMask(ExprDef * expr,
916 ExprResult * val_rtrn,
917 IdentLookupFunc lookup, char * lookupPriv)
920 ExprResult leftRtrn, rightRtrn;
921 ExprDef *left, *right;
927 if (expr->type != TypeInt)
930 ("Found constant of type %s where a mask was expected\n",
931 exprTypeText(expr->type));
934 val_rtrn->ival = expr->value.ival;
939 ok = (*lookup) (lookupPriv,
940 None, expr->value.str, TypeInt, val_rtrn);
943 ERROR("Identifier \"%s\" of type int is unknown\n",
944 XkbcAtomText(expr->value.str));
949 ok = (*lookup) (lookupPriv,
950 expr->value.field.element,
951 expr->value.field.field, TypeInt, val_rtrn);
954 ERROR("Default \"%s.%s\" of type int is unknown\n",
955 XkbcAtomText(expr->value.field.element),
956 XkbcAtomText(expr->value.field.field));
959 bogus = "array reference";
962 bogus = "function use";
963 ERROR("Unexpected %s in mask expression\n", bogus);
964 ACTION("Expression ignored\n");
970 left = expr->value.binary.left;
971 right = expr->value.binary.right;
972 if (ExprResolveMask(left, &leftRtrn, lookup, lookupPriv) &&
973 ExprResolveMask(right, &rightRtrn, lookup, lookupPriv))
978 val_rtrn->ival = leftRtrn.ival | rightRtrn.ival;
981 val_rtrn->ival = leftRtrn.ival & (~rightRtrn.ival);
985 ERROR("Cannot %s masks\n",
986 expr->op == OpDivide ? "divide" : "multiply");
987 ACTION("Illegal operation ignored\n");
994 WSGO("Assignment operator not implemented yet\n");
997 left = expr->value.child;
998 if (ExprResolveInteger(left, &leftRtrn, lookup, lookupPriv))
1000 val_rtrn->ival = ~leftRtrn.ival;
1007 left = expr->value.child;
1008 if (ExprResolveInteger(left, &leftRtrn, lookup, lookupPriv))
1010 ERROR("The %s operator cannot be used with a mask\n",
1011 (expr->op == OpNegate ? "-" : "!"));
1015 WSGO("Unknown operator %d in ResolveMask\n", expr->op);
1022 ExprResolveKeySym(ExprDef * expr,
1023 ExprResult * val_rtrn,
1024 IdentLookupFunc lookup, char * lookupPriv)
1029 if (expr->op == ExprIdent)
1032 str = XkbcAtomText(expr->value.str);
1033 if ((str != NULL) && ((sym = xkb_string_to_keysym(str)) != NoSymbol))
1035 val_rtrn->uval = sym;
1039 ok = ExprResolveInteger(expr, val_rtrn, lookup, lookupPriv);
1040 if ((ok) && (val_rtrn->uval < 10))
1041 val_rtrn->uval += '0';