Use (1u << idx) instead of (1 << idx) where appropriate
[platform/upstream/libxkbcommon.git] / src / xkbcomp / expr.c
1 /************************************************************
2  * Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
3  *
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.
15  *
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.
24  *
25  ********************************************************/
26
27 #include "xkbcomp-priv.h"
28 #include "text.h"
29 #include "expr.h"
30
31 typedef bool (*IdentLookupFunc)(struct xkb_context *ctx, const void *priv,
32                                 xkb_atom_t field, enum expr_value_type type,
33                                 unsigned int *val_rtrn);
34
35 bool
36 ExprResolveLhs(struct xkb_context *ctx, const ExprDef *expr,
37                const char **elem_rtrn, const char **field_rtrn,
38                ExprDef **index_rtrn)
39 {
40     switch (expr->expr.op) {
41     case EXPR_IDENT:
42         *elem_rtrn = NULL;
43         *field_rtrn = xkb_atom_text(ctx, expr->ident.ident);
44         *index_rtrn = NULL;
45         return true;
46     case EXPR_FIELD_REF:
47         *elem_rtrn = xkb_atom_text(ctx, expr->field_ref.element);
48         *field_rtrn = xkb_atom_text(ctx, expr->field_ref.field);
49         *index_rtrn = NULL;
50         return true;
51     case EXPR_ARRAY_REF:
52         *elem_rtrn = xkb_atom_text(ctx, expr->array_ref.element);
53         *field_rtrn = xkb_atom_text(ctx, expr->array_ref.field);
54         *index_rtrn = expr->array_ref.entry;
55         return true;
56     default:
57         break;
58     }
59     log_wsgo(ctx, "Unexpected operator %d in ResolveLhs\n", expr->expr.op);
60     return false;
61 }
62
63 static bool
64 SimpleLookup(struct xkb_context *ctx, const void *priv, xkb_atom_t field,
65              enum expr_value_type type, unsigned int *val_rtrn)
66 {
67     const LookupEntry *entry;
68     const char *str;
69
70     if (!priv || field == XKB_ATOM_NONE || type != EXPR_TYPE_INT)
71         return false;
72
73     str = xkb_atom_text(ctx, field);
74     for (entry = priv; entry && entry->name; entry++) {
75         if (istreq(str, entry->name)) {
76             *val_rtrn = entry->value;
77             return true;
78         }
79     }
80
81     return false;
82 }
83
84 /* Data passed in the *priv argument for LookupModMask. */
85 typedef struct {
86     const struct xkb_keymap *keymap;
87     enum mod_type mod_type;
88 } LookupModMaskPriv;
89
90 static bool
91 LookupModMask(struct xkb_context *ctx, const void *priv, xkb_atom_t field,
92               enum expr_value_type type, xkb_mod_mask_t *val_rtrn)
93 {
94     const char *str;
95     xkb_mod_index_t ndx;
96     const LookupModMaskPriv *arg = priv;
97     const struct xkb_keymap *keymap = arg->keymap;
98     enum mod_type mod_type = arg->mod_type;
99
100     if (type != EXPR_TYPE_INT)
101         return false;
102
103     str = xkb_atom_text(ctx, field);
104
105     if (istreq(str, "all")) {
106         *val_rtrn  = MOD_REAL_MASK_ALL;
107         return true;
108     }
109
110     if (istreq(str, "none")) {
111         *val_rtrn = 0;
112         return true;
113     }
114
115     ndx = ModNameToIndex(keymap, field, mod_type);
116     if (ndx == XKB_MOD_INVALID)
117         return false;
118
119     *val_rtrn = (1u << ndx);
120     return true;
121 }
122
123 bool
124 ExprResolveBoolean(struct xkb_context *ctx, const ExprDef *expr,
125                    bool *set_rtrn)
126 {
127     bool ok = false;
128     const char *ident;
129
130     switch (expr->expr.op) {
131     case EXPR_VALUE:
132         if (expr->expr.value_type != EXPR_TYPE_BOOLEAN) {
133             log_err(ctx,
134                     "Found constant of type %s where boolean was expected\n",
135                     expr_value_type_to_string(expr->expr.value_type));
136             return false;
137         }
138         *set_rtrn = expr->boolean.set;
139         return true;
140
141     case EXPR_IDENT:
142         ident = xkb_atom_text(ctx, expr->ident.ident);
143         if (ident) {
144             if (istreq(ident, "true") ||
145                 istreq(ident, "yes") ||
146                 istreq(ident, "on")) {
147                 *set_rtrn = true;
148                 return true;
149             }
150             else if (istreq(ident, "false") ||
151                      istreq(ident, "no") ||
152                      istreq(ident, "off")) {
153                 *set_rtrn = false;
154                 return true;
155             }
156         }
157         log_err(ctx, "Identifier \"%s\" of type boolean is unknown\n", ident);
158         return false;
159
160     case EXPR_FIELD_REF:
161         log_err(ctx, "Default \"%s.%s\" of type boolean is unknown\n",
162                 xkb_atom_text(ctx, expr->field_ref.element),
163                 xkb_atom_text(ctx, expr->field_ref.field));
164         return false;
165
166     case EXPR_INVERT:
167     case EXPR_NOT:
168         ok = ExprResolveBoolean(ctx, expr, set_rtrn);
169         if (ok)
170             *set_rtrn = !*set_rtrn;
171         return ok;
172     case EXPR_ADD:
173     case EXPR_SUBTRACT:
174     case EXPR_MULTIPLY:
175     case EXPR_DIVIDE:
176     case EXPR_ASSIGN:
177     case EXPR_NEGATE:
178     case EXPR_UNARY_PLUS:
179         log_err(ctx, "%s of boolean values not permitted\n",
180                 expr_op_type_to_string(expr->expr.op));
181         break;
182
183     default:
184         log_wsgo(ctx, "Unknown operator %d in ResolveBoolean\n",
185                  expr->expr.op);
186         break;
187     }
188
189     return false;
190 }
191
192 bool
193 ExprResolveKeyCode(struct xkb_context *ctx, const ExprDef *expr,
194                    xkb_keycode_t *kc)
195 {
196     xkb_keycode_t leftRtrn, rightRtrn;
197
198     switch (expr->expr.op) {
199     case EXPR_VALUE:
200         if (expr->expr.value_type != EXPR_TYPE_INT) {
201             log_err(ctx,
202                     "Found constant of type %s where an int was expected\n",
203                     expr_value_type_to_string(expr->expr.value_type));
204             return false;
205         }
206
207         *kc = (xkb_keycode_t) expr->integer.ival;
208         return true;
209
210     case EXPR_ADD:
211     case EXPR_SUBTRACT:
212     case EXPR_MULTIPLY:
213     case EXPR_DIVIDE:
214         if (!ExprResolveKeyCode(ctx, expr->binary.left, &leftRtrn) ||
215             !ExprResolveKeyCode(ctx, expr->binary.right, &rightRtrn))
216             return false;
217
218         switch (expr->expr.op) {
219         case EXPR_ADD:
220             *kc = leftRtrn + rightRtrn;
221             break;
222         case EXPR_SUBTRACT:
223             *kc = leftRtrn - rightRtrn;
224             break;
225         case EXPR_MULTIPLY:
226             *kc = leftRtrn * rightRtrn;
227             break;
228         case EXPR_DIVIDE:
229             if (rightRtrn == 0) {
230                 log_err(ctx, "Cannot divide by zero: %d / %d\n",
231                         leftRtrn, rightRtrn);
232                 return false;
233             }
234
235             *kc = leftRtrn / rightRtrn;
236             break;
237         default:
238             break;
239         }
240
241         return true;
242
243     case EXPR_NEGATE:
244         if (!ExprResolveKeyCode(ctx, expr->unary.child, &leftRtrn))
245             return false;
246
247         *kc = ~leftRtrn;
248         return true;
249
250     case EXPR_UNARY_PLUS:
251         return ExprResolveKeyCode(ctx, expr->unary.child, kc);
252
253     default:
254         log_wsgo(ctx, "Unknown operator %d in ResolveKeyCode\n",
255                  expr->expr.op);
256         break;
257     }
258
259     return false;
260 }
261
262 /**
263  * This function returns ... something.  It's a bit of a guess, really.
264  *
265  * If an integer is given in value ctx, it will be returned in ival.
266  * If an ident or field reference is given, the lookup function (if given)
267  * will be called.  At the moment, only SimpleLookup use this, and they both
268  * return the results in uval.  And don't support field references.
269  *
270  * Cool.
271  */
272 static bool
273 ExprResolveIntegerLookup(struct xkb_context *ctx, const ExprDef *expr,
274                          int *val_rtrn, IdentLookupFunc lookup,
275                          const void *lookupPriv)
276 {
277     bool ok = false;
278     int l, r;
279     unsigned u;
280     ExprDef *left, *right;
281
282     switch (expr->expr.op) {
283     case EXPR_VALUE:
284         if (expr->expr.value_type != EXPR_TYPE_INT) {
285             log_err(ctx,
286                     "Found constant of type %s where an int was expected\n",
287                     expr_value_type_to_string(expr->expr.value_type));
288             return false;
289         }
290
291         *val_rtrn = expr->integer.ival;
292         return true;
293
294     case EXPR_IDENT:
295         if (lookup)
296             ok = lookup(ctx, lookupPriv, expr->ident.ident, EXPR_TYPE_INT, &u);
297
298         if (!ok)
299             log_err(ctx, "Identifier \"%s\" of type int is unknown\n",
300                     xkb_atom_text(ctx, expr->ident.ident));
301         else
302             *val_rtrn = (int) u;
303
304         return ok;
305
306     case EXPR_FIELD_REF:
307         log_err(ctx, "Default \"%s.%s\" of type int is unknown\n",
308                 xkb_atom_text(ctx, expr->field_ref.element),
309                 xkb_atom_text(ctx, expr->field_ref.field));
310         return false;
311
312     case EXPR_ADD:
313     case EXPR_SUBTRACT:
314     case EXPR_MULTIPLY:
315     case EXPR_DIVIDE:
316         left = expr->binary.left;
317         right = expr->binary.right;
318         if (!ExprResolveIntegerLookup(ctx, left, &l, lookup, lookupPriv) ||
319             !ExprResolveIntegerLookup(ctx, right, &r, lookup, lookupPriv))
320             return false;
321
322         switch (expr->expr.op) {
323         case EXPR_ADD:
324             *val_rtrn = l + r;
325             break;
326         case EXPR_SUBTRACT:
327             *val_rtrn = l - r;
328             break;
329         case EXPR_MULTIPLY:
330             *val_rtrn = l * r;
331             break;
332         case EXPR_DIVIDE:
333             if (r == 0) {
334                 log_err(ctx, "Cannot divide by zero: %d / %d\n", l, r);
335                 return false;
336             }
337             *val_rtrn = l / r;
338             break;
339         default:
340             break;
341         }
342
343         return true;
344
345     case EXPR_ASSIGN:
346         log_wsgo(ctx, "Assignment operator not implemented yet\n");
347         break;
348
349     case EXPR_NOT:
350         log_err(ctx, "The ! operator cannot be applied to an integer\n");
351         return false;
352
353     case EXPR_INVERT:
354     case EXPR_NEGATE:
355         left = expr->unary.child;
356         if (!ExprResolveIntegerLookup(ctx, left, &l, lookup, lookupPriv))
357             return false;
358
359         *val_rtrn = (expr->expr.op == EXPR_NEGATE ? -l : ~l);
360         return true;
361
362     case EXPR_UNARY_PLUS:
363         left = expr->unary.child;
364         return ExprResolveIntegerLookup(ctx, left, val_rtrn, lookup,
365                                         lookupPriv);
366
367     default:
368         log_wsgo(ctx, "Unknown operator %d in ResolveInteger\n",
369                  expr->expr.op);
370         break;
371     }
372
373     return false;
374 }
375
376 bool
377 ExprResolveInteger(struct xkb_context *ctx, const ExprDef *expr,
378                    int *val_rtrn)
379 {
380     return ExprResolveIntegerLookup(ctx, expr, val_rtrn, NULL, NULL);
381 }
382
383 bool
384 ExprResolveGroup(struct xkb_context *ctx, const ExprDef *expr,
385                  xkb_layout_index_t *group_rtrn)
386 {
387     bool ok;
388     int result;
389
390     ok = ExprResolveIntegerLookup(ctx, expr, &result, SimpleLookup,
391                                   groupNames);
392     if (!ok)
393         return false;
394
395     if (result <= 0 || result > XKB_MAX_GROUPS) {
396         log_err(ctx, "Group index %u is out of range (1..%d)\n",
397                 result, XKB_MAX_GROUPS);
398         return false;
399     }
400
401     *group_rtrn = (xkb_layout_index_t) result;
402     return true;
403 }
404
405 bool
406 ExprResolveLevel(struct xkb_context *ctx, const ExprDef *expr,
407                  xkb_level_index_t *level_rtrn)
408 {
409     bool ok;
410     int result;
411
412     ok = ExprResolveIntegerLookup(ctx, expr, &result, SimpleLookup,
413                                   levelNames);
414     if (!ok)
415         return false;
416
417     if (result < 1) {
418         log_err(ctx, "Shift level %d is out of range\n", result);
419         return false;
420     }
421
422     /* Level is zero-indexed from now on. */
423     *level_rtrn = (unsigned int) (result - 1);
424     return true;
425 }
426
427 bool
428 ExprResolveButton(struct xkb_context *ctx, const ExprDef *expr, int *btn_rtrn)
429 {
430     int result;
431
432     if (!ExprResolveIntegerLookup(ctx, expr, &result, SimpleLookup,
433                                   buttonNames))
434         return false;
435
436     *btn_rtrn = result;
437     return true;
438 }
439
440 bool
441 ExprResolveString(struct xkb_context *ctx, const ExprDef *expr,
442                   xkb_atom_t *val_rtrn)
443 {
444     switch (expr->expr.op) {
445     case EXPR_VALUE:
446         if (expr->expr.value_type != EXPR_TYPE_STRING) {
447             log_err(ctx, "Found constant of type %s, expected a string\n",
448                     expr_value_type_to_string(expr->expr.value_type));
449             return false;
450         }
451
452         *val_rtrn = expr->string.str;
453         return true;
454
455     case EXPR_IDENT:
456         log_err(ctx, "Identifier \"%s\" of type string not found\n",
457                 xkb_atom_text(ctx, expr->ident.ident));
458         return false;
459
460     case EXPR_FIELD_REF:
461         log_err(ctx, "Default \"%s.%s\" of type string not found\n",
462                 xkb_atom_text(ctx, expr->field_ref.element),
463                 xkb_atom_text(ctx, expr->field_ref.field));
464         return false;
465
466     case EXPR_ADD:
467     case EXPR_SUBTRACT:
468     case EXPR_MULTIPLY:
469     case EXPR_DIVIDE:
470     case EXPR_ASSIGN:
471     case EXPR_NEGATE:
472     case EXPR_INVERT:
473     case EXPR_NOT:
474     case EXPR_UNARY_PLUS:
475         log_err(ctx, "%s of strings not permitted\n",
476                 expr_op_type_to_string(expr->expr.op));
477         return false;
478
479     default:
480         log_wsgo(ctx, "Unknown operator %d in ResolveString\n",
481                  expr->expr.op);
482         break;
483     }
484     return false;
485 }
486
487 bool
488 ExprResolveEnum(struct xkb_context *ctx, const ExprDef *expr,
489                 unsigned int *val_rtrn, const LookupEntry *values)
490 {
491     if (expr->expr.op != EXPR_IDENT) {
492         log_err(ctx, "Found a %s where an enumerated value was expected\n",
493                 expr_op_type_to_string(expr->expr.op));
494         return false;
495     }
496
497     if (!SimpleLookup(ctx, values, expr->ident.ident, EXPR_TYPE_INT,
498                       val_rtrn)) {
499         log_err(ctx, "Illegal identifier %s; expected one of:\n",
500                 xkb_atom_text(ctx, expr->ident.ident));
501         while (values && values->name)
502         {
503             log_err(ctx, "\t%s\n", values->name);
504             values++;
505         }
506         return false;
507     }
508
509     return true;
510 }
511
512 static bool
513 ExprResolveMaskLookup(struct xkb_context *ctx, const ExprDef *expr,
514                       unsigned int *val_rtrn, IdentLookupFunc lookup,
515                       const void *lookupPriv)
516 {
517     bool ok = 0;
518     unsigned int l, r;
519     int v;
520     ExprDef *left, *right;
521     const char *bogus = NULL;
522
523     switch (expr->expr.op) {
524     case EXPR_VALUE:
525         if (expr->expr.value_type != EXPR_TYPE_INT) {
526             log_err(ctx,
527                     "Found constant of type %s where a mask was expected\n",
528                     expr_value_type_to_string(expr->expr.value_type));
529             return false;
530         }
531         *val_rtrn = (unsigned int) expr->integer.ival;
532         return true;
533
534     case EXPR_IDENT:
535         ok = lookup(ctx, lookupPriv, expr->ident.ident, EXPR_TYPE_INT,
536                     val_rtrn);
537         if (!ok)
538             log_err(ctx, "Identifier \"%s\" of type int is unknown\n",
539                     xkb_atom_text(ctx, expr->ident.ident));
540         return ok;
541
542     case EXPR_FIELD_REF:
543         log_err(ctx, "Default \"%s.%s\" of type int is unknown\n",
544                 xkb_atom_text(ctx, expr->field_ref.element),
545                 xkb_atom_text(ctx, expr->field_ref.field));
546         return false;
547
548     case EXPR_ARRAY_REF:
549         bogus = "array reference";
550
551     case EXPR_ACTION_DECL:
552         if (bogus == NULL)
553             bogus = "function use";
554         log_err(ctx,
555                 "Unexpected %s in mask expression; Expression Ignored\n",
556                 bogus);
557         return false;
558
559     case EXPR_ADD:
560     case EXPR_SUBTRACT:
561     case EXPR_MULTIPLY:
562     case EXPR_DIVIDE:
563         left = expr->binary.left;
564         right = expr->binary.right;
565         if (!ExprResolveMaskLookup(ctx, left, &l, lookup, lookupPriv) ||
566             !ExprResolveMaskLookup(ctx, right, &r, lookup, lookupPriv))
567             return false;
568
569         switch (expr->expr.op) {
570         case EXPR_ADD:
571             *val_rtrn = l | r;
572             break;
573         case EXPR_SUBTRACT:
574             *val_rtrn = l & (~r);
575             break;
576         case EXPR_MULTIPLY:
577         case EXPR_DIVIDE:
578             log_err(ctx, "Cannot %s masks; Illegal operation ignored\n",
579                     (expr->expr.op == EXPR_DIVIDE ? "divide" : "multiply"));
580             return false;
581         default:
582             break;
583         }
584
585         return true;
586
587     case EXPR_ASSIGN:
588         log_wsgo(ctx, "Assignment operator not implemented yet\n");
589         break;
590
591     case EXPR_INVERT:
592         left = expr->unary.child;
593         if (!ExprResolveIntegerLookup(ctx, left, &v, lookup, lookupPriv))
594             return false;
595
596         *val_rtrn = ~v;
597         return true;
598
599     case EXPR_UNARY_PLUS:
600     case EXPR_NEGATE:
601     case EXPR_NOT:
602         left = expr->unary.child;
603         if (!ExprResolveIntegerLookup(ctx, left, &v, lookup, lookupPriv))
604             log_err(ctx, "The %s operator cannot be used with a mask\n",
605                     (expr->expr.op == EXPR_NEGATE ? "-" : "!"));
606         return false;
607
608     default:
609         log_wsgo(ctx, "Unknown operator %d in ResolveMask\n",
610                  expr->expr.op);
611         break;
612     }
613
614     return false;
615 }
616
617 bool
618 ExprResolveMask(struct xkb_context *ctx, const ExprDef *expr,
619                 unsigned int *mask_rtrn, const LookupEntry *values)
620 {
621     return ExprResolveMaskLookup(ctx, expr, mask_rtrn, SimpleLookup, values);
622 }
623
624 bool
625 ExprResolveModMask(struct xkb_keymap *keymap, const ExprDef *expr,
626                    enum mod_type mod_type, xkb_mod_mask_t *mask_rtrn)
627 {
628     LookupModMaskPriv priv = { .keymap = keymap, .mod_type = mod_type };
629     return ExprResolveMaskLookup(keymap->ctx, expr, mask_rtrn, LookupModMask,
630                                  &priv);
631 }
632
633 bool
634 ExprResolveKeySym(struct xkb_context *ctx, const ExprDef *expr,
635                   xkb_keysym_t *sym_rtrn)
636 {
637     int val;
638
639     if (expr->expr.op == EXPR_IDENT) {
640         const char *str = xkb_atom_text(ctx, expr->ident.ident);
641         *sym_rtrn = xkb_keysym_from_name(str, 0);
642         if (*sym_rtrn != XKB_KEY_NoSymbol)
643             return true;
644     }
645
646     if (!ExprResolveInteger(ctx, expr, &val))
647         return false;
648
649     if (val < 0 || val >= 10)
650         return false;
651
652     *sym_rtrn = XKB_KEY_0 + (xkb_keysym_t) val;
653     return true;
654 }
655
656 bool
657 ExprResolveMod(struct xkb_keymap *keymap, const ExprDef *def,
658                enum mod_type mod_type, xkb_mod_index_t *ndx_rtrn)
659 {
660     xkb_mod_index_t ndx;
661     xkb_atom_t name;
662
663     if (def->expr.op != EXPR_IDENT) {
664         log_err(keymap->ctx,
665                 "Cannot resolve virtual modifier: "
666                 "found %s where a virtual modifier name was expected\n",
667                 expr_op_type_to_string(def->expr.op));
668         return false;
669     }
670
671     name = def->ident.ident;
672     ndx = ModNameToIndex(keymap, name, mod_type);
673     if (ndx == XKB_MOD_INVALID) {
674         log_err(keymap->ctx,
675                 "Cannot resolve virtual modifier: "
676                 "\"%s\" was not previously declared\n",
677                 xkb_atom_text(keymap->ctx, name));
678         return false;
679     }
680
681     *ndx_rtrn = ndx;
682     return true;
683 }