aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2009-11-11 02:03:36 +0200
committerSergey Poznyakoff <gray@gnu.org.ua>2009-11-11 02:08:10 +0200
commita622ce06070048f43b31762677cf5d4a8e5c8934 (patch)
treee31050b7b3ee0da92e1a556e28bd35d9203c5b80
parent75767d432e61a4e8a9be5de612740faa42fdc2d0 (diff)
downloadanubis-a622ce06070048f43b31762677cf5d4a8e5c8934.tar.gz
anubis-a622ce06070048f43b31762677cf5d4a8e5c8934.tar.bz2
Improve diagnostics.
* src/Makefile.am (AM_LFLAGS): Add -dvp (INCLUDES): Remove obsolete path. * src/env.opt: New option location-column. * src/headers.h (T_LOCATION_COLUMN): New define. * src/rc-gram.y: Use Bison location support. Improve diagnostics. * src/rc-lex.l: Likewise. * src/rcfile.h (struct rc_loc): New member `column'. (rc_yyltype): New struct. (YYLTYPE,RC_LOCUS_FILE_EQ,RC_LOCUS_EQ): New defines. (RC_ERROR_PRINTER): Change signature. * src/xdatabase.c (_xdb_error_printer): Change signature.
-rw-r--r--src/Makefile.am5
-rw-r--r--src/anubisusr.c2
-rw-r--r--src/env.opt6
-rw-r--r--src/headers.h1
-rw-r--r--src/rc-gram.y200
-rw-r--r--src/rc-lex.l66
-rw-r--r--src/rcfile.h25
-rw-r--r--src/xdatabase.c11
8 files changed, 211 insertions, 105 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index d892344..b074b01 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -87,15 +87,14 @@ libanubisdb_a_SOURCES = \
url.c
AM_YFLAGS = -dtv
+AM_LFLAGS = -dvp
EXTRA_DIST = getopt.m4 env.opt
BUILT_SOURCES = env.c
localedir = $(datadir)/locale
DEFS = @DEFS@ -DLOCALEDIR=\"$(localedir)\"
-INCLUDES = @INCLUDES@ @LIBGNUTLS_CFLAGS@ -I$(top_srcdir)/lib \
- -I$(top_srcdir)/intl
-
+INCLUDES = @INCLUDES@ @LIBGNUTLS_CFLAGS@ -I$(top_srcdir)/lib
SUFFIXES=.opt .c
.opt.c:
diff --git a/src/anubisusr.c b/src/anubisusr.c
index 6d9dbb2..08f9c56 100644
--- a/src/anubisusr.c
+++ b/src/anubisusr.c
@@ -889,7 +889,7 @@ diff (char *file, struct smtp_reply *repl)
error (_("Invalid MD5 digest: %s"), repl->argv[0]);
return CMP_ERROR;
}
- string_hex_to_bin (sample, repl->argv[0], len);
+ string_hex_to_bin (sample, (unsigned char*)repl->argv[0], len);
return memcmp (digest, sample, sizeof digest) == 0 ?
CMP_UNCHANGED : CMP_CHANGED;
diff --git a/src/env.opt b/src/env.opt
index 7b52f86..304ad5e 100644
--- a/src/env.opt
+++ b/src/env.opt
@@ -137,6 +137,12 @@ BEGIN
print_config_options ();
END
+OPTION(location-column,,,
+ Print location column numbers in parser diagnostics)
+BEGIN
+ topt |= T_LOCATION_COLUMN;
+END
+
OPTION(relax-perm-check,,,
Do not check user configuration file permissions)
BEGIN
diff --git a/src/headers.h b/src/headers.h
index c83c556..03db1cc 100644
--- a/src/headers.h
+++ b/src/headers.h
@@ -240,6 +240,7 @@ ANUBIS_MODE;
#define T_TRACEFILE_SYS 0x04000000
#define T_TRACEFILE_USR 0x08000000
#define T_XELO 0x10000000
+#define T_LOCATION_COLUMN 0x20000000
/* Regexp modifiers */
/* Basic types */
diff --git a/src/rc-gram.y b/src/rc-gram.y
index d215156..4a894c5 100644
--- a/src/rc-gram.y
+++ b/src/rc-gram.y
@@ -33,32 +33,74 @@
extern int yylex (void);
int yyerror (char *s);
-static RC_SECTION *rc_section_create (char *, size_t, RC_STMT *);
+static RC_SECTION *rc_section_create (char *, RC_LOC *, RC_STMT *);
static void rc_section_destroy (RC_SECTION **);
static void rc_section_print (RC_SECTION *);
static void rc_asgn_destroy (RC_ASGN *);
static void rc_bool_destroy (RC_BOOL *);
static void rc_level_print (int, char *);
-static RC_NODE *rc_node_create (enum rc_node_type);
+ static RC_NODE *rc_node_create (enum rc_node_type, struct rc_loc *loc);
static void rc_node_destroy (RC_NODE *);
static void rc_node_print (RC_NODE *);
static void rc_rule_destroy (RC_RULE *);
static void rc_cond_destroy (RC_COND *);
-static RC_STMT *rc_stmt_create (enum rc_stmt_type);
+ static RC_STMT *rc_stmt_create (enum rc_stmt_type, struct rc_loc *loc);
static void rc_stmt_destroy (RC_STMT *);
static void rc_stmt_list_destroy (RC_STMT *);
static void rc_stmt_print (RC_STMT *, int);
-static int reg_modifier_add (int *, char *);
+ static int reg_modifier_add (int *, char *, struct rc_loc *);
static int check_kw (char *ident, int *flags);
-static int is_prog_allowed (void);
+static int is_prog_allowed (struct rc_loc *);
static RC_SECTION *rc_section;
static int debug_level;
static int error_count;
static int def_regex_modifier = R_POSIX;
static struct rc_secdef *rc_secdef;
+
+#define YYLLOC_DEFAULT(Current, Rhs, N) \
+ do \
+ { \
+ if (N) \
+ { \
+ (Current).beg = YYRHSLOC(Rhs, 1).beg; \
+ (Current).end = YYRHSLOC(Rhs, N).end; \
+ } \
+ else \
+ { \
+ (Current).beg = YYRHSLOC(Rhs, 0).end; \
+ (Current).end = (Current).beg; \
+ } \
+ } \
+ while (0)
+
+#define YY_LOCATION_PRINT(File, Loc) \
+ do \
+ { \
+ if (RC_LOCUS_FILE_EQ(&(Loc).beg, &(Loc).end)) \
+ fprintf(File, "%s:%lu.%lu-%lu.%lu", \
+ (Loc).beg.file, \
+ (unsigned long) (Loc).beg.line, \
+ (unsigned long) (Loc).beg.column, \
+ (unsigned long) (Loc).end.line, \
+ (unsigned long) (Loc).end.column); \
+ else \
+ fprintf(File, "%s:%lu.%lu-%s:%lu.%lu", \
+ (Loc).beg.file, \
+ (unsigned long) (Loc).beg.line, \
+ (unsigned long) (Loc).beg.column, \
+ (Loc).end.file, \
+ (unsigned long) (Loc).end.line, \
+ (unsigned long) (Loc).end.column); \
+ } \
+ while (0)
+
%}
+%error-verbose
+%locations
+%expect 2
+
%union {
char *string;
RC_SECTION *section;
@@ -79,10 +121,7 @@ static struct rc_secdef *rc_secdef;
char *sep;
} msgpart;
RC_LOC loc;
- struct {
- size_t line;
- char *name;
- } begin_sec;
+ char *begin_sec;
ANUBIS_LIST *list;
int eq;
};
@@ -153,7 +192,7 @@ section : /* empty */ EOL
}
| begin stmtlist end
{
- $$ = rc_section_create ($1.name, $1.line, $2.head);
+ $$ = rc_section_create ($1, &@1.beg, $2.head);
}
| begin end
{
@@ -163,18 +202,16 @@ section : /* empty */ EOL
begin : T_BEGIN { verbatim (); } string EOL
{
- $$.line = cfg_line_num - 1;
- $$.name = $3;
+ $$ = $3;
if (rc_section_lookup (rc_section, $3))
- parse_error (_("Section %s already defined"), $3);
+ parse_error (&@3.beg, _("Section %s already defined"), $3);
rc_secdef = anubis_find_section ($3);
}
| D_BEGIN EOL
{
- $$.line = cfg_line_num - 1;
- $$.name = $1;
+ $$ = $1;
if (rc_section_lookup (rc_section, $1))
- parse_error (_("Section %s already defined"), $1);
+ parse_error (&@1.beg, _("Section %s already defined"), $1);
rc_secdef = anubis_find_section ($1);
}
;
@@ -226,11 +263,11 @@ asgn_stmt: keyword arglist
int flags;
if (!check_kw ($1, &flags))
{
- parse_error (_("unknown keyword: %s"), $1);
+ parse_error (&@1.beg, _("unknown keyword: %s"), $1);
YYERROR;
}
- $$ = rc_stmt_create (rc_stmt_asgn);
+ $$ = rc_stmt_create (rc_stmt_asgn, &@1.beg);
$$->v.asgn.lhs = $1;
if (list_count ($2))
{
@@ -266,14 +303,14 @@ arg : string
cond_stmt: if cond stmtlist fi
{
- $$ = rc_stmt_create (rc_stmt_cond);
+ $$ = rc_stmt_create (rc_stmt_cond, &@1.beg);
$$->v.cond.node = $2;
$$->v.cond.iftrue = $3.head;
$$->v.cond.iffalse = NULL;
}
| if cond stmtlist else stmtlist fi
{
- $$ = rc_stmt_create (rc_stmt_cond);
+ $$ = rc_stmt_create (rc_stmt_cond, &@1.beg);
$$->v.cond.node = $2;
$$->v.cond.iftrue = $3.head;
$$->v.cond.iffalse = $5.head;
@@ -287,21 +324,21 @@ cond : expr
}
| cond AND cond
{
- $$ = rc_node_create (rc_node_bool);
+ $$ = rc_node_create (rc_node_bool, &@2.beg);
$$->v.bool.op = bool_and;
$$->v.bool.left = $1;
$$->v.bool.right = $3;
}
| cond OR cond
{
- $$ = rc_node_create (rc_node_bool);
+ $$ = rc_node_create (rc_node_bool, &@2.beg);
$$->v.bool.op = bool_or;
$$->v.bool.left = $1;
$$->v.bool.right = $3;
}
| NOT cond
{
- $$ = rc_node_create (rc_node_bool);
+ $$ = rc_node_create (rc_node_bool, &@1.beg);
$$->v.bool.op = bool_not;
$$->v.bool.left = $2;
$$->v.bool.right = NULL;
@@ -367,7 +404,8 @@ s_msgpart: msgpart
{
$$ = $1;
if ($$.key)
- parse_error ("regexp is not allowed in this context");
+ parse_error (&@1.beg,
+ _("regexp is not allowed in this context"));
}
;
@@ -388,7 +426,8 @@ regex : modlist '[' string ']'
free ($3);
if (!$$)
{
- parse_error (_("Invalid regular expression (see the above message)"));
+ parse_error (&@3.beg,
+ _("Invalid regular expression (see the above message)"));
YYERROR;
}
}
@@ -406,7 +445,7 @@ string_key: /* empty */
expr : s_msgpart opt_sep meq opt_modlist string
{
- RC_NODE *node = rc_node_create (rc_node_expr);
+ RC_NODE *node = rc_node_create (rc_node_expr, &@1.beg);
node->v.expr.part = $1.part;
node->v.expr.key = $1.string;
node->v.expr.sep = $2;
@@ -416,7 +455,7 @@ expr : s_msgpart opt_sep meq opt_modlist string
$$ = node;
else
{
- $$ = rc_node_create (rc_node_bool);
+ $$ = rc_node_create (rc_node_bool, &@1.beg);
$$->v.bool.op = bool_not;
$$->v.bool.left = node;
$$->v.bool.right = NULL;
@@ -427,12 +466,12 @@ expr : s_msgpart opt_sep meq opt_modlist string
modlist : modifier
{
$$ = def_regex_modifier;
- reg_modifier_add (&$$, $1);
+ reg_modifier_add (&$$, $1, &@1.beg);
xfree ($1);
}
| modlist modifier
{
- reg_modifier_add (&$1, $2);
+ reg_modifier_add (&$1, $2, &@1.beg);
xfree ($2);
$$ = $1;
}
@@ -453,7 +492,7 @@ modifier : ':' IDENT
if : IF
{
- if (!is_prog_allowed ())
+ if (!is_prog_allowed (&@1.beg))
YYERROR;
}
;
@@ -466,7 +505,7 @@ else : ELSE
rule_stmt: rule_start EOL stmtlist DONE
{
- $$ = rc_stmt_create (rc_stmt_rule);
+ $$ = rc_stmt_create (rc_stmt_rule, &@1.beg);
$$->v.rule.node = $1;
$$->v.rule.stmt = $3.head;
}
@@ -474,7 +513,7 @@ rule_stmt: rule_start EOL stmtlist DONE
rule_start: rule opt_modlist string
{
- $$ = rc_node_create (rc_node_expr);
+ $$ = rc_node_create (rc_node_expr, &@1.beg);
$$->v.expr.part = HEADER;
$$->v.expr.key = strdup (X_ANUBIS_RULE_HEADER);
$$->v.expr.re = anubis_regex_compile ($3, $2);
@@ -484,7 +523,7 @@ rule_start: rule opt_modlist string
rule : RULE
{
- if (!is_prog_allowed ())
+ if (!is_prog_allowed (&@1.beg))
YYERROR;
}
;
@@ -495,10 +534,10 @@ string : STRING
inst_stmt: STOP
{
- if (!is_prog_allowed ())
+ if (!is_prog_allowed (&@1.beg))
YYERROR;
- $$ = rc_stmt_create (rc_stmt_inst);
+ $$ = rc_stmt_create (rc_stmt_inst, &@1.beg);
$$->v.inst.opcode = inst_stop;
$$->v.inst.part = NIL;
$$->v.inst.key = NULL;
@@ -507,10 +546,10 @@ inst_stmt: STOP
}
| CALL string
{
- if (!is_prog_allowed ())
+ if (!is_prog_allowed (&@1.beg))
YYERROR;
- $$ = rc_stmt_create (rc_stmt_inst);
+ $$ = rc_stmt_create (rc_stmt_inst, &@1.beg);
$$->v.inst.opcode = inst_call;
$$->v.inst.key = NULL;
$$->v.inst.part = NIL;
@@ -519,10 +558,10 @@ inst_stmt: STOP
}
| ADD s_msgpart string
{
- if (!is_prog_allowed ())
+ if (!is_prog_allowed (&@1.beg))
YYERROR;
- $$ = rc_stmt_create (rc_stmt_inst);
+ $$ = rc_stmt_create (rc_stmt_inst, &@1.beg);
$$->v.inst.opcode = inst_add;
$$->v.inst.part = $2.part;
$$->v.inst.key = NULL;
@@ -531,10 +570,10 @@ inst_stmt: STOP
}
| REMOVE r_msgpart
{
- if (!is_prog_allowed ())
+ if (!is_prog_allowed (&@1.beg))
YYERROR;
- $$ = rc_stmt_create (rc_stmt_inst);
+ $$ = rc_stmt_create (rc_stmt_inst, &@1.beg);
$$->v.inst.opcode = inst_remove;
$$->v.inst.part = $2.part;
$$->v.inst.key = $2.key;
@@ -543,10 +582,10 @@ inst_stmt: STOP
}
| MODIFY r_msgpart string_key string
{
- if (!is_prog_allowed ())
+ if (!is_prog_allowed (&@1.beg))
YYERROR;
- $$ = rc_stmt_create (rc_stmt_inst);
+ $$ = rc_stmt_create (rc_stmt_inst, &@1.beg);
$$->v.inst.opcode = inst_modify;
$$->v.inst.part = $2.part;
$$->v.inst.key = $2.key;
@@ -555,16 +594,17 @@ inst_stmt: STOP
}
| MODIFY r_msgpart string_key
{
- if (!is_prog_allowed ())
+ if (!is_prog_allowed (&@1.beg))
YYERROR;
- $$ = rc_stmt_create (rc_stmt_inst);
+ $$ = rc_stmt_create (rc_stmt_inst, &@1.beg);
$$->v.inst.opcode = inst_modify;
$$->v.inst.part = $2.part;
$$->v.inst.key = $2.key;
if ($3 == NULL && anubis_regex_refcnt ($2.key))
{
- parse_error (_("missing replacement value"));
+ /* FIXME: Perhaps --line? */
+ parse_error (&@2.end, _("missing replacement value"));
}
$$->v.inst.key2 = $3;
$$->v.inst.arg = NULL;
@@ -573,7 +613,7 @@ inst_stmt: STOP
modf_stmt: REGEX modlist
{
- if (!is_prog_allowed ())
+ if (!is_prog_allowed (&@1.beg))
YYERROR;
def_regex_modifier = $2;
@@ -583,33 +623,34 @@ modf_stmt: REGEX modlist
%%
-static int
-err_line_num (void)
-{
- return yychar == EOL ? cfg_line_num - 1 : cfg_line_num;
-}
-
static void
default_error_printer (void *data,
- const char *filename, int line,
+ struct rc_loc *loc,
const char *fmt, va_list ap)
{
char buf[LINEBUFFER];
vsnprintf (buf, sizeof buf, fmt, ap);
- anubis_error (0, 0, "%s:%d: %s", filename, line, buf);
+ if (topt & T_LOCATION_COLUMN)
+ anubis_error (0, 0, "%s:%lu.%lu: %s",
+ loc->file,
+ (unsigned long)loc->line,
+ (unsigned long)loc->column,
+ buf);
+ else
+ anubis_error (0, 0, "%s:%lu: %s",
+ loc->file, (unsigned long)loc->line, buf);
}
static void *rc_error_printer_data;
static RC_ERROR_PRINTER rc_error_printer = default_error_printer;
void
-parse_error (const char *fmt, ...)
+parse_error (struct rc_loc *loc, const char *fmt, ...)
{
va_list ap;
va_start (ap, fmt);
- rc_error_printer (rc_error_printer_data,
- cfg_file, err_line_num (), fmt, ap);
+ rc_error_printer (rc_error_printer_data, loc ? loc : &rc_locus, fmt, ap);
va_end (ap);
error_count++;
}
@@ -617,7 +658,7 @@ parse_error (const char *fmt, ...)
int
yyerror (char *s)
{
- parse_error ("%s", s);
+ parse_error (NULL, "%s", s);
return 0;
}
@@ -625,6 +666,15 @@ RC_SECTION *
rc_parse (char *name)
{
int status;
+
+ yydebug = yy_flex_debug = 0;
+ if (debug_level > 1)
+ {
+ yydebug = 1;
+ if (debug_level > 2)
+ yy_flex_debug = 1;
+ }
+
if (rc_open (name))
return NULL;
@@ -666,8 +716,6 @@ rc_set_debug_level (char *arg)
}
else
debug_level = arg[0] - '0';
- if (debug_level > 1)
- yydebug = debug_level;
}
@@ -738,10 +786,11 @@ string_destroy (char *str)
/* Initializes LOC with the current location. If the second argument
is not zero, it overrides the current line number. */
void
-rc_mark_loc (RC_LOC *loc, size_t line)
+rc_mark_loc (RC_LOC *dst, RC_LOC *src)
{
- loc->file = string_create (cfg_file);
- loc->line = line ? line : cfg_line_num;
+ dst->file = string_create (src->file);
+ dst->line = src->line;
+ dst->column = src->column;
}
/* Reclaims the memory associated with the LOC */
@@ -755,10 +804,10 @@ rc_destroy_loc (RC_LOC *loc)
/* Section manipulation */
RC_SECTION *
-rc_section_create (char *name, size_t line, RC_STMT *stmt)
+rc_section_create (char *name, struct rc_loc *loc, RC_STMT *stmt)
{
RC_SECTION *p = xmalloc (sizeof (*p));
- rc_mark_loc (&p->loc, line);
+ rc_mark_loc (&p->loc, loc);
p->next = NULL;
p->name = name;
p->stmt = stmt;
@@ -892,12 +941,13 @@ rc_bool_destroy (RC_BOOL *bool)
/* Nodes */
+/* FIXME: 2nd should better be struct rc_yyltype */
RC_NODE *
-rc_node_create (enum rc_node_type t)
+rc_node_create (enum rc_node_type t, struct rc_loc *loc)
{
RC_NODE *p = xmalloc (sizeof (*p));
memset (p, 0, sizeof (*p));
- rc_mark_loc (&p->loc, 0);
+ rc_mark_loc (&p->loc, loc);
p->type = t;
return p;
}
@@ -1055,13 +1105,13 @@ rc_inst_print (RC_INST *inst, int level)
}
/* Statements */
-
+/* FIXME: See rc_node_create */
RC_STMT *
-rc_stmt_create (enum rc_stmt_type type)
+rc_stmt_create (enum rc_stmt_type type, struct rc_loc *loc)
{
RC_STMT *p = xmalloc (sizeof (*p));
memset (p, 0, sizeof (*p));
- rc_mark_loc (&p->loc, 0);
+ rc_mark_loc (&p->loc, loc);
p->type = type;
return p;
}
@@ -1173,7 +1223,7 @@ rc_stmt_print (RC_STMT *stmt, int level)
}
int
-reg_modifier_add (int *flag, char *opt)
+reg_modifier_add (int *flag, char *opt, struct rc_loc *loc)
{
/* Regex types: */
if (!strcasecmp (opt, "re") || !strcasecmp (opt, "regex"))
@@ -1213,7 +1263,7 @@ reg_modifier_add (int *flag, char *opt)
re_clear_flag (*flag, R_SCASE);
else
{
- parse_error (_("Unknown regexp modifier"));
+ parse_error (loc, _("Unknown regexp modifier"));
return 1;
}
return 0;
@@ -1665,13 +1715,13 @@ check_kw (char *ident, int *flags)
}
static int
-is_prog_allowed (void)
+is_prog_allowed (struct rc_loc *loc)
{
struct rc_secdef *p = rc_secdef;
if (!p)
p = anubis_find_section ("RULE");
if (!p->allow_prog)
- parse_error (_("program is not allowed in this section"));
+ parse_error (loc, _("program is not allowed in this section"));
return p->allow_prog;
}
diff --git a/src/rc-lex.l b/src/rc-lex.l
index 105451b..50d67aa 100644
--- a/src/rc-lex.l
+++ b/src/rc-lex.l
@@ -56,15 +56,35 @@ static char *multiline_delimiter;
static int strip_tabs;
static struct string_list *str_head, *str_tail;
-int cfg_line_num;
-char *cfg_file;
-
-extern int yydebug;
-#define DBG(t,s) do {\
- if (yydebug > 1) \
- printf ("LEX %s:%d: %s %s\n", cfg_file, cfg_line_num, t, s);\
- } while (0)
-
+struct rc_loc rc_locus;
+
+#define DBG(t,s) \
+ do \
+ { \
+ if (yy_flex_debug) \
+ fprintf (stderr, \
+ "LEX %s:%lu.%lu-%lu.%lu: %s %s\n", \
+ yylloc.beg.file, \
+ (unsigned long) yylloc.beg.line, \
+ (unsigned long) yylloc.beg.column, \
+ (unsigned long) yylloc.end.line, \
+ (unsigned long) yylloc.end.column, \
+ t, s); \
+ } \
+ while (0)
+
+/* Advance locus to the next line */
+void
+advance_line ()
+{
+ ++rc_locus.line;
+ rc_locus.column = 0;
+}
+
+#define YY_USER_ACTION \
+ yylloc.beg = yylloc.end = rc_locus; \
+ yylloc.end.column += yyleng;
+
%}
%x STR LIT ML
@@ -76,7 +96,7 @@ RDASHES [ \t]*---
PUNCT [=:()\[\]]
%%
/* End-of-line comments */
-#.*\n { cfg_line_num++; return EOL; }
+#.*\n { advance_line(); return EOL; }
#.* /* end-of-file comment */;
/* Keywords */
BEGIN return T_BEGIN;
@@ -141,9 +161,9 @@ END |
<INITIAL,LIT>"<<"-?{IDENT}[ \t]*\n |
<INITIAL,LIT>"<<"-?{IDENT}[ \t]*#.*\n { BEGIN (ML);
multiline_begin ();
- cfg_line_num++; }
+ advance_line (); }
<ML>.*\n { char *p = multiline_strip_tabs (yytext);
- cfg_line_num++;
+ advance_line ();
if (strncmp (p, multiline_delimiter, strlen (multiline_delimiter))
== 0
@@ -157,25 +177,26 @@ END |
multiline_add (p);
}
/* Literal */
-<LIT>\\\n { cfg_line_num++; }
+<LIT>\\\n { advance_line (); }
<LIT>[^ \t\n]+\\\n { yylval.string = malloc (yyleng-1);
memcpy (yylval.string, yytext, yyleng-2);
yylval.string[yyleng-2] = 0;
DBG ("<LIT>STRING", yylval.string);
- cfg_line_num++;
+ advance_line ();
return STRING; }
<LIT>[^ \t\n]+ { yylval.string = trimcpy ();
DBG ("<LIT>STRING", yylval.string);
return STRING; }
<LIT>{WS} ;
-<LIT>\n { BEGIN (INITIAL); cfg_line_num++; return EOL; }
+<LIT>\n { BEGIN (INITIAL); advance_line (); return EOL; }
/* Other tokens */
{WS} ;
-\\\n { cfg_line_num++; }
-\n { cfg_line_num++; return EOL; }
+\\\n { advance_line (); }
+\n { advance_line (); return EOL; }
{PUNCT} return yytext[0];
!= return NE;
-. { parse_error (_("Stray character in config: \\%03o. Possibly missing quotes around the string"), yytext[0]); }
+. { parse_error (&rc_locus,
+ _("Stray character in config: \\%03o. Possibly missing quotes around the string"), yytext[0]); }
%%
@@ -386,8 +407,9 @@ rc_open (char *name)
return -1;
}
- cfg_file = name;
- cfg_line_num = 1;
+ rc_locus.file = name;
+ rc_locus.line = 1;
+ rc_locus.column = 0;
return 0;
}
@@ -400,13 +422,17 @@ error_sync_begin ()
{
if (c == T_BEGIN)
{
+ rc_locus.column -= yyleng;
yyless (0);
+ yylloc.beg = yylloc.end = rc_locus;
break;
}
else if (c == D_BEGIN)
{
xfree (yylval.string);
+ rc_locus.column -= yyleng;
yyless (0);
+ yylloc.beg = yylloc.end = rc_locus;
break;
}
}
diff --git a/src/rcfile.h b/src/rcfile.h
index 252379e..e272906 100644
--- a/src/rcfile.h
+++ b/src/rcfile.h
@@ -34,8 +34,25 @@ struct rc_loc
{
char *file;
size_t line;
+ size_t column;
};
+/* Input location for the parser */
+struct rc_yyltype
+{
+ struct rc_loc beg;
+ struct rc_loc end;
+};
+
+#define YYLTYPE struct rc_yyltype
+
+#define RC_LOCUS_FILE_EQ(a,b) \
+ (((a)->file == (b)->file) || \
+ ((a)->file && (b)->file && strcmp ((a)->file, (b)->file) == 0))
+
+#define RC_LOCUS_EQ(a,b) \
+ (RC_LOCUS_FILE_EQ(a,b) && (a)->line == (b)->line)
+
struct rc_section
{ /* RC Section */
RC_LOC loc; /* Location in the config file */
@@ -195,12 +212,11 @@ struct rc_secdef
};
typedef void (*RC_ERROR_PRINTER) (void *data,
- const char *filename, int line,
+ struct rc_loc *loc,
const char *fmt, va_list ap);
/* Global data */
-extern int cfg_line_num;
-extern char *cfg_file;
+struct rc_loc rc_locus;
/* Function declarations */
void verbatim (void);
@@ -225,7 +241,8 @@ int rc_open (char *);
struct rc_secdef *anubis_add_section (char *);
struct rc_secdef *anubis_find_section (char *);
-void parse_error (const char *fmt, ...);
+void parse_error (struct rc_loc *loc, const char *fmt, ...);
void tracefile (RC_LOC *, const char *fmt, ...);
+extern int yy_flex_debug;
/* EOF */
diff --git a/src/xdatabase.c b/src/xdatabase.c
index cf9e907..e0fbe8f 100644
--- a/src/xdatabase.c
+++ b/src/xdatabase.c
@@ -101,7 +101,7 @@ make_temp_file (struct obstack *stk, char *rcname, char **name)
static void
_xdb_error_printer (void *data,
- const char *filename, int line,
+ struct rc_loc *loc,
const char *fmt, va_list ap)
{
struct obstack *stk = data;
@@ -109,8 +109,15 @@ _xdb_error_printer (void *data,
int n;
obstack_grow (stk, ERROR_PREFIX, sizeof ERROR_PREFIX - 1);
- n = snprintf (buf, sizeof buf, "%d: ", line);
+ /* FIXME: column? */
+ n = snprintf (buf, sizeof buf, "%lu", (unsigned long)loc->line);
obstack_grow (stk, buf, n);
+ if (topt & T_LOCATION_COLUMN)
+ {
+ n = snprintf (buf, sizeof buf, ".%lu", (unsigned long)loc->column);
+ obstack_grow (stk, buf, n);
+ }
+ obstack_grow (stk, ": ", 2);
n = vsnprintf (buf, sizeof buf, fmt, ap);
obstack_grow (stk, buf, n);
obstack_grow (stk, CRLF, 2);

Return to:

Send suggestions and report system problems to the System administrator.