diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2007-04-22 21:54:39 +0000 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2007-04-22 21:54:39 +0000 |
commit | c112aa5a76f7800297677fa372de65ad721a4666 (patch) | |
tree | 4b7eee0d91462fffe2c4814e8d162242f5084052 /src | |
parent | 44b3537859dd32e2730119ce3363f032fc39cb27 (diff) | |
download | mailfromd-c112aa5a76f7800297677fa372de65ad721a4666.tar.gz mailfromd-c112aa5a76f7800297677fa372de65ad721a4666.tar.bz2 |
Introduce the module system
git-svn-id: file:///svnroot/mailfromd/trunk@1373 7a8a7f39-df28-0410-adc6-e0d955640f24
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile.am | 2 | ||||
-rw-r--r-- | src/bi_other.m4 | 27 | ||||
-rw-r--r-- | src/debug.cin | 72 | ||||
-rw-r--r-- | src/debugdef.m4 | 4 | ||||
-rw-r--r-- | src/lex.l | 120 | ||||
-rw-r--r-- | src/main.c | 10 |
6 files changed, 186 insertions, 49 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index aea0dccc..57f099f4 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -154,7 +154,7 @@ optab.c optab.h: opcodes .cin.c: SRCLIST=`echo $(mailfromd_SOURCES) | tr -s ' ' ','`; \ - $(M4) -DSRCLIST="$$SRCLIST" $(top_srcdir)/src/debugdef.m4 $< > $@ + $(M4) -s -DSRCLIST="$$SRCLIST" $(top_srcdir)/src/debugdef.m4 $< > $@ .hin.h: SRCLIST=`echo $(mailfromd_SOURCES) | tr -s ' ' ','`; \ diff --git a/src/bi_other.m4 b/src/bi_other.m4 index c32a7a8f..f414b0bd 100644 --- a/src/bi_other.m4 +++ b/src/bi_other.m4 @@ -88,6 +88,33 @@ MF_DEFUN(rate, NUMBER, STRING key, NUMBER interval) } END +MF_DEFUN(debug_level, NUMBER, OPTIONAL, STRING modname) +{ + int level; + MF_ASSERT(debug_module_level(MF_OPTVAL(modname, NULL), &level) == 0, + mf_range, + "invalid module name: %s", modname); + MF_RETURN(level); +} +END + +MF_DEFUN(debug_spec, STRING, OPTIONAL, STRING modnames) +{ + char *buf; + char *s; + size_t off; + + int rc = debug_spec_string(MF_OPTVAL(modnames, NULL), &buf); + MF_ASSERT(rc == 0, + mf_failure, + "%s", mu_strerror(rc)); + s = MF_ALLOC_HEAP(off, strlen(buf) + 1); + strcpy(s, buf); + free(buf); + MF_RETURN(off); +} +END + MF_DEFUN(debug, VOID, STRING spec) { debug_parse_spec(spec); diff --git a/src/debug.cin b/src/debug.cin index c8b8deac..78696136 100644 --- a/src/debug.cin +++ b/src/debug.cin @@ -28,12 +28,12 @@ struct modinfo { unsigned code; }; -static struct modinfo modinfo[] = { - { "all", 0 }, +static char *modname[] = { + "all", MAKEDEBUGTAB(SRCLIST) }; -#define NMODULES (sizeof modinfo / sizeof modinfo[0]) +#define NMODULES (sizeof modname / sizeof modname[0]) static int modlevel[NMODULES]; /* Per-module levels */ @@ -66,10 +66,10 @@ find_module(const char *name) else len = strlen(p); - for (mp = modinfo; mp < modinfo + NMODULES; mp++) { - if (strlen(mp->name) == len - && memcmp(mp->name, p, len) == 0) - return mp->code; + for (i = 0; i < NMODULES; i++) { + if (strlen(modname[i]) == len + && memcmp(modname[i], p, len) == 0) + return i; } return -1; } @@ -138,5 +138,61 @@ debug_parse_spec(const char *spec) parse_spec(s); free(copy); } - + +int +debug_spec_string(const char *spec, char **pbuf) +{ + char mods[NMODULES]; + size_t len = 0, i; + char nbuf[NUMERIC_BUFSIZE_BOUND]; + char *buf, *ptr; + + if (!spec) { + memset(mods, 0xff, sizeof mods); + } else { + char *copy = xstrdup(spec); + char *s; + memset(mods, 0, sizeof mods); + for (s = strtok(copy, ","); s; s = strtok(NULL, ",")) { + int n = find_module(s); + if (n < 0) { + free(copy); + return EINVAL; + } + mods[n] = 1; + } + } + + if (mods[0]) { + snprintf(nbuf, sizeof nbuf, "%d", modlevel[0]); + len += strlen(nbuf) + 1; + } + for (i = 1; i < NMODULES; i++) { + if (mods[i]) { + snprintf(nbuf, sizeof nbuf, "%d", modlevel[i]); + len += strlen(modname[i]) + 1 + strlen(nbuf) + 1; + } + } + + buf = malloc(len + 1); + if (!buf) + return ENOMEM; + + ptr = buf; + if (mods[0]) { + sprintf(ptr, "%d", modlevel[0]); + ptr += strlen(ptr); + } + for (i = 1; i < NMODULES; i++) { + if (mods[i]) { + if (ptr > buf) + *ptr++ = ','; + sprintf(ptr, "%s=%d", modname[i], modlevel[i]); + ptr += strlen(ptr); + } + } + *ptr = 0; + *pbuf = buf; + return 0; +} diff --git a/src/debugdef.m4 b/src/debugdef.m4 index 67f86e91..f9c16082 100644 --- a/src/debugdef.m4 +++ b/src/debugdef.m4 @@ -21,10 +21,10 @@ changequote([<,>]) changecom(/*,*/) define([<__makedebugtab>],[<dnl -ifelse($2,,[< { NULL }>], +ifelse($2,,, [<ifelse(regexp($2,[<\(.*\)\.[cyl]>],[<\1>]),, [<__makedebugtab($1,shift(shift($@)))>], -[< { "patsubst($2,\(.*\)\.[cyl],\1)", $1 }, +[< "patsubst($2,\(.*\)\.[cyl],\1)", >]dnl [<__makedebugtab(incr($1),shift(shift($@)))>])>])>]) @@ -301,6 +301,41 @@ pop_source() return 0; } +int +try_file(const char *name, int allow_cwd, char **newp) +{ + static char *cwd = "."; + char *tmp = NULL; + char *p = NULL; + + struct file_data fd; + + fd.name = name; + fd.namelen = strlen(name); + fd.buf = NULL; + fd.buflen = 0; + fd.found = 0; + + if (allow_cwd) { + mu_list_prepend(include_path, cwd); + mu_list_do(include_path, find_include_file, &fd); + mu_list_remove(std_include_path, cwd); + } else + mu_list_do(include_path, find_include_file, &fd); + + if (!fd.found) { + mu_list_do(std_include_path, find_include_file, &fd); + + if (!fd.found) { + parse_error("%s: No such file or directory", name); + *newp = NULL; + } + } + if (fd.found) + *newp = fd.buf; + return fd.found; +} + void parse_include(int once) { @@ -316,7 +351,6 @@ parse_include(int once) else { size_t len; int allow_cwd; - static char *cwd = "."; p = argv[1]; len = strlen(p); @@ -328,38 +362,8 @@ parse_include(int once) } else allow_cwd = 1; - if (p[0] != '/') { - struct file_data fd; - - fd.name = p; - fd.namelen = strlen(p); - fd.buf = NULL; - fd.buflen = 0; - fd.found = 0; - - if (allow_cwd) { - mu_list_prepend(include_path, cwd); - mu_list_do(include_path, - find_include_file, &fd); - mu_list_remove(std_include_path, cwd); - } else - mu_list_do(include_path, - find_include_file, &fd); - - if (!fd.found) { - mu_list_do(std_include_path, - find_include_file, &fd); - - if (!fd.found) { - parse_error("%s: No such file or directory", - p); - p = NULL; - } - } - if (fd.found) - p = tmp = fd.buf; - } - + if (p[0] != '/' && try_file(p, allow_cwd, &tmp)) + p = tmp; } locus.line++; @@ -369,6 +373,55 @@ parse_include(int once) mu_argcv_free(argc, argv); } +#define DEFAULT_SUFFIX ".mf" + +void +parse_require() +{ + int argc; + char **argv; + char *tmp = NULL; + char *p = NULL; + + if (mu_argcv_get(yytext, "", NULL, &argc, &argv)) + parse_error("cannot parse require line"); + else if (argc != 2) + parse_error("invalid require statement"); + else { + size_t len; + char *fname; + + p = argv[1]; + len = strlen(p); + + /* For compatibility with #include */ + if (p[0] == '<' && p[len - 1] == '>') { + p[--len] = 0; + p++; + } + + if (len > sizeof DEFAULT_SUFFIX + && memcmp(p + len - sizeof DEFAULT_SUFFIX - 1, + DEFAULT_SUFFIX, + sizeof DEFAULT_SUFFIX - 1)) { + fname = xmalloc(len + sizeof DEFAULT_SUFFIX); + strcpy(fname, p); + strcat(fname, DEFAULT_SUFFIX); + p = fname; + } else + fname = NULL; + + if (p[0] != '/' && try_file(p, 0, &tmp)) + p = tmp; + free(fname); + } + locus.line++; + if (p) + push_source(p, 1); + free(tmp); + mu_argcv_free(argc, argv); +} + static int get_const(const char *name) { @@ -433,6 +486,7 @@ MACRO {LOCUS}|{VMACRO}|__statedir__ ^[ \t]*#[ \t]*pragma[ \t].*/\n parse_pragma(yytext); ^[ \t]*#[ \t]*include_once[ \t].*\n parse_include(1); ^[ \t]*#[ \t]*include[ \t].*\n parse_include(0); +^[ \t]*#[ \t]*require[ \t].*\n parse_require(yytext); ^[ \t]*#[ \t]*error[ \t].*\n { parse_error("%s", yytext); locus.line++; } /* End-of-line comments */ #.*\n { locus.line++; } @@ -937,20 +937,20 @@ static struct argp_option options[] = { { NULL, 0, NULL, 0, N_("Informational and debugging options"), GRP }, { "transcript", 'X', NULL, 0, - N_("Enable transcript"), GRP+1 }, + N_("Enable transcript of SMTP sessions"), GRP+1 }, { "trace", OPTION_TRACE, NULL, 0, - N_("Enable tracing configuration"), GRP+1 }, + N_("Trace executed actions"), GRP+1 }, { "trace-program", OPTION_TRACE_PROGRAM, N_("MODULES"), OPTION_ARG_OPTIONAL, - N_("Enable program tracing"), GRP+1 }, + N_("Enable filter program tracing"), GRP+1 }, { "debug", 'd', N_("LEVEL"), 0, N_("Set debugging level"), GRP+1 }, { "dump-code", OPTION_DUMP_CODE, NULL, 0, N_("Dump disassembled code"), GRP+1 }, { "dump-grammar-trace", OPTION_DUMP_GRAMMAR_TRACE, NULL, 0, - N_("Dump grammar traces when parsing the config"), GRP+1 }, + N_("Dump grammar traces"), GRP+1 }, { "dump-lex-trace", OPTION_DUMP_LEX_TRACE, NULL, 0, - N_("Dump lexical analizer traces when parsing the config"), GRP+1 }, + N_("Dump lexical analizer traces"), GRP+1 }, { "dump-tree", OPTION_DUMP_TREE, NULL, 0, N_("Dump parser tree"), GRP+1 }, { "dump-macros", OPTION_DUMP_MACROS, NULL, 0, |