Organize xkbcomp/ header files
[platform/upstream/libxkbcommon.git] / src / xkbcomp / scanner.l
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 %{
28 #include "xkbcomp-priv.h"
29 #include "parser-priv.h"
30
31 #pragma GCC diagnostic ignored "-Wmissing-noreturn"
32
33 struct scanner_extra {
34     struct xkb_context *ctx;
35     char *scanFile;
36     char scanBuf[1024];
37     char *s;
38 };
39
40 static void
41 scanner_error_extra(struct YYLTYPE *loc, struct scanner_extra *extra,
42                     const char *msg);
43
44 #define YY_USER_ACTION {                \
45         yylloc->first_line = yylineno;  \
46         yylloc->last_line = yylineno;   \
47 }
48
49 #define APPEND_S(ch) do {                                               \
50     if (yyextra->s - yyextra->scanBuf >= sizeof(yyextra->scanBuf) - 1)  \
51         return ERROR_TOK;                                               \
52     *yyextra->s++ = ch;                                                 \
53 } while (0)
54 %}
55
56 %option reentrant
57 %option extra-type="struct scanner_extra *"
58 %option bison-bridge bison-locations
59 %option yylineno
60 %option nounistd noyywrap noinput nounput
61 %option never-interactive
62 %option case-insensitive
63
64 %x S_STR S_KEY
65
66 %%
67
68 "//"[^\n]*
69 "#"[^\n]*
70
71 \"                      yyextra->s = yyextra->scanBuf; BEGIN(S_STR);
72 \<                      yyextra->s = yyextra->scanBuf; BEGIN(S_KEY);
73
74 <S_STR>\" {
75                         BEGIN(INITIAL);
76                         *yyextra->s = '\0';
77                         yylval->str = strdup(yyextra->scanBuf);
78                         return STRING;
79                     }
80 <S_KEY>\> {
81                         BEGIN(INITIAL);
82
83                         *yyextra->s = '\0';
84                         if (yyextra->s - yyextra->scanBuf > XkbKeyNameLength) {
85                             scanner_error_extra(yylloc, yyextra,
86                                                 "Key name too long");
87                             return ERROR_TOK;
88                         }
89
90                         strncpy(yylval->keyName, yyextra->scanBuf, XkbKeyNameLength);
91                         return KEYNAME;
92                     }
93
94 <S_STR,S_KEY>\\[0-7]{1,3} {
95                         /* octal escape sequence */
96                         unsigned int result;
97
98                         (void) sscanf( yytext + 1, "%o", &result );
99
100                         if (result > 0xff) {
101                             scanner_error_extra(yylloc, yyextra,
102                                                 "Illegal octal escape");
103                             return ERROR_TOK;
104                         }
105
106                         APPEND_S(result);
107                     }
108
109 <S_STR,S_KEY>\\[0-9]+ {
110                         scanner_error_extra(yylloc, yyextra,
111                                             "Illegal octal escape");
112                         return ERROR_TOK;
113                     }
114
115 <S_STR,S_KEY>\\n        APPEND_S('\n');
116 <S_STR,S_KEY>\\t        APPEND_S('\t');
117 <S_STR,S_KEY>\\r        APPEND_S('\r');
118 <S_STR,S_KEY>\\b        APPEND_S('\b');
119 <S_STR,S_KEY>\\f        APPEND_S('\f');
120 <S_STR,S_KEY>\\v        APPEND_S('\v');
121 <S_STR,S_KEY>\\e        APPEND_S('\033');
122
123 <S_STR,S_KEY>.          APPEND_S(yytext[0]);
124
125 xkb_keymap              return XKB_KEYMAP;
126 xkb_keycodes            return XKB_KEYCODES;
127 xkb_types               return XKB_TYPES;
128 xkb_symbols             return XKB_SYMBOLS;
129 xkb_compat              return XKB_COMPATMAP;
130 xkb_compat_map          return XKB_COMPATMAP;
131 xkb_compatibility       return XKB_COMPATMAP;
132 xkb_compatibility_map   return XKB_COMPATMAP;
133 xkb_geometry            return XKB_GEOMETRY;
134 xkb_semantics           return XKB_SEMANTICS;
135 xkb_layout              return XKB_LAYOUT;
136 include                 return INCLUDE;
137 override                return OVERRIDE;
138 augment                 return AUGMENT;
139 replace                 return REPLACE;
140 alternate               return ALTERNATE;
141 partial                 return PARTIAL;
142 default                 return DEFAULT;
143 hidden                  return HIDDEN;
144 virtual_modifiers       return VIRTUAL_MODS;
145 type                    return TYPE;
146 interpret               return INTERPRET;
147 action                  return ACTION_TOK;
148 key                     return KEY;
149 alias                   return ALIAS;
150 group                   return GROUP;
151 modmap                  return MODIFIER_MAP;
152 mod_map                 return MODIFIER_MAP;
153 modifier_map            return MODIFIER_MAP;
154 indicator               return INDICATOR;
155 shape                   return SHAPE;
156 row                     return ROW;
157 keys                    return KEYS;
158 section                 return SECTION;
159 overlay                 return OVERLAY;
160 text                    return TEXT;
161 outline                 return OUTLINE;
162 solid                   return SOLID;
163 logo                    return LOGO;
164 virtual                 return VIRTUAL;
165 alphanumeric_keys       return ALPHANUMERIC_KEYS;
166 modifier_keys           return MODIFIER_KEYS;
167 keypad_keys             return KEYPAD_KEYS;
168 function_keys           return FUNCTION_KEYS;
169 alternate_group         return ALTERNATE_GROUP;
170
171 [a-zA-Z_][a-zA-Z_0-9]*  yylval->str = strdup(yytext); return IDENT;
172
173 0x[a-fA-F0-9]+          |
174 [0-9]+                  {
175                             char *end;
176                             yylval->num = strtoul(yytext, &end, 0);
177
178                             return INTEGER;
179                         }
180 [0-9]+\.[0-9]+ {
181                             char *end;
182                             yylval->num = strtod(yytext, &end) * XkbGeomPtsPerMM;
183
184                             return FLOAT;
185                         }
186
187 "="                     return EQUALS;
188 "+"                     return PLUS;
189 "-"                     return MINUS;
190 "/"                     return DIVIDE;
191 "*"                     return TIMES;
192 "{"                     return OBRACE;
193 "}"                     return CBRACE;
194 "("                     return OPAREN;
195 ")"                     return CPAREN;
196 "["                     return OBRACKET;
197 "]"                     return CBRACKET;
198 "."                     return DOT;
199 ","                     return COMMA;
200 ";"                     return SEMI;
201 "!"                     return EXCLAM;
202 "~"                     return INVERT;
203
204 [ \t\r\n\v]+
205
206 <<EOF>>                 return END_OF_FILE;
207
208 .                       return ERROR_TOK;
209
210 %%
211
212 static void
213 scanner_error_extra(struct YYLTYPE *loc, struct scanner_extra *extra,
214                     const char *msg)
215 {
216     log_err(extra->ctx, "%s: line %d of %s\n", msg,
217             loc->first_line,
218             extra->scanFile ? extra->scanFile : "(unknown)");
219
220     log_err(extra->ctx, "last scanned symbol was: %s\n",
221             extra->scanBuf);
222 }
223
224 void
225 scanner_error(struct YYLTYPE *loc, void *scanner, const char *msg)
226 {
227     struct scanner_extra *extra = yyget_extra(scanner);
228     scanner_error_extra(loc, extra, msg);
229 }
230
231 static void
232 CheckDefaultMap(struct xkb_context *ctx, XkbFile *maps, const char *fileName)
233 {
234     XkbFile *dflt = NULL, *tmp;
235
236     for (tmp = maps; tmp; tmp = (XkbFile *) tmp->common.next) {
237         if (!(tmp->flags & XkbLC_Default))
238             continue;
239
240         if (!dflt) {
241             dflt = tmp;
242             continue;
243         }
244
245         log_lvl(ctx, 3,
246                 "Multiple default components in %s; "
247                 "Using %s, ignoring %s\n",
248                 (fileName ? fileName : "(unknown)"),
249                 (dflt->name ? dflt->name : "(first)"),
250                 (tmp->name ? tmp->name : "(subsequent)"));
251
252         tmp->flags &= (~XkbLC_Default);
253     }
254 }
255
256 bool
257 XkbParseString(struct xkb_context *ctx, const char *string,
258                const char *file_name, XkbFile **out)
259 {
260     int ret;
261     struct parser_param param;
262     struct scanner_extra extra;
263     YY_BUFFER_STATE state;
264
265     if (string == NULL)
266         return false;
267
268     param.ctx = ctx;
269
270     memset(&extra, 0, sizeof(extra));
271     ret = yylex_init_extra(&extra, &param.scanner);
272     if (ret != 0)
273         return false;
274
275     extra.ctx = ctx;
276
277     extra.scanFile = strdup(file_name);
278     if (!extra.scanFile)
279         return false;
280
281     state = yy_scan_string(string, param.scanner);
282     ret = yyparse(&param);
283     yy_delete_buffer(state, param.scanner);
284     yylex_destroy(param.scanner);
285     free(extra.scanFile);
286     if (ret != 0)
287         return false;
288
289     CheckDefaultMap(param.ctx, param.rtrn, file_name);
290     *out = param.rtrn;
291     return true;
292 }
293
294 bool
295 XkbParseFile(struct xkb_context *ctx, FILE *file,
296              const char *file_name, XkbFile **out)
297 {
298     int ret;
299     struct parser_param param;
300     struct scanner_extra extra;
301
302     if (!file)
303         return false;
304
305     param.ctx = ctx;
306
307     memset(&extra, 0, sizeof(extra));
308     ret = yylex_init_extra(&extra, &param.scanner);
309     if (ret != 0)
310         return false;
311
312     extra.ctx = ctx;
313
314     extra.scanFile = strdup(file_name);
315     if (!extra.scanFile)
316         return false;
317
318     yyset_in(file, param.scanner);
319     ret = yyparse(&param);
320     yylex_destroy(param.scanner);
321     free(extra.scanFile);
322     if (ret != 0)
323         return false;
324
325     CheckDefaultMap(param.ctx, param.rtrn, file_name);
326     *out = param.rtrn;
327     return true;
328 }