diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2011-05-22 20:17:43 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2011-05-22 20:32:34 +0300 |
commit | 4a994c621995aafa110caa26114acb75f6ad76ed (patch) | |
tree | 0304a8ec0e434bac53a3caae132756cec526a69b /src | |
parent | 024cfd63846c0c7ef630a5dab819ad97942264a1 (diff) | |
download | grecs-4a994c621995aafa110caa26114acb75f6ad76ed.tar.gz grecs-4a994c621995aafa110caa26114acb75f6ad76ed.tar.bz2 |
Optionally use preprocessor for bind configs.
* src/bind-lex.l: Parse #line directives.
(_pop_context): Use fclose or pclose, depending on how
the stream was opened.
(grecs_bind_new_source): Use preprocessor if grecs_preprocessor
was set.
* src/grecs-lex.l (parse_line): Rename to grecs_parse_line_directive.
(parse_line_cpp): Rename to grecs_parse_line_directive_cpp.
* src/grecs.h (grecs_parse_line_directive)
(grecs_parse_line_directive_cpp): New protos.
* src/lookup.c (grecs_match_first): Bugfix.
Diffstat (limited to 'src')
-rw-r--r-- | src/bind-lex.l | 31 | ||||
-rw-r--r-- | src/grecs-lex.l | 18 | ||||
-rw-r--r-- | src/grecs.h | 6 | ||||
-rw-r--r-- | src/lookup.c | 4 |
4 files changed, 46 insertions, 13 deletions
diff --git a/src/bind-lex.l b/src/bind-lex.l index 440b17a..7a9ff90 100644 --- a/src/bind-lex.l +++ b/src/bind-lex.l @@ -44,12 +44,19 @@ P [1-9][0-9]* /* C-style comments */ "/*" BEGIN(COMMENT); <COMMENT>[^*\n]* /* eat anything that's not a '*' */ <COMMENT>"*"+[^*/\n]* /* eat up '*'s not followed by '/'s */ <COMMENT>\n ++grecs_current_locus.line; <COMMENT>"*"+"/" BEGIN(INITIAL); + /* Line directive */ +^[ \t]*#[ \t]*{P}[ \t]+\".*\".*\n { grecs_parse_line_directive_cpp(yytext, + &grecs_current_locus, + NULL); } +^[ \t]*#[ \t]*line[ \t].*\n { grecs_parse_line_directive(yytext, + &grecs_current_locus, + NULL); } /* End-of-line comments */ #.*\n { grecs_current_locus.line++; } #.* /* end-of-file comment */; "//".*\n { grecs_current_locus.line++; } "//".* /* end-of-file comment */; /* Identifiers */ @@ -162,13 +169,16 @@ static int _pop_context() { struct bind_input_context *pctx; if (!yyin) return 1; - fclose(yyin); + if (grecs_preprocessor) + pclose(yyin); + else + fclose(yyin); pctx = grecs_list_pop(input_stack); if (!pctx) { yyin = NULL; return 1; } i_node = pctx->i_node; @@ -213,14 +223,31 @@ grecs_bind_new_source(const char *name) } if (fstat(fileno(fp), &st)) { grecs_error(loc, errno, _("can't state %s"), name); fclose(fp); return 1; } - if (_push_context(name, st.st_ino, st.st_dev)) { + if (grecs_preprocessor) { + char *cmd = NULL; + size_t size = 0; + fclose(fp); + if (grecs_asprintf(&cmd, &size, "%s \"%s\"", + grecs_preprocessor, name)) + grecs_alloc_die(); + + fp = popen(cmd, "r"); + if (!fp) { + grecs_error(loc, errno, _("cannot open `%s'"), cmd); + grecs_free(cmd); + return 1; + } + grecs_free(cmd); + } + + if (_push_context(name, st.st_ino, st.st_dev)) { return 1; } i_node = st.st_ino; i_dev = st.st_dev; yyin = fp; yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE)); diff --git a/src/grecs-lex.l b/src/grecs-lex.l index 84ee858..205a8f4 100644 --- a/src/grecs-lex.l +++ b/src/grecs-lex.l @@ -50,15 +50,12 @@ static size_t xlines; static void multiline_begin(char *); static void multiline_add(char *); static char *multiline_strip_tabs(char *text); static int ident(void); static int isemptystr(int off); -static void parse_line(char *text, grecs_locus_t *ploc, size_t *pxlines); -static void parse_line_cpp(char *text, grecs_locus_t *ploc, size_t *pxlines); - #undef YY_INPUT #define YY_INPUT(buf,result,max_size) \ do \ { \ if (grecs_preprocessor) \ result = fread(buf, 1, max_size, yyin); \ @@ -81,16 +78,16 @@ P [1-9][0-9]* "/*" BEGIN(COMMENT); <COMMENT>[^*\n]* /* eat anything that's not a '*' */ <COMMENT>"*"+[^*/\n]* /* eat up '*'s not followed by '/'s */ <COMMENT>\n ++grecs_current_locus.line; <COMMENT>"*"+"/" BEGIN(INITIAL); /* Line directive */ -^[ \t]*#[ \t]*{P}[ \t]+\".*\".*\n { parse_line_cpp(yytext, +^[ \t]*#[ \t]*{P}[ \t]+\".*\".*\n { grecs_parse_line_directive_cpp(yytext, &grecs_current_locus, &xlines); } -^[ \t]*#[ \t]*line[ \t].*\n { parse_line(yytext, &grecs_current_locus, +^[ \t]*#[ \t]*line[ \t].*\n { grecs_parse_line_directive(yytext, &grecs_current_locus, &xlines); } /* End-of-line comments */ #.*\n { grecs_current_locus.line++; } #.* /* end-of-file comment */; "//".*\n { grecs_current_locus.line++; } "//".* /* end-of-file comment */; @@ -327,14 +324,14 @@ assign_locus(grecs_locus_t *ploc, char *name, char *line, size_t *pxlines) ploc->file = grecs_install_text(name); } ploc->line = strtoul(line, &p, 10) - (pxlines ? *pxlines : 0); return *p != 0; } -static void -parse_line(char *text, grecs_locus_t *ploc, size_t *pxlines) +void +grecs_parse_line_directive(char *text, grecs_locus_t *ploc, size_t *pxlines) { int rc = 1; struct wordsplit ws; if (wordsplit(text, &ws, WRDSF_DEFFLAGS)) grecs_error(ploc, 0, _("cannot parse #line line")); @@ -345,13 +342,13 @@ parse_line(char *text, grecs_locus_t *ploc, size_t *pxlines) else if (ws.ws_wordc == 3) rc = assign_locus(ploc, ws.ws_wordv[2], ws.ws_wordv[1], pxlines); else if (ws.ws_wordc == 4) { rc = assign_locus(ploc, ws.ws_wordv[2], ws.ws_wordv[1], 0); - if (rc == 0) { + if (pxlines && rc == 0) { char *p; unsigned long x = strtoul(ws.ws_wordv[3], &p, 10); rc = *p != 0; if (rc == 0) *pxlines = x; @@ -362,14 +359,15 @@ parse_line(char *text, grecs_locus_t *ploc, size_t *pxlines) if (rc) grecs_error(ploc, 0, _("malformed #line statement")); wordsplit_free(&ws); } } -static void -parse_line_cpp(char *text, grecs_locus_t *ploc, size_t *pxlines) +void +grecs_parse_line_directive_cpp(char *text, grecs_locus_t *ploc, + size_t *pxlines) { struct wordsplit ws; if (wordsplit(text, &ws, WRDSF_DEFFLAGS)) { grecs_error(ploc, 0, _("cannot parse #line line")); return; diff --git a/src/grecs.h b/src/grecs.h index c254439..7be6b21 100644 --- a/src/grecs.h +++ b/src/grecs.h @@ -203,12 +203,18 @@ void grecs_error(grecs_locus_t *locus, int errcode, const char *fmt, ...) extern int grecs_trace_flags; #define GRECS_TRACE_GRAM 0x01 #define GRECS_TRACE_LEX 0x02 void grecs_gram_trace(int n); void grecs_lex_trace(int n); + +void grecs_parse_line_directive(char *text, grecs_locus_t *ploc, + size_t *pxlines); +void grecs_parse_line_directive_cpp(char *text, grecs_locus_t *ploc, + size_t *pxlines); + int grecs_lex_begin(const char*, int); void grecs_lex_end(int err); struct grecs_node *grecs_parse(const char *name); diff --git a/src/lookup.c b/src/lookup.c index a67edb9..f16e94b 100644 --- a/src/lookup.c +++ b/src/lookup.c @@ -454,14 +454,16 @@ grecs_match_first(struct grecs_node *tree, const char *pattern, if (tree->type != grecs_node_root) { errno = EINVAL; return NULL; } errno = 0; - if (strcmp(pattern, ".") == 0) + if (strcmp(pattern, ".") == 0) { + *pbuf = NULL; return tree; + } buf = grecs_zalloc(sizeof(*buf)); if (split_cfg_path(pattern, &buf->argc, &buf->argv, &buf->labelv)) { free(buf); return NULL; } |