aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog18
-rw-r--r--mfd/bi_sprintf.m42
-rw-r--r--mfd/drivers.c2
-rw-r--r--mfd/gram.y29
-rw-r--r--mfd/mailfromd.h13
-rw-r--r--mfd/snarf.m421
-rw-r--r--mfd/symtab.c10
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 <gray@gnu.org.ua>
+
+ 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 <gray@gnu.org.ua>
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_shift(m4_shift(m4_shift($*)))>])
-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__>],[<MFD_BUILTIN_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>],[<__mf_defun(0, $@)>])
+m4_define([<MF_DEFUN>],[<m4_pushdef([<__MF_VARARGS__>], 0)m4_dnl
+__mf_defun(0, $@)>])
-m4_define([<MF_DEFUN_VARARGS>],[<m4_dnl
-m4_ifelse(__mf_has_optarg(m4_shift(m4_shift(m4_shift($@)))),0,m4_dnl
-[<__mf_defun(1, $@)>],m4_dnl
-[<m4_errprint(m4___file__:m4___line__: A vararg function cannot take optional arguments
+m4_define([<__mf_defun_varargs>],[<m4_dnl
+m4_pushdef([<__MF_VARARGS__>], 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
+[<m4_errprint(m4___file__:m4___line__: A variadic function cannot take optional arguments
)
m4_define([<__mf_error_code>],1)>])>])
+m4_define([<MF_DEFUN_VARARGS>],[<__mf_defun_varargs(MFD_BUILTIN_VARIADIC,$@)>])
+
+m4_define([<MF_DEFUN_VARARGS_NO_PROM>],[<m4_dnl
+__mf_defun_varargs(MFD_BUILTIN_VARIADIC|MFD_BUILTIN_NO_PROMOTE,$@)>])
+
/* MF_RETURN(value) - Return a numeric value
*/
m4_define([<MF_RETURN>],[<
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;
}

Return to:

Send suggestions and report system problems to the System administrator.