aboutsummaryrefslogtreecommitdiff
path: root/src/grecs-lex.l
diff options
context:
space:
mode:
Diffstat (limited to 'src/grecs-lex.l')
-rw-r--r--src/grecs-lex.l133
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*/
49static size_t xlines; 48static size_t xlines;
50 49
51static struct grecs_list *line_acc;
52
53static void multiline_begin(char *); 50static void multiline_begin(char *);
54static void multiline_add(char *); 51static void multiline_add(char *);
55static char *multiline_strip_tabs(char *text); 52static char *multiline_strip_tabs(char *text);
56static void line_add_unescape_last(char *text, size_t len);
57static int ident(void); 53static int ident(void);
58static int isemptystr(int off); 54static 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
173static void
174line_acc_free_entry(void *ptr)
175{
176 grecs_free(ptr);
177}
178
179int 170int
180grecs_lex_begin(const char *name) 171grecs_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)
211void 200void
212grecs_lex_end(int err) 201grecs_lex_end(int err)
213{ 202{
214 grecs_list_clear(line_acc); 203 grecs_line_acc_free();
215} 204}
216 205
217static int 206static int
@@ -239,95 +228,21 @@ multiline_strip_tabs(char *text)
239 return text; 228 return text;
240} 229}
241 230
242static int
243unquote_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
256struct line_acc_entry
257{
258 size_t size;
259};
260#define line_acc_ptr(entry) (char*)(entry + 1)
261
262static void
263line_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
273static void
274line_acc_add_char(int c)
275{
276 char t = c;
277 line_acc_add_string(&t, 1);
278}
279
280static void
281list_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
296void
297grecs_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 */
303static void
304line_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
310static void 231static void
311multiline_add(char *s) 232multiline_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
325void
326grecs_line_begin()
327{
328 /* FIXME: nothing so far. Maybe prepare stk by calling obstack_finish? */
329}
330
331static int 246static int
332is_tab(char c) 247is_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
377char *
378grecs_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
401static int 292static int
402ident() 293ident()
403{ 294{
@@ -416,12 +307,6 @@ ident()
416 return IDENT; 307 return IDENT;
417} 308}
418 309
419void
420grecs_lex_trace(int n)
421{
422 yy_flex_debug = -n;
423}
424
425grecs_value_t * 310grecs_value_t *
426grecs_value_ptr_from_static(grecs_value_t *input) 311grecs_value_ptr_from_static(grecs_value_t *input)
427{ 312{

Return to:

Send suggestions and report system problems to the System administrator.