diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2009-10-05 23:14:08 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2009-10-05 23:14:08 +0300 |
commit | 7cba7905432f55ff89c014329f7bf7f929855463 (patch) | |
tree | d53f27e3f499abf66a8c07062805e73a1f560776 | |
parent | b4e793c632902e8dbd93bf8023cfc3a8631afb4e (diff) | |
download | mailfromd-7cba7905432f55ff89c014329f7bf7f929855463.tar.gz mailfromd-7cba7905432f55ff89c014329f7bf7f929855463.tar.bz2 |
Improve fixup script generation.
* mfd/deprecation.c (open_change_conf)
(close_change_conf): Remove.
(write_db_config, write_db_config, write_change_conf): Rewrite.
(add_fixup_command, add_fixup_command_fmt)
(add_fixup_command_locus): New functions.
(fixup_create_script): New functions.
* mfd/gram.y: Issue fix-up statements for every deprecation
warning.
* mfd/lex.l ({IDENT} rule): update locus.point along
with each call to input and unput.
* mfd/mailfromd.h (parse_require): Take locus as the 2nd
parameter.
(open_change_conf,close_change_conf): Remove.
(fixup_op): New enumeration.
(add_fixup_command,add_fixup_command_fmt)
(add_fixup_command_locus, fixup_create_script): New functions.
* mfd/main.c (set_option): Update.
(main): Call fixup_create_script instead of close_change_conf.
* mfd/pp.c (parse_require): Issue a fixup statement.
-rw-r--r-- | mfd/deprecation.c | 589 | ||||
-rw-r--r-- | mfd/engine.c | 1 | ||||
-rw-r--r-- | mfd/gram.y | 23 | ||||
-rw-r--r-- | mfd/lex.l | 9 | ||||
-rw-r--r-- | mfd/mailfromd.h | 27 | ||||
-rw-r--r-- | mfd/main.c | 12 | ||||
-rw-r--r-- | mfd/pp.c | 10 |
7 files changed, 479 insertions, 192 deletions
diff --git a/mfd/deprecation.c b/mfd/deprecation.c index be4d0607..bbf069a0 100644 --- a/mfd/deprecation.c +++ b/mfd/deprecation.c @@ -76,233 +76,443 @@ final_deprecation_warning() } -static FILE *change_conf_fp; -static size_t change_conf_deletes; -static int rename_legacy_file; +struct db_statement { + struct db_statement *next; + char *name; + struct obstack obstack; +}; +static struct db_statement *dbhead, *dbtail; -extern enum mu_cfg_param_data_type config_statement_type(const char *name); +static struct db_statement * +find_db_statement(const char *name) +{ + struct db_statement *p; + for (p = dbhead; p; p = p->next) + if (strcmp(p->name, name) == 0) + return p; -int -open_change_conf() + p = xmalloc(sizeof(*p)); + p->next = NULL; + obstack_init(&p->obstack); + obstack_grow(&p->obstack, name, strlen(name)); + obstack_1grow(&p->obstack, 0); + p->name = obstack_finish(&p->obstack); + obstack_grow(&p->obstack, "database ", 9); + obstack_grow(&p->obstack, name, strlen(name)); + obstack_grow(&p->obstack, " {\n", 3); + if (!dbhead) + dbhead = p; + else + dbtail->next = p; + dbtail = p; + return p; +} + + +void +write_db_config(const char *name, const char *stmt, const char *value) { - if (change_conf_fp) - return 0; - change_conf_fp = tmpfile(); - if (change_conf_fp == NULL) - return 1; - return 0; + struct db_statement *dbs = find_db_statement(name); + obstack_grow(&dbs->obstack, " ", 4); + obstack_grow(&dbs->obstack, stmt, strlen(stmt)); + obstack_1grow(&dbs->obstack, ' '); + obstack_grow(&dbs->obstack, value, strlen(value)); + obstack_grow(&dbs->obstack, ";\n", 2); } + +static int fixup_opweight[] = { + 0, /* fixup_noop */ + 90, /* fixup_delete_line */ + 91, /* fixup_insert_line */ + 92, /* fixup_append_line */ + 93, /* fixup_replace_line */ + 0, /* fixup_delete_chars */ + 1, /* fixup_insert_chars */ + 2, /* fixup_replace_chars */ + 100, /* fixup_rename_file */ + 1000 /* fixup_end */ +}; + +struct fixup_cmd { + enum fixup_op opcode; + mf_yyltype_t locus; + char *arg; +}; + +static struct obstack fixup_stk; +static struct obstack fixup_literal_stk; +static size_t fixup_cnt; + void -write_change_conf(const char *confkw, const char *value) +add_fixup_command(enum fixup_op opcode, mf_yyltype_t *locus, char *arg) { - enum mu_cfg_param_data_type type = config_statement_type (confkw); - const struct locus *loc = get_locus(); - - fprintf(change_conf_fp, - "D %lu %s\n", loc->line, loc->file); - fprintf(change_conf_fp, "C %s ", confkw); - switch (MU_CFG_TYPE(type)) { - case mu_cfg_string: - case mu_cfg_callback: - fprintf(change_conf_fp, "\"%s\"", value); - break; + struct fixup_cmd cmd; - default: - fprintf(change_conf_fp, "%s", value); + if (!enable_deprecation_warnings()) + return; + if (opcode < 0 || opcode > fixup_end) + abort(); + if (fixup_cnt == 0) { + obstack_init(&fixup_stk); + obstack_init(&fixup_literal_stk); } - fprintf(change_conf_fp, ";\n"); - change_conf_deletes++; + cmd.opcode = opcode; + if (locus) + cmd.locus = *locus; + else + memset(&cmd.locus, 0, sizeof(cmd.locus)); + cmd.arg = arg; + obstack_grow(&fixup_stk, &cmd, sizeof(cmd)); + fixup_cnt++; } void -write_db_config(const char *name, const char *stmt, const char *value) +add_fixup_command_fmt(enum fixup_op opcode, mf_yyltype_t *locus, + const char *fmt, ...) { - if (open_change_conf() == 0) { - const struct locus *loc = get_locus(); - - fprintf(change_conf_fp, - "D %lu %s\n", loc->line, loc->file); - fprintf(change_conf_fp, "G %s %s %s;\n", name, stmt, value); - change_conf_deletes++; - } + va_list ap; + char *str; + va_start(ap, fmt); + vasprintf(&str, fmt, ap); + va_end(ap); + obstack_grow(&fixup_literal_stk, str, strlen(str)); + obstack_1grow(&fixup_literal_stk, 0); + free(str); + add_fixup_command(opcode, locus, obstack_finish(&fixup_literal_stk)); +} + +void +add_fixup_command_locus(enum fixup_op opcode, const struct locus *beg, + char *arg) +{ + mf_yyltype_t locus; + locus.beg = *beg; + add_fixup_command(opcode, &locus, arg); } static int -loc_cmp(const void *a, const void *b) +fixup_cmd_comp(const void *a, const void *b) { - const struct locus *la = a; - const struct locus *lb = b; - int rc = strcmp(la->file, lb->file); + const struct fixup_cmd *acmd = a; + const struct fixup_cmd *bcmd = b; + int rc; - if (rc == 0) { - if (la->line > lb->line) + if (acmd->opcode == fixup_end) + return 1; + else if (bcmd->opcode == fixup_end) + return -1; + rc = strcmp(acmd->locus.beg.file, bcmd->locus.beg.file); + if (rc) + return rc; + + if (acmd->opcode != bcmd->opcode) + return fixup_opweight[acmd->opcode] - + fixup_opweight[bcmd->opcode]; + + switch (acmd->opcode) { + case fixup_delete_line: + case fixup_replace_line: + if (acmd->locus.beg.line > bcmd->locus.beg.line) rc = -1; - else if (la->line < lb->line) + else if (acmd->locus.beg.line < bcmd->locus.beg.line) rc = 1; + else + rc = 0; + break; + + case fixup_insert_line: + case fixup_delete_chars: + case fixup_insert_chars: + case fixup_replace_chars: + if (acmd->locus.beg.line > bcmd->locus.beg.line) + rc = 1; + else if (acmd->locus.beg.line < bcmd->locus.beg.line) + rc = -1; + else if (acmd->locus.beg.point > bcmd->locus.beg.point) + rc = -1; + else if (acmd->locus.beg.point < bcmd->locus.beg.point) + rc = 1; + else + rc = 0; + break; + + case fixup_append_line: + case fixup_rename_file: + case fixup_end: + case fixup_noop: + rc = 0; } return rc; } -struct db_statement { - struct db_statement *next; - char *name; - struct obstack obstack; -}; +static void +fprint_ml(FILE *fp, const char *arg) +{ + /* FIXME: Quote (escape) arg */ + while (*arg) { + int len = strcspn(arg, "\n"); + fwrite(arg, len, 1, fp); + arg += len; + if (*arg) { + fprintf(fp, "\\\n"); + arg++; + } + } +} -static struct db_statement * -find_db_statement(struct db_statement **phead, struct db_statement **ptail, - const char *name, size_t len) +void +format_fixup_cmd(FILE *fp, const struct fixup_cmd *cmd) { - struct db_statement *p; - for (p = *phead; p; p = p->next) - if (strncmp(p->name, name, len) == 0) - return p; + switch (cmd->opcode) { + case fixup_delete_line: + fprintf(fp, "%lud\n", (unsigned long) cmd->locus.beg.line); + break; - p = xmalloc(sizeof(*p)); - p->next = NULL; - p->name = xmalloc(len + 1); - memcpy(p->name, name, len); - p->name[len] = 0; - obstack_init(&p->obstack); - if (!*phead) - *phead = p; - else - (*ptail)->next = p; - *ptail = p; - return p; + case fixup_insert_line: + fprintf(fp, "%lui\\\n", (unsigned long) cmd->locus.beg.line); + fprint_ml(fp, cmd->arg); + fprintf(fp, "\n"); + break; + + case fixup_append_line: + fprintf(fp, "$a\\\n"); + fprint_ml(fp, cmd->arg); + fprintf(fp, "\n"); + break; + + case fixup_replace_line: + fprintf(fp, "%luc\\\n", cmd->locus.beg.line); + fprint_ml(fp, cmd->arg); + fprintf(fp, "\n"); + break; + + case fixup_delete_chars: + fprintf(fp, "%lus/\\(.\\{%lu\\}\\)\\(.\\{%lu\\}\\)\\(.*\\)/\\1\\3/\n", + cmd->locus.beg.line, + cmd->locus.beg.point, + cmd->locus.end.point - cmd->locus.beg.point); + break; + + case fixup_insert_chars: + fprintf(fp, "%lus/\\(.\\{%lu\\}\\)\\(.*\\)/\\1%s\\2/\n", + cmd->locus.beg.line, + cmd->locus.beg.point, + cmd->arg); + break; + + case fixup_replace_chars: + fprintf(fp, "%lus/\\(.\\{%lu\\}\\)\\(.\\{%lu\\}\\)\\(.*\\)/\\1%s\\3/\n", + cmd->locus.beg.line, + cmd->locus.beg.point, + cmd->locus.end.point - cmd->locus.beg.point, + cmd->arg); + break; + + case fixup_noop: + case fixup_rename_file: + case fixup_end: + break; + } } -void -close_change_conf() + +static void +condense_append_line(struct fixup_cmd *cmd, size_t start, size_t *pend) { - size_t size = 0; - char *buf = NULL; - char *p; + size_t i; const char *last_file; - size_t len; - struct locus *locus; - int i; - FILE *fp; - const char *script_name = rename_legacy_file ? - LEGACY_SCRIPT_FILE : DEFAULT_SCRIPT_FILE; - const char *file_name = "/tmp/mailfromd-newconf.sh"; - struct db_statement *dcg_head = NULL, *dcg_tail = NULL, *dcg; - time_t now = time(NULL); - if (!change_conf_fp) + if (cmd[start+1].opcode != fixup_append_line) { + *pend = start+1; return; + } + last_file = cmd[start].locus.beg.file; + for (i = start; i < fixup_cnt; i++) { + if (cmd[i].opcode != fixup_append_line + || strcmp(cmd[i].locus.beg.file, last_file)) + break; + if (i > start) + obstack_1grow(&fixup_literal_stk, '\n'); + obstack_grow(&fixup_literal_stk, cmd[i].arg, + strlen(cmd[i].arg)); + cmd[i].opcode = fixup_noop; + } + obstack_1grow(&fixup_literal_stk, 0); + cmd[start].opcode = fixup_append_line; + cmd[start].arg = obstack_finish(&fixup_literal_stk); + *pend = i; +} - fp = fopen(file_name, "w"); - if (fp) { - mu_diag_output(MU_DIAG_INFO, - _("run script %s to fix the above warnings"), - file_name); - } else - fp = stdout; - locus = xcalloc(change_conf_deletes, sizeof(locus[0])); - fseek(change_conf_fp, 0, SEEK_SET); +/* Condense fixup_append_lines */ +static void +condense_all_appends(struct fixup_cmd *cmd) +{ + size_t i; + for (i = 0; i < fixup_cnt; i++) { + if (cmd[i].opcode == fixup_end) + break; + if (cmd[i].opcode == fixup_append_line) + condense_append_line(cmd, i, &i); + else + i++; + } +} + +static void +append_db_stmts() +{ + struct db_statement *p; + for (p = dbhead; p; p = p->next) { + struct locus locus; + + locus.file = mu_app_rcfile; + obstack_grow(&p->obstack, "}\n", 3); + add_fixup_command_locus(fixup_append_line, &locus, + obstack_finish(&p->obstack)); + } +} + +static void +free_db_stmts() +{ + while (dbhead) { + struct db_statement *next = dbhead->next; + obstack_free(&dbhead->obstack, NULL); + free(dbhead); + dbhead = next; + } +} + +static void +script_prologue(FILE *fp) +{ + time_t now; fprintf(fp, "#! /bin/sh\n"); fprintf(fp, "# Conversion script created by mailfromd on %s", ctime (&now)); fprintf(fp, "# Run this script to fix mailfromd deprecation warnings\n\n"); fprintf(fp, - "set -e\n" + "set -e\n\n" "if test -r " DEFAULT_CONFIG_FILE " ; then\n" " echo >&2 \"$0: " DEFAULT_CONFIG_FILE " already exists\"\n" " exit 1\n" - "fi\n" - "if ! test -r %s ; then\n" - " echo >&2 \"$0: %s does not exist\"\n" - " exit 1\n" - "fi\n" - "if test %s -nt $0; then\n" - " echo >&2 \"$0: %s is updated, re-run mailfromd --lint\"\n" - " exit 1\n" - "fi\n", - script_name, - script_name, - script_name, - script_name); - fprintf(fp, "# 1. Create new configuration file\n"); - fprintf(fp, "cat > %s <<'EOT'\n", DEFAULT_CONFIG_FILE); - i = 0; - while (getline(&buf, &size, change_conf_fp) > 0) { - switch (buf[0]) { - case 'D': - locus[i].line = strtoul(buf+1, &p, 0); - p++; - len = strlen(p); - p[len-1] = 0; - locus[i].file = xstrdup(p); - i++; - break; + "fi\n"); - case 'G': - p = strchr (buf+2, ' '); - dcg = find_db_statement(&dcg_head, &dcg_tail, - buf + 2, p - buf - 2); - obstack_grow (&dcg->obstack, " ", 2); - obstack_grow (&dcg->obstack, p + 1, strlen (p + 1)); - break; - - case 'C': - fprintf(fp, "%s", buf+2); - } - } + fprintf(fp, + "modfiles=\n" + "script=newconf.$$\n" + "trap \"rm -f $script\" 1 2 13 15\n"); +} +char script_epilogue[] = "\ +rm -f $script\n\ +set -- $modfiles\n\ +while test $# -ne 0\n\ +do\n\ + orig=$1\n\ + shift\n\ + file=$1\n\ + shift\n\ + mv $orig $orig.bak\n\ + mv $orig.tmp $file\n\ +done\n"; - for (dcg = dcg_head; dcg;) { - struct db_statement *next = dcg->next; - fprintf(fp, "database %s {\n", dcg->name); - obstack_1grow (&dcg->obstack, 0); - p = obstack_finish(&dcg->obstack); - fprintf(fp, "%s", p); - fprintf(fp, "}\n"); - obstack_free(&dcg->obstack, NULL); - free(dcg->name); - free(dcg); - dcg = next; - } - fprintf(fp, "EOT\n"); - fclose(change_conf_fp); - free(buf); - - fprintf(fp, "#\n# 2. Fix existing script file(s)\n"); - qsort(locus, change_conf_deletes, sizeof(locus[0]), loc_cmp); - - last_file = NULL; - for (i = 0; i < change_conf_deletes; i++) { - if (last_file == NULL || strcmp(locus[i].file, last_file)) { - if (last_file) - fprintf(fp, "' %s.tmp > %s\n", - last_file, last_file); - last_file = locus[i].file; - fprintf(fp, "mv %s %s.tmp\n", +void +fixup_create_script() +{ + struct fixup_cmd *cmd, *cmdbase; + size_t i; + FILE *fp; + const char *file_name = "/tmp/mailfromd-newconf.sh"; + const char *last_file; + const char *new_name; + + if (fixup_cnt == 0) + return; + + fp = fopen(file_name, "w"); + if (fp) { + mu_diag_output(MU_DIAG_INFO, + _("run script %s to fix the above warnings"), + file_name); + } else + fp = stdout; + + append_db_stmts(); + add_fixup_command(fixup_end, NULL, NULL); + cmdbase = obstack_finish(&fixup_stk); + qsort(cmdbase, fixup_cnt, sizeof(*cmd), fixup_cmd_comp); + + condense_all_appends(cmdbase); + + script_prologue(fp); + + new_name = NULL; + last_file = cmdbase->locus.beg.file; + fprintf(fp, "#\n# Fix %s\n#\n", last_file); + fprintf(fp, "cat > $script <<'EOT'\n"); + for (i = 0, cmd = cmdbase; i < fixup_cnt; i++, cmd++) { + if (cmd->opcode == fixup_end + || strcmp(cmd->locus.beg.file, last_file)) { + + /* Terminate current here-document */ + fprintf(fp, "EOT\n"); + + /* Check if the last_file has not been modified + in between */ + fprintf(fp, + "if test %s -nt $0; then\n" + " echo >&2 \"$0: %s is updated, re-run mailfromd --lint\"\n" + " exit 1\n" + "fi\n", last_file, last_file); - fprintf(fp, "sed '"); + + /* Modify the file */ + fprintf(fp, "test -r %s || " + "echo \"# File generated by $0 on `date`\" > %s\n", + last_file, last_file); + fprintf(fp, "sed -f $script < %s > %s.tmp\n", + last_file, last_file); + fprintf(fp, "if cmp %s %s.tmp >/dev/null 2>&1; then\n", + last_file, last_file); + fprintf(fp, " rm %s.tmp\n", last_file); + fprintf(fp, "else\n modfiles=\"$modfiles %s %s\"\nfi\n", + last_file, new_name ? new_name : last_file); + + if (cmd->opcode == fixup_end) + break; + new_name = NULL; + last_file = cmd->locus.beg.file; + fprintf(fp, "#\n# Fix %s\n#\n", last_file); + fprintf(fp, "cat > $script <<'EOT'\n"); } - fprintf(fp, "%lud;", locus[i].line); - } - fprintf(fp, "' %s.tmp > %s\n", last_file, last_file); - if (rename_legacy_file) { - fprintf(fp, "#\n# 3. Rename script file\n"); - fprintf(fp, "mv %s %s\n", - LEGACY_SCRIPT_FILE, DEFAULT_SCRIPT_FILE); + if (cmd->opcode == fixup_rename_file) + new_name = cmd->arg; + else + format_fixup_cmd(fp, cmd); } + + fprintf(fp, "#\n# Flush changes\n#\n"); + fprintf(fp, "%s\n", script_epilogue); fprintf(fp, "# EOF\n"); - fclose(fp); + fclose(fp); - for (i = 0; i < change_conf_deletes; i++) - free((char*)locus[i].file); - free(locus); + /* Free allocated memory */ + obstack_free(&fixup_stk, NULL); + obstack_free(&fixup_literal_stk, NULL); + free_db_stmts(); } + + void legacy_script_warning() { + mf_yyltype_t locus; + mu_diag_output(MU_DIAG_WARNING, _("using legacy script file %s"), LEGACY_SCRIPT_FILE); @@ -310,5 +520,42 @@ legacy_script_warning() _("rename it to %s or use script-file statement in %s to disable this warning"), DEFAULT_SCRIPT_FILE, DEFAULT_CONFIG_FILE); - rename_legacy_file = 1; + memset(&locus, 0, sizeof(locus)); + locus.beg.file = LEGACY_SCRIPT_FILE; + add_fixup_command(fixup_rename_file, &locus, DEFAULT_SCRIPT_FILE); } + +extern enum mu_cfg_param_data_type config_statement_type(const char *name); + +void +write_change_conf(const char *confkw, const char *value) +{ + enum mu_cfg_param_data_type type = config_statement_type(confkw); + mf_yyltype_t locus; + char *arg; + + locus.beg = *get_locus(); + + add_fixup_command(fixup_delete_line, &locus, NULL); + + memset(&locus, 0, sizeof(locus)); + locus.beg.file = mu_app_rcfile; + + switch (MU_CFG_TYPE(type)) { + case mu_cfg_string: + case mu_cfg_callback: + asprintf(&arg, "%s \"%s\";", confkw, value); + break; + + default: + asprintf(&arg, "%s %s;", confkw, value); + break; + } + + obstack_grow(&fixup_literal_stk, arg, strlen(arg)); + obstack_1grow(&fixup_literal_stk, 0); + free(arg); + arg = obstack_finish(&fixup_literal_stk); + add_fixup_command(fixup_append_line, &locus, arg); +} + diff --git a/mfd/engine.c b/mfd/engine.c index 48af651e..13075fa5 100644 --- a/mfd/engine.c +++ b/mfd/engine.c @@ -1577,7 +1577,6 @@ save_cmdline(int argc, char **argv) x_argv[i] = NULL; } - static RETSIGTYPE sig_stop(int sig) { @@ -601,7 +601,8 @@ require : T_REQUIRE literal } | T_SHARPREQR { - parse_require($1); + deprecation_warning(_("#require is deprecated, use `require' or `from ... import' instead")); + parse_require($1, &@1); } ; @@ -1739,6 +1740,8 @@ concat_expr: simp_expr _("implicit concatenation is deprecated")); deprecation_warning_locus(&@2.beg, _("use `.' operator")); + add_fixup_command_locus(fixup_insert_chars, + &@2.beg, ". "); $$ = alloc_node(node_type_concat, &@1.beg); } $$->v.concat.arg[0] = cast_to(dtype_string, $1); @@ -1962,6 +1965,8 @@ funcall : T_BUILTIN '(' arglist ')' | T_BUILTIN_P expr { deprecation_warning(_("use of function name as a prefix operator is deprecated")); + add_fixup_command_locus(fixup_insert_chars, &@2.beg, "("); + add_fixup_command_locus(fixup_insert_chars, &@2.end, ")"); if (check_builtin_usage($1)) YYERROR; if ($1->parmcount - $1->optcount > 1) { @@ -2002,6 +2007,8 @@ funcall : T_BUILTIN '(' arglist ')' | T_FUNCTION_P expr { deprecation_warning(_("use of function name as a prefix operator is deprecated")); + add_fixup_command_locus(fixup_insert_chars, &@2.beg, "("); + add_fixup_command_locus(fixup_insert_chars, &@2.end, ")"); if (check_func_usage($1, &@1.beg)) YYERROR; $$ = function_call($1, 1, $2); @@ -2050,8 +2057,13 @@ proccall : T_BUILTIN_PROC '(' arglist ')' } | T_BUILTIN_PROC expr { - if (!paren_follows) + if (!paren_follows) { deprecation_warning(_("use of function name as a prefix operator is deprecated")); + add_fixup_command_locus(fixup_insert_chars, + &@2.beg, "("); + add_fixup_command_locus(fixup_insert_chars, + &@2.end, ")"); + } if (check_builtin_usage($1)) YYERROR; if ($1->parmcount - $1->optcount > 1) { @@ -2091,8 +2103,13 @@ proccall : T_BUILTIN_PROC '(' arglist ')' } | T_FUNCTION_PROC expr { - if (!paren_follows) + if (!paren_follows) { deprecation_warning(_("use of function name as a prefix operator is deprecated")); + add_fixup_command_locus(fixup_insert_chars, + &@2.beg, "("); + add_fixup_command_locus(fixup_insert_chars, + &@2.end, ")"); + } if (check_func_usage($1, &@1.beg)) YYERROR; $$ = function_call($1, 1, $2); @@ -491,7 +491,6 @@ ICONST {LOCUS}|{VCONST}|{STATEDIR}|{PREPROC} parse_include(yytext, 0); } ^[ \t]*#[ \t]*require[ \t].*\n { - deprecation_warning(_("#require is deprecated, use `require' or `from ... import' instead")); /* parse_require cannot be called directly from lexer to avoid switching module context in the middle of grammar rule. */ yylval.string = yytext; @@ -586,7 +585,7 @@ bye return T_BYE; <ML,CML,STR>\%\{({ICONST})\} { compose_add_builtin_const(yytext + 2, yyleng - 3); } -<INITIAL,ONBLOCK>\%{IDENT} { +<INITIAL,ONBLOCK>\%{IDENT} { string(yytext + 1, yyleng - 1); return variable_or_const(); } @@ -671,12 +670,14 @@ bye return T_BYE; if (state != is_ident) { int c; - while ((c = input()) && c_isascii(c) && c_isspace(c)) + while ((locus.point++, c = input()) + && c_isascii(c) && c_isspace(c)) if (c == '\n') advance_line(); - + paren_follows = (c == '('); unput(c); + locus.point--; } if (state == is_builtin) diff --git a/mfd/mailfromd.h b/mfd/mailfromd.h index 769f1e45..a5c483c8 100644 --- a/mfd/mailfromd.h +++ b/mfd/mailfromd.h @@ -789,7 +789,7 @@ int preprocess_input(void); void require_module(const char *modname, struct import_rule *import_rules); int parse_include(const char *text, int once); -int parse_require(const char *text); +int parse_require(const char *text, mf_yyltype_t *loc); int parse_line(char *text, struct locus *ploc); void parse_line_cpp(char *text, struct locus *ploc); void alloc_ext_pp(void); @@ -1067,7 +1067,28 @@ void deprecation_warning_locus(const struct locus *locus, const char *fmt, ...) void final_deprecation_warning(void); int enable_deprecation_warnings(void); void legacy_script_warning(void); -int open_change_conf(void); + +enum fixup_op +{ + fixup_noop, + fixup_delete_line, + fixup_insert_line, + fixup_append_line, + fixup_replace_line, + fixup_delete_chars, + fixup_insert_chars, + fixup_replace_chars, + fixup_rename_file, + fixup_end +}; + +void add_fixup_command(enum fixup_op opcode, mf_yyltype_t *locus, char *arg); +void add_fixup_command_fmt(enum fixup_op opcode, mf_yyltype_t *locus, + const char *fmt, ...) + MU_PRINTFLIKE(3,4); +void add_fixup_command_locus(enum fixup_op opcode, const struct locus *locus, + char *arg); +void fixup_create_script(void); void write_change_conf(const char *confkw, const char *value); void write_db_config(const char *name, const char *stmt, const char *value); -void close_change_conf(void); + @@ -886,12 +886,10 @@ set_option(char *name, char *value, int override, int pragma) deprecation_warning(_("this pragma is deprecated: " "use %s configuration statement instead"), p->confkw); - if (open_change_conf() == 0) { - if (p->conffn) - p->conffn(p->confkw, value); - else - write_change_conf(p->confkw, value); - } + if (p->conffn) + p->conffn(p->confkw, value); + else + write_change_conf(p->confkw, value); } if (!(p->flags & MFD_OPTION_CUMULATIVE) && !override && p->value) @@ -2467,7 +2465,7 @@ main(int argc, char **argv) if (parse_program(script_file, script_ydebug)) exit(EX_CONFIG); } - close_change_conf(); + fixup_create_script(); process_options(); fixup_state_dir_names(); @@ -217,7 +217,7 @@ parse_include(const char *text, int once) #define DEFAULT_SUFFIX ".mf" int -parse_require(const char *text) +parse_require(const char *text, mf_yyltype_t *loc) { int argc; char **argv; @@ -225,7 +225,7 @@ parse_require(const char *text) char *p = NULL; char *modname; int rc = 1; - + if (mu_argcv_get(text, "", NULL, &argc, &argv)) parse_error(_("cannot parse require line")); else if (argc != 2) @@ -270,8 +270,12 @@ parse_require(const char *text) advance_line(); - if (p) + if (p) { rc = begin_module(modname, p, NULL); + add_fixup_command_fmt(fixup_replace_line, loc, + "require \"%s\"", modname); + } + free(tmp); free(modname); mu_argcv_free(argc, argv); |