Split header files on public and private and add lk_ prefix for all public functions
[platform/upstream/kbd.git] / src / libkeymap / parser.y
1 /* loadkeys.parse.y
2  *
3  * This file is part of kbd project.
4  * Copyright (C) 1993  Risto Kankkunen.
5  * Copyright (C) 1993  Eugene G. Crosser.
6  * Copyright (C) 1994-2007  Andries E. Brouwer.
7  * Copyright (C) 2007-2012  Alexey Gladkov <gladkov.alexey@gmail.com>
8  *
9  * This file is covered by the GNU General Public License,
10  * which should be included with kbd as the file COPYING.
11  */
12 %{
13 #define YY_HEADER_EXPORT_START_CONDITIONS 1
14
15 #include <errno.h>
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <stdarg.h>
19 #include <ctype.h>
20 #include <sys/ioctl.h>
21 #include <linux/kd.h>
22 #include <linux/keyboard.h>
23 #include <unistd.h>
24
25 #include "ksyms.h"
26 #include "modifiers.h"
27 #include "nls.h"
28 #include "kbd.h"
29
30 #include "parser.h"
31 #include "analyze.h"
32 %}
33
34 %code requires {
35 #include "keymap.h"
36 #include "parseP.h"
37 }
38
39 %language "C"
40 %yacc
41 %defines
42 %debug
43 %error-verbose
44
45 /* Pure yylex.  */
46 %define api.pure
47 %lex-param { yyscan_t scanner }
48
49 /* Pure yyparse.  */
50 %parse-param { void *scanner }
51 %parse-param { struct keymap *kmap }
52
53 %token EOL NUMBER LITERAL CHARSET KEYMAPS KEYCODE EQUALS
54 %token PLAIN SHIFT CONTROL ALT ALTGR SHIFTL SHIFTR CTRLL CTRLR CAPSSHIFT
55 %token COMMA DASH STRING STRLITERAL COMPOSE TO CCHAR ERROR PLUS
56 %token UNUMBER ALT_IS_META STRINGS AS USUAL ON FOR
57
58 %union {
59         long long int num;
60         struct strdata str;
61 }
62
63 %type <str>  STRLITERAL
64 %type <num>  CCHAR
65 %type <num>  LITERAL
66 %type <num>  NUMBER
67 %type <num>  UNUMBER
68
69 %type <num>  compsym
70 %type <num>  rvalue
71
72 %{
73
74 int yyerror(yyscan_t scanner, struct keymap *kmap, const char *s);
75
76 #include "ksyms.h"
77
78 int
79 yyerror(yyscan_t scanner attr_unused, struct keymap *kmap, const char *s)
80 {
81         log_error(kmap, "%s", s);
82         return 0;
83 }
84
85 static int
86 addmap(struct keymap *kmap, int i, int explicit)
87 {
88         if (i < 0 || i >= MAX_NR_KEYMAPS) {
89                 log_error(kmap, _("addmap called with bad index %d"), i);
90                 return -1;
91         }
92
93         if (!kmap->defining[i]) {
94                 if (kmap->keymaps_line_seen && !explicit) {
95                         log_error(kmap, _("adding map %d violates explicit keymaps line"), i);
96                         return -1;
97                 }
98
99                 kmap->defining[i] = i+1;
100                 if (kmap->max_keymap <= i)
101                         kmap->max_keymap = i + 1;
102         }
103         return 0;
104 }
105
106 /* unset a key */
107 static int
108 killkey(struct keymap *kmap, int k_index, int k_table)
109 {
110         /* roughly: addkey(k_index, k_table, K_HOLE); */
111
112         if (k_index < 0 || k_index >= NR_KEYS) {
113                 log_error(kmap, _("killkey called with bad index %d"), k_index);
114                 return -1;
115         }
116
117         if (k_table < 0 || k_table >= MAX_NR_KEYMAPS) {
118                 log_error(kmap, _("killkey called with bad table %d"), k_table);
119                 return -1;
120         }
121
122         if (kmap->key_map[k_table])
123                 (kmap->key_map[k_table])[k_index] = K_HOLE;
124
125         if (kmap->keymap_was_set[k_table])
126                 (kmap->keymap_was_set[k_table])[k_index] = 0;
127
128         return 0;
129 }
130
131 int
132 addkey(struct keymap *kmap, int k_index, int k_table, int keycode)
133 {
134         int i;
135
136         if (keycode == CODE_FOR_UNKNOWN_KSYM) {
137                 /* is safer not to be silent in this case, 
138                  * it can be caused by coding errors as well. */
139                 log_error(kmap, _("addkey called with bad keycode %d"), keycode);
140                 return -1;
141         }
142
143         if (k_index < 0 || k_index >= NR_KEYS) {
144                 log_error(kmap, _("addkey called with bad index %d"), k_index);
145                 return -1;
146         }
147
148         if (k_table < 0 || k_table >= MAX_NR_KEYMAPS) {
149                 log_error(kmap, _("addkey called with bad table %d"), k_table);
150                 return -1;
151         }
152
153         if (!k_index && keycode == K_NOSUCHMAP)
154                 return 0;
155
156         if (!kmap->defining[k_table]) {
157                 if (addmap(kmap, k_table, 0) == -1)
158                         return -1;
159         }
160
161         if (!kmap->key_map[k_table]) {
162                 kmap->key_map[k_table] = (u_short *)malloc(NR_KEYS * sizeof(u_short));
163
164                 if (kmap->key_map[k_table] == NULL) {
165                         log_error(kmap, _("out of memory"));
166                         return -1;
167                 }
168
169                 for (i = 0; i < NR_KEYS; i++)
170                         (kmap->key_map[k_table])[i] = K_HOLE;
171         }
172
173         if (!kmap->keymap_was_set[k_table]) {
174                 kmap->keymap_was_set[k_table] = (char *)malloc(NR_KEYS);
175
176                 if (kmap->key_map[k_table] == NULL) {
177                         log_error(kmap, _("out of memory"));
178                         return -1;
179                 }
180
181                 for (i = 0; i < NR_KEYS; i++)
182                         (kmap->keymap_was_set[k_table])[i] = 0;
183         }
184
185         if (kmap->alt_is_meta && keycode == K_HOLE
186             && (kmap->keymap_was_set[k_table])[k_index])
187                 return 0;
188
189         (kmap->key_map[k_table])[k_index] = keycode;
190         (kmap->keymap_was_set[k_table])[k_index] = 1;
191
192         if (kmap->alt_is_meta) {
193                 int alttable = k_table | M_ALT;
194                 int type = KTYP(keycode);
195                 int val = KVAL(keycode);
196
197                 if (alttable != k_table && kmap->defining[alttable] &&
198                     (!kmap->keymap_was_set[alttable] ||
199                      !(kmap->keymap_was_set[alttable])[k_index]) &&
200                     (type == KT_LATIN || type == KT_LETTER) && val < 128) {
201                         if (addkey(kmap, k_index, alttable, K(KT_META, val)) == -1)
202                                 return -1;
203                 }
204         }
205         return 0;
206 }
207
208 int
209 addfunc(struct keymap *kmap, struct kbsentry kbs)
210 {
211         int x;
212
213         x = kbs.kb_func;
214
215         if (x >= MAX_NR_FUNC) {
216                 log_error(kmap, _("addfunc called with bad func %d"), kbs.kb_func);
217                 return -1;
218         }
219
220         if(kmap->func_table[x]) {
221                 free(kmap->func_table[x]);
222                 kmap->func_table[x] = NULL;
223         }
224
225         kmap->func_table[x] = strdup((char *)kbs.kb_string);
226
227         if (!kmap->func_table[x]) {
228                 log_error(kmap, _("out of memory"));
229                 return -1;
230         }
231
232         return 0;
233 }
234
235 int
236 compose(struct keymap *kmap, unsigned int diacr, unsigned int base, unsigned int res)
237 {
238         accent_entry *ptr;
239         int direction;
240
241 #ifdef KDSKBDIACRUC
242         if (kmap->prefer_unicode)
243                 direction = TO_UNICODE;
244         else
245 #endif
246                 direction = TO_8BIT;
247
248         if (kmap->accent_table_size == MAX_DIACR) {
249                 log_error(kmap, _("compose table overflow"));
250                 return -1;
251         }
252
253         ptr = &(kmap->accent_table[kmap->accent_table_size++]);
254         ptr->diacr  = convert_code(kmap, diacr, direction);
255         ptr->base   = convert_code(kmap, base, direction);
256         ptr->result = convert_code(kmap, res, direction);
257
258         return 0;
259 }
260
261 static int
262 defkeys(struct keymap *kmap, int fd, int kbd_mode)
263 {
264         struct kbentry ke;
265         int ct = 0;
266         int i, j, fail;
267
268         if (kmap->flags & LKFLAG_UNICODE_MODE) {
269                 /* temporarily switch to K_UNICODE while defining keys */
270                 if (ioctl(fd, KDSKBMODE, K_UNICODE)) {
271                         log_error(kmap, _("KDSKBMODE: %s: could not switch to Unicode mode"),
272                                 strerror(errno));
273                         goto fail;
274                 }
275         }
276
277         for (i = 0; i < MAX_NR_KEYMAPS; i++) {
278                 if (kmap->key_map[i]) {
279                         for (j = 0; j < NR_KEYS; j++) {
280                                 if (!((kmap->keymap_was_set[i])[j]))
281                                         continue;
282
283                                 ke.kb_index = j;
284                                 ke.kb_table = i;
285                                 ke.kb_value = (kmap->key_map[i])[j];
286
287                                 fail = ioctl(fd, KDSKBENT, (unsigned long)&ke);
288
289                                 if (fail) {
290                                         if (errno == EPERM) {
291                                                 log_error(kmap, _("Keymap %d: Permission denied"), i);
292                                                 j = NR_KEYS;
293                                                 continue;
294                                         }
295                                         log_error(kmap, "%s", strerror(errno));
296                                 } else
297                                         ct++;
298
299                                 log_verbose(kmap, LOG_VERBOSE1, _("keycode %d, table %d = %d%s"),
300                                         j, i, (kmap->key_map[i])[j], fail ? _("    FAILED") : "");
301
302                                 if (fail && kmap->verbose > 1)
303                                         log_error(kmap, _("failed to bind key %d to value %d"),
304                                                 j, (kmap->key_map[i])[j]);
305                         }
306
307                 } else if (kmap->keymaps_line_seen && !kmap->defining[i]) {
308                         /* deallocate keymap */
309                         ke.kb_index = 0;
310                         ke.kb_table = i;
311                         ke.kb_value = K_NOSUCHMAP;
312
313                         log_verbose(kmap, LOG_VERBOSE2, _("deallocate keymap %d"), i);
314
315                         if (ioctl(fd, KDSKBENT, (unsigned long)&ke)) {
316                                 if (errno != EINVAL) {
317                                         log_error(kmap, _("KDSKBENT: %s: could not deallocate keymap %d"),
318                                                 strerror(errno), i);
319                                         goto fail;
320                                 }
321                                 /* probably an old kernel */
322                                 /* clear keymap by hand */
323                                 for (j = 0; j < NR_KEYS; j++) {
324                                         ke.kb_index = j;
325                                         ke.kb_table = i;
326                                         ke.kb_value = K_HOLE;
327
328                                         if (ioctl(fd, KDSKBENT, (unsigned long)&ke)) {
329                                                 if (errno == EINVAL && i >= 16)
330                                                         break;  /* old kernel */
331
332                                                 log_error(kmap, _("KDSKBENT: %s: cannot deallocate or clear keymap"),
333                                                         strerror(errno));
334                                                 goto fail;
335                                         }
336                                 }
337                         }
338                 }
339         }
340
341         if ((kmap->flags & LKFLAG_UNICODE_MODE) && ioctl(fd, KDSKBMODE, kbd_mode)) {
342                 log_error(kmap, _("KDSKBMODE: %s: could not return to original keyboard mode"),
343                         strerror(errno));
344                 goto fail;
345         }
346
347         return ct;
348
349  fail:  return -1;
350 }
351
352
353 static char *
354 ostr(struct keymap *kmap, char *s)
355 {
356         int lth = strlen(s);
357         char *ns0 = malloc(4 * lth + 1);
358         char *ns = ns0;
359
360         if (ns == NULL) {
361                 log_error(kmap, _("out of memory"));
362                 return NULL;
363         }
364
365         while (*s) {
366                 switch (*s) {
367                 case '\n':
368                         *ns++ = '\\';
369                         *ns++ = 'n';
370                         break;
371                 case '\033':
372                         *ns++ = '\\';
373                         *ns++ = '0';
374                         *ns++ = '3';
375                         *ns++ = '3';
376                         break;
377                 default:
378                         *ns++ = *s;
379                 }
380                 s++;
381         }
382         *ns = 0;
383         return ns0;
384 }
385
386 static int
387 deffuncs(struct keymap *kmap, int fd)
388 {
389         int i, ct = 0;
390         char *ptr, *s;
391         struct kbsentry kbs;
392
393         for (i = 0; i < MAX_NR_FUNC; i++) {
394                 kbs.kb_func = i;
395
396                 if ((ptr = kmap->func_table[i])) {
397                         strcpy((char *)kbs.kb_string, ptr);
398                         if (ioctl(fd, KDSKBSENT, (unsigned long)&kbs)) {
399                                 s = ostr(kmap, (char *)kbs.kb_string);
400                                 if (s == NULL)
401                                         return -1;
402                                 log_error(kmap, _("failed to bind string '%s' to function %s"),
403                                         s, syms[KT_FN].table[kbs.kb_func]);
404                                 free(s);
405                         } else {
406                                 ct++;
407                         }
408                 } else if (kmap->flags & LKFLAG_CLEAR_STRINGS) {
409                         kbs.kb_string[0] = 0;
410
411                         if (ioctl(fd, KDSKBSENT, (unsigned long)&kbs)) {
412                                 log_error(kmap, _("failed to clear string %s"),
413                                         syms[KT_FN].table[kbs.kb_func]);
414                         } else {
415                                 ct++;
416                         }
417                 }
418         }
419         return ct;
420 }
421
422 static int
423 defdiacs(struct keymap *kmap, int fd)
424 {
425         unsigned int i, count;
426         struct kbdiacrs kd;
427 #ifdef KDSKBDIACRUC
428         struct kbdiacrsuc kdu;
429 #endif
430
431         count = kmap->accent_table_size;
432         if (count > MAX_DIACR) {
433                 count = MAX_DIACR;
434                 log_error(kmap, _("too many compose definitions"));
435         }
436 #ifdef KDSKBDIACRUC
437         if (kmap->prefer_unicode) {
438                 kdu.kb_cnt = count;
439
440                 for (i = 0; i < kdu.kb_cnt; i++) {
441                         kdu.kbdiacruc[i].diacr  = kmap->accent_table[i].diacr;
442                         kdu.kbdiacruc[i].base   = kmap->accent_table[i].base;
443                         kdu.kbdiacruc[i].result = kmap->accent_table[i].result;
444                 }
445
446                 if (ioctl(fd, KDSKBDIACRUC, (unsigned long)&kdu))
447                         goto fail2;
448         } else
449 #endif
450         {
451                 kd.kb_cnt = count;
452                 for (i = 0; i < kd.kb_cnt; i++) {
453                         kd.kbdiacr[i].diacr  = kmap->accent_table[i].diacr;
454                         kd.kbdiacr[i].base   = kmap->accent_table[i].base;
455                         kd.kbdiacr[i].result = kmap->accent_table[i].result;
456                 }
457
458                 if (ioctl(fd, KDSKBDIACR, (unsigned long)&kd))
459                         goto fail1;
460         }
461
462         return kd.kb_cnt;
463
464  fail1: log_error(kmap, "KDSKBDIACR: %s", strerror(errno));
465         return -1;
466
467 #ifdef KDSKBDIACRUC
468  fail2: log_error(kmap, "KDSKBDIACRUC: %s", strerror(errno));
469         return -1;
470 #endif
471 }
472
473 static int
474 do_constant_key(struct keymap *kmap, int i, u_short key)
475 {
476         int typ, val, j;
477
478         typ = KTYP(key);
479         val = KVAL(key);
480
481         if ((typ == KT_LATIN || typ == KT_LETTER) &&
482             ((val >= 'a' && val <= 'z') || (val >= 'A' && val <= 'Z'))) {
483                 u_short defs[16];
484                 defs[0] = K(KT_LETTER, val);
485                 defs[1] = K(KT_LETTER, val ^ 32);
486                 defs[2] = defs[0];
487                 defs[3] = defs[1];
488
489                 for (j = 4; j < 8; j++)
490                         defs[j] = K(KT_LATIN, val & ~96);
491
492                 for (j = 8; j < 16; j++)
493                         defs[j] = K(KT_META, KVAL(defs[j - 8]));
494
495                 for (j = 0; j < kmap->max_keymap; j++) {
496                         if (!kmap->defining[j])
497                                 continue;
498
499                         if (j > 0 &&
500                             kmap->keymap_was_set[j] && (kmap->keymap_was_set[j])[i])
501                                 continue;
502
503                         if (addkey(kmap, i, j, defs[j % 16]) == -1)
504                                 return -1;
505                 }
506
507         } else {
508                 /* do this also for keys like Escape,
509                    as promised in the man page */
510                 for (j = 1; j < kmap->max_keymap; j++) {
511                         if (kmap->defining[j] &&
512                             (!(kmap->keymap_was_set[j]) || !(kmap->keymap_was_set[j])[i])) {
513                                 if (addkey(kmap, i, j, key) == -1)
514                                         return -1;
515                         }
516                 }
517         }
518         return 0;
519 }
520
521 int
522 do_constant(struct keymap *kmap)
523 {
524         int i, r0 = 0;
525
526         if (kmap->keymaps_line_seen) {
527                 while (r0 < kmap->max_keymap && !kmap->defining[r0])
528                         r0++;
529         }
530
531         for (i = 0; i < NR_KEYS; i++) {
532                 if (kmap->key_is_constant[i]) {
533                         u_short key;
534
535                         if (!kmap->key_map[r0]) {
536                                 log_error(kmap, _("impossible error in do_constant"));
537                                 return -1;
538                         }
539
540                         key = (kmap->key_map[r0])[i];
541                         if (do_constant_key(kmap, i, key) == -1)
542                                 return -1;
543                 }
544         }
545         return 0;
546 }
547
548
549 static int
550 strings_as_usual(struct keymap *kmap)
551 {
552         /*
553          * 26 strings, mostly inspired by the VT100 family
554          */
555         char *stringvalues[30] = {
556                 /* F1 .. F20 */
557                 "\033[[A",  "\033[[B",  "\033[[C",  "\033[[D",  "\033[[E",
558                 "\033[17~", "\033[18~", "\033[19~", "\033[20~", "\033[21~",
559                 "\033[23~", "\033[24~", "\033[25~", "\033[26~",
560                 "\033[28~", "\033[29~",
561                 "\033[31~", "\033[32~", "\033[33~", "\033[34~",
562                 /* Find,    Insert,     Remove,     Select,     Prior */
563                 "\033[1~",  "\033[2~",  "\033[3~",  "\033[4~",  "\033[5~",
564                 /* Next,    Macro,      Help,       Do,         Pause */
565                 "\033[6~",  0,          0,          0,          0
566         };
567         int i;
568
569         for (i = 0; i < 30; i++) {
570                 if (stringvalues[i]) {
571                         struct kbsentry ke;
572                         ke.kb_func = i;
573                         strncpy((char *)ke.kb_string, stringvalues[i],
574                                 sizeof(ke.kb_string));
575                         ke.kb_string[sizeof(ke.kb_string) - 1] = 0;
576
577                         if (addfunc(kmap, ke) == -1)
578                                 return -1;
579                 }
580         }
581         return 0;
582 }
583
584 static int
585 compose_as_usual(struct keymap *kmap, char *charset)
586 {
587         if (charset && strcmp(charset, "iso-8859-1")) {
588                 log_error(kmap, _("loadkeys: don't know how to compose for %s"), charset);
589                 return -1;
590
591         } else {
592                 struct ccc {
593                         unsigned char c1, c2, c3;
594                 } def_latin1_composes[68] = {
595                         { '`', 'A', 0300 }, { '`', 'a', 0340 },
596                         { '\'', 'A', 0301 }, { '\'', 'a', 0341 },
597                         { '^', 'A', 0302 }, { '^', 'a', 0342 },
598                         { '~', 'A', 0303 }, { '~', 'a', 0343 },
599                         { '"', 'A', 0304 }, { '"', 'a', 0344 },
600                         { 'O', 'A', 0305 }, { 'o', 'a', 0345 },
601                         { '0', 'A', 0305 }, { '0', 'a', 0345 },
602                         { 'A', 'A', 0305 }, { 'a', 'a', 0345 },
603                         { 'A', 'E', 0306 }, { 'a', 'e', 0346 },
604                         { ',', 'C', 0307 }, { ',', 'c', 0347 },
605                         { '`', 'E', 0310 }, { '`', 'e', 0350 },
606                         { '\'', 'E', 0311 }, { '\'', 'e', 0351 },
607                         { '^', 'E', 0312 }, { '^', 'e', 0352 },
608                         { '"', 'E', 0313 }, { '"', 'e', 0353 },
609                         { '`', 'I', 0314 }, { '`', 'i', 0354 },
610                         { '\'', 'I', 0315 }, { '\'', 'i', 0355 },
611                         { '^', 'I', 0316 }, { '^', 'i', 0356 },
612                         { '"', 'I', 0317 }, { '"', 'i', 0357 },
613                         { '-', 'D', 0320 }, { '-', 'd', 0360 },
614                         { '~', 'N', 0321 }, { '~', 'n', 0361 },
615                         { '`', 'O', 0322 }, { '`', 'o', 0362 },
616                         { '\'', 'O', 0323 }, { '\'', 'o', 0363 },
617                         { '^', 'O', 0324 }, { '^', 'o', 0364 },
618                         { '~', 'O', 0325 }, { '~', 'o', 0365 },
619                         { '"', 'O', 0326 }, { '"', 'o', 0366 },
620                         { '/', 'O', 0330 }, { '/', 'o', 0370 },
621                         { '`', 'U', 0331 }, { '`', 'u', 0371 },
622                         { '\'', 'U', 0332 }, { '\'', 'u', 0372 },
623                         { '^', 'U', 0333 }, { '^', 'u', 0373 },
624                         { '"', 'U', 0334 }, { '"', 'u', 0374 },
625                         { '\'', 'Y', 0335 }, { '\'', 'y', 0375 },
626                         { 'T', 'H', 0336 }, { 't', 'h', 0376 },
627                         { 's', 's', 0337 }, { '"', 'y', 0377 },
628                         { 's', 'z', 0337 }, { 'i', 'j', 0377 }
629                 };
630                 int i;
631                 for (i = 0; i < 68; i++) {
632                         struct ccc ptr = def_latin1_composes[i];
633                         if (compose(kmap, ptr.c1, ptr.c2, ptr.c3) == -1)
634                                 return -1;
635                 }
636         }
637         return 0;
638 }
639
640 /*
641  * mktable.c
642  *
643  */
644 char *
645 mk_mapname(char modifier)
646 {
647         static char *mods[8] = {
648                 "shift", "altgr", "ctrl", "alt", "shl", "shr", "ctl", "ctr"
649         };
650         static char buf[60];
651         int i;
652
653         if (!modifier)
654                 return "plain";
655         buf[0] = 0;
656         for (i = 0; i < 8; i++)
657                 if (modifier & (1 << i)) {
658                         if (buf[0])
659                                 strcat(buf, "_");
660                         strcat(buf, mods[i]);
661                 }
662         return buf;
663 }
664
665 void
666 outchar(FILE *fd, unsigned char c, int comma)
667 {
668         fprintf(fd, "'");
669         fprintf(fd, (c == '\'' || c == '\\') ? "\\%c"
670                : isgraph(c) ? "%c"
671                : "\\%03o", c);
672         fprintf(fd, comma ? "', " : "'");
673 }
674
675 // FIXME: Merge outchar ?
676 void
677 dumpchar(FILE *fd, unsigned char c, int comma)
678 {
679         fprintf(fd, "'");
680         fprintf(fd, (c == '\'' || c == '\\') ? "\\%c"
681                : (isgraph(c) || c == ' ' || c >= 0200) ? "%c"
682                : "\\%03o", c);
683         fprintf(fd, comma ? "', " : "'");
684 }
685
686 %}
687
688 %%
689 keytable        :
690                 | keytable line
691                 ;
692 line            : EOL
693                 | charsetline
694                 | altismetaline
695                 | usualstringsline
696                 | usualcomposeline
697                 | keymapline
698                 | fullline
699                 | singleline
700                 | strline
701                 | compline
702                 ;
703 charsetline     : CHARSET STRLITERAL EOL
704                         {
705                                 if (set_charset((char *) $2.data)) {
706                                         log_error(kmap,
707                                                 _("unknown charset %s - ignoring charset request\n"),
708                                                 (char *) $2.data);
709                                         YYERROR;
710                                 }
711
712                                 /* Unicode: The first 256 code points were made
713                                    identical to the content of ISO 8859-1 */
714                                 if (kmap->prefer_unicode &&
715                                     !strcasecmp((char *) $2.data, "iso-8859-1"))
716                                         kmap->prefer_unicode = 0;
717                         }
718                 ;
719 altismetaline   : ALT_IS_META EOL
720                         {
721                                 kmap->alt_is_meta = 1;
722                         }
723                 ;
724 usualstringsline: STRINGS AS USUAL EOL
725                         {
726                                 if (strings_as_usual(kmap) == -1)
727                                         YYERROR;
728                         }
729                 ;
730 usualcomposeline: COMPOSE AS USUAL FOR STRLITERAL EOL
731                         {
732                                 if (compose_as_usual(kmap, (char *) $5.data) == -1)
733                                         YYERROR;
734                         }
735                   | COMPOSE AS USUAL EOL
736                         {
737                                 if (compose_as_usual(kmap, 0) == -1)
738                                         YYERROR;
739                         }
740                 ;
741 keymapline      : KEYMAPS range EOL
742                         {
743                                 kmap->keymaps_line_seen = 1;
744                         }
745                 ;
746 range           : range COMMA range0
747                 | range0
748                 ;
749 range0          : NUMBER DASH NUMBER
750                         {
751                                 int i;
752                                 for (i = $1; i <= $3; i++) {
753                                         if (addmap(kmap, i, 1) == -1)
754                                                 YYERROR;
755                                 }
756                         }
757                 | NUMBER
758                         {
759                                 if (addmap(kmap, $1, 1) == -1)
760                                         YYERROR;
761                         }
762                 ;
763 strline         : STRING LITERAL EQUALS STRLITERAL EOL
764                         {
765                                 struct kbsentry ke;
766
767                                 if (KTYP($2) != KT_FN) {
768                                         log_error(kmap, _("'%s' is not a function key symbol"),
769                                                 syms[KTYP($2)].table[KVAL($2)]);
770                                         YYERROR;
771                                 }
772
773                                 ke.kb_func = KVAL($2);
774                                 strncpy((char *) ke.kb_string,
775                                         (char *) $4.data,
776                                         sizeof(ke.kb_string));
777                                 ke.kb_string[sizeof(ke.kb_string) - 1] = 0;
778
779                                 if (addfunc(kmap, ke) == -1)
780                                         YYERROR;
781                         }
782                 ;
783 compline        : COMPOSE compsym compsym TO compsym EOL
784                         {
785                                 if (compose(kmap, $2, $3, $5) == -1)
786                                         YYERROR;
787                         }
788                  | COMPOSE compsym compsym TO rvalue EOL
789                         {
790                                 if (compose(kmap, $2, $3, $5) == -1)
791                                         YYERROR;
792                         }
793                 ;
794 compsym         : CCHAR         {       $$ = $1;                }
795                 | UNUMBER       {       $$ = $1 ^ 0xf000;       }
796                 ;
797 singleline      :       {
798                                 kmap->mod = 0;
799                         }
800                   modifiers KEYCODE NUMBER EQUALS rvalue EOL
801                         {
802                                 if (addkey(kmap, $4, kmap->mod, $6) == -1)
803                                         YYERROR;
804                         }
805                 | PLAIN KEYCODE NUMBER EQUALS rvalue EOL
806                         {
807                                 if (addkey(kmap, $3, 0, $5) == -1)
808                                         YYERROR;
809                         }
810                 ;
811 modifiers       : modifiers modifier
812                 | modifier
813                 ;
814 modifier        : SHIFT         { kmap->mod |= M_SHIFT; }
815                 | CONTROL       { kmap->mod |= M_CTRL;  }
816                 | ALT           { kmap->mod |= M_ALT;           }
817                 | ALTGR         { kmap->mod |= M_ALTGR; }
818                 | SHIFTL        { kmap->mod |= M_SHIFTL;        }
819                 | SHIFTR        { kmap->mod |= M_SHIFTR;        }
820                 | CTRLL         { kmap->mod |= M_CTRLL; }
821                 | CTRLR         { kmap->mod |= M_CTRLR; }
822                 | CAPSSHIFT     { kmap->mod |= M_CAPSSHIFT;     }
823                 ;
824 fullline        : KEYCODE NUMBER EQUALS rvalue0 EOL
825                         {
826                                 int i, j, keycode;
827
828                                 if (kmap->rvalct == 1) {
829                                         /* Some files do not have a keymaps line, and
830                                          * we have to wait until all input has been read
831                                          * before we know which maps to fill. */
832                                         kmap->key_is_constant[$2] = 1;
833
834                                         /* On the other hand, we now have include files,
835                                          * and it should be possible to override lines
836                                          * from an include file. So, kill old defs. */
837                                         for (j = 0; j < kmap->max_keymap; j++) {
838                                                 if (!(kmap->defining[j]))
839                                                         continue;
840
841                                                 if (killkey(kmap, $2, j) == -1)
842                                                         YYERROR;
843                                         }
844                                 }
845
846                                 if (kmap->keymaps_line_seen) {
847                                         i = 0;
848
849                                         for (j = 0; j < kmap->max_keymap; j++) {
850                                                 if (!(kmap->defining[j]))
851                                                         continue;
852
853                                                 if (kmap->rvalct != 1 || i == 0) {
854                                                         keycode = (i < kmap->rvalct)
855                                                                 ? kmap->key_buf[i]
856                                                                 : K_HOLE;
857
858                                                         if (addkey(kmap, $2, j, keycode) == -1)
859                                                                 YYERROR;
860                                                 }
861                                                 i++;
862                                         }
863
864                                         if (i < kmap->rvalct) {
865                                                 log_error(kmap, _("too many (%d) entries on one line"),
866                                                         kmap->rvalct);
867                                                 YYERROR;
868                                         }
869                                 } else {
870                                         for (i = 0; i < kmap->rvalct; i++) {
871                                                 if (addkey(kmap, $2, i, kmap->key_buf[i]) == -1)
872                                                         YYERROR;
873                                         }
874                                 }
875                         }
876                 ;
877
878 rvalue0         :
879                 | rvalue1 rvalue0
880                 ;
881 rvalue1         : rvalue
882                         {
883                                 if (kmap->rvalct >= MAX_NR_KEYMAPS) {
884                                         log_error(kmap, _("too many key definitions on one line"));
885                                         YYERROR;
886                                 }
887                                 kmap->key_buf[kmap->rvalct++] = $1;
888                         }
889                 ;
890 rvalue          : NUMBER        { $$ = convert_code(kmap, $1, TO_AUTO);         }
891                 | PLUS NUMBER   { $$ = add_capslock(kmap, $2);                  }
892                 | UNUMBER       { $$ = convert_code(kmap, $1^0xf000, TO_AUTO);  }
893                 | PLUS UNUMBER  { $$ = add_capslock(kmap, $2^0xf000);           }
894                 | LITERAL       { $$ = $1;                                      }
895                 | PLUS LITERAL  { $$ = add_capslock(kmap, $2);                  }
896                 ;
897 %%
898
899 int
900 lk_parse_keymap(struct keymap *kmap, lkfile_t *f)
901 {
902         yyscan_t scanner;
903         int rc = -1;
904
905         yylex_init(&scanner);
906         yylex_init_extra(kmap, &scanner);
907
908         log_verbose(kmap, LOG_NORMAL, _("Loading %s"), f->pathname);
909
910         if (stack_push(kmap, f, scanner) == -1)
911                 goto fail;
912
913         if (yyparse(scanner, kmap))
914                 goto fail;
915
916         rc = 0;
917
918         stack_pop(kmap, scanner);
919
920  fail:  yylex_destroy(scanner);
921         return rc;
922 }
923
924 int
925 lk_loadkeys(struct keymap *kmap, int fd, int kbd_mode)
926 {
927         int keyct, funcct, diacct;
928
929         if (do_constant(kmap) < 0)
930                 return -1;
931
932         if ((keyct = defkeys(kmap, fd, kbd_mode)) < 0 || (funcct = deffuncs(kmap, fd)) < 0)
933                 return -1;
934
935         log_verbose(kmap, LOG_VERBOSE1, _("\nChanged %d %s and %d %s"),
936                 keyct, (keyct == 1) ? _("key") : _("keys"),
937                 funcct, (funcct == 1) ? _("string") : _("strings"));
938
939         if (kmap->accent_table_size > 0 || kmap->flags & LKFLAG_CLEAR_COMPOSE) {
940                 diacct = defdiacs(kmap, fd);
941
942                 if (diacct < 0)
943                         return -1;
944
945                 log_verbose(kmap, LOG_VERBOSE1, _("Loaded %d compose %s"),
946                         diacct, (diacct == 1) ? _("definition") : _("definitions"));
947
948         } else {
949                 log_verbose(kmap, LOG_VERBOSE1, _("(No change in compose definitions)"));
950         }
951
952         return 0;
953 }
954