diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2011-03-01 14:10:12 +0200 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2011-03-01 14:18:38 +0200 |
commit | dfb2a4fb8358c12816e120b16607b272697e20be (patch) | |
tree | cd9f89cd64d5f93e1f7247f72baa620453462823 | |
parent | f1b7f42ce6d83a8e37d5b836c7d801afb2b18c43 (diff) | |
download | mailfromd-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.awk | 12 | ||||
-rw-r--r-- | src/Makefile.am | 3 | ||||
-rw-r--r-- | src/exclist.c | 103 | ||||
-rw-r--r-- | src/gram.y | 19 | ||||
-rw-r--r-- | src/mailfromd.h | 14 | ||||
-rw-r--r-- | src/main.c | 1 | ||||
-rw-r--r-- | src/mf-status.c | 100 | ||||
-rw-r--r-- | src/prog.c | 14 | ||||
-rw-r--r-- | src/prog.h | 1 | ||||
-rw-r--r-- | src/symbols.c | 3 | ||||
-rw-r--r-- | tests/eof.at | 2 | ||||
-rw-r--r-- | tests/hdr-gete.at | 2 |
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; +} + @@ -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); + + @@ -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; -} @@ -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 @@ -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 ]) ]) |