diff options
Diffstat (limited to 'src')
42 files changed, 1328 insertions, 1171 deletions
diff --git a/src/Make-inst.am b/src/Make-inst.am index 1eb04bb..f13c10d 100644 --- a/src/Make-inst.am +++ b/src/Make-inst.am @@ -1,5 +1,5 @@ # This file is part of grecs - Gray's Extensible Configuration System -# Copyright (C) 2007-2019 Sergey Poznyakoff +# Copyright (C) 2007-2022 Sergey Poznyakoff # # Grecs is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by diff --git a/src/Make-shared.am b/src/Make-shared.am index f080e46..34bbd8e 100644 --- a/src/Make-shared.am +++ b/src/Make-shared.am @@ -1,5 +1,5 @@ # This file is part of grecs - Gray's Extensible Configuration System -# Copyright (C) 2007-2019 Sergey Poznyakoff +# Copyright (C) 2007-2022 Sergey Poznyakoff # # Grecs is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by diff --git a/src/Make-static.am b/src/Make-static.am index 1f4cd3e..7b0c9e1 100644 --- a/src/Make-static.am +++ b/src/Make-static.am @@ -1,5 +1,5 @@ # This file is part of grecs - Gray's Extensible Configuration System -# Copyright (C) 2007-2019 Sergey Poznyakoff +# Copyright (C) 2007-2022 Sergey Poznyakoff # # Grecs is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by diff --git a/src/Make.am b/src/Make.am index 5199991..5444e1d 100644 --- a/src/Make.am +++ b/src/Make.am @@ -1,5 +1,5 @@ # This file is part of grecs - Gray's Extensible Configuration System -# Copyright (C) 2007-2019 Sergey Poznyakoff +# Copyright (C) 2007-2022 Sergey Poznyakoff # # Grecs is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -15,34 +15,10 @@ # along with Grecs. If not, see <http://www.gnu.org/licenses/>. PARSER_DEFS = - -if GRECS_COND_META1_PARSER - GRECS_PARSER_META1 = meta1-gram.y meta1-lex.l - GRECS_EXTRA_META1 = meta1-gram.h - PARSER_DEFS += -DENABLE_META1_PARSER -endif - -if GRECS_COND_BIND_PARSER - GRECS_PARSER_BIND = bind-gram.y bind-lex.l - GRECS_EXTRA_BIND = bind-gram.h - PARSER_DEFS += -DENABLE_BIND_PARSER -endif - -if GRECS_COND_DHCPD_PARSER - GRECS_PARSER_DHCPD = dhcpd-gram.y dhcpd-lex.l - GRECS_EXTRA_DHCPD = dhcpd-gram.h - PARSER_DEFS += -DENABLE_DHCPD_PARSER -endif - -if GRECS_COND_GIT_PARSER - GRECS_PARSER_GIT = git-parser.c - PARSER_DEFS += -DENABLE_GIT_PARSER -endif - -if GRECS_COND_JSON - GRECS_JSON = json-gram.y json-lex.l jsonfmt.c - GRECS_EXTRA_JSON = json-gram.h -endif +BUILT_SOURCES = grecs-gram.h +EXTRA_DIST=\ + $(PP_SETUP_FILE)\ + Make.am Make-inst.am Make-shared.am Make-static.am GRECS_SRC = \ asprintf.c\ @@ -52,6 +28,7 @@ GRECS_SRC = \ format.c\ grecs-gram.y\ grecs-lex.l\ + grecs-gram.h\ ipstr.c\ join.c\ lineacc.c\ @@ -62,18 +39,46 @@ GRECS_SRC = \ parser.c\ parsertab.c\ path-parser.c\ - preproc.c\ sort.c\ symtab.c\ text.c\ tree.c\ txtacc.c\ - version.c\ - $(GRECS_JSON)\ - $(GRECS_PARSER_BIND)\ - $(GRECS_PARSER_DHCPD)\ - $(GRECS_PARSER_GIT)\ - $(GRECS_PARSER_META1) + version.c + +grecs-gram.h: grecs-gram.c + +if GRECS_COND_META1_PARSER + GRECS_SRC += meta1-gram.y meta1-lex.l meta1-gram.h + BUILT_SOURCES += meta1-gram.h + PARSER_DEFS += -DENABLE_META1_PARSER +meta1-gram.h: meta1-gram.c +endif + +if GRECS_COND_BIND_PARSER + GRECS_SRC += bind-gram.y bind-lex.l bind-gram.h + BUILT_SOURCES += bind-gram.h + PARSER_DEFS += -DENABLE_BIND_PARSER +bind-gram.h: bind-gram.c +endif + +if GRECS_COND_DHCPD_PARSER + GRECS_SRC += dhcpd-gram.y dhcpd-lex.l dhcpd-gram.h + BUILT_SOURCES += dhcpd-gram.h + PARSER_DEFS += -DENABLE_DHCPD_PARSER +dhcpd-gram.h: dhcpd-gram.c +endif + +if GRECS_COND_GIT_PARSER + GRECS_SRC += git-parser.c + PARSER_DEFS += -DENABLE_GIT_PARSER +endif + +if GRECS_COND_JSON + GRECS_SRC += json-gram.y json-lex.l jsonfmt.c json-gram.h + BUILT_SOURCES += json-gram.h +json-gram.h: json-gram.c +endif VPATH += $(top_srcdir)/@GRECS_SUBDIR@/wordsplit NODIST_GRECS_SRC = wordsplit.c @@ -82,15 +87,6 @@ if GRECS_COND_SOCKADDR_LIST GRECS_SRC += sockaddr.c endif -EXTRA_DIST=\ - grecs-gram.h\ - $(GRECS_EXTRA_BIND)\ - $(GRECS_EXTRA_DHCPD)\ - $(GRECS_EXTRA_JSON)\ - $(GRECS_EXTRA_META1)\ - $(PP_SETUP_FILE)\ - Make.am Make-inst.am Make-shared.am Make-static.am - AM_CPPFLAGS = \ -I$(srcdir)\ -I$(top_srcdir)/@GRECS_SUBDIR@\ diff --git a/src/asprintf.c b/src/asprintf.c index a92b88a..cd650a5 100644 --- a/src/asprintf.c +++ b/src/asprintf.c @@ -1,5 +1,5 @@ /* grecs - Gray's Extensible Configuration System - Copyright (C) 2007-2016 Sergey Poznyakoff + Copyright (C) 2007-2022 Sergey Poznyakoff Grecs is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the diff --git a/src/assert.c b/src/assert.c index c1cfc01..74ffee8 100644 --- a/src/assert.c +++ b/src/assert.c @@ -1,5 +1,5 @@ /* grecs - Gray's Extensible Configuration System - Copyright (C) 2007-2019 Sergey Poznyakoff + Copyright (C) 2007-2022 Sergey Poznyakoff Grecs is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the diff --git a/src/bind-gram.y b/src/bind-gram.y index 18deb0d..47db766 100644 --- a/src/bind-gram.y +++ b/src/bind-gram.y @@ -1,6 +1,6 @@ %{ /* grecs - Gray's Extensible Configuration System - Copyright (C) 2007-2016 Sergey Poznyakoff + Copyright (C) 2007-2022 Sergey Poznyakoff Grecs is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the @@ -36,7 +36,7 @@ extern void grecs_bind_close_sources(void); static struct grecs_value *stmtlist_to_value(struct grecs_node *node); %} -%error-verbose +%define parse.error verbose %locations %union { diff --git a/src/bind-lex.l b/src/bind-lex.l index e0659e7..bc2eb70 100644 --- a/src/bind-lex.l +++ b/src/bind-lex.l @@ -8,7 +8,7 @@ } %{ /* grecs - Gray's Extensible Configuration System - Copyright (C) 2007-2016 Sergey Poznyakoff + Copyright (C) 2007-2022 Sergey Poznyakoff Grecs is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the @@ -60,12 +60,10 @@ P [1-9][0-9]* /* Line directive */ ^[ \t]*#[ \t]*{P}[ \t]+\".*\".*\n { grecs_parse_line_directive_cpp(yytext, &yylloc, - &grecs_current_locus_point, - NULL); } + &grecs_current_locus_point); } ^[ \t]*#[ \t]*line[ \t].*\n { grecs_parse_line_directive(yytext, &yylloc, - &grecs_current_locus_point, - NULL); } + &grecs_current_locus_point); } /* End-of-line comments */ #.*\n { grecs_locus_point_advance_line(grecs_current_locus_point); } #.* /* end-of-file comment */; @@ -1,5 +1,5 @@ /* grecs - Gray's Extensible Configuration System - Copyright (C) 2007-2016 Sergey Poznyakoff + Copyright (C) 2007-2022 Sergey Poznyakoff Grecs is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the diff --git a/src/dhcpd-gram.y b/src/dhcpd-gram.y index 11dd1b2..ec51c33 100644 --- a/src/dhcpd-gram.y +++ b/src/dhcpd-gram.y @@ -1,6 +1,6 @@ %{ /* grecs - Gray's Extensible Configuration System - Copyright (C) 2007-2016 Sergey Poznyakoff + Copyright (C) 2007-2022 Sergey Poznyakoff Grecs is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the @@ -49,7 +49,7 @@ make_string_value(char *string) %} -%error-verbose +%define parse.error verbose %locations %union { diff --git a/src/dhcpd-lex.l b/src/dhcpd-lex.l index 79c7274..76e9e28 100644 --- a/src/dhcpd-lex.l +++ b/src/dhcpd-lex.l @@ -7,7 +7,7 @@ } %{ /* grecs - Gray's Extensible Configuration System - Copyright (C) 2007-2016 Sergey Poznyakoff + Copyright (C) 2007-2022 Sergey Poznyakoff Grecs is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the @@ -56,12 +56,10 @@ P [1-9][0-9]* /* Line directive */ ^[ \t]*#[ \t]*{P}[ \t]+\".*\".*\n { grecs_parse_line_directive_cpp(yytext, &yylloc, - &grecs_current_locus_point, - NULL); } + &grecs_current_locus_point); } ^[ \t]*#[ \t]*line[ \t].*\n { grecs_parse_line_directive(yytext, &yylloc, - &grecs_current_locus_point, - NULL); } + &grecs_current_locus_point); } /* End-of-line comments */ #.*\n { grecs_locus_point_advance_line(grecs_current_locus_point); } #.* /* end-of-file comment */; @@ -1,5 +1,5 @@ /* grecs - Gray's Extensible Configuration System - Copyright (C) 2007-2016 Sergey Poznyakoff + Copyright (C) 2007-2022 Sergey Poznyakoff Grecs is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the diff --git a/src/format.c b/src/format.c index d7cdb0f..8ef5fc6 100644 --- a/src/format.c +++ b/src/format.c @@ -1,5 +1,5 @@ /* grecs - Gray's Extensible Configuration System - Copyright (C) 2007-2016 Sergey Poznyakoff + Copyright (C) 2007-2022 Sergey Poznyakoff Grecs is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the @@ -25,49 +25,50 @@ #include <string.h> #include <errno.h> +static struct type_string { + char *nominative; + char *genitive; +} type_string[] = { + /* TRANSLATORS: The msgids below are data types in direct (nominative) + and indirect (most often, genitive) cases. The indirect case is + used only in the construct "list %s" (e.g., for "number" data type, + this makes "list of numbers"). Please, translate it so that it + forms a correct sentence in this context. */ + [grecs_type_void] = { N_("void"), NULL }, + [grecs_type_string] = { N_("string"), N_("of strings") }, + [grecs_type_short] = { N_("number"), N_("of numbers") }, + [grecs_type_ushort] = { N_("number"), N_("of numbers") }, + [grecs_type_int] = { N_("number"), N_("of numbers") }, + [grecs_type_uint] = { N_("number"), N_("of numbers") }, + [grecs_type_long] = { N_("number"), N_("of numbers") }, + [grecs_type_ulong] = { N_("number"), N_("of numbers") }, + [grecs_type_size] = { N_("number"), N_("of numbers") }, + [grecs_type_time] = { N_("time"), N_("of times") }, + [grecs_type_bool] = { N_("boolean"), N_("of booleans") }, + [grecs_type_ipv4] = { N_("IPv4"), N_("of IPv4") }, + [grecs_type_cidr] = { N_("CIDR"), N_("of CIDR") }, + [grecs_type_host] = { N_("hostname"), N_("of hostnames") }, + [grecs_type_sockaddr] = { N_("sockaddr"), N_("of sockaddr") }, + [grecs_type_section] = { N_("section"), NULL }, + [grecs_type_null] = { N_("null"), NULL }, +}; + const char * grecs_data_type_string(enum grecs_data_type type) { - switch (type) { - case grecs_type_void: - return N_("void"); - - case grecs_type_string: - return N_("string"); - - case grecs_type_short: - case grecs_type_ushort: - case grecs_type_int: - case grecs_type_uint: - case grecs_type_long: - case grecs_type_ulong: - case grecs_type_size: - /*FIXME case grecs_type_off:*/ - return N_("number"); - - case grecs_type_time: - return N_("time"); - - case grecs_type_bool: - return N_("boolean"); - - case grecs_type_ipv4: - return N_("IPv4"); - - case grecs_type_cidr: - return N_("CIDR"); - - case grecs_type_host: - return N_("hostname"); - - case grecs_type_sockaddr: - return N_("sockaddr"); - - case grecs_type_section: - return N_("section"); + if (type >= 0 && type <= sizeof(type_string) / sizeof(type_string[0]) + && type_string[type].nominative) { + return type_string[type].nominative; + } + return "UNKNOWN?"; +} - case grecs_type_null: - return N_("null"); +const char * +grecs_data_type_genitive(enum grecs_data_type type) +{ + if (type >= 0 && type <= sizeof(type_string) / sizeof(type_string[0]) + && type_string[type].genitive) { + return type_string[type].genitive; } return "UNKNOWN?"; } @@ -140,7 +141,9 @@ grecs_print_simple_statement(struct grecs_keyword *kwp, unsigned level, else argstr = N_("arg"); - if (strchr("<[", argstr[0])) + if (argstr[0] == 0) + fprintf(stream, "%s;\n", kwp->ident); + else if (strchr("<[", argstr[0])) fprintf(stream, "%s %s;\n", kwp->ident, gettext(argstr)); else if (argstr[0] == '\'') fprintf(stream, "%s %s;\n", kwp->ident, argstr + 1); @@ -149,11 +152,14 @@ grecs_print_simple_statement(struct grecs_keyword *kwp, unsigned level, else { fprintf(stream, "%s <%s: ", kwp->ident, gettext(argstr)); if (kwp->flags & GRECS_LIST) - fprintf(stream, "list of %s", - gettext(grecs_data_type_string(kwp->type))); + /* TRANSLATORS: The %s in this message will be expanded + to a data type in indirect case (see above). The two + must form a grammatically correct sentence. */ + fprintf(stream, _("list %s"), + gettext(grecs_data_type_genitive(kwp->type))); else fprintf(stream, "%s", - gettext(grecs_data_type_string(kwp->type))); + gettext(grecs_data_type_string(kwp->type))); fprintf(stream, ">;\n"); } } @@ -166,7 +172,7 @@ grecs_print_block_statement(struct grecs_keyword *kwp, unsigned level, grecs_print_docstring(kwp->docstring, level, stream); format_level(level, stream); fprintf(stream, "%s", kwp->ident); - if (kwp->argname) { + if (kwp->argname && kwp->argname[0]) { if (kwp->argname[0] == '\'') fprintf(stream, " %s", kwp->argname + 1); else diff --git a/src/git-parser.c b/src/git-parser.c index d1c7600..54c7b33 100644 --- a/src/git-parser.c +++ b/src/git-parser.c @@ -1,5 +1,5 @@ /* Git-style configuration file parser for Grecs. - Copyright (C) 2011-2016 Sergey Poznyakoff + Copyright (C) 2011-2022 Sergey Poznyakoff Grecs is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the diff --git a/src/grecs-gram.y b/src/grecs-gram.y index 05ed2f5..ad36795 100644 --- a/src/grecs-gram.y +++ b/src/grecs-gram.y @@ -1,6 +1,6 @@ %{ /* grecs - Gray's Extensible Configuration System - Copyright (C) 2007-2016 Sergey Poznyakoff + Copyright (C) 2007-2022 Sergey Poznyakoff Grecs is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the @@ -31,7 +31,7 @@ int yyerror(char const *s); static struct grecs_node *parse_tree; %} -%error-verbose +%define parse.error verbose %locations %union { @@ -241,10 +241,13 @@ opt_sc : /* empty */ %% +int grecs_yyerror_suppress; + int yyerror(char const *s) { - grecs_error(&yylloc, 0, "%s", s); + if (!grecs_yyerror_suppress) + grecs_error(&yylloc, 0, "%s", s); return 0; } diff --git a/src/grecs-lex.l b/src/grecs-lex.l index f7be62f..032c905 100644 --- a/src/grecs-lex.l +++ b/src/grecs-lex.l @@ -1,6 +1,5 @@ /* grecs - Gray's Extensible Configuration System -*- c -*- */ %option nounput -%option noinput %top { #ifdef HAVE_CONFIG_H # include <config.h> @@ -8,7 +7,7 @@ } %{ /* grecs - Gray's Extensible Configuration System - Copyright (C) 2007-2016 Sergey Poznyakoff + Copyright (C) 2007-2022 Sergey Poznyakoff Grecs is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the @@ -30,47 +29,19 @@ #include <ctype.h> #include <stdlib.h> #include <errno.h> - +#include <sys/stat.h> +#include <sys/wait.h> +#include <glob.h> +#include <signal.h> #include <wordsplit.h> -static char *multiline_delimiter; -static size_t multiline_delimiter_len; -static int multiline_unescape; /* Unescape here-document contents */ -static int (*char_to_strip)(char); /* Strip matching characters of each - here-document line */ - +/* + * Locus tracking + */ struct grecs_locus_point grecs_current_locus_point; /* Input file location */ -/* Line correction. Equals to the number of #line directives inserted into - the input by the preprocessor instance. The external preprocessor, if - any, counts these as input lines and therefore the line numbers in *its* - #line directives are offset by the value of XLINES. - - Uff, running two preprocessors is confusing... -*/ -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 qstring_locus_fixup(void); - -#define qstring() \ - ((grecs_parser_options & GRECS_OPTION_QUOTED_STRING_CONCAT) \ - ? QSTRING : STRING) - -#undef YY_INPUT -#define YY_INPUT(buf,result,max_size) \ - do { \ - if (grecs_preprocessor) \ - result = fread(buf, 1, max_size, yyin); \ - else \ - result = grecs_preproc_fill_buffer(buf, max_size); \ - } while(0) #define YY_USER_ACTION do { \ - if (YYSTATE == 0) { \ + if (YYSTATE == INITIAL) { \ yylloc.beg = grecs_current_locus_point; \ yylloc.beg.col++; \ } \ @@ -78,71 +49,299 @@ static void qstring_locus_fixup(void); yylloc.end = grecs_current_locus_point; \ } while (0); +/* + * Redefine default error reporting function. + */ +#define YY_FATAL_ERROR(t) grecs_error(NULL, errno, "%s", t) + +/* + * Preprocessing and synclines. + */ +static int preproc_mode; +static int emit_syncline; /* If not null, emit syncline before next output + * line. + */ +static int beginning_of_line; /* True if output is at the beginning of line */ + +/* + * Echo LEN bytes from TEXT to yyout. + */ +static void +echo(char const *text, size_t len) +{ + if (len == 0) return; + /* Check if we should print a syncline */ + if (beginning_of_line && emit_syncline) { + fprintf(yyout, "#line %lu \"%s\"\n", + (unsigned long)yylloc.end.line, + yylloc.end.file); + emit_syncline = 0; + } + /* Actually echo the text. */ + fwrite(text, len, 1, yyout); + /* Determine the beginning of line status. */ + beginning_of_line = text[len-1] == '\n'; +} +/* Inform flex that it should use echo. */ +#define ECHO echo(yytext, yyleng) +#define PPECHO do { if (preproc_mode) ECHO; } while(0) + +/* + * String concatenation support. + * + * String concatenation is a legacy feature of Grecs parser that instructs + * it to concatenate adjacent quoted strings. It is enabled if the + * GRECS_OPTION_QUOTED_STRING_CONCAT bit is set in parser options. This + * bit causes the lexer to qualify each double-quoted string as QSTRING. + */ +#define qstring() \ + ((grecs_parser_options & GRECS_OPTION_QUOTED_STRING_CONCAT) \ + ? QSTRING : STRING) + +/* + * Lexical tie-in variables. + */ +extern int grecs_yyerror_suppress; + +/* + * Here-document support. + */ +static char *multiline_delimiter; /* Here-document delimiter text. */ +static size_t multiline_delimiter_len; /* Its length. */ +static int multiline_unescape; /* Unescape here-document contents */ +static int (*char_to_strip)(char); /* Strips matching characters of each + here-document line */ + +static void multiline_begin(char *); +static void multiline_add(char *); +static char *multiline_strip_tabs(char *text); +static int isemptystr(int off); + +/* + * Forward declarations. + */ +static int string_or_ident(void); +static void qstring_locus_fixup(void); +static int parse_include(char *text); +static int push_source(const char *name, int once); +static int pop_source(void); +static void ctx_abort(void); + +/* + * Versions of grecs up to 03044f768f didn't recognize comment starters that + * followed a non-quoted string constituent, as in inet://127.0.0.1. That + * silently encouraged a bad practice of omitting quotes around such strings. + * + * To discontinue such practice and point to the source of the problem, a + * warning is emitted each time a comment starter is encountered immediately + * following a non-quoted string constituent. + */ +static int emit_comment_warning; +static void +comment_warning(void) +{ + if (emit_comment_warning) { + grecs_warning(&yylloc, 0, + _("\"%2.2s\" starts comment here; use quotes if you want it to be a part of string, or insert a whitespace to suppress this warning"), yytext); + emit_comment_warning = 0; + } +} + +/* + * The report_diag should be called only when yytext begins with the following + * prefix: + * ^[ \t]*#[ \t]*.{LEN} + * It returns a pointer to yytext past the prefix. + */ +static char * +report_diag(size_t len) +{ + char *p = strchr(yytext, '#'); + p += strspn(p, " \t") + len; + p += strspn(p, " \t"); + yytext[yyleng-1] = 0; + if (p[0] == '"' && yytext[yyleng-2] == '"') { + char *q, *r; + + yytext[yyleng-2] = 0; + p++; + q = r = p; + do { + if (*r == '\\') { + int c = wordsplit_c_unquote_char(*++r); + *q = c ? c : *r; + } else + *q = *r++; + } while (*q++ == 0); + } + return p; +} %} - -%x COMMENT ML STR + +%x COMMENT ML STR NQSTR WS [ \t\f][ \t\f]* ID [a-zA-Z_][a-zA-Z_0-9-]* P [1-9][0-9]* - +NQSC [^ \t\f\n'"(){},;/*] %% /* 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_locus_point_advance_line(grecs_current_locus_point); -<COMMENT>"*"+"/" BEGIN(INITIAL); +"/*" { + BEGIN(COMMENT); + beginning_of_line = 0; + comment_warning(); + } +<COMMENT>{ +[^*\n]* /* eat anything that's not a '*' */ +"*"+[^*/\n]* /* eat up '*'s not followed by '/'s */ +\n { grecs_locus_point_advance_line(grecs_current_locus_point); + emit_syncline = 1; } +"*"+"/" { + BEGIN(INITIAL); + if (preproc_mode) { + if (yylloc.end.line != yylloc.beg.line) { + if (!(yylloc.beg.line == 1 && yylloc.beg.col == 1)) + echo("\n", 1); + beginning_of_line = 1; + } else + beginning_of_line = 0; + } + } +<<EOF>> { grecs_error(&yylloc, 0, _("end of file in comment")); + return 0; + } +} + /* Line directive */ -^[ \t]*#[ \t]*{P}[ \t]+\".*\".*\n { grecs_parse_line_directive_cpp(yytext, - &yylloc, - &grecs_current_locus_point, - &xlines); } -^[ \t]*#[ \t]*line[ \t].*\n { grecs_parse_line_directive(yytext, - &yylloc, - &grecs_current_locus_point, - &xlines); } +^[ \t]*#[ \t]*{P}[ \t]+\".*\".*\n { + PPECHO; + grecs_parse_line_directive_cpp(yytext, &yylloc, &grecs_current_locus_point); + } +^[ \t]*#[ \t]*line[ \t].*\n { + PPECHO; + grecs_parse_line_directive(yytext, &yylloc, &grecs_current_locus_point); + } + + /* Includes */ +^[ \t]*#[ \t]*include(_once)?.*/\n { parse_include(yytext); } + /* Error directives */ +^[ \t]*#[ \t]*error[ \t].*\n { + grecs_error(&yylloc, 0, "%s", report_diag(sizeof("error"))); + } +^[ \t]*#[ \t]*warning[ \t].*\n { + grecs_warning(&yylloc, 0, "%s", report_diag(sizeof("warning"))); + } +^[ \t]*#[ \t]*abend[ \t].*\n { + grecs_error(&yylloc, 0, "%s", report_diag(sizeof("abend"))); + ctx_abort(); + grecs_yyerror_suppress = 1; + return 0; + } /* End-of-line comments */ -#.*\n { grecs_locus_point_advance_line(grecs_current_locus_point); } -#.* /* end-of-file comment */; -"//".*\n { grecs_locus_point_advance_line(grecs_current_locus_point); } -"//".* /* end-of-file comment */; - /* Identifiers */ -<INITIAL>{ID} return ident(); - /* Strings */ -[a-zA-Z0-9_\.\*/:@\[\]-]([a-zA-Z0-9_\./:@\[\]-][a-zA-Z0-9_\.\*/:@\[\]-]*)? { - grecs_line_begin(); - grecs_line_add(yytext, yyleng); - yylval.string = grecs_line_finish(); - return STRING; } +#.*\n { grecs_locus_point_advance_line(grecs_current_locus_point); + emit_syncline = 1; } +#.* /* end-of-file comment */; +"//".*\n { comment_warning(); + grecs_locus_point_advance_line(grecs_current_locus_point); + emit_syncline = 1; } +"//".* { comment_warning(); } /* end of file comment */ + + /* Non-quoted strings and identifiers */ +{NQSC}+ { + PPECHO; + grecs_line_begin(); + grecs_line_add(yytext, yyleng); |