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 ********************************************************/
34 /***====================================================================***/
37 exprOpText(unsigned type)
44 strcpy(buf, "literal");
47 strcpy(buf, "identifier");
50 strcpy(buf, "action declaration");
53 strcpy(buf, "field reference");
56 strcpy(buf, "array reference");
59 strcpy(buf, "list of keysyms");
62 strcpy(buf, "list of actions");
65 strcpy(buf, "addition");
68 strcpy(buf, "subtraction");
71 strcpy(buf, "multiplication");
74 strcpy(buf, "division");
77 strcpy(buf, "assignment");
80 strcpy(buf, "logical not");
83 strcpy(buf, "arithmetic negation");
86 strcpy(buf, "bitwise inversion");
89 strcpy(buf, "plus sign");
92 snprintf(buf, sizeof(buf), "illegal(%d)", type);
99 exprTypeText(unsigned type)
106 strcpy(buf, "unknown");
109 strcpy(buf, "boolean");
115 strcpy(buf, "string");
118 strcpy(buf, "action");
121 strcpy(buf, "keyname");
124 snprintf(buf, sizeof(buf), "illegal(%d)", type);
131 ExprResolveLhs(ExprDef * expr,
132 ExprResult * elem_rtrn,
133 ExprResult * field_rtrn, ExprDef ** index_rtrn)
138 elem_rtrn->str = NULL;
139 field_rtrn->str = XkbcAtomGetString(expr->value.str);
143 elem_rtrn->str = XkbcAtomGetString(expr->value.field.element);
144 field_rtrn->str = XkbcAtomGetString(expr->value.field.field);
148 elem_rtrn->str = XkbcAtomGetString(expr->value.array.element);
149 field_rtrn->str = XkbcAtomGetString(expr->value.array.field);
150 *index_rtrn = expr->value.array.entry;
153 WSGO("Unexpected operator %d in ResolveLhs\n", expr->op);
158 SimpleLookup(char * priv,
159 uint32_t elem, uint32_t field, unsigned type, ExprResult * val_rtrn)
164 if ((priv == NULL) ||
165 (field == None) || (elem != None) ||
166 ((type != TypeInt) && (type != TypeFloat)))
170 str = XkbcAtomText(field);
171 for (entry = (LookupEntry *) priv;
172 (entry != NULL) && (entry->name != NULL); entry++)
174 if (uStrCaseCmp(str, entry->name) == 0)
176 val_rtrn->uval = entry->result;
177 if (type == TypeFloat)
178 val_rtrn->uval *= XkbGeomPtsPerMM;
186 RadioLookup(char * priv,
187 uint32_t elem, uint32_t field, unsigned type, ExprResult * val_rtrn)
192 if ((field == None) || (elem != None) || (type != TypeInt))
194 str = XkbcAtomText(field);
197 if (uStrCasePrefix("group", str))
198 str += strlen("group");
199 else if (uStrCasePrefix("radiogroup", str))
200 str += strlen("radiogroup");
201 else if (uStrCasePrefix("rg", str))
203 else if (!isdigit(str[0]))
206 if ((!str) || (sscanf(str, "%i", &rg) < 1) || (rg < 1)
207 || (rg > XkbMaxRadioGroups))
213 static LookupEntry modIndexNames[] = {
214 {"shift", ShiftMapIndex},
215 {"control", ControlMapIndex},
216 {"lock", LockMapIndex},
217 {"mod1", Mod1MapIndex},
218 {"mod2", Mod2MapIndex},
219 {"mod3", Mod3MapIndex},
220 {"mod4", Mod4MapIndex},
221 {"mod5", Mod5MapIndex},
222 {"none", XkbNoModifier},
227 LookupModIndex(char * priv,
228 uint32_t elem, uint32_t field, unsigned type, ExprResult * val_rtrn)
230 return SimpleLookup((char *) modIndexNames, elem, field, type,
235 LookupModMask(char * priv,
236 uint32_t elem, uint32_t field, unsigned type, ExprResult * val_rtrn)
241 if ((elem != None) || (type != TypeInt))
243 str = XkbcAtomGetString(field);
246 if (uStrCaseCmp(str, "all") == 0)
247 val_rtrn->uval = 0xff;
248 else if (uStrCaseCmp(str, "none") == 0)
250 else if (LookupModIndex(priv, elem, field, type, val_rtrn))
251 val_rtrn->uval = (1 << val_rtrn->uval);
252 else if (priv != NULL)
254 LookupPriv *lpriv = (LookupPriv *) priv;
255 if ((lpriv->chain == NULL) ||
256 (!(*lpriv->chain) (lpriv->chainPriv, elem, field, type,
267 ExprResolveModMask(ExprDef * expr,
268 ExprResult * val_rtrn,
269 IdentLookupFunc lookup, char * lookupPriv)
275 priv.chainPriv = lookupPriv;
276 return ExprResolveMask(expr, val_rtrn, LookupModMask, (char *) & priv);
280 ExprResolveBoolean(ExprDef * expr,
281 ExprResult * val_rtrn,
282 IdentLookupFunc lookup, char * lookupPriv)
285 const char *bogus = NULL;
290 if (expr->type != TypeBoolean)
293 ("Found constant of type %s where boolean was expected\n",
294 exprTypeText(expr->type));
297 val_rtrn->ival = expr->value.ival;
300 bogus = XkbcAtomText(expr->value.str);
303 if ((uStrCaseCmp(bogus, "true") == 0) ||
304 (uStrCaseCmp(bogus, "yes") == 0) ||
305 (uStrCaseCmp(bogus, "on") == 0))
310 else if ((uStrCaseCmp(bogus, "false") == 0) ||
311 (uStrCaseCmp(bogus, "no") == 0) ||
312 (uStrCaseCmp(bogus, "off") == 0))
320 ok = (*lookup) (lookupPriv,
321 None, expr->value.str, TypeBoolean, val_rtrn);
324 ERROR("Identifier \"%s\" of type int is unknown\n",
325 XkbcAtomText(expr->value.str));
330 ok = (*lookup) (lookupPriv,
331 expr->value.field.element,
332 expr->value.field.field, TypeBoolean, val_rtrn);
335 ERROR("Default \"%s.%s\" of type boolean is unknown\n",
336 XkbcAtomText(expr->value.field.element),
337 XkbcAtomText(expr->value.field.field));
341 ok = ExprResolveBoolean(expr, val_rtrn, lookup, lookupPriv);
343 val_rtrn->uval = !val_rtrn->uval;
350 bogus = "Subtraction";
353 bogus = "Multiplication";
359 bogus = "Assignment";
363 ERROR("%s of boolean values not permitted\n", bogus);
366 ERROR("Unary \"+\" operator not permitted for boolean values\n");
369 WSGO("Unknown operator %d in ResolveBoolean\n", expr->op);
376 ExprResolveFloat(ExprDef * expr,
377 ExprResult * val_rtrn,
378 IdentLookupFunc lookup, char * lookupPriv)
381 ExprResult leftRtrn, rightRtrn;
382 ExprDef *left, *right;
387 if (expr->type == TypeString)
390 str = XkbcAtomText(expr->value.str);
391 if ((str != NULL) && (strlen(str) == 1))
393 val_rtrn->uval = str[0] * XkbGeomPtsPerMM;
397 if ((expr->type != TypeInt) && (expr->type != TypeFloat))
399 ERROR("Found constant of type %s, expected a number\n",
400 exprTypeText(expr->type));
403 val_rtrn->ival = expr->value.ival;
404 if (expr->type == TypeInt)
405 val_rtrn->ival *= XkbGeomPtsPerMM;
410 ok = (*lookup) (lookupPriv,
411 None, expr->value.str, TypeFloat, val_rtrn);
414 ERROR("Numeric identifier \"%s\" unknown\n",
415 XkbcAtomText(expr->value.str));
420 ok = (*lookup) (lookupPriv,
421 expr->value.field.element,
422 expr->value.field.field, TypeFloat, val_rtrn);
425 ERROR("Numeric default \"%s.%s\" unknown\n",
426 XkbcAtomText(expr->value.field.element),
427 XkbcAtomText(expr->value.field.field));
433 left = expr->value.binary.left;
434 right = expr->value.binary.right;
435 if (ExprResolveFloat(left, &leftRtrn, lookup, lookupPriv) &&
436 ExprResolveFloat(right, &rightRtrn, lookup, lookupPriv))
441 val_rtrn->ival = leftRtrn.ival + rightRtrn.ival;
444 val_rtrn->ival = leftRtrn.ival - rightRtrn.ival;
447 val_rtrn->ival = leftRtrn.ival * rightRtrn.ival;
450 val_rtrn->ival = leftRtrn.ival / rightRtrn.ival;
457 WSGO("Assignment operator not implemented yet\n");
460 left = expr->value.child;
461 if (ExprResolveFloat(left, &leftRtrn, lookup, lookupPriv))
463 ERROR("The ! operator cannot be applied to a number\n");
468 left = expr->value.child;
469 if (ExprResolveFloat(left, &leftRtrn, lookup, lookupPriv))
471 if (expr->op == OpNegate)
472 val_rtrn->ival = -leftRtrn.ival;
474 val_rtrn->ival = ~leftRtrn.ival;
479 left = expr->value.child;
480 return ExprResolveFloat(left, val_rtrn, lookup, lookupPriv);
482 WSGO("Unknown operator %d in ResolveFloat\n", expr->op);
489 ExprResolveKeyCode(ExprDef * expr,
490 ExprResult * val_rtrn)
492 ExprResult leftRtrn, rightRtrn;
493 ExprDef *left, *right;
498 if (expr->type != TypeInt)
501 ("Found constant of type %s where an int was expected\n",
502 exprTypeText(expr->type));
505 val_rtrn->uval = expr->value.uval;
511 left = expr->value.binary.left;
512 right = expr->value.binary.right;
513 if (ExprResolveKeyCode(left, &leftRtrn) &&
514 ExprResolveKeyCode(right, &rightRtrn))
519 val_rtrn->uval = leftRtrn.uval + rightRtrn.uval;
522 val_rtrn->uval = leftRtrn.uval - rightRtrn.uval;
525 val_rtrn->uval = leftRtrn.uval * rightRtrn.uval;
528 val_rtrn->uval = leftRtrn.uval / rightRtrn.uval;
535 left = expr->value.child;
536 if (ExprResolveKeyCode(left, &leftRtrn))
538 val_rtrn->uval = ~leftRtrn.uval;
543 left = expr->value.child;
544 return ExprResolveKeyCode(left, val_rtrn);
546 WSGO("Unknown operator %d in ResolveInteger\n", expr->op);
552 ExprResolveInteger(ExprDef * expr,
553 ExprResult * val_rtrn,
554 IdentLookupFunc lookup, char * lookupPriv)
557 ExprResult leftRtrn, rightRtrn;
558 ExprDef *left, *right;
563 if (expr->type == TypeString)
566 str = XkbcAtomText(expr->value.str);
574 val_rtrn->uval = str[0];
580 if ((expr->type != TypeInt) && (expr->type != TypeFloat))
583 ("Found constant of type %s where an int was expected\n",
584 exprTypeText(expr->type));
587 val_rtrn->ival = expr->value.ival;
588 if (expr->type == TypeFloat)
589 val_rtrn->ival /= XkbGeomPtsPerMM;
594 ok = (*lookup) (lookupPriv,
595 None, expr->value.str, TypeInt, val_rtrn);
598 ERROR("Identifier \"%s\" of type int is unknown\n",
599 XkbcAtomText(expr->value.str));
604 ok = (*lookup) (lookupPriv,
605 expr->value.field.element,
606 expr->value.field.field, TypeInt, val_rtrn);
609 ERROR("Default \"%s.%s\" of type int is unknown\n",
610 XkbcAtomText(expr->value.field.element),
611 XkbcAtomText(expr->value.field.field));
617 left = expr->value.binary.left;
618 right = expr->value.binary.right;
619 if (ExprResolveInteger(left, &leftRtrn, lookup, lookupPriv) &&
620 ExprResolveInteger(right, &rightRtrn, lookup, lookupPriv))
625 val_rtrn->ival = leftRtrn.ival + rightRtrn.ival;
628 val_rtrn->ival = leftRtrn.ival - rightRtrn.ival;
631 val_rtrn->ival = leftRtrn.ival * rightRtrn.ival;
634 val_rtrn->ival = leftRtrn.ival / rightRtrn.ival;
641 WSGO("Assignment operator not implemented yet\n");
644 left = expr->value.child;
645 if (ExprResolveInteger(left, &leftRtrn, lookup, lookupPriv))
647 ERROR("The ! operator cannot be applied to an integer\n");
652 left = expr->value.child;
653 if (ExprResolveInteger(left, &leftRtrn, lookup, lookupPriv))
655 if (expr->op == OpNegate)
656 val_rtrn->ival = -leftRtrn.ival;
658 val_rtrn->ival = ~leftRtrn.ival;
663 left = expr->value.child;
664 return ExprResolveInteger(left, val_rtrn, lookup, lookupPriv);
666 WSGO("Unknown operator %d in ResolveInteger\n", expr->op);
673 ExprResolveString(ExprDef * expr,
674 ExprResult * val_rtrn,
675 IdentLookupFunc lookup, char * lookupPriv)
678 ExprResult leftRtrn, rightRtrn;
686 if (expr->type != TypeString)
688 ERROR("Found constant of type %s, expected a string\n",
689 exprTypeText(expr->type));
692 val_rtrn->str = XkbcAtomGetString(expr->value.str);
693 if (val_rtrn->str == NULL)
695 static char *empty = "";
696 val_rtrn->str = empty;
702 ok = (*lookup) (lookupPriv,
703 None, expr->value.str, TypeString, val_rtrn);
706 ERROR("Identifier \"%s\" of type string not found\n",
707 XkbcAtomText(expr->value.str));
712 ok = (*lookup) (lookupPriv,
713 expr->value.field.element,
714 expr->value.field.field, TypeString, val_rtrn);
717 ERROR("Default \"%s.%s\" of type string not found\n",
718 XkbcAtomText(expr->value.field.element),
719 XkbcAtomText(expr->value.field.field));
722 left = expr->value.binary.left;
723 right = expr->value.binary.right;
724 if (ExprResolveString(left, &leftRtrn, lookup, lookupPriv) &&
725 ExprResolveString(right, &rightRtrn, lookup, lookupPriv))
729 len = strlen(leftRtrn.str) + strlen(rightRtrn.str) + 1;
730 new = (char *) malloc(len);
733 sprintf(new, "%s%s", leftRtrn.str, rightRtrn.str);
741 bogus = "Subtraction";
744 bogus = "Multiplication";
750 bogus = "Assignment";
756 bogus = "Bitwise complement";
757 ERROR("%s of string values not permitted\n", bogus);
760 left = expr->value.child;
761 if (ExprResolveString(left, &leftRtrn, lookup, lookupPriv))
763 ERROR("The ! operator cannot be applied to a string\n");
767 left = expr->value.child;
768 if (ExprResolveString(left, &leftRtrn, lookup, lookupPriv))
770 ERROR("The + operator cannot be applied to a string\n");
774 WSGO("Unknown operator %d in ResolveString\n", expr->op);
781 ExprResolveKeyName(ExprDef * expr,
782 ExprResult * val_rtrn,
783 IdentLookupFunc lookup, char * lookupPriv)
793 if (expr->type != TypeKeyName)
795 ERROR("Found constant of type %s, expected a key name\n",
796 exprTypeText(expr->type));
799 memcpy(val_rtrn->keyName.name, expr->value.keyName, XkbKeyNameLength);
804 ok = (*lookup) (lookupPriv,
805 None, expr->value.str, TypeString, val_rtrn);
808 ERROR("Identifier \"%s\" of type string not found\n",
809 XkbcAtomText(expr->value.str));
814 ok = (*lookup) (lookupPriv,
815 expr->value.field.element,
816 expr->value.field.field, TypeString, val_rtrn);
819 ERROR("Default \"%s.%s\" of type key name not found\n",
820 XkbcAtomText(expr->value.field.element),
821 XkbcAtomText(expr->value.field.field));
828 bogus = "Subtraction";
831 bogus = "Multiplication";
837 bogus = "Assignment";
843 bogus = "Bitwise complement";
844 ERROR("%s of key name values not permitted\n", bogus);
847 left = expr->value.binary.left;
848 if (ExprResolveString(left, &leftRtrn, lookup, lookupPriv))
850 ERROR("The ! operator cannot be applied to a key name\n");
854 left = expr->value.binary.left;
855 if (ExprResolveString(left, &leftRtrn, lookup, lookupPriv))
857 ERROR("The + operator cannot be applied to a key name\n");
861 WSGO("Unknown operator %d in ResolveKeyName\n", expr->op);
867 /***====================================================================***/
870 ExprResolveEnum(ExprDef * expr, ExprResult * val_rtrn, LookupEntry * values)
872 if (expr->op != ExprIdent)
874 ERROR("Found a %s where an enumerated value was expected\n",
875 exprOpText(expr->op));
878 if (!SimpleLookup((char *) values, (uint32_t) None, expr->value.str,
879 (unsigned) TypeInt, val_rtrn))
882 ERROR("Illegal identifier %s (expected one of: ",
883 XkbcAtomText(expr->value.str));
884 while (values && values->name)
887 INFO(", %s", values->name);
889 INFO("%s", values->name);
900 ExprResolveMask(ExprDef * expr,
901 ExprResult * val_rtrn,
902 IdentLookupFunc lookup, char * lookupPriv)
905 ExprResult leftRtrn, rightRtrn;
906 ExprDef *left, *right;
912 if (expr->type != TypeInt)
915 ("Found constant of type %s where a mask was expected\n",
916 exprTypeText(expr->type));
919 val_rtrn->ival = expr->value.ival;
924 ok = (*lookup) (lookupPriv,
925 None, expr->value.str, TypeInt, val_rtrn);
928 ERROR("Identifier \"%s\" of type int is unknown\n",
929 XkbcAtomText(expr->value.str));
934 ok = (*lookup) (lookupPriv,
935 expr->value.field.element,
936 expr->value.field.field, TypeInt, val_rtrn);
939 ERROR("Default \"%s.%s\" of type int is unknown\n",
940 XkbcAtomText(expr->value.field.element),
941 XkbcAtomText(expr->value.field.field));
944 bogus = "array reference";
947 bogus = "function use";
948 ERROR("Unexpected %s in mask expression\n", bogus);
949 ACTION("Expression ignored\n");
955 left = expr->value.binary.left;
956 right = expr->value.binary.right;
957 if (ExprResolveMask(left, &leftRtrn, lookup, lookupPriv) &&
958 ExprResolveMask(right, &rightRtrn, lookup, lookupPriv))
963 val_rtrn->ival = leftRtrn.ival | rightRtrn.ival;
966 val_rtrn->ival = leftRtrn.ival & (~rightRtrn.ival);
970 ERROR("Cannot %s masks\n",
971 expr->op == OpDivide ? "divide" : "multiply");
972 ACTION("Illegal operation ignored\n");
979 WSGO("Assignment operator not implemented yet\n");
982 left = expr->value.child;
983 if (ExprResolveInteger(left, &leftRtrn, lookup, lookupPriv))
985 val_rtrn->ival = ~leftRtrn.ival;
992 left = expr->value.child;
993 if (ExprResolveInteger(left, &leftRtrn, lookup, lookupPriv))
995 ERROR("The %s operator cannot be used with a mask\n",
996 (expr->op == OpNegate ? "-" : "!"));
1000 WSGO("Unknown operator %d in ResolveMask\n", expr->op);
1007 ExprResolveKeySym(ExprDef * expr,
1008 ExprResult * val_rtrn,
1009 IdentLookupFunc lookup, char * lookupPriv)
1014 if (expr->op == ExprIdent)
1017 str = XkbcAtomText(expr->value.str);
1018 if ((str != NULL) && ((sym = xkb_string_to_keysym(str)) != NoSymbol))
1020 val_rtrn->uval = sym;
1024 ok = ExprResolveInteger(expr, val_rtrn, lookup, lookupPriv);
1025 if ((ok) && (val_rtrn->uval < 10))
1026 val_rtrn->uval += '0';