aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2011-03-01 14:10:12 +0200
committerSergey Poznyakoff <gray@gnu.org.ua>2011-03-01 14:18:38 +0200
commitdfb2a4fb8358c12816e120b16607b272697e20be (patch)
treecd9f89cd64d5f93e1f7247f72baa620453462823
parentf1b7f42ce6d83a8e37d5b836c7d801afb2b18c43 (diff)
downloadmailfromd-dfb2a4fb8358c12816e120b16607b272697e20be.tar.gz
mailfromd-dfb2a4fb8358c12816e120b16607b272697e20be.tar.bz2
Store exception names in the dataseg.
* src/mf-status.c: Remove. * src/exclist.c: New file. * src/Makefile.am (mailfromd_SOURCES): Remove mf-status.c, add exclist.c. * src/gram.y (exdecl): Call define_exception. (dataseg_layout): Create table of exception names in dataseg. * src/mailfromd.h (define_constant): Change return value. (string_to_exception): Remove. (define_exception,enumerate_exceptions) (free_exceptions): New protos. * src/main.c (main): Call free_exceptions. * src/prog.c (exception_count): Move declaration to exclist.c (instr_throw): Add trace print. (dump_throw): Print exception number along with its symbolic value. (env_throw_0): Reword default message. * src/prog.h (EXTABIND): New macro. * src/symbols.c (define_constant): Return pointer to the allocated struct constant. * tests/eof.at: Reflect changes to env_throw_0. * tests/hdr-gete.at: Likewise. * mflib/mfex.awk: Simplify.
-rw-r--r--mflib/mfex.awk12
-rw-r--r--src/Makefile.am3
-rw-r--r--src/exclist.c103
-rw-r--r--src/gram.y19
-rw-r--r--src/mailfromd.h14
-rw-r--r--src/main.c1
-rw-r--r--src/mf-status.c100
-rw-r--r--src/prog.c14
-rw-r--r--src/prog.h1
-rw-r--r--src/symbols.c3
-rw-r--r--tests/eof.at2
-rw-r--r--tests/hdr-gete.at2
12 files changed, 145 insertions, 129 deletions
diff --git a/mflib/mfex.awk b/mflib/mfex.awk
index e134c409..96d0808c 100644
--- a/mflib/mfex.awk
+++ b/mflib/mfex.awk
@@ -21,17 +21,7 @@ BEGIN {
}
/dclex[ \t][ \t]*e_/ {
- extab[excnt++] = $2
-}
-
-END {
- print "#ifdef __MF_EXCEPTION_C_ARRAY"
- for (i = 0; i < excnt; i++)
- printf("{ mf%s, \"%s\" },\n", extab[i], extab[i]);
- print "#else"
- for (i = 0; i < excnt; i++)
- printf("mf%s,\n", extab[i])
- print "#endif"
+ printf("mf%s,\n", $2)
}
diff --git a/src/Makefile.am b/src/Makefile.am
index a49a41a4..7afa8030 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -29,10 +29,10 @@ libcallout_a_SOURCES = \
mailfromd_SOURCES = \
deprecation.c\
engine.c\
+ exclist.c\
gram.y\
lex.l\
main.c\
- mf-status.c\
optab.c\
optab.h\
pp.c\
@@ -98,7 +98,6 @@ EXTRA_DIST = \
BUILT_SOURCES=\
callout-dbgmod.h\
- mf-status.c\
mfd-dbgmod.h\
node-tab.c\
node-type.h\
diff --git a/src/exclist.c b/src/exclist.c
new file mode 100644
index 00000000..e5d7330c
--- /dev/null
+++ b/src/exclist.c
@@ -0,0 +1,103 @@
+/* This file is part of Mailfromd.
+ Copyright (C) 2011 Sergey Poznyakoff
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "mailfromd.h"
+#include "prog.h"
+
+struct exclist {
+ struct exclist *next;
+ struct literal *lit;
+ const struct constant *cp;
+};
+
+static struct exclist *head, *tail;
+size_t exception_count = 0;
+
+void
+define_exception(struct literal *lit, struct locus *locus)
+{
+ const struct constant *cp;
+ struct value value;
+ struct exclist *exdef;
+
+ value.type = dtype_number;
+ value.v.number = exception_count++;
+ cp = define_constant(lit->text, &value, 0, locus);
+ lit->flags |= SYM_REFERENCED;
+ exdef = xmalloc(sizeof(*exdef));
+ exdef->cp = cp;
+ exdef->lit = lit;
+ exdef->next = NULL;
+ if (tail)
+ tail->next = exdef;
+ else
+ head = exdef;
+ tail = exdef;
+}
+
+void
+enumerate_exceptions(int (*efn)(const struct constant *cp,
+ const struct literal *lit,
+ void *data),
+ void *data)
+{
+ struct exclist *p;
+
+ for (p = head; p && efn(p->cp, p->lit, data) == 0; p = p->next)
+ ;
+}
+
+void
+free_exceptions()
+{
+ while (head) {
+ struct exclist *next = head->next;
+ free(head);
+ head = next;
+ }
+ tail = NULL;
+}
+
+const char *
+mf_exception_str(unsigned ex)
+{
+ return (char*) (dataseg + (size_t) dataseg[EXTABIND + ex]);
+}
+
+mf_exception
+mf_status_to_exception(mf_status s)
+{
+ switch (s) {
+ case mf_success:
+ return mfe_success;
+
+ case mf_not_found:
+ return mfe_not_found;
+
+ case mf_failure:
+ return mfe_failure;
+
+ case mf_temp_failure:
+ case mf_timeout:
+ return mfe_temp_failure;
+ }
+ return s;
+}
+
diff --git a/src/gram.y b/src/gram.y
index 5ab951b7..8aed5cf8 100644
--- a/src/gram.y
+++ b/src/gram.y
@@ -874,10 +874,7 @@ constdecl : qualifiers T_CONST varname expr
exdecl : T_DCLEX T_IDENTIFIER
{
- struct value value;
- value.type = dtype_number;
- value.v.number = exception_count++;
- define_constant($2->text, &value, 0, &@1.beg);
+ define_exception($2, &@1.beg);
}
;
@@ -3992,6 +3989,14 @@ vtab_comp(const void *a, const void *b)
return 0;
}
+static int
+place_exc(const struct constant *cp, const struct literal *lit, void *data)
+{
+ STKVAL *tab = data;
+ tab[cp->value.v.number] = (STKVAL) lit->off;
+ return 0;
+}
+
static void
dataseg_layout()
{
@@ -4057,6 +4062,9 @@ dataseg_layout()
}
datasize += exmask->bm.bm_size + 1;
}
+
+ /* Account for exception name table */
+ datasize += exception_count;
/* Allocate data segment and relocation table */
dataseg = xcalloc(datasize, sizeof(STKVAL));
@@ -4097,6 +4105,9 @@ dataseg_layout()
for (i = 0; i < exmask->bm.bm_size; i++)
dataseg[off++] = (STKVAL) exmask->bm.bm_bits[i++];
}
+
+ /* Initialize exception name table */
+ enumerate_exceptions(place_exc, dataseg + EXTABIND);
}
diff --git a/src/mailfromd.h b/src/mailfromd.h
index c9ca3c70..e45f26e2 100644
--- a/src/mailfromd.h
+++ b/src/mailfromd.h
@@ -584,8 +584,8 @@ struct function *function_install(const char *name,
const struct locus *locus);
struct function *function_lookup(const char *name);
struct literal *literal_lookup(const char *text);
-void define_constant(const char *name, struct value *value,
- unsigned flags, struct locus *loc);
+const struct constant *define_constant(const char *name, struct value *value,
+ unsigned flags, struct locus *loc);
const struct constant *constant_lookup(const char *name);
const struct value *constant_lookup_value(const char *name);
@@ -728,7 +728,6 @@ const struct locus *get_locus(void);
const char *msgmod_opcode_str(enum msgmod_opcode opcode);
const char *sfsistat_str(sfsistat s);
const char *mf_exception_str(unsigned ex);
-int string_to_exception(const char *str, mf_exception *status);
mf_exception mf_status_to_exception(mf_status s);
@@ -959,3 +958,12 @@ void schedule_callout(const char *email, const char *ehlo,
extern struct sockaddr *callout_server_sa;
extern socklen_t callout_server_sa_len;
+/* exclist.c */
+void define_exception(struct literal *lit, struct locus *locus);
+void enumerate_exceptions(int (*efn)(const struct constant *cp,
+ const struct literal *lit,
+ void *data),
+ void *data);
+void free_exceptions(void);
+
+
diff --git a/src/main.c b/src/main.c
index f2c0c037..f27a971e 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1263,6 +1263,7 @@ main(int argc, char **argv)
}
}
+ free_exceptions();
free_symbols();
free_string_space();
free_parser_data();
diff --git a/src/mf-status.c b/src/mf-status.c
deleted file mode 100644
index 38040d07..00000000
--- a/src/mf-status.c
+++ /dev/null
@@ -1,100 +0,0 @@
-/* This file is part of Mailfromd.
- Copyright (C) 2005, 2006, 2007, 2008, 2010, 2011 Sergey Poznyakoff
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include "mailfromd.h"
-
-struct status_tab {
- mf_exception ex;
- char *name;
-};
-
-static struct status_tab std_status_tab[] = {
-#define __MF_EXCEPTION_C_ARRAY
-#include <mflib/status.ex>
-#undef __MF_EXCEPTION_C_ARRAY
- { 0, NULL }
-};
-
-static size_t usr_status_count;
-static char **usr_status_tab;
-
-#define USR_EX_TEXT "USER-DEFINED"
-
-static const char *
-user_exception_str(unsigned ex)
-{
- size_t num = ex - mf_exception_count;
- if (num >= usr_status_count) {
- size_t nmax = num + 1;
- usr_status_tab = xrealloc(usr_status_tab,
- nmax * sizeof(usr_status_tab[0]));
- memset(usr_status_tab + usr_status_count, 0,
- (nmax - usr_status_count) * sizeof(usr_status_tab[0]));
- usr_status_count = num;
- }
- if (!usr_status_tab[num]) {
- char buf[sizeof(USR_EX_TEXT) + 1 + NUMERIC_BUFSIZE_BOUND];
- snprintf(buf, sizeof buf, USR_EX_TEXT "-%u", ex);
- usr_status_tab[num] = strdup (buf);
- }
- return usr_status_tab[num] ? usr_status_tab[num] : USR_EX_TEXT;
-}
-
-int
-string_to_exception(const char *str, mf_exception *status)
-{
- struct status_tab *sp;
- for (sp = std_status_tab; sp->name; sp++)
- if (strcmp(str, sp->name) == 0) {
- *status = sp->ex;
- return 0;
- }
- return 1;
-}
-
-const char *
-mf_exception_str(unsigned ex)
-{
- struct status_tab *sp;
- for (sp = std_status_tab; sp->name; sp++)
- if (sp->ex == ex)
- return sp->name;
- return user_exception_str(ex);
-}
-
-mf_exception
-mf_status_to_exception(mf_status s)
-{
- switch (s) {
- case mf_success:
- return mfe_success;
-
- case mf_not_found:
- return mfe_not_found;
-
- case mf_failure:
- return mfe_failure;
-
- case mf_temp_failure:
- case mf_timeout:
- return mfe_temp_failure;
- }
- return s;
-}
diff --git a/src/prog.c b/src/prog.c
index 8135b735..0cddc348 100644
--- a/src/prog.c
+++ b/src/prog.c
@@ -59,9 +59,6 @@ struct rt_regex *regtab;
size_t regcount;
struct obstack regstk;
-/* Exceptions */
-size_t exception_count = 0;
-
void
code_init()
@@ -1711,13 +1708,16 @@ instr_throw(eval_environ_t env)
adjust_stack(env, 1);
if (n > exception_count)
runtime_error(env, _("invalid exception number: %lu"), n);
+ if (PROG_TRACE_ENGINE)
+ prog_trace(env, "THROW %s(%ld)", mf_exception_str(n), n);
env_throw_0(env, (mf_status) n, off);
}
void
dump_throw(prog_counter_t i)
{
- printf("%s", mf_exception_str((unsigned)prog[i]));
+ printf("%s (%u)", mf_exception_str((unsigned)prog[i]),
+ (unsigned)prog[i]);
}
@@ -2185,7 +2185,7 @@ env_throw_0(eval_environ_t env, mf_exception status, size_t off)
prog_counter_t pc;
if (status > exception_count)
- runtime_error(env, "unknown exception: %d", status);
+ runtime_error(env, _("unknown exception: %d"), status);
pc = env->catch_ctx[status].pc;
if (pc) {
@@ -2202,7 +2202,9 @@ env_throw_0(eval_environ_t env, mf_exception status, size_t off)
env_make_frame(env);
longjmp(env->catch_jmp, 1);
}
- runtime_error(env, "%s", (char*) env_data_ref(env, off));
+ runtime_error(env, _("uncaught exception %s: %s"),
+ mf_exception_str(status),
+ (char*) env_data_ref(env, off));
}
void
diff --git a/src/prog.h b/src/prog.h
index 7bcf62fe..92ba31f0 100644
--- a/src/prog.h
+++ b/src/prog.h
@@ -91,6 +91,7 @@ extern unsigned long prog_trace_option;
extern STKVAL *dataseg;
extern size_t datasize;
extern size_t dvarsize;
+#define EXTABIND (datasize - exception_count)
extern size_t *dataseg_reloc;
extern size_t dataseg_reloc_count;
diff --git a/src/symbols.c b/src/symbols.c
index 0a4494f2..83339e66 100644
--- a/src/symbols.c
+++ b/src/symbols.c
@@ -928,7 +928,7 @@ literal_lookup(const char *text)
}
-void
+const struct constant *
define_constant(const char *name, struct value *value, unsigned flags,
struct locus *locus)
{
@@ -959,6 +959,7 @@ define_constant(const char *name, struct value *value, unsigned flags,
cp->sym.locus = *locus;
cp->sym.flags = flags;
cp->value = *value;
+ return cp;
}
const struct constant *
diff --git a/tests/eof.at b/tests/eof.at
index 1c829f8e..7064ffd4 100644
--- a/tests/eof.at
+++ b/tests/eof.at
@@ -44,7 +44,7 @@ done
[1: Subtlety is the art of saying
2: what you think and getting out
3: of the way before it is understood.
-mailfromd: RUNTIME ERROR near prog:9: getline: EOF on infile
+mailfromd: RUNTIME ERROR near prog:9: uncaught exception e_eof: getline: EOF on infile
])
AT_CLEANUP
diff --git a/tests/hdr-gete.at b/tests/hdr-gete.at
index f30fcf04..5c1f5ed7 100644
--- a/tests/hdr-gete.at
+++ b/tests/hdr-gete.at
@@ -28,7 +28,7 @@ done
[hdr.mts],
[0],
[],
-[mailfromd#1: RUNTIME ERROR near filter:5: current_header: requested item (Received,3) not found
+[mailfromd#1: RUNTIME ERROR near filter:5: uncaught exception e_not_found: current_header: requested item (Received,3) not found
mailfromd#1: execution of the filter program was not finished
])
])

Return to:

Send suggestions and report system problems to the System administrator.