diff options
Diffstat (limited to 'src/grecs-lex.l')
-rw-r--r-- | src/grecs-lex.l | 133 |
1 files changed, 9 insertions, 124 deletions
diff --git a/src/grecs-lex.l b/src/grecs-lex.l index 4d491fe..84ee858 100644 --- a/src/grecs-lex.l +++ b/src/grecs-lex.l | |||
@@ -3,7 +3,6 @@ | |||
3 | #ifdef HAVE_CONFIG_H | 3 | #ifdef HAVE_CONFIG_H |
4 | # include <config.h> | 4 | # include <config.h> |
5 | #endif | 5 | #endif |
6 | #include "yygrecs.h" | ||
7 | } | 6 | } |
8 | %{ | 7 | %{ |
9 | /* grecs - Gray's Extensible Configuration System | 8 | /* grecs - Gray's Extensible Configuration System |
@@ -48,12 +47,9 @@ grecs_locus_t grecs_current_locus; /* Input file location */ | |||
48 | */ | 47 | */ |
49 | static size_t xlines; | 48 | static size_t xlines; |
50 | 49 | ||
51 | static struct grecs_list *line_acc; | ||
52 | |||
53 | static void multiline_begin(char *); | 50 | static void multiline_begin(char *); |
54 | static void multiline_add(char *); | 51 | static void multiline_add(char *); |
55 | static char *multiline_strip_tabs(char *text); | 52 | static char *multiline_strip_tabs(char *text); |
56 | static void line_add_unescape_last(char *text, size_t len); | ||
57 | static int ident(void); | 53 | static int ident(void); |
58 | static int isemptystr(int off); | 54 | static int isemptystr(int off); |
59 | 55 | ||
@@ -113,9 +109,10 @@ P [1-9][0-9]* | |||
113 | \"[^\\"\n]*\\. | | 109 | \"[^\\"\n]*\\. | |
114 | \"[^\\"\n]*\\\n { BEGIN(STR); | 110 | \"[^\\"\n]*\\\n { BEGIN(STR); |
115 | grecs_line_begin(); | 111 | grecs_line_begin(); |
116 | line_add_unescape_last(yytext + 1, yyleng - 1); } | 112 | grecs_line_acc_grow_unescape_last(yytext + 1, |
113 | yyleng - 1); } | ||
117 | <STR>[^\\"\n]*\\. | | 114 | <STR>[^\\"\n]*\\. | |
118 | <STR>\"[^\\"\n]*\\\n { line_add_unescape_last(yytext, yyleng); } | 115 | <STR>\"[^\\"\n]*\\\n { grecs_line_acc_grow_unescape_last(yytext, yyleng); } |
119 | <STR>[^\\"\n]*\" { BEGIN(INITIAL); | 116 | <STR>[^\\"\n]*\" { BEGIN(INITIAL); |
120 | if (yyleng > 1) | 117 | if (yyleng > 1) |
121 | grecs_line_add(yytext, yyleng - 1); | 118 | grecs_line_add(yytext, yyleng - 1); |
@@ -170,20 +167,12 @@ yywrap() | |||
170 | return 1; | 167 | return 1; |
171 | } | 168 | } |
172 | 169 | ||
173 | static void | ||
174 | line_acc_free_entry(void *ptr) | ||
175 | { | ||
176 | grecs_free(ptr); | ||
177 | } | ||
178 | |||
179 | int | 170 | int |
180 | grecs_lex_begin(const char *name) | 171 | grecs_lex_begin(const char *name, int trace) |
181 | { | 172 | { |
182 | if (yy_flex_debug > 0) | 173 | yy_flex_debug = trace; |
183 | yy_flex_debug = 0; | ||
184 | 174 | ||
185 | line_acc = grecs_list_create(); | 175 | grecs_line_acc_create(); |
186 | line_acc->free_entry = line_acc_free_entry; | ||
187 | 176 | ||
188 | if (grecs_preprocessor) { | 177 | if (grecs_preprocessor) { |
189 | int fd; | 178 | int fd; |
@@ -211,7 +200,7 @@ grecs_lex_begin(const char *name) | |||
211 | void | 200 | void |
212 | grecs_lex_end(int err) | 201 | grecs_lex_end(int err) |
213 | { | 202 | { |
214 | grecs_list_clear(line_acc); | 203 | grecs_line_acc_free(); |
215 | } | 204 | } |
216 | 205 | ||
217 | static int | 206 | static int |
@@ -239,95 +228,21 @@ multiline_strip_tabs(char *text) | |||
239 | return text; | 228 | return text; |
240 | } | 229 | } |
241 | 230 | ||
242 | static int | ||
243 | unquote_char(int c) | ||
244 | { | ||
245 | static char quote_transtab[] = "\\\\\"\"a\ab\bf\fn\nr\rt\tv\v"; | ||
246 | |||
247 | char *p; | ||
248 | |||
249 | for (p = quote_transtab; *p; p += 2) { | ||
250 | if (*p == c) | ||
251 | return p[1]; | ||
252 | } | ||
253 | return -1; | ||
254 | } | ||
255 | |||
256 | struct line_acc_entry | ||
257 | { | ||
258 | size_t size; | ||
259 | }; | ||
260 | #define line_acc_ptr(entry) (char*)(entry + 1) | ||
261 | |||
262 | static void | ||
263 | line_acc_add_string(const char *str, size_t len) | ||
264 | { | ||
265 | struct line_acc_entry *ent = grecs_malloc(sizeof(*ent) + len + 1); | ||
266 | char *p = line_acc_ptr(ent); | ||
267 | memcpy(p, str, len); | ||
268 | p[len] = 0; | ||
269 | ent->size = len; | ||
270 | grecs_list_append(line_acc, ent); | ||
271 | } | ||
272 | |||
273 | static void | ||
274 | line_acc_add_char(int c) | ||
275 | { | ||
276 | char t = c; | ||
277 | line_acc_add_string(&t, 1); | ||
278 | } | ||
279 | |||
280 | static void | ||
281 | list_acc_unescape_char(int c) | ||
282 | { | ||
283 | if (c != '\n') { | ||
284 | int t = unquote_char(c); | ||
285 | if (t != -1) | ||
286 | line_acc_add_char(t); | ||
287 | else { | ||
288 | grecs_warning(&grecs_current_locus, 0, | ||
289 | _("unknown escape sequence '\\%c'"), | ||
290 | c); | ||
291 | line_acc_add_char(c); | ||
292 | } | ||
293 | } | ||
294 | } | ||
295 | |||
296 | void | ||
297 | grecs_line_add(const char *text, size_t len) | ||
298 | { | ||
299 | line_acc_add_string(text, len); | ||
300 | } | ||
301 | |||
302 | /* Same, but unescapes the last character from yytext */ | ||
303 | static void | ||
304 | line_add_unescape_last(char *text, size_t len) | ||
305 | { | ||
306 | line_acc_add_string(text, len - 2); | ||
307 | list_acc_unescape_char(text[len - 1]); | ||
308 | } | ||
309 | |||
310 | static void | 231 | static void |
311 | multiline_add(char *s) | 232 | multiline_add(char *s) |
312 | { | 233 | { |
313 | if (multiline_unescape) { | 234 | if (multiline_unescape) { |
314 | for (; *s; s++) { | 235 | for (; *s; s++) { |
315 | if (*s == '\\') { | 236 | if (*s == '\\') { |
316 | list_acc_unescape_char(s[1]); | 237 | grecs_line_acc_grow_char_unescape(s[1]); |
317 | ++s; | 238 | ++s; |
318 | } else | 239 | } else |
319 | line_acc_add_char(*s); | 240 | grecs_line_acc_grow_char(*s); |
320 | } | 241 | } |
321 | } else | 242 | } else |
322 | grecs_line_add(s, strlen(s)); | 243 | grecs_line_add(s, strlen(s)); |
323 | } | 244 | } |
324 | 245 | ||
325 | void | ||
326 | grecs_line_begin() | ||
327 | { | ||
328 | /* FIXME: nothing so far. Maybe prepare stk by calling obstack_finish? */ | ||
329 | } | ||
330 | |||
331 | static int | 246 | static int |
332 | is_tab(char c) | 247 | is_tab(char c) |
333 | { | 248 | { |
@@ -374,30 +289,6 @@ multiline_begin(char *p) | |||
374 | grecs_line_begin(); | 289 | grecs_line_begin(); |
375 | } | 290 | } |
376 | 291 | ||
377 | char * | ||
378 | grecs_line_finish() | ||
379 | { | ||
380 | struct grecs_list_entry *ep; | ||
381 | size_t size = 0; | ||
382 | char *str, *p; | ||
383 | |||
384 | for (ep = line_acc->head; ep; ep = ep->next) { | ||
385 | struct line_acc_entry *ent = ep->data; | ||
386 | size += ent->size; | ||
387 | } | ||
388 | |||
389 | str = grecs_malloc(size + 1); | ||
390 | for (ep = line_acc->head, p = str; ep; ep = ep->next) { | ||
391 | struct line_acc_entry *ent = ep->data; | ||
392 | char *str = line_acc_ptr(ent); | ||
393 | memcpy(p, str, ent->size); | ||
394 | p += ent->size; | ||
395 | } | ||
396 | *p = 0; | ||
397 | grecs_list_clear(line_acc); | ||
398 | return str; | ||
399 | } | ||
400 | |||
401 | static int | 292 | static int |
402 | ident() | 293 | ident() |
403 | { | 294 | { |
@@ -416,12 +307,6 @@ ident() | |||
416 | return IDENT; | 307 | return IDENT; |
417 | } | 308 | } |
418 | 309 | ||
419 | void | ||
420 | grecs_lex_trace(int n) | ||
421 | { | ||
422 | yy_flex_debug = -n; | ||
423 | } | ||
424 | |||
425 | grecs_value_t * | 310 | grecs_value_t * |
426 | grecs_value_ptr_from_static(grecs_value_t *input) | 311 | grecs_value_ptr_from_static(grecs_value_t *input) |
427 | { | 312 | { |