aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2007-04-22 21:54:39 +0000
committerSergey Poznyakoff <gray@gnu.org.ua>2007-04-22 21:54:39 +0000
commitc112aa5a76f7800297677fa372de65ad721a4666 (patch)
tree4b7eee0d91462fffe2c4814e8d162242f5084052 /src
parent44b3537859dd32e2730119ce3363f032fc39cb27 (diff)
downloadmailfromd-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.am2
-rw-r--r--src/bi_other.m427
-rw-r--r--src/debug.cin72
-rw-r--r--src/debugdef.m44
-rw-r--r--src/lex.l120
-rw-r--r--src/main.c10
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($@)))>])>])>])
diff --git a/src/lex.l b/src/lex.l
index 91e58386..cb7b10d4 100644
--- a/src/lex.l
+++ b/src/lex.l
@@ -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++; }
diff --git a/src/main.c b/src/main.c
index 190b0840..56aa2af2 100644
--- a/src/main.c
+++ b/src/main.c
@@ -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,

Return to:

Send suggestions and report system problems to the System administrator.