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