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-2013 Alexey Gladkov <gladkov.alexey@gmail.com>
9 * This file is covered by the GNU General Public License,
10 * which should be included with kbd as the file COPYING.
13 #define YY_HEADER_EXPORT_START_CONDITIONS 1
19 #include "modifiers.h"
28 #ifndef STRDATA_STRUCT
29 #define STRDATA_STRUCT
30 #define MAX_PARSER_STRING 512
33 unsigned char data[MAX_PARSER_STRING];
46 %lex-param { yyscan_t scanner }
49 %parse-param { void *scanner }
50 %parse-param { struct keymap *kmap }
52 %token EOL NUMBER LITERAL CHARSET KEYMAPS KEYCODE EQUALS
53 %token PLAIN SHIFT CONTROL ALT ALTGR SHIFTL SHIFTR CTRLL CTRLR CAPSSHIFT
54 %token COMMA DASH STRING STRLITERAL COMPOSE TO CCHAR ERROR PLUS
55 %token UNUMBER ALT_IS_META STRINGS AS USUAL ON FOR
62 %type <str> STRLITERAL
72 yyerror(yyscan_t scanner __attribute__ ((unused)),
73 struct keymap *kmap, const char *s)
80 strings_as_usual(struct keymap *kmap)
83 * 26 strings, mostly inspired by the VT100 family
85 char *stringvalues[30] = {
87 "\033[[A", "\033[[B", "\033[[C", "\033[[D", "\033[[E",
88 "\033[17~", "\033[18~", "\033[19~", "\033[20~", "\033[21~",
89 "\033[23~", "\033[24~", "\033[25~", "\033[26~",
90 "\033[28~", "\033[29~",
91 "\033[31~", "\033[32~", "\033[33~", "\033[34~",
92 /* Find, Insert, Remove, Select, Prior */
93 "\033[1~", "\033[2~", "\033[3~", "\033[4~", "\033[5~",
94 /* Next, Macro, Help, Do, Pause */
99 for (i = 0; i < 30; i++) {
100 if (stringvalues[i]) {
103 strncpy((char *)ke.kb_string, stringvalues[i],
104 sizeof(ke.kb_string));
105 ke.kb_string[sizeof(ke.kb_string) - 1] = 0;
107 if (lk_add_func(kmap, ke) == -1)
115 compose_as_usual(struct keymap *kmap, char *charset)
117 if (charset && strcmp(charset, "iso-8859-1")) {
118 ERR(kmap, _("loadkeys: don't know how to compose for %s"), charset);
123 unsigned char c1, c2, c3;
124 } def_latin1_composes[68] = {
125 { '`', 'A', 0300 }, { '`', 'a', 0340 },
126 { '\'', 'A', 0301 }, { '\'', 'a', 0341 },
127 { '^', 'A', 0302 }, { '^', 'a', 0342 },
128 { '~', 'A', 0303 }, { '~', 'a', 0343 },
129 { '"', 'A', 0304 }, { '"', 'a', 0344 },
130 { 'O', 'A', 0305 }, { 'o', 'a', 0345 },
131 { '0', 'A', 0305 }, { '0', 'a', 0345 },
132 { 'A', 'A', 0305 }, { 'a', 'a', 0345 },
133 { 'A', 'E', 0306 }, { 'a', 'e', 0346 },
134 { ',', 'C', 0307 }, { ',', 'c', 0347 },
135 { '`', 'E', 0310 }, { '`', 'e', 0350 },
136 { '\'', 'E', 0311 }, { '\'', 'e', 0351 },
137 { '^', 'E', 0312 }, { '^', 'e', 0352 },
138 { '"', 'E', 0313 }, { '"', 'e', 0353 },
139 { '`', 'I', 0314 }, { '`', 'i', 0354 },
140 { '\'', 'I', 0315 }, { '\'', 'i', 0355 },
141 { '^', 'I', 0316 }, { '^', 'i', 0356 },
142 { '"', 'I', 0317 }, { '"', 'i', 0357 },
143 { '-', 'D', 0320 }, { '-', 'd', 0360 },
144 { '~', 'N', 0321 }, { '~', 'n', 0361 },
145 { '`', 'O', 0322 }, { '`', 'o', 0362 },
146 { '\'', 'O', 0323 }, { '\'', 'o', 0363 },
147 { '^', 'O', 0324 }, { '^', 'o', 0364 },
148 { '~', 'O', 0325 }, { '~', 'o', 0365 },
149 { '"', 'O', 0326 }, { '"', 'o', 0366 },
150 { '/', 'O', 0330 }, { '/', 'o', 0370 },
151 { '`', 'U', 0331 }, { '`', 'u', 0371 },
152 { '\'', 'U', 0332 }, { '\'', 'u', 0372 },
153 { '^', 'U', 0333 }, { '^', 'u', 0373 },
154 { '"', 'U', 0334 }, { '"', 'u', 0374 },
155 { '\'', 'Y', 0335 }, { '\'', 'y', 0375 },
156 { 'T', 'H', 0336 }, { 't', 'h', 0376 },
157 { 's', 's', 0337 }, { '"', 'y', 0377 },
158 { 's', 'z', 0337 }, { 'i', 'j', 0377 }
161 for (i = 0; i < 68; i++) {
162 struct ccc ptr = def_latin1_composes[i];
163 if (lk_add_compose(kmap, ptr.c1, ptr.c2, ptr.c3) == -1)
187 charsetline : CHARSET STRLITERAL EOL
189 if (lk_set_charset(kmap, (char *) $2.data)) {
191 _("unknown charset %s - ignoring charset request\n"),
195 kmap->keywords |= LK_KEYWORD_CHARSET;
197 /* Unicode: The first 256 code points were made
198 identical to the content of ISO 8859-1 */
199 if (kmap->flags & LK_FLAG_PREFER_UNICODE &&
200 !strcasecmp((char *) $2.data, "iso-8859-1"))
201 kmap->flags ^= LK_FLAG_PREFER_UNICODE;
204 altismetaline : ALT_IS_META EOL
206 kmap->keywords |= LK_KEYWORD_ALTISMETA;
209 usualstringsline: STRINGS AS USUAL EOL
211 if (strings_as_usual(kmap) == -1)
213 kmap->keywords |= LK_KEYWORD_STRASUSUAL;
216 usualcomposeline: COMPOSE AS USUAL FOR STRLITERAL EOL
218 if (compose_as_usual(kmap, (char *) $5.data) == -1)
221 | COMPOSE AS USUAL EOL
223 if (compose_as_usual(kmap, 0) == -1)
227 keymapline : KEYMAPS range EOL
229 kmap->keywords |= LK_KEYWORD_KEYMAPS;
232 range : range COMMA range0
235 range0 : NUMBER DASH NUMBER
238 for (i = $1; i <= $3; i++) {
239 if (lk_add_map(kmap, i) == -1)
245 if (lk_add_map(kmap, $1) == -1)
249 strline : STRING LITERAL EQUALS STRLITERAL EOL
253 if (KTYP($2) != KT_FN) {
254 ERR(kmap, _("'%s' is not a function key symbol"),
255 syms[KTYP($2)].table[KVAL($2)]);
259 ke.kb_func = KVAL($2);
260 strncpy((char *) ke.kb_string,
262 sizeof(ke.kb_string));
263 ke.kb_string[sizeof(ke.kb_string) - 1] = 0;
265 if (lk_add_func(kmap, ke) == -1)
269 compline : COMPOSE compsym compsym TO compsym EOL
271 if (lk_add_compose(kmap, $2, $3, $5) == -1)
274 | COMPOSE compsym compsym TO rvalue EOL
276 if (lk_add_compose(kmap, $2, $3, $5) == -1)
280 compsym : CCHAR { $$ = $1; }
281 | UNUMBER { $$ = $1 ^ 0xf000; }
286 modifiers KEYCODE NUMBER EQUALS rvalue EOL
288 if (lk_add_key(kmap, kmap->mod, $4, $6) < 0)
291 | PLAIN KEYCODE NUMBER EQUALS rvalue EOL
293 if (lk_add_key(kmap, 0, $3, $5) < 0)
297 modifiers : modifiers modifier
300 modifier : SHIFT { kmap->mod |= M_SHIFT; }
301 | CONTROL { kmap->mod |= M_CTRL; }
302 | ALT { kmap->mod |= M_ALT; }
303 | ALTGR { kmap->mod |= M_ALTGR; }
304 | SHIFTL { kmap->mod |= M_SHIFTL; }
305 | SHIFTR { kmap->mod |= M_SHIFTR; }
306 | CTRLL { kmap->mod |= M_CTRLL; }
307 | CTRLR { kmap->mod |= M_CTRLR; }
308 | CAPSSHIFT { kmap->mod |= M_CAPSSHIFT; }
310 fullline : KEYCODE NUMBER EQUALS rvalue0 EOL
312 unsigned int j, i, keycode;
315 if (kmap->key_line->count == 1) {
317 /* Some files do not have a keymaps line, and
318 * we have to wait until all input has been read
319 * before we know which maps to fill. */
320 lk_array_set(kmap->key_constant, $2, &one);
322 /* On the other hand, we now have include files,
323 * and it should be possible to override lines
324 * from an include file. So, kill old defs. */
325 for (j = 0; j < kmap->keymap->total; j++) {
326 if (!lk_map_exist(kmap, j))
329 if (lk_del_key(kmap, j, $2) < 0)
334 if (kmap->keywords & LK_KEYWORD_KEYMAPS) {
337 for (j = 0; j < kmap->keymap->total; j++) {
338 if (!lk_map_exist(kmap, j))
341 if (kmap->key_line->count != 1 || i == 0) {
344 if (i < kmap->key_line->count) {
345 val = lk_array_get(kmap->key_line, i);
349 if (lk_add_key(kmap, j, $2, keycode) < 0)
355 if (i < kmap->key_line->count) {
356 ERR(kmap, _("too many (%d) entries on one line"),
357 kmap->key_line->count);
361 for (i = 0; i < kmap->key_line->count; i++) {
362 val = lk_array_get(kmap->key_line, i);
364 if (lk_add_key(kmap, i, $2, *val) < 0)
377 lk_array_append(kmap->key_line, &val);
380 rvalue : NUMBER { $$ = convert_code(kmap, $1, TO_AUTO); }
381 | PLUS NUMBER { $$ = add_capslock(kmap, $2); }
382 | UNUMBER { $$ = convert_code(kmap, $1^0xf000, TO_AUTO); }
383 | PLUS UNUMBER { $$ = add_capslock(kmap, $2^0xf000); }
384 | LITERAL { $$ = $1; }
385 | PLUS LITERAL { $$ = add_capslock(kmap, $2); }
390 lk_parse_keymap(struct keymap *kmap, lkfile_t *f)
395 yylex_init(&scanner);
396 yylex_init_extra(kmap, &scanner);
398 INFO(kmap, _("Loading %s"), f->pathname);
400 if (stack_push(kmap, f, scanner) == -1)
403 if (yyparse(scanner, kmap))
408 stack_pop(kmap, scanner);
410 fail: yylex_destroy(scanner);