Big rename functions and source files
[platform/upstream/kbd.git] / src / libkeymap / parser.y
1 /* parser.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-2013  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 "nls.h"
16 #include "kbd.h"
17
18 #include "ksyms.h"
19 #include "modifiers.h"
20
21 #include "parser.h"
22 #include "analyze.h"
23 %}
24
25 %code requires {
26 #include "keymap.h"
27
28 #ifndef STRDATA_STRUCT
29 #define STRDATA_STRUCT
30 #define MAX_PARSER_STRING 512
31 struct strdata {
32         unsigned int len;
33         unsigned char data[MAX_PARSER_STRING];
34 };
35 #endif
36 }
37
38 %language "C"
39 %yacc
40 %defines
41 %debug
42 %error-verbose
43
44 /* Pure yylex.  */
45 %define api.pure
46 %lex-param { yyscan_t scanner }
47
48 /* Pure yyparse.  */
49 %parse-param { void *scanner }
50 %parse-param { struct keymap *kmap }
51
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
56
57 %union {
58         long long int num;
59         struct strdata str;
60 }
61
62 %type <str>  STRLITERAL
63 %type <num>  CCHAR
64 %type <num>  LITERAL
65 %type <num>  NUMBER
66 %type <num>  UNUMBER
67 %type <num>  compsym
68 %type <num>  rvalue
69
70 %{
71 static int
72 yyerror(yyscan_t scanner attr_unused, struct keymap *kmap, const char *s)
73 {
74         log_error(kmap, "%s", s);
75         return 0;
76 }
77
78 static int
79 strings_as_usual(struct keymap *kmap)
80 {
81         /*
82          * 26 strings, mostly inspired by the VT100 family
83          */
84         char *stringvalues[30] = {
85                 /* F1 .. F20 */
86                 "\033[[A",  "\033[[B",  "\033[[C",  "\033[[D",  "\033[[E",
87                 "\033[17~", "\033[18~", "\033[19~", "\033[20~", "\033[21~",
88                 "\033[23~", "\033[24~", "\033[25~", "\033[26~",
89                 "\033[28~", "\033[29~",
90                 "\033[31~", "\033[32~", "\033[33~", "\033[34~",
91                 /* Find,    Insert,     Remove,     Select,     Prior */
92                 "\033[1~",  "\033[2~",  "\033[3~",  "\033[4~",  "\033[5~",
93                 /* Next,    Macro,      Help,       Do,         Pause */
94                 "\033[6~",  0,          0,          0,          0
95         };
96         int i;
97
98         for (i = 0; i < 30; i++) {
99                 if (stringvalues[i]) {
100                         struct kbsentry ke;
101                         ke.kb_func = i;
102                         strncpy((char *)ke.kb_string, stringvalues[i],
103                                 sizeof(ke.kb_string));
104                         ke.kb_string[sizeof(ke.kb_string) - 1] = 0;
105
106                         if (lk_add_func(kmap, ke) == -1)
107                                 return -1;
108                 }
109         }
110         return 0;
111 }
112
113 static int
114 compose_as_usual(struct keymap *kmap, char *charset)
115 {
116         if (charset && strcmp(charset, "iso-8859-1")) {
117                 log_error(kmap, _("loadkeys: don't know how to compose for %s"), charset);
118                 return -1;
119
120         } else {
121                 struct ccc {
122                         unsigned char c1, c2, c3;
123                 } def_latin1_composes[68] = {
124                         { '`', 'A', 0300 }, { '`', 'a', 0340 },
125                         { '\'', 'A', 0301 }, { '\'', 'a', 0341 },
126                         { '^', 'A', 0302 }, { '^', 'a', 0342 },
127                         { '~', 'A', 0303 }, { '~', 'a', 0343 },
128                         { '"', 'A', 0304 }, { '"', 'a', 0344 },
129                         { 'O', 'A', 0305 }, { 'o', 'a', 0345 },
130                         { '0', 'A', 0305 }, { '0', 'a', 0345 },
131                         { 'A', 'A', 0305 }, { 'a', 'a', 0345 },
132                         { 'A', 'E', 0306 }, { 'a', 'e', 0346 },
133                         { ',', 'C', 0307 }, { ',', 'c', 0347 },
134                         { '`', 'E', 0310 }, { '`', 'e', 0350 },
135                         { '\'', 'E', 0311 }, { '\'', 'e', 0351 },
136                         { '^', 'E', 0312 }, { '^', 'e', 0352 },
137                         { '"', 'E', 0313 }, { '"', 'e', 0353 },
138                         { '`', 'I', 0314 }, { '`', 'i', 0354 },
139                         { '\'', 'I', 0315 }, { '\'', 'i', 0355 },
140                         { '^', 'I', 0316 }, { '^', 'i', 0356 },
141                         { '"', 'I', 0317 }, { '"', 'i', 0357 },
142                         { '-', 'D', 0320 }, { '-', 'd', 0360 },
143                         { '~', 'N', 0321 }, { '~', 'n', 0361 },
144                         { '`', 'O', 0322 }, { '`', 'o', 0362 },
145                         { '\'', 'O', 0323 }, { '\'', 'o', 0363 },
146                         { '^', 'O', 0324 }, { '^', 'o', 0364 },
147                         { '~', 'O', 0325 }, { '~', 'o', 0365 },
148                         { '"', 'O', 0326 }, { '"', 'o', 0366 },
149                         { '/', 'O', 0330 }, { '/', 'o', 0370 },
150                         { '`', 'U', 0331 }, { '`', 'u', 0371 },
151                         { '\'', 'U', 0332 }, { '\'', 'u', 0372 },
152                         { '^', 'U', 0333 }, { '^', 'u', 0373 },
153                         { '"', 'U', 0334 }, { '"', 'u', 0374 },
154                         { '\'', 'Y', 0335 }, { '\'', 'y', 0375 },
155                         { 'T', 'H', 0336 }, { 't', 'h', 0376 },
156                         { 's', 's', 0337 }, { '"', 'y', 0377 },
157                         { 's', 'z', 0337 }, { 'i', 'j', 0377 }
158                 };
159                 int i;
160                 for (i = 0; i < 68; i++) {
161                         struct ccc ptr = def_latin1_composes[i];
162                         if (lk_add_compose(kmap, ptr.c1, ptr.c2, ptr.c3) == -1)
163                                 return -1;
164                 }
165         }
166         return 0;
167 }
168
169 %}
170
171 %%
172 keytable        :
173                 | keytable line
174                 ;
175 line            : EOL
176                 | charsetline
177                 | altismetaline
178                 | usualstringsline
179                 | usualcomposeline
180                 | keymapline
181                 | fullline
182                 | singleline
183                 | strline
184                 | compline
185                 ;
186 charsetline     : CHARSET STRLITERAL EOL
187                         {
188                                 if (lk_set_charset(kmap, (char *) $2.data)) {
189                                         log_error(kmap,
190                                                 _("unknown charset %s - ignoring charset request\n"),
191                                                 (char *) $2.data);
192                                         YYERROR;
193                                 }
194
195                                 /* Unicode: The first 256 code points were made
196                                    identical to the content of ISO 8859-1 */
197                                 if (kmap->prefer_unicode &&
198                                     !strcasecmp((char *) $2.data, "iso-8859-1"))
199                                         kmap->prefer_unicode = 0;
200                         }
201                 ;
202 altismetaline   : ALT_IS_META EOL
203                         {
204                                 kmap->alt_is_meta = 1;
205                         }
206                 ;
207 usualstringsline: STRINGS AS USUAL EOL
208                         {
209                                 if (strings_as_usual(kmap) == -1)
210                                         YYERROR;
211                         }
212                 ;
213 usualcomposeline: COMPOSE AS USUAL FOR STRLITERAL EOL
214                         {
215                                 if (compose_as_usual(kmap, (char *) $5.data) == -1)
216                                         YYERROR;
217                         }
218                   | COMPOSE AS USUAL EOL
219                         {
220                                 if (compose_as_usual(kmap, 0) == -1)
221                                         YYERROR;
222                         }
223                 ;
224 keymapline      : KEYMAPS range EOL
225                         {
226                                 kmap->keymaps_line_seen = 1;
227                         }
228                 ;
229 range           : range COMMA range0
230                 | range0
231                 ;
232 range0          : NUMBER DASH NUMBER
233                         {
234                                 int i;
235                                 for (i = $1; i <= $3; i++) {
236                                         if (lk_add_map(kmap, i, 1) == -1)
237                                                 YYERROR;
238                                 }
239                         }
240                 | NUMBER
241                         {
242                                 if (lk_add_map(kmap, $1, 1) == -1)
243                                         YYERROR;
244                         }
245                 ;
246 strline         : STRING LITERAL EQUALS STRLITERAL EOL
247                         {
248                                 struct kbsentry ke;
249
250                                 if (KTYP($2) != KT_FN) {
251                                         log_error(kmap, _("'%s' is not a function key symbol"),
252                                                 syms[KTYP($2)].table[KVAL($2)]);
253                                         YYERROR;
254                                 }
255
256                                 ke.kb_func = KVAL($2);
257                                 strncpy((char *) ke.kb_string,
258                                         (char *) $4.data,
259                                         sizeof(ke.kb_string));
260                                 ke.kb_string[sizeof(ke.kb_string) - 1] = 0;
261
262                                 if (lk_add_func(kmap, ke) == -1)
263                                         YYERROR;
264                         }
265                 ;
266 compline        : COMPOSE compsym compsym TO compsym EOL
267                         {
268                                 if (lk_add_compose(kmap, $2, $3, $5) == -1)
269                                         YYERROR;
270                         }
271                  | COMPOSE compsym compsym TO rvalue EOL
272                         {
273                                 if (lk_add_compose(kmap, $2, $3, $5) == -1)
274                                         YYERROR;
275                         }
276                 ;
277 compsym         : CCHAR         {       $$ = $1;                }
278                 | UNUMBER       {       $$ = $1 ^ 0xf000;       }
279                 ;
280 singleline      :       {
281                                 kmap->mod = 0;
282                         }
283                   modifiers KEYCODE NUMBER EQUALS rvalue EOL
284                         {
285                                 if (lk_add_key(kmap, $4, kmap->mod, $6) == -1)
286                                         YYERROR;
287                         }
288                 | PLAIN KEYCODE NUMBER EQUALS rvalue EOL
289                         {
290                                 if (lk_add_key(kmap, $3, 0, $5) == -1)
291                                         YYERROR;
292                         }
293                 ;
294 modifiers       : modifiers modifier
295                 | modifier
296                 ;
297 modifier        : SHIFT         { kmap->mod |= M_SHIFT; }
298                 | CONTROL       { kmap->mod |= M_CTRL;  }
299                 | ALT           { kmap->mod |= M_ALT;           }
300                 | ALTGR         { kmap->mod |= M_ALTGR; }
301                 | SHIFTL        { kmap->mod |= M_SHIFTL;        }
302                 | SHIFTR        { kmap->mod |= M_SHIFTR;        }
303                 | CTRLL         { kmap->mod |= M_CTRLL; }
304                 | CTRLR         { kmap->mod |= M_CTRLR; }
305                 | CAPSSHIFT     { kmap->mod |= M_CAPSSHIFT;     }
306                 ;
307 fullline        : KEYCODE NUMBER EQUALS rvalue0 EOL
308                         {
309                                 int i, j, keycode;
310
311                                 if (kmap->rvalct == 1) {
312                                         /* Some files do not have a keymaps line, and
313                                          * we have to wait until all input has been read
314                                          * before we know which maps to fill. */
315                                         kmap->key_is_constant[$2] = 1;
316
317                                         /* On the other hand, we now have include files,
318                                          * and it should be possible to override lines
319                                          * from an include file. So, kill old defs. */
320                                         for (j = 0; j < kmap->max_keymap; j++) {
321                                                 if (!(kmap->defining[j]))
322                                                         continue;
323
324                                                 if (lk_remove_key(kmap, $2, j) == -1)
325                                                         YYERROR;
326                                         }
327                                 }
328
329                                 if (kmap->keymaps_line_seen) {
330                                         i = 0;
331
332                                         for (j = 0; j < kmap->max_keymap; j++) {
333                                                 if (!(kmap->defining[j]))
334                                                         continue;
335
336                                                 if (kmap->rvalct != 1 || i == 0) {
337                                                         keycode = (i < kmap->rvalct)
338                                                                 ? kmap->key_buf[i]
339                                                                 : K_HOLE;
340
341                                                         if (lk_add_key(kmap, $2, j, keycode) == -1)
342                                                                 YYERROR;
343                                                 }
344                                                 i++;
345                                         }
346
347                                         if (i < kmap->rvalct) {
348                                                 log_error(kmap, _("too many (%d) entries on one line"),
349                                                         kmap->rvalct);
350                                                 YYERROR;
351                                         }
352                                 } else {
353                                         for (i = 0; i < kmap->rvalct; i++) {
354                                                 if (lk_add_key(kmap, $2, i, kmap->key_buf[i]) == -1)
355                                                         YYERROR;
356                                         }
357                                 }
358                         }
359                 ;
360
361 rvalue0         :
362                 | rvalue1 rvalue0
363                 ;
364 rvalue1         : rvalue
365                         {
366                                 if (kmap->rvalct >= MAX_NR_KEYMAPS) {
367                                         log_error(kmap, _("too many key definitions on one line"));
368                                         YYERROR;
369                                 }
370                                 kmap->key_buf[kmap->rvalct++] = $1;
371                         }
372                 ;
373 rvalue          : NUMBER        { $$ = convert_code(kmap, $1, TO_AUTO);         }
374                 | PLUS NUMBER   { $$ = add_capslock(kmap, $2);                  }
375                 | UNUMBER       { $$ = convert_code(kmap, $1^0xf000, TO_AUTO);  }
376                 | PLUS UNUMBER  { $$ = add_capslock(kmap, $2^0xf000);           }
377                 | LITERAL       { $$ = $1;                                      }
378                 | PLUS LITERAL  { $$ = add_capslock(kmap, $2);                  }
379                 ;
380 %%
381
382 int
383 lk_parse_keymap(struct keymap *kmap, lkfile_t *f)
384 {
385         yyscan_t scanner;
386         int rc = -1;
387
388         yylex_init(&scanner);
389         yylex_init_extra(kmap, &scanner);
390
391         log_verbose(kmap, LOG_NORMAL, _("Loading %s"), f->pathname);
392
393         if (stack_push(kmap, f, scanner) == -1)
394                 goto fail;
395
396         if (yyparse(scanner, kmap))
397                 goto fail;
398
399         rc = 0;
400
401         stack_pop(kmap, scanner);
402
403  fail:  yylex_destroy(scanner);
404         return rc;
405 }