aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2009-10-05 23:14:08 +0300
committerSergey Poznyakoff <gray@gnu.org.ua>2009-10-05 23:14:08 +0300
commit7cba7905432f55ff89c014329f7bf7f929855463 (patch)
treed53f27e3f499abf66a8c07062805e73a1f560776
parentb4e793c632902e8dbd93bf8023cfc3a8631afb4e (diff)
downloadmailfromd-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.c589
-rw-r--r--mfd/engine.c1
-rw-r--r--mfd/gram.y23
-rw-r--r--mfd/lex.l9
-rw-r--r--mfd/mailfromd.h27
-rw-r--r--mfd/main.c12
-rw-r--r--mfd/pp.c10
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)
{
diff --git a/mfd/gram.y b/mfd/gram.y
index 08881574..dd527b71 100644
--- a/mfd/gram.y
+++ b/mfd/gram.y
@@ -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);
diff --git a/mfd/lex.l b/mfd/lex.l
index b39015b3..46130d12 100644
--- a/mfd/lex.l
+++ b/mfd/lex.l
@@ -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);
+
diff --git a/mfd/main.c b/mfd/main.c
index b78ca6dd..4ae56b85 100644
--- a/mfd/main.c
+++ b/mfd/main.c
@@ -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();
diff --git a/mfd/pp.c b/mfd/pp.c
index 659d4b9c..60df1f1d 100644
--- a/mfd/pp.c
+++ b/mfd/pp.c
@@ -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);

Return to:

Send suggestions and report system problems to the System administrator.