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)
694 val_rtrn->str = strdup("");
699 ok = (*lookup) (lookupPriv,
700 None, expr->value.str, TypeString, val_rtrn);
703 ERROR("Identifier \"%s\" of type string not found\n",
704 XkbcAtomText(expr->value.str));
709 ok = (*lookup) (lookupPriv,
710 expr->value.field.element,
711 expr->value.field.field, TypeString, val_rtrn);
714 ERROR("Default \"%s.%s\" of type string not found\n",
715 XkbcAtomText(expr->value.field.element),
716 XkbcAtomText(expr->value.field.field));
719 left = expr->value.binary.left;
720 right = expr->value.binary.right;
721 if (ExprResolveString(left, &leftRtrn, lookup, lookupPriv) &&
722 ExprResolveString(right, &rightRtrn, lookup, lookupPriv))
726 len = strlen(leftRtrn.str) + strlen(rightRtrn.str) + 1;
727 new = (char *) malloc(len);
730 sprintf(new, "%s%s", leftRtrn.str, rightRtrn.str);
742 bogus = "Subtraction";
745 bogus = "Multiplication";
751 bogus = "Assignment";
757 bogus = "Bitwise complement";
758 ERROR("%s of string values not permitted\n", bogus);
761 left = expr->value.child;
762 if (ExprResolveString(left, &leftRtrn, lookup, lookupPriv))
764 ERROR("The ! operator cannot be applied to a string\n");
768 left = expr->value.child;
769 if (ExprResolveString(left, &leftRtrn, lookup, lookupPriv))
771 ERROR("The + operator cannot be applied to a string\n");
775 WSGO("Unknown operator %d in ResolveString\n", expr->op);
782 ExprResolveKeyName(ExprDef * expr,
783 ExprResult * val_rtrn,
784 IdentLookupFunc lookup, char * lookupPriv)
794 if (expr->type != TypeKeyName)
796 ERROR("Found constant of type %s, expected a key name\n",
797 exprTypeText(expr->type));
800 memcpy(val_rtrn->keyName.name, expr->value.keyName, XkbKeyNameLength);
805 ok = (*lookup) (lookupPriv,
806 None, expr->value.str, TypeString, val_rtrn);
809 ERROR("Identifier \"%s\" of type string not found\n",
810 XkbcAtomText(expr->value.str));
815 ok = (*lookup) (lookupPriv,
816 expr->value.field.element,
817 expr->value.field.field, TypeString, val_rtrn);
820 ERROR("Default \"%s.%s\" of type key name not found\n",
821 XkbcAtomText(expr->value.field.element),
822 XkbcAtomText(expr->value.field.field));
829 bogus = "Subtraction";
832 bogus = "Multiplication";
838 bogus = "Assignment";
844 bogus = "Bitwise complement";
845 ERROR("%s of key name values not permitted\n", bogus);
848 left = expr->value.binary.left;
849 if (ExprResolveString(left, &leftRtrn, lookup, lookupPriv))
851 ERROR("The ! operator cannot be applied to a key name\n");
855 left = expr->value.binary.left;
856 if (ExprResolveString(left, &leftRtrn, lookup, lookupPriv))
858 ERROR("The + operator cannot be applied to a key name\n");
862 WSGO("Unknown operator %d in ResolveKeyName\n", expr->op);
868 /***====================================================================***/
871 ExprResolveEnum(ExprDef * expr, ExprResult * val_rtrn, LookupEntry * values)
873 if (expr->op != ExprIdent)
875 ERROR("Found a %s where an enumerated value was expected\n",
876 exprOpText(expr->op));
879 if (!SimpleLookup((char *) values, (uint32_t) None, expr->value.str,
880 (unsigned) TypeInt, val_rtrn))
883 ERROR("Illegal identifier %s (expected one of: ",
884 XkbcAtomText(expr->value.str));
885 while (values && values->name)
888 INFO(", %s", values->name);
890 INFO("%s", values->name);
901 ExprResolveMask(ExprDef * expr,
902 ExprResult * val_rtrn,
903 IdentLookupFunc lookup, char * lookupPriv)
906 ExprResult leftRtrn, rightRtrn;
907 ExprDef *left, *right;
913 if (expr->type != TypeInt)
916 ("Found constant of type %s where a mask was expected\n",
917 exprTypeText(expr->type));
920 val_rtrn->ival = expr->value.ival;
925 ok = (*lookup) (lookupPriv,
926 None, expr->value.str, TypeInt, val_rtrn);
929 ERROR("Identifier \"%s\" of type int is unknown\n",
930 XkbcAtomText(expr->value.str));
935 ok = (*lookup) (lookupPriv,
936 expr->value.field.element,
937 expr->value.field.field, TypeInt, val_rtrn);
940 ERROR("Default \"%s.%s\" of type int is unknown\n",
941 XkbcAtomText(expr->value.field.element),
942 XkbcAtomText(expr->value.field.field));
945 bogus = "array reference";
948 bogus = "function use";
949 ERROR("Unexpected %s in mask expression\n", bogus);
950 ACTION("Expression ignored\n");
956 left = expr->value.binary.left;
957 right = expr->value.binary.right;
958 if (ExprResolveMask(left, &leftRtrn, lookup, lookupPriv) &&
959 ExprResolveMask(right, &rightRtrn, lookup, lookupPriv))
964 val_rtrn->ival = leftRtrn.ival | rightRtrn.ival;
967 val_rtrn->ival = leftRtrn.ival & (~rightRtrn.ival);
971 ERROR("Cannot %s masks\n",
972 expr->op == OpDivide ? "divide" : "multiply");
973 ACTION("Illegal operation ignored\n");
980 WSGO("Assignment operator not implemented yet\n");
983 left = expr->value.child;
984 if (ExprResolveInteger(left, &leftRtrn, lookup, lookupPriv))
986 val_rtrn->ival = ~leftRtrn.ival;
993 left = expr->value.child;
994 if (ExprResolveInteger(left, &leftRtrn, lookup, lookupPriv))
996 ERROR("The %s operator cannot be used with a mask\n",
997 (expr->op == OpNegate ? "-" : "!"));
1001 WSGO("Unknown operator %d in ResolveMask\n", expr->op);
1008 ExprResolveKeySym(ExprDef * expr,
1009 ExprResult * val_rtrn,
1010 IdentLookupFunc lookup, char * lookupPriv)
1015 if (expr->op == ExprIdent)
1018 str = XkbcAtomText(expr->value.str);
1019 if ((str != NULL) && ((sym = xkb_string_to_keysym(str)) != NoSymbol))
1021 val_rtrn->uval = sym;
1025 ok = ExprResolveInteger(expr, val_rtrn, lookup, lookupPriv);
1026 if ((ok) && (val_rtrn->uval < 10))
1027 val_rtrn->uval += '0';