From 3faf6f97adb88ad88aea7fdffb683f737fe5b068 Mon Sep 17 00:00:00 2001 From: Sergey Poznyakoff Date: Tue, 16 Dec 2008 11:54:14 +0000 Subject: Fix sprintf, accidentally broken on 2008-07-14. * mfd/symtab.c (va_builtin_install): Initialize flags to 0. (va_builtin_install_ex): Remove capture and varargs, replace them with flags. * mfd/snarf.m4 (__mf_defun,MF_DEFUN_VARARGS): Reflect changes to va_builtin_install_ex. (MF_DEFUN_VARARGS_NO_PROM): New defun. * mfd/gram.y (cast_arg_list): Add 4th argument, controlling argument type promotion. * mfd/drivers.c (code_type_builtin): Use builtin.flags. * mfd/mailfromd.h (MFD_BUILTIN_*): New defines. (struct builtin): Remove capture and varargs, replace them with flags. * mfd/bi_sprintf.m4: Define sprintf as MF_DEFUN_VARARGS_NO_PROM. git-svn-id: file:///svnroot/mailfromd/trunk@1770 7a8a7f39-df28-0410-adc6-e0d955640f24 --- ChangeLog | 18 ++++++++++++++++++ mfd/bi_sprintf.m4 | 2 +- mfd/drivers.c | 2 +- mfd/gram.y | 29 +++++++++++++++++++---------- mfd/mailfromd.h | 13 ++++++++----- mfd/snarf.m4 | 21 +++++++++++++-------- mfd/symtab.c | 10 ++++------ 7 files changed, 64 insertions(+), 31 deletions(-) diff --git a/ChangeLog b/ChangeLog index a9863dd1..d6a4357b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,21 @@ +2008-12-16 Sergey Poznyakoff + + Fix sprintf, accidentally broken on 2008-07-14. + + * mfd/symtab.c (va_builtin_install): Initialize flags to 0. + (va_builtin_install_ex): Remove capture and varargs, replace them + with flags. + * mfd/snarf.m4 (__mf_defun,MF_DEFUN_VARARGS): Reflect changes to + va_builtin_install_ex. + (MF_DEFUN_VARARGS_NO_PROM): New defun. + * mfd/gram.y (cast_arg_list): Add 4th argument, controlling + argument type promotion. + * mfd/drivers.c (code_type_builtin): Use builtin.flags. + * mfd/mailfromd.h (MFD_BUILTIN_*): New defines. + (struct builtin): Remove capture and varargs, replace them + with flags. + * mfd/bi_sprintf.m4: Define sprintf as MF_DEFUN_VARARGS_NO_PROM. + 2008-12-01 Sergey Poznyakoff Documentation and minor fixes. diff --git a/mfd/bi_sprintf.m4 b/mfd/bi_sprintf.m4 index 65727157..61082d74 100644 --- a/mfd/bi_sprintf.m4 +++ b/mfd/bi_sprintf.m4 @@ -45,7 +45,7 @@ get_num(char *p, unsigned *pn) #define __MF_MAX(a,b) ((a)>(b) ? (a) : (b)) #define SPRINTF_BUF_SIZE (__MF_MAX(3*sizeof(long), NUMERIC_BUFSIZE_BOUND) + 2) -MF_DEFUN_VARARGS(sprintf, STRING, STRING format) +MF_DEFUN_VARARGS_NO_PROM(sprintf, STRING, STRING format) { int i = 0; char *p = format; diff --git a/mfd/drivers.c b/mfd/drivers.c index 5ecaad07..bb6d9e09 100644 --- a/mfd/drivers.c +++ b/mfd/drivers.c @@ -1050,7 +1050,7 @@ code_type_builtin(NODE *node, struct locus **old_locus) /* Pass arguments */ for (p = node->v.builtin.args, i = 0; p; p = p->next, i++) code_node(p); - if (bp->optcount || bp->varargs) { + if (bp->optcount || (bp->flags & MFD_BUILTIN_VARIADIC)) { /* Pass the number of actual arguments in a hidden arg */ code_op(opcode_push); code_immediate((void*)i); diff --git a/mfd/gram.y b/mfd/gram.y index 677bbe57..38cdce07 100644 --- a/mfd/gram.y +++ b/mfd/gram.y @@ -47,7 +47,8 @@ static NODE *declare_function(struct function *func, struct locus *loc, size_t nautos); static data_type_t node_type(NODE *node); static NODE *cast_to(data_type_t type, NODE *node); -static NODE *cast_arg_list(NODE *args, size_t parmc, data_type_t *parmtype); +static NODE *cast_arg_list(NODE *args, size_t parmc, data_type_t *parmtype, + int disable_prom); static void add_xref(struct variable *var, const struct locus *locus); static struct variable *vardecl(const char *name, data_type_t type, storage_class_t sc, struct locus *loc); @@ -269,7 +270,7 @@ check_builtin_usage(const struct builtin *bp) break; } - if (bp->capture) + if (bp->flags & MFD_BUILTIN_CAPTURE) capture_on(); return 0; } @@ -1609,7 +1610,8 @@ funcall : BUILTIN '(' arglist ')' parse_error(_("Too few arguments in call to `%s'"), $1->name); YYERROR; - } else if ($3.count > $1->parmcount && !$1->varargs) { + } else if ($3.count > $1->parmcount + && !($1->flags & MFD_BUILTIN_VARIADIC)) { parse_error(_("Too many arguments in call to `%s'"), $1->name); YYERROR; @@ -1619,7 +1621,8 @@ funcall : BUILTIN '(' arglist ')' $$->v.builtin.args = reverse(cast_arg_list($3.head, $1->parmcount, - $1->parmtype)); + $1->parmtype, + $$->v.builtin.builtin->flags & MFD_BUILTIN_NO_PROMOTE)); } } | BUILTIN '(' ')' @@ -1653,7 +1656,8 @@ funcall : BUILTIN '(' arglist ')' $$->v.builtin.builtin = $1; $$->v.builtin.args = cast_arg_list($2, $1->parmcount, - $1->parmtype); + $1->parmtype, + 0); } } | FUNCTION '(' arglist ')' @@ -1699,7 +1703,8 @@ proccall : BUILTIN_PROC '(' arglist ')' $$->v.builtin.builtin = $1; $$->v.builtin.args = reverse(cast_arg_list($3.head, $1->parmcount, - $1->parmtype)); + $1->parmtype, + 0)); } } | BUILTIN_PROC '(' ')' @@ -1733,7 +1738,8 @@ proccall : BUILTIN_PROC '(' arglist ')' $$->v.builtin.builtin = $1; $$->v.builtin.args = cast_arg_list($2, $1->parmcount, - $1->parmtype); + $1->parmtype, + 0); } } | FUNCTION_PROC '(' arglist ')' @@ -3491,7 +3497,8 @@ function_call(struct function *function, size_t count, NODE *subtree) np->v.call.func = function; np->v.call.args = reverse(cast_arg_list(subtree, function->parmcount, - function->parmtype)); + function->parmtype, + 0)); } return np; } @@ -3606,7 +3613,7 @@ cast_to(data_type_t type, NODE *node) } NODE * -cast_arg_list(NODE *args, size_t parmc, data_type_t *parmtype) +cast_arg_list(NODE *args, size_t parmc, data_type_t *parmtype, int disable_prom) { NODE *head = NULL, *tail = NULL; @@ -3618,7 +3625,9 @@ cast_arg_list(NODE *args, size_t parmc, data_type_t *parmtype) if (parmc) { type = *parmtype++; parmc--; - } else + } else if (disable_prom) + type = node_type(args); + else type = dtype_string; p = cast_to(type, args); diff --git a/mfd/mailfromd.h b/mfd/mailfromd.h index 43502e99..8e54d0c3 100644 --- a/mfd/mailfromd.h +++ b/mfd/mailfromd.h @@ -506,6 +506,11 @@ typedef unsigned long prog_counter_t; /* Program counter */ /* Data types */ +#define MFD_BUILTIN_CAPTURE 0x01 /* Builtin needs message capturing */ +#define MFD_BUILTIN_VARIADIC 0x02 /* Builtin is variadic */ +#define MFD_BUILTIN_NO_PROMOTE 0x04 /* For variadic functions: + do not promote varargs to string */ + struct builtin { char *name; /* Built-in function name */ void (*handler) (eval_environ_t); /* C handler */ @@ -516,9 +521,7 @@ struct builtin { data_type_t rettype; /* Return type */ unsigned statemask; /* States where the function can be used */ - int capture; /* Does it need message capturing */ - int varargs; /* Does it take optional number of - arguments */ + int flags; /* Flags */ }; struct function { /* User-defined function */ @@ -613,9 +616,9 @@ void print_used_macros(void); void va_builtin_install (char *name, void (*handler) (eval_environ_t), data_type_t rettype, size_t argcount, ...); void va_builtin_install_ex (char *name, void (*handler) (eval_environ_t), - unsigned statemsk, int capture, + unsigned statemsk, data_type_t rettype, size_t argcount, - size_t optcount, int varargs, ...); + size_t optcount, int flags, ...); const struct builtin *builtin_lookup(const char *name); struct variable *variable_install(const char *name); diff --git a/mfd/snarf.m4 b/mfd/snarf.m4 index 77d9b95d..633c2ec1 100644 --- a/mfd/snarf.m4 +++ b/mfd/snarf.m4 @@ -341,15 +341,13 @@ void bi_$2(eval_environ_t env) m4_pushdef([<__MF_FUNCTION__>], $2)m4_dnl m4_pushdef([<__MF_ARGLIST__>], []) -m4_pushdef([<__MF_VARARGS__>], $1)m4_dnl m4_divert(1)m4_dnl va_builtin_install_ex("$2", bi_$2,m4_dnl m4_ifdef([<__MF_STATE__>],__MF_STATE__,0),m4_dnl - m4_ifdef([<__MF_CAPTURE__>],__MF_CAPTURE__,0),m4_dnl __mf_argtype($3),m4_dnl mf_argcount(m4_shift(m4_shift(m4_shift($@)))),m4_dnl mf_optcount(m4_shift(m4_shift(m4_shift($@)))),m4_dnl - $1,m4_dnl + m4_ifdef([<__MF_CAPTURE__>],[],0)|$1,m4_dnl mf_typelist(m4_shift(m4_shift(m4_shift($@))))); m4_divert(0)m4_dnl { @@ -358,15 +356,22 @@ m4_divert(0)m4_dnl mf_prog_trace($2,m4_shift(m4_shift(m4_shift($@)))); >]) -m4_define([],[<__mf_defun(0, $@)>]) +m4_define([],[], 0)m4_dnl +__mf_defun(0, $@)>]) -m4_define([],[],m4_dnl -[],[], 1)m4_dnl +m4_ifelse(__mf_has_optarg(m4_shift(m4_shift(m4_shift(m4_shift($@))))),0,m4_dnl +[<__mf_defun($1, m4_shift($@))>],m4_dnl +[],1)>])>]) +m4_define([],[<__mf_defun_varargs(MFD_BUILTIN_VARIADIC,$@)>]) + +m4_define([],[]) + /* MF_RETURN(value) - Return a numeric value */ m4_define([],[< diff --git a/mfd/symtab.c b/mfd/symtab.c index 537dbed4..ffa8f642 100644 --- a/mfd/symtab.c +++ b/mfd/symtab.c @@ -308,18 +308,17 @@ va_builtin_install (char *name, sp->vp->builtin.parmtype = argtype; sp->vp->builtin.rettype = rettype; sp->vp->builtin.statemask = 0; - sp->vp->builtin.capture = 0; + sp->vp->builtin.flags = 0; } void va_builtin_install_ex (char *name, void (*handler) (eval_environ_t), unsigned statemsk, - int capture, data_type_t rettype, size_t argcount, size_t optcount, - int varargs, + int flags, ...) { struct symtab *sp; @@ -327,7 +326,7 @@ va_builtin_install_ex (char *name, size_t i; data_type_t *argtype = xmalloc (argcount * sizeof *argtype); - va_start(ap, varargs); + va_start(ap, flags); for (i = 0; i < argcount; i++) argtype[i] = va_arg(ap, data_type_t); va_end(ap); @@ -349,11 +348,10 @@ va_builtin_install_ex (char *name, sp->vp->builtin.handler = handler; sp->vp->builtin.parmcount = argcount; sp->vp->builtin.optcount = optcount; - sp->vp->builtin.varargs = varargs; sp->vp->builtin.parmtype = argtype; sp->vp->builtin.rettype = rettype; sp->vp->builtin.statemask = statemsk; - sp->vp->builtin.capture = capture; + sp->vp->builtin.flags = flags; } -- cgit v1.2.1