aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2011-05-22 20:17:43 +0300
committerSergey Poznyakoff <gray@gnu.org.ua>2011-05-22 20:32:34 +0300
commit4a994c621995aafa110caa26114acb75f6ad76ed (patch)
tree0304a8ec0e434bac53a3caae132756cec526a69b /src
parent024cfd63846c0c7ef630a5dab819ad97942264a1 (diff)
downloadgrecs-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.l31
-rw-r--r--src/grecs-lex.l18
-rw-r--r--src/grecs.h6
-rw-r--r--src/lookup.c4
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;
}

Return to:

Send suggestions and report system problems to the System administrator.