diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2011-03-09 11:00:12 +0200 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2011-03-09 11:47:52 +0200 |
commit | 30dfac6b8bc411481c9dd333bd8baab9e15c2d00 (patch) | |
tree | 08209280450a3c569f6d57088f97db482f956d40 /src/main.c | |
parent | fedbf1d7be7a92ae10bd2e2c05f0bf5c10b933ce (diff) | |
download | mailfromd-30dfac6b8bc411481c9dd333bd8baab9e15c2d00.tar.gz mailfromd-30dfac6b8bc411481c9dd333bd8baab9e15c2d00.tar.bz2 |
Fix deferred variable initialization.
The bug was spotted by Brian Kroth.
* src/gram.y (deferred_decl) <locus>: New member.
(defer_initialize_variable): Use string_alloc
instead of literal_lookup. Take additional argument (ptr to locus). All
uses updated.
(apply_deferred_init): Pass a ptr to the actual locus to initialize_variable.
* src/mailfromd.h (defer_initialize_variable): Change signature.
* src/main.c (cb_set_variable): Deduce definition location from
mu_strerr.
* THANKS: Update.
* tests/setvar.at: New testcase.
* tests/Makefile.am (TESTSUITE_AT): Add setvar.at.
* tests/testsuite.at: Include setvar.at.
* tests/invcidr.at: Update experr.
* tests/invcidr2.at: Likewise.
Diffstat (limited to 'src/main.c')
-rw-r--r-- | src/main.c | 28 |
1 files changed, 24 insertions, 4 deletions
@@ -541,32 +541,33 @@ parse_opt(int key, char *arg, struct argp_state *state) if (test_state == smtp_state_none) argp_error(state, _("unknown smtp state tag: %s"), arg); } log_stream = "stderr"; need_script = 1; break; case 'v': { char *p; + struct locus locus = { "<command line>", 1, 0 }; p = strchr(arg, '='); if (!p) argp_error(state, _("expected assignment, but found `%s'"), arg); *p++ = 0; - defer_initialize_variable(arg, p); + defer_initialize_variable(arg, p, &locus); break; } case OPTION_DAEMON: mode = MAILFROMD_DAEMON; need_script = 1; break; case OPTION_DOMAIN_FILE: mf_optcache_set_option("relay", arg); break; @@ -707,25 +708,27 @@ cb_timeout(void *data, mu_config_value_t *arg) struct timeval tv; int rc = config_cb_timeout (&tv, arg); if (rc == 0) *(time_t*) data = tv.tv_sec; return rc; } static int cb_set_variable(void *data, mu_config_value_t *arg) { const char *value; char *alloc_str = NULL; - + struct mu_locus mloc; + struct locus locus; + if (mu_cfg_assert_value_type(arg, MU_CFG_ARRAY)) return 1; if (arg->v.arg.c < 2) { mu_error(_("not enough arguments")); return 1; } else if (arg->v.arg.c > 2) { mu_error(_("too many arguments")); return 1; } if (mu_cfg_assert_value_type(&arg->v.arg.v[0], MU_CFG_STRING)) return 1; @@ -740,26 +743,43 @@ cb_set_variable(void *data, mu_config_value_t *arg) value = alloc_str; break; case MU_CFG_LIST: mu_error(_("unexpected list")); return 1; default: mu_error (_("INTERNAL ERROR at %s:%d: please report"), __FILE__, __LINE__); abort(); } - - defer_initialize_variable(arg->v.arg.v[0].v.string, value); + + locus.leng = 0; + if (mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM, + MU_IOCTL_LOGSTREAM_GET_LOCUS, &mloc)) { + locus.file = "<unknown>"; + locus.line = 0; + locus.point = 0; + } else { + if (mloc.mu_file) { + struct literal *lit = string_alloc(mloc.mu_file, + strlen(mloc.mu_file)); + free(mloc.mu_file); + locus.file = lit->text; + } else + locus.file = "<unknown>"; + locus.line = mloc.mu_line; + locus.point = mloc.mu_col; + } + defer_initialize_variable(arg->v.arg.v[0].v.string, value, &locus); free(alloc_str); return 0; } static int cb_include_path(void *data, mu_config_value_t *val) { int i, rc = 0; struct mu_wordsplit ws; mu_iterator_t itr; switch (val->type) { |