summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2017-06-13 17:47:19 +0300
committerSergey Poznyakoff <gray@gnu.org.ua>2017-06-13 17:47:19 +0300
commit82e2f8ee6a860c427d69d1a3652945356f27920e (patch)
tree0a141d04a4f6a138b23918bfd3a2f4c3aa20aafb
parent4f24c098704dd28622d1d653945388a4abbfb434 (diff)
downloadmailutils-82e2f8ee6a860c427d69d1a3652945356f27920e.tar.gz
mailutils-82e2f8ee6a860c427d69d1a3652945356f27920e.tar.bz2
Switch mh_aliases to line tracker
* mh/mh.h (ali_parse_error): Remove. * mh/mh_alias_gram.y: Simplify parser. Use location tracking. * mh/mh_alias_lex.l: Switch to mu_linetrack facility * mh/tests/ali.at: Update expected location.
-rw-r--r--mh/mh.h1
-rw-r--r--mh/mh_alias_gram.y46
-rw-r--r--mh/mh_alias_lex.l253
-rw-r--r--mh/tests/ali.at4
4 files changed, 86 insertions, 218 deletions
diff --git a/mh/mh.h b/mh/mh.h
index c15f8569f..69be72de2 100644
--- a/mh/mh.h
+++ b/mh/mh.h
@@ -381,7 +381,6 @@ const char *mh_seq_read (mu_mailbox_t mbox, const char *name, int flags);
void mh_comp_draft (const char *formfile, const char *draftfile);
int check_draft_disposition (struct mh_whatnow_env *wh, int use_draft);
-void ali_parse_error (const char *fmt, ...) MU_PRINTFLIKE(1,2);
void ali_verbatim (int enable);
char *mh_safe_make_file_name (const char *dir, const char *file);
diff --git a/mh/mh_alias_gram.y b/mh/mh_alias_gram.y
index 0d6bffcc2..d7229983a 100644
--- a/mh/mh_alias_gram.y
+++ b/mh/mh_alias_gram.y
@@ -20,6 +20,8 @@
#include <pwd.h>
#include <grp.h>
#include <sys/types.h>
+#include <mailutils/locus.h>
+#include <mailutils/yyloc.h>
struct mh_alias
{
@@ -31,7 +33,7 @@ struct mh_alias
static mu_list_t alias_list;
static mu_list_t
-list_create_or_die ()
+list_create_or_die (void)
{
int status;
mu_list_t list;
@@ -39,7 +41,7 @@ list_create_or_die ()
status = mu_list_create (&list);
if (status)
{
- ali_parse_error (_("can't create list: %s"), mu_strerror (status));
+ mu_error (_("can't create list: %s"), mu_strerror (status));
exit (1);
}
return list;
@@ -86,6 +88,17 @@ ali_list_to_string (mu_list_t *plist)
return string;
}
+static void
+ali_append (struct mh_alias *ali)
+{
+ if (ali)
+ {
+ if (!alias_list)
+ alias_list = list_create_or_die ();
+ mu_list_append (alias_list, ali);
+ }
+}
+
static mu_list_t unix_group_to_list (char *name);
static mu_list_t unix_gid_to_list (char *name);
static mu_list_t unix_passwd_to_list (void);
@@ -101,37 +114,34 @@ int yylex (void);
struct mh_alias *alias;
}
+%token EOL
%token <string> STRING
%type <list> address_list address_group string_list
%type <string> address
%type <alias> alias
+%locations
+
%%
-input : /* empty */
- | alias_list
- | alias_list nl
- | nl alias_list
- | nl alias_list nl
+input : alias_list
;
alias_list : alias
{
- if (!alias_list)
- alias_list = list_create_or_die ();
- mu_list_append (alias_list, $1);
+ ali_append ($1);
}
- | alias_list nl alias
+ | alias_list EOL alias
{
- mu_list_append (alias_list, $3);
+ ali_append ($3);
}
;
-nl : '\n'
- | nl '\n'
- ;
-
-alias : STRING ':' { ali_verbatim (1); } address_group
+alias : /* empty */
+ {
+ $$ = NULL;
+ }
+ | STRING ':' { ali_verbatim (1); } address_group
{
ali_verbatim (0);
$$ = mu_alloc (sizeof (*$$));
@@ -489,7 +499,7 @@ unix_passwd_to_list ()
}
int
-mh_read_aliases ()
+mh_read_aliases (void)
{
const char *p;
diff --git a/mh/mh_alias_lex.l b/mh/mh_alias_lex.l
index 0d854b46b..445522c65 100644
--- a/mh/mh_alias_lex.l
+++ b/mh/mh_alias_lex.l
@@ -23,58 +23,23 @@
%{
#include <mh.h>
+#include <mailutils/locus.h>
+#include <mailutils/yyloc.h>
#include <mh_alias_gram.h>
#include <sys/stat.h>
#include <mailutils/cctype.h>
#include <mailutils/io.h>
-
-char *ali_filename;
-size_t ali_line_num;
-ino_t ali_source_inode;
-
-void
-va_ali_parse_error_loc (const char *name, size_t line,
- const char *fmt, va_list ap)
-{
- char *buf = NULL;
- size_t size = 0;
- mu_vasnprintf (&buf, &size, fmt, ap);
- if (name)
- mu_error ("%s:%lu: %s", name, (unsigned long) line, buf);
- else
- mu_error ("%s", buf);
- free (buf);
-}
-
-void
-ali_parse_error_loc (const char *name, size_t line, const char *fmt, ...)
-{
- va_list ap;
-
- va_start (ap, fmt);
- va_ali_parse_error_loc (name, line, fmt, ap);
- va_end (ap);
-}
-
-void
-ali_parse_error (const char *fmt, ...)
-{
- va_list ap;
-
- va_start (ap, fmt);
- va_ali_parse_error_loc (ali_filename, ali_line_num, fmt, ap);
- va_end (ap);
-}
+static mu_linetrack_t trk;
+static ino_t ali_source_inode;
int
yyerror (char *s)
{
- ali_parse_error ("%s", s);
+ mu_error ("%s", s);
return 0;
}
-#ifdef FLEX_SCANNER
#define xinput() (yyin ? getc(yyin) : EOF)
#undef YY_INPUT
#define YY_INPUT(buf,result,max_size) do { \
@@ -97,127 +62,20 @@ yyerror (char *s)
yy_switch_to_buffer(s); \
} while (0)
-#else
-/* AT&T Lex */
-
-static void lex_set_buffer (FILE *fp);
-static void lex_delete_buffer (LEX_BUFFER_STATE buf);
-static int xinput (void);
-static int xunput (void);
-
-#undef unput
-#define unput(c) xunput(c)
-#undef input
-#define input() xinput()
-
-#define LEX_BUF_SIZE 16384
-#define LEX_PUTBACK_SIZE 32
-
-typedef struct {
- FILE *yyin;
- char *buffer;
- size_t bufsize;
- size_t level;
- char *ptr;
- char *putback;
- size_t pb_size;
- size_t pb_level;
-} LEX_BUFFER_STATE;
-LEX_BUFFER_STATE current_buffer;
+#define YY_USER_ACTION \
+ do \
+ { \
+ mu_linetrack_advance (trk, &yylloc, yytext, yyleng); \
+ mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM, \
+ MU_IOCTL_LOGSTREAM_SET_LOCUS_RANGE, &yylloc); \
+ } \
+ while (0);
-#define SET_BUFFER_STATE(s) do { \
- (s) = current_buffer; \
- lex_set_buffer(yyin); \
-} while (0)
-#define RESTORE_BUFFER_STATE(s) do { \
- lex_delete_buffer(current_buffer); \
- current_buffer = (s); \
- yyin = current_buffer.yyin; \
-} while (0)
-
-void
-lex_set_buffer (FILE *fp)
-{
- char *buf;
- size_t size;
-
- for (size = LEX_BUF_SIZE; size > 1; size /= 2)
- if (buf = malloc (size))
- break;
-
- if (!buf)
- {
- ali_parse_error (_("not enough memory"));
- abort ();
- }
-
- current_buffer.yyin = yyin;
- current_buffer.buffer = buf;
- current_buffer.bufsize = size;
- current_buffer.level = 0;
- current_buffer.ptr = current_buffer.buffer;
- current_buffer.pb_size = current_buffer.pb_level = 0;
- current_buffer.putback = NULL;
-}
-
-void
-lex_delete_buffer (LEX_BUFFER_STATE buf)
-{
- free (buf.buffer);
- if (buf.putback)
- free (buf.putback);
-}
-
-int
-xinput ()
-{
- if (!yyin)
- return EOF;
-
- if (current_buffer.pb_level)
- return current_buffer.putback[--current_buffer.pb_level];
-
- if (current_buffer.level <= 0)
- {
- int n;
-
- if (feof (yyin))
- return 0;
- n = fread (current_buffer.buffer, 1,
- current_buffer.bufsize, yyin);
- if (n <= 0)
- return 0;
- current_buffer.level = n;
- current_buffer.ptr = current_buffer.buffer;
- }
- current_buffer.level--;
- return *current_buffer.ptr++;
-}
-
-int
-xunput (int c)
-{
- if (current_buffer.pb_level == current_buffer.pb_size)
- {
- char *putback;
- current_buffer.pb_size += LEX_PUTBACK_SIZE;
- putback = mu_alloc (current_buffer.pb_size);
- memcpy (putback, current_buffer.putback,
- current_buffer.pb_level);
- free (current_buffer.putback);
- current_buffer.putback = putback;
- }
- current_buffer.putback[current_buffer.pb_level++] = c;
- return c;
-}
-
-#endif
-
struct buffer_ctx {
struct buffer_ctx *prev;
- char *filename;
- int line;
+ mu_linetrack_t trk;
ino_t i_node;
+ struct mu_locus_range incl_range;
FILE *yyin;
int exec_p;
LEX_BUFFER_STATE state;
@@ -250,27 +108,26 @@ push_source (const char *name, int fail)
if (stat (filename, &st))
{
if (fail)
- ali_parse_error (_("can't stat `%s': %s"), filename, strerror (errno));
+ mu_error (_("can't stat `%s': %s"), filename, strerror (errno));
free (filename);
return 1;
}
- if (ali_filename && st.st_ino == ali_source_inode)
+ if (yylloc.beg.mu_file && st.st_ino == ali_source_inode)
{
- ali_parse_error (_("recursive inclusion"));
+ mu_error (_("recursive inclusion"));
free (filename);
return 1;
}
if ((ctx = ctx_lookup (st.st_ino)))
{
- ali_parse_error (_("recursive inclusion"));
+ mu_error (_("recursive inclusion"));
if (ctx->prev)
- ali_parse_error_loc (ctx->prev->filename, ctx->prev->line,
- _("`%s' already included here"),
- filename);
+ mu_diag_at_locus_range (MU_LOG_ERROR, &ctx->incl_range,
+ _("`%s' already included here"),
+ filename);
else
- ali_parse_error (_("`%s' already included at top level"),
- filename);
+ mu_error (_("`%s' already included at top level"), filename);
free (filename);
return 1;
}
@@ -278,7 +135,7 @@ push_source (const char *name, int fail)
fp = fopen (filename, "r");
if (!fp)
{
- ali_parse_error (_("can't open `%s': %s"), filename, strerror (errno));
+ mu_error (_("can't open `%s': %s"), filename, strerror (errno));
free (filename);
return 1;
}
@@ -295,8 +152,8 @@ push_source (const char *name, int fail)
fp = popen (filename, "r");
if (!fp)
{
- ali_parse_error (_("can't execute `%s': %s"),
- filename, strerror (errno));
+ mu_error (_("can't execute `%s': %s"),
+ filename, strerror (errno));
free (filename);
return 1;
}
@@ -306,12 +163,12 @@ push_source (const char *name, int fail)
}
/* Push current context */
- if (ali_filename)
+ if (yylloc.beg.mu_file)
{
ctx = mu_alloc (sizeof (*ctx));
- ctx->filename = ali_filename;
+ ctx->trk = trk;
+ mu_locus_range_copy (&ctx->incl_range, &yylloc);
ctx->exec_p = exec_p;
- ctx->line = ali_line_num;
ctx->i_node = ali_source_inode;
ctx->yyin = yyin;
ctx->prev = context_stack;
@@ -330,34 +187,30 @@ push_source (const char *name, int fail)
lex_set_buffer (yyin);
#endif
}
- ali_filename = filename;
- ali_line_num = 1;
+ MU_ASSERT (mu_linetrack_create (&trk, filename, 2));
+ free (filename);
ali_source_inode = st.st_ino;
exec_p = ex;
return 0;
}
static int
-pop_source ()
+pop_source (void)
{
struct buffer_ctx *ctx;
if (yyin)
(exec_p ? pclose : fclose) (yyin);
-#ifndef FLEX_SCANNER
- lex_delete_buffer (current_buffer);
-#endif
- if (ali_filename)
- free (ali_filename);
- ali_filename = NULL;
+ mu_linetrack_destroy (&trk);
if (!context_stack)
{
+ mu_locus_range_deinit (&yylloc);
yyin = NULL;
return 1;
}
+ mu_locus_range_deinit (&context_stack->incl_range);
/* Restore previous context */
- ali_filename = context_stack->filename;
- ali_line_num = context_stack->line + 1; /* < line did not increment it */
+ trk = context_stack->trk;
ali_source_inode = context_stack->i_node;
exec_p = context_stack->exec_p;
RESTORE_BUFFER_STATE (context_stack->state);
@@ -378,15 +231,15 @@ WORD [^ \t\n,:;<+=\*]+
SPEC [,:;+=\*]
%s VERBATIM
%%
-\\\n { ali_line_num++; }
-\n { ali_line_num++; return '\n';}
-^[ \t]*\;.*\n ali_line_num++;
+\\\n ;
+\n+ return EOL;
+^[ \t]*\;.*\n ;
^[ \t]*{WORD}\* { char *p;
for (p = yytext; p < yytext + yyleng; p++)
if (!mu_isspace (*p))
break;
yylval.string = mu_strdup (p);
- return STRING;}
+ return STRING; }
{WS} ;
{WORD} { yylval.string = mu_strdup (yytext); return STRING;}
^{WS}?"<"{WS}?{WORD} {
@@ -403,26 +256,24 @@ SPEC [,:;+=\*]
memcpy(yylval.string, yytext, yyleng);
yylval.string[yyleng] = 0;
return STRING;}
-. { char *p;
- mu_asprintf (&p,
- _("Stray character %03o in alias file"),
- yytext[0]);
- yyerror (p);
- free (p); }
+. { mu_error (_("Stray character %03o in alias file"),
+ yytext[0]); }
%%
int
-yywrap ()
+yywrap (void)
{
- return pop_source();
+ return pop_source ();
}
/* Parses the named alias file */
int
mh_alias_read (char const *name, int fail)
{
+ int rc;
+ int old_mode, mode;
extern int yydebug;
- char *p = getenv("ALI_YYDEBUG");
+ char *p = getenv ("ALI_YYDEBUG");
if (p && *p > '0' && *p < '9')
yydebug = 1;
@@ -431,7 +282,15 @@ mh_alias_read (char const *name, int fail)
return 1;
if (yydebug)
fprintf (stderr, "Starting parse of %s\n", name);
- return yyparse ();
+
+ mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM,
+ MU_IOCTL_LOGSTREAM_GET_MODE, &old_mode);
+ mode = old_mode | MU_LOGMODE_LOCUS;
+ mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM,
+ MU_IOCTL_LOGSTREAM_SET_MODE, &mode);
+ rc = yyparse ();
+ mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM,
+ MU_IOCTL_LOGSTREAM_SET_MODE, &old_mode);
}
void
diff --git a/mh/tests/ali.at b/mh/tests/ali.at
index d18a9107b..28c0e5451 100644
--- a/mh/tests/ali.at
+++ b/mh/tests/ali.at
@@ -70,8 +70,8 @@ exit $code
[0],
[gray, polak, admin
],
-[ali: mh_aliases2:2: recursive inclusion
-ali: mh_aliases2:2: `mh_aliases' already included at top level
+[ali: mh_aliases2:2.1-11: recursive inclusion
+ali: mh_aliases2:2.1-11: `mh_aliases' already included at top level
])
MH_CHECK([ali: group name],[ali04 ali-group-name],[

Return to:

Send suggestions and report system problems to the System administrator.