m4-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

FYI: 27-gary-builtin-argument-count-check-refactoring.patch


From: Gary V. Vaughan
Subject: FYI: 27-gary-builtin-argument-count-check-refactoring.patch
Date: Fri, 12 Oct 2001 21:05:27 +0100
User-agent: Mutt/1.3.16i

Now we decalre builtins like this:

        /*      function        macros  blind argmin  argmax */
        BUILTIN(builtin,        FALSE,  TRUE,   2,      -1 )    \

Pretty cool huh?

Cheers,
        Gary.

Index: ChangeLog
from  Gary V. Vaughan  <address@hidden>

        Rather than forcing each builtin definition to manage its own
        argument range checking, tabulate the maxima and minima for all
        builtins in each module.  This forces us to consider what the
        valid ranges for each builtin should be, and moves the checking
        code out of each builtin implementation and into the builtin
        caller infrastructure.

        * m4/m4module.h (struct m4_builtin): Add argument minima and
        maxima.
        * m4/m4private.h (struct m4_token): Reflect them here too.
        * m4/input.c (struct input_block): ...and here.
        (m4_token_copy): New function for token copying.
        (init_macro_token): Copy them from a token to the input stack.
        (m4_next_token): Don't forget to initialise them for text
        macros.
        * m4/macro.c (expand_argument): Use m4_token_copy, and also
        check argument counts before calling the builtin handler.
        * m4/symtab.c (m4_symbol_builtin): Take minima and maxima params.
        (m4_symbol_macro): Likewise.
        * m4/builtin.c (m4_builtin_pushdef): Add min_args and max_args
        parameters.  Updated all callers.
        (m4_builtin_define): Ditto.
        (m4_macro_pushdef, m4_macro_define): Ditto.
        * m4/symtab.c (m4_symbol_builtin, m4_symbol_define): Ditto.
        * modules/evalparse.c:  Declare argument counts for defined
        builtins and remove explicit calls to m4_bad_argc().
        * modules/gnu.c: Ditto.
        * modules/load.c: Ditto.
        * modules/m4.c: Ditto.
        * modules/modtest.c: Ditto.
        * modules/mpeval.c: Ditto.
        * modules/perl.c: Ditto.
        * modules/shadow.c: Ditto.
        * modules/stdlib.c: Ditto.
        * modules/time.c: Ditto.
        * TODO: Updated.

Index: TODO
===================================================================
RCS file: /cvsroot/m4/m4/TODO,v
retrieving revision 1.8
diff -u -p -u -r1.8 TODO
--- TODO 2001/09/30 11:55:18 1.8
+++ TODO 2001/10/12 19:52:22
@@ -84,6 +84,10 @@ for any of these ideas or if you have ot
        maintaining the string lengths, and avoiding strlen, strcpy,
        etc.).
 
+  + The argument count limits are handled for all tokens passed around by
+    the internals:  we should enable attaching these values to text macros
+    too.
+
 * MODULE SPECIFIC ISSUES
 
   + Some way of linking a module statically is needed, for systems
Index: m4/builtin.c
===================================================================
RCS file: /cvsroot/m4/m4/m4/builtin.c,v
retrieving revision 1.13
diff -u -p -u -r1.13 builtin.c
--- m4/builtin.c 2001/10/11 21:09:15 1.13
+++ m4/builtin.c 2001/10/12 19:52:24
@@ -72,7 +72,8 @@ m4_builtin_find_by_func (const m4_builti
 
 m4_symbol *
 m4_builtin_pushdef (const char *name, lt_dlhandle handle,
-                   m4_builtin_func *func, int flags)
+                   m4_builtin_func *func, int flags, int min_args,
+                   int max_args)
 {
   m4_symbol *symbol;
 
@@ -83,14 +84,15 @@ m4_builtin_pushdef (const char *name, lt
   symbol = m4_symbol_pushdef (name);
 
   if (symbol)
-    m4_symbol_builtin (symbol, handle, func, flags);
+    m4_symbol_builtin (symbol, handle, func, flags, min_args, max_args);
 
   return symbol;
 }
 
 m4_symbol *
 m4_builtin_define (const char *name, lt_dlhandle handle,
-                  m4_builtin_func *func, int flags)
+                  m4_builtin_func *func, int flags,
+                  int min_args, int max_args)
 {
   m4_symbol *symbol;
 
@@ -101,7 +103,7 @@ m4_builtin_define (const char *name, lt_
   symbol = m4_symbol_define (name);
 
   if (symbol)
-    m4_symbol_builtin (symbol, handle, func, flags);
+    m4_symbol_builtin (symbol, handle, func, flags, min_args, max_args);
 
   return symbol;
 }
@@ -133,7 +135,8 @@ m4_builtin_table_install (lt_dlhandle ha
       if (bp->groks_macro_args) BIT_SET (flags, TOKEN_MACRO_ARGS_BIT);
       if (bp->blind_if_no_args) BIT_SET (flags, TOKEN_BLIND_ARGS_BIT);
 
-      m4_builtin_pushdef (key, handle, bp->func, flags);
+      m4_builtin_pushdef (key, handle, bp->func, flags,
+                         bp->min_args, bp->max_args);
 
       if (prefix_all_builtins)
        xfree (key);
@@ -142,7 +145,7 @@ m4_builtin_table_install (lt_dlhandle ha
 
 m4_symbol *
 m4_macro_pushdef (const char *name, lt_dlhandle handle, const char *text,
-                 int flags)
+                 int flags, int min_args, int max_args)
 {
   m4_symbol *symbol;
 
@@ -152,14 +155,14 @@ m4_macro_pushdef (const char *name, lt_d
   symbol = m4_symbol_pushdef (name);
 
   if (symbol)
-    m4_symbol_macro (symbol, handle, text, flags);
+    m4_symbol_macro (symbol, handle, text, flags, min_args, max_args);
 
   return symbol;
 }
 
 m4_symbol *
 m4_macro_define (const char *name, lt_dlhandle handle, const char *text,
-                int flags)
+                int flags, int min_args, int max_args)
 {
   m4_symbol *symbol;
 
@@ -169,7 +172,7 @@ m4_macro_define (const char *name, lt_dl
   symbol = m4_symbol_define (name);
 
   if (symbol)
-    m4_symbol_macro (symbol, handle, text, flags);
+    m4_symbol_macro (symbol, handle, text, flags, min_args, max_args);
 
   return symbol;
 }
@@ -181,5 +184,5 @@ m4_macro_table_install (lt_dlhandle hand
   const m4_macro *mp;
 
   for (mp = table; mp->name != NULL; mp++)
-    m4_macro_pushdef (mp->name, handle, mp->value, 0);
+    m4_macro_pushdef (mp->name, handle, mp->value, 0, 0, -1);
 }
Index: m4/input.c
===================================================================
RCS file: /cvsroot/m4/m4/m4/input.c,v
retrieving revision 1.14
diff -u -p -u -r1.14 input.c
--- m4/input.c 2001/10/11 21:09:15 1.14
+++ m4/input.c 2001/10/12 19:52:28
@@ -198,6 +198,7 @@ struct input_block
          m4_builtin_func *func;/* pointer to macros function */
          lt_dlhandle handle;   /* originating module */
          int flags;            /* flags associated with the builtin */
+         int min_args, max_args; /* argv maxima and minima for the builtin. */
          boolean traced;       /* TRUE iff builtin is traced */
          boolean read;         /* TRUE iff block has been read */
        }
@@ -607,6 +608,8 @@ init_macro_token (m4_token *td)
   TOKEN_FUNC (td)      = isp->u.u_m.func;
   TOKEN_HANDLE (td)    = isp->u.u_m.handle;
   TOKEN_FLAGS (td)     = isp->u.u_m.flags;
+  TOKEN_MIN_ARGS (td)  = isp->u.u_m.min_args;
+  TOKEN_MAX_ARGS (td)  = isp->u.u_m.max_args;
 }
 
 
@@ -1204,12 +1207,25 @@ m4_next_token (m4_token *td)
   TOKEN_TEXT (td)      = obstack_finish (&token_stack);
   TOKEN_HANDLE (td)    = NULL;
   TOKEN_FLAGS (td)     = 0x0;
+  TOKEN_MIN_ARGS (td)  = -1;
+  TOKEN_MAX_ARGS (td)  = -1;
 
 #ifdef DEBUG_INPUT
   print_token("next_token", type, td);
 #endif
 
   return type;
+}
+
+void
+m4_token_copy (m4_token *dest, m4_token *src)
+{
+  TOKEN_TYPE (dest)    = TOKEN_TYPE (src);
+  TOKEN_FUNC (dest)    = TOKEN_FUNC (src);
+  TOKEN_HANDLE (dest)   = TOKEN_HANDLE (src);
+  TOKEN_FLAGS (dest)    = TOKEN_FLAGS (src);
+  TOKEN_MIN_ARGS (dest) = TOKEN_MIN_ARGS (src);
+  TOKEN_MAX_ARGS (dest) = TOKEN_MAX_ARGS (src);
 }
 
 
Index: m4/m4module.h
===================================================================
RCS file: /cvsroot/m4/m4/m4/m4module.h,v
retrieving revision 1.33
diff -u -p -u -r1.33 m4module.h
--- m4/m4module.h 2001/10/11 21:09:15 1.33
+++ m4/m4module.h 2001/10/12 19:52:29
@@ -50,10 +50,10 @@ typedef struct {
 } m4_macro;
 
 typedef struct {
-  const char      *name;
-  m4_builtin_func  *func;
-  boolean          groks_macro_args;
-  boolean          blind_if_no_args;
+  const char *     name;
+  m4_builtin_func * func;
+  boolean          groks_macro_args, blind_if_no_args;
+  int              min_args, max_args;
 } m4_builtin;
 
 
@@ -73,16 +73,20 @@ extern lt_dlhandle  m4_module_find_by_bu
 
 
 extern m4_symbol *m4_macro_pushdef     (const char *name, lt_dlhandle handle,
-                                        const char *text, int flags);
+                                        const char *text, int flags,
+                                        int min_args, int max_args);
 extern m4_symbol *m4_macro_define      (const char *name, lt_dlhandle handle,
-                                        const char *text, int flags);
+                                        const char *text, int flags,
+                                        int min_args, int max_args);
 extern void      m4_macro_table_install (lt_dlhandle handle,
                                          const m4_macro *table);
 
 extern m4_symbol *m4_builtin_pushdef   (const char *name, lt_dlhandle handle,
-                                        m4_builtin_func *func, int flags);
+                                        m4_builtin_func *func, int flags,
+                                        int min_args, int max_args);
 extern m4_symbol *m4_builtin_define    (const char *name, lt_dlhandle handle,
-                                        m4_builtin_func *func, int flags);
+                                        m4_builtin_func *func, int flags,
+                                        int min_args, int max_args);
 extern void      m4_builtin_table_install (lt_dlhandle handle,
                                         const m4_builtin *table);
 
@@ -104,9 +108,11 @@ extern m4_symbol *m4_symbol_define (cons
 extern void       m4_symbol_popdef     (const char *);
 extern void       m4_symbol_delete     (const char *);
 extern void      m4_symbol_builtin     (m4_symbol *symbol, lt_dlhandle handle,
-                                        m4_builtin_func *func, int flags);
+                                        m4_builtin_func *func, int flags,
+                                        int min_args, int max_args);
 extern void      m4_symbol_macro       (m4_symbol *symbol, lt_dlhandle handle,
-                                        const char *text, int flags);
+                                        const char *text, int flags,
+                                        int min_args, int max_args);
 
 
 /* Various different token types.  */
@@ -382,6 +388,7 @@ extern      void    m4_input_exit   (void);
 extern void    m4_syntax_init  (void);
 extern int     m4_peek_input   (void);
 extern m4_token_t m4_next_token (m4_token *);
+extern void    m4_token_copy   (m4_token *dest, m4_token *src);
 extern void    m4_skip_line    (void);
 
 /* push back input */
Index: m4/m4private.h
===================================================================
RCS file: /cvsroot/m4/m4/m4/m4private.h,v
retrieving revision 1.13
diff -u -p -u -r1.13 m4private.h
--- m4/m4private.h 2001/10/11 21:09:16 1.13
+++ m4/m4private.h 2001/10/12 19:52:29
@@ -43,6 +43,7 @@ struct m4_token {
   m4_token *   next;
   lt_dlhandle          handle;
   int                  flags;
+  int                  min_args, max_args;
 
   m4_data_t            type;
   union {
@@ -54,6 +55,8 @@ struct m4_token {
 #define TOKEN_NEXT(T)          ((T)->next)
 #define TOKEN_HANDLE(T)        ((T)->handle)
 #define TOKEN_FLAGS(T)         ((T)->flags)
+#define TOKEN_MIN_ARGS(T)      ((T)->min_args)
+#define TOKEN_MAX_ARGS(T)      ((T)->max_args)
 #define TOKEN_TYPE(T)          ((T)->type)
 #define TOKEN_TEXT(T)          ((T)->u.text)
 #define TOKEN_FUNC(T)          ((T)->u.func)
@@ -78,12 +81,14 @@ struct m4_symbol
 #define SYMBOL_TRACED(S)       ((S)->traced)
 #define SYMBOL_TOKEN(S)                ((S)->token)
 
-#define SYMBOL_NEXT(S)         (TOKEN_NEXT   (SYMBOL_TOKEN (S)))
-#define SYMBOL_HANDLE(S)       (TOKEN_HANDLE (SYMBOL_TOKEN (S)))
-#define SYMBOL_FLAGS(S)                (TOKEN_FLAGS  (SYMBOL_TOKEN (S)))
-#define SYMBOL_TYPE(S)         (TOKEN_TYPE   (SYMBOL_TOKEN (S)))
-#define SYMBOL_TEXT(S)         (TOKEN_TEXT   (SYMBOL_TOKEN (S)))
-#define SYMBOL_FUNC(S)         (TOKEN_FUNC   (SYMBOL_TOKEN (S)))
+#define SYMBOL_NEXT(S)         (TOKEN_NEXT     (SYMBOL_TOKEN (S)))
+#define SYMBOL_HANDLE(S)       (TOKEN_HANDLE   (SYMBOL_TOKEN (S)))
+#define SYMBOL_FLAGS(S)                (TOKEN_FLAGS    (SYMBOL_TOKEN (S)))
+#define SYMBOL_MIN_ARGS(S)     (TOKEN_MIN_ARGS (SYMBOL_TOKEN (S)))
+#define SYMBOL_MAX_ARGS(S)     (TOKEN_MAX_ARGS (SYMBOL_TOKEN (S)))
+#define SYMBOL_TYPE(S)         (TOKEN_TYPE     (SYMBOL_TOKEN (S)))
+#define SYMBOL_TEXT(S)         (TOKEN_TEXT     (SYMBOL_TOKEN (S)))
+#define SYMBOL_FUNC(S)         (TOKEN_FUNC     (SYMBOL_TOKEN (S)))
 
 
 
Index: m4/macro.c
===================================================================
RCS file: /cvsroot/m4/m4/m4/macro.c,v
retrieving revision 1.16
diff -u -p -u -r1.16 macro.c
--- m4/macro.c 2001/10/11 21:09:16 1.16
+++ m4/macro.c 2001/10/12 19:52:30
@@ -165,12 +165,7 @@ expand_argument (struct obstack *obs, m4
 
        case M4_TOKEN_MACDEF:
          if (obstack_object_size (obs) == 0)
-           {
-             TOKEN_TYPE (argp)   = M4_TOKEN_FUNC;
-             TOKEN_FUNC (argp)   = TOKEN_FUNC (&td);
-             TOKEN_HANDLE (argp) = TOKEN_HANDLE (&td);
-             TOKEN_FLAGS (argp)  = TOKEN_FLAGS (&td);
-           }
+           m4_token_copy (argp, &td);
          break;
 
        default:
@@ -298,7 +293,17 @@ ERROR: Recursion limit of %d exceeded, u
     m4_trace_pre (name, my_call_id, argc, argv);
 
   expansion = m4_push_string_init ();
-  m4_call_macro (symbol, argc, argv, expansion);
+  {
+    boolean bad_args = FALSE;
+
+    /* If argument limits are set for this builtin, check them and
+       only call the builtin handler if the check passes.  */
+    if ((SYMBOL_MIN_ARGS (symbol) > 0) || (SYMBOL_MAX_ARGS (symbol) > 0))
+      bad_args = m4_bad_argc (argv[0], argc, SYMBOL_MIN_ARGS (symbol),
+                            SYMBOL_MAX_ARGS (symbol));
+    if (!bad_args)
+      m4_call_macro (symbol, argc, argv, expansion);
+  }
   expanded = m4_push_string_finish ();
 
   if (traced)
Index: m4/symtab.c
===================================================================
RCS file: /cvsroot/m4/m4/m4/symtab.c,v
retrieving revision 1.25
diff -u -p -u -r1.25 symtab.c
--- m4/symtab.c 2001/10/11 21:09:16 1.25
+++ m4/symtab.c 2001/10/12 19:52:31
@@ -295,7 +295,8 @@ m4_symbol_delete (const char *name)
    be appropriately set by the caller.  */
 void
 m4_symbol_builtin (m4_symbol *symbol, lt_dlhandle handle,
-                  m4_builtin_func *func, int flags)
+                  m4_builtin_func *func, int flags,
+                  int min_args, int max_args)
 {
   assert (symbol);
   assert (handle);
@@ -308,12 +309,14 @@ m4_symbol_builtin (m4_symbol *symbol, lt
   SYMBOL_FUNC (symbol)         = func;
   SYMBOL_HANDLE (symbol)       = handle;
   SYMBOL_FLAGS (symbol)                = flags;
+  SYMBOL_MIN_ARGS (symbol)     = min_args;
+  SYMBOL_MAX_ARGS (symbol)     = max_args;
 }
 
 /* ...and similarly for macro valued symbols.  */
 void
 m4_symbol_macro (m4_symbol *symbol, lt_dlhandle handle,
-                const char *text, int flags)
+                const char *text, int flags, int min_args, int max_args)
 {
   assert (symbol);
 
@@ -323,7 +326,9 @@ m4_symbol_macro (m4_symbol *symbol, lt_d
   SYMBOL_TYPE (symbol)                 = M4_TOKEN_TEXT;
   SYMBOL_TEXT (symbol)                 = xstrdup (text);
   SYMBOL_HANDLE (symbol)       = handle;
-  SYMBOL_FLAGS (symbol)                = 0;
+  SYMBOL_FLAGS (symbol)                = flags;
+  SYMBOL_MIN_ARGS (symbol)     = min_args;
+  SYMBOL_MAX_ARGS (symbol)     = max_args;
 }
 
 
Index: modules/evalparse.c
===================================================================
RCS file: /cvsroot/m4/m4/modules/evalparse.c,v
retrieving revision 1.3
diff -u -p -u -r1.3 evalparse.c
--- modules/evalparse.c 2001/10/11 21:09:16 1.3
+++ modules/evalparse.c 2001/10/12 19:52:37
@@ -774,9 +774,6 @@ m4_evaluate (struct obstack *obs, int ar
   eval_token   et;
   eval_error   err;
 
-  if (m4_bad_argc (argv[0], argc, 2, 4))
-    return;
-
   if (argc >= 3 && !m4_numeric_arg (argv[0], M4ARG (2), &radix))
     return;
 
Index: modules/gnu.c
===================================================================
RCS file: /cvsroot/m4/m4/modules/gnu.c,v
retrieving revision 1.16
diff -u -p -u -r1.16 gnu.c
--- modules/gnu.c 2001/10/11 21:09:16 1.16
+++ modules/gnu.c 2001/10/12 19:52:37
@@ -67,27 +67,27 @@ int errno;
 /* Maintain each of the builtins implemented in this modules along
    with their details in a single table for easy maintenance.
 
-               function        macros  blind */
+               function        macros  blind argmin  argmax */
 #define builtin_functions                      \
-       BUILTIN(__file__,       FALSE,  FALSE ) \
-       BUILTIN(__line__,       FALSE,  FALSE ) \
-       BUILTIN(builtin,        FALSE,  TRUE  ) \
-       BUILTIN(changesyntax,   FALSE,  TRUE  ) \
-       BUILTIN(debugmode,      FALSE,  FALSE ) \
-       BUILTIN(debugfile,      FALSE,  FALSE ) \
-       BUILTIN(eregexp,        FALSE,  TRUE  ) \
-       BUILTIN(epatsubst,      FALSE,  TRUE  ) \
-       BUILTIN(esyscmd,        FALSE,  TRUE  ) \
-       BUILTIN(format,         FALSE,  TRUE  ) \
-       BUILTIN(indir,          FALSE,  TRUE  ) \
-       BUILTIN(patsubst,       FALSE,  TRUE  ) \
-       BUILTIN(regexp,         FALSE,  TRUE  ) \
-       BUILTIN(symbols,        FALSE,  FALSE ) \
-       BUILTIN(syncoutput,     FALSE,  TRUE  ) \
+       BUILTIN(__file__,       FALSE,  FALSE,  1,      1  )    \
+       BUILTIN(__line__,       FALSE,  FALSE,  1,      1  )    \
+       BUILTIN(builtin,        FALSE,  TRUE,   2,      -1 )    \
+       BUILTIN(changesyntax,   FALSE,  TRUE,   1,      -1 )    \
+       BUILTIN(debugmode,      FALSE,  FALSE,  1,      2  )    \
+       BUILTIN(debugfile,      FALSE,  FALSE,  1,      2  )    \
+       BUILTIN(eregexp,        FALSE,  TRUE,   3,      4  )    \
+       BUILTIN(epatsubst,      FALSE,  TRUE,   3,      4  )    \
+       BUILTIN(esyscmd,        FALSE,  TRUE,   2,      2  )    \
+       BUILTIN(format,         FALSE,  TRUE,   2,      -1 )    \
+       BUILTIN(indir,          FALSE,  TRUE,   2,      -1 )    \
+       BUILTIN(patsubst,       FALSE,  TRUE,   3,      4  )    \
+       BUILTIN(regexp,         FALSE,  TRUE,   3,      4  )    \
+       BUILTIN(symbols,        FALSE,  FALSE,  0,      -1 )    \
+       BUILTIN(syncoutput,     FALSE,  TRUE,   2,      2  )    \
 
 
 /* Generate prototypes for each builtin handler function. */
-#define BUILTIN(handler, macros,  blind)       M4BUILTIN(handler)
+#define BUILTIN(handler, macros,  blind, min, max)  M4BUILTIN(handler)
   builtin_functions
 #undef BUILTIN
 
@@ -95,12 +95,12 @@ int errno;
 /* Generate a table for mapping m4 symbol names to handler functions. */
 m4_builtin m4_builtin_table[] =
 {
-#define BUILTIN(handler, macros, blind)                \
-       { STR(handler), CONC(builtin_, handler), macros, blind },
+#define BUILTIN(handler, macros, blind, min, max)              \
+       { STR(handler), CONC(builtin_, handler), macros, blind, min, max },
   builtin_functions
 #undef BUILTIN
 
-  { 0, 0, FALSE, FALSE },
+  { 0, 0, FALSE, FALSE, 0, 0 },
 };
 
 
@@ -137,9 +137,6 @@ M4BUILTIN_HANDLER (builtin)
   const m4_builtin *bp = NULL;
   const char *name = M4ARG (1);
 
-  if (m4_bad_argc (argv[0], argc, 2, -1))
-    return;
-
   bp = m4_builtin_find_by_name (NULL, name);
 
   if (bp == NULL)
@@ -163,9 +160,6 @@ M4BUILTIN_HANDLER (indir)
   m4_symbol *symbol;
   const char *name = M4ARG (1);
 
-  if (m4_bad_argc (argv[0], argc, 2, -1))
-    return;
-
   symbol = m4_symbol_lookup (name);
   if (symbol == NULL)
     M4ERROR ((warning_status, 0,
@@ -187,9 +181,6 @@ M4BUILTIN_HANDLER (changesyntax)
 {
   int i;
 
-  if (m4_bad_argc (argv[0], argc, 1, -1))
-    return;
-
   for (i = 1; i < argc; i++)
     {
       m4_set_syntax (*M4ARG (i),
@@ -209,9 +200,6 @@ M4BUILTIN_HANDLER (debugmode)
   int new_debug_level;
   int change_flag;
 
-  if (m4_bad_argc (argv[0], argc, 1, 2))
-    return;
-
   if (argc == 1)
     debug_level = 0;
   else
@@ -258,9 +246,6 @@ M4BUILTIN_HANDLER (debugmode)
  **/
 M4BUILTIN_HANDLER (debugfile)
 {
-  if (m4_bad_argc (argv[0], argc, 1, 2))
-    return;
-
   if (argc == 1)
     m4_debug_set_output (NULL);
   else if (!m4_debug_set_output (M4ARG (1)))
@@ -324,9 +309,6 @@ m4_regexp_do (struct obstack *obs, int a
   int startpos;                        /* start position of match */
   int length;                  /* length of first argument */
 
-  if (m4_bad_argc (argv[0], argc, 3, 4))
-    return;
-
   victim = M4ARG (1);
   regexp = M4ARG (2);
 
@@ -499,9 +481,6 @@ M4BUILTIN_HANDLER (symbols)
  **/
 M4BUILTIN_HANDLER (syncoutput)
 {
-  if (m4_bad_argc (argv[0], argc, 2, 2))
-    return;
-
   if (TOKEN_TYPE (argv[1]) != M4_TOKEN_TEXT)
     return;
 
@@ -524,9 +503,6 @@ M4BUILTIN_HANDLER (esyscmd)
   FILE *pin;
   int ch;
 
-  if (m4_bad_argc (argv[0], argc, 2, 2))
-    return;
-
   m4_debug_flush_files ();
   pin = popen (M4ARG (1), "r");
   if (pin == NULL)
@@ -560,9 +536,6 @@ M4BUILTIN_HANDLER (format)
  **/
 M4BUILTIN_HANDLER (__file__)
 {
-  if (m4_bad_argc (argv[0], argc, 1, 1))
-    return;
-
   m4_shipout_string (obs, m4_current_file, 0, TRUE);
 }
 
@@ -572,8 +545,6 @@ M4BUILTIN_HANDLER (__file__)
  **/
 M4BUILTIN_HANDLER (__line__)
 {
-  if (m4_bad_argc (argv[0], argc, 1, 1))
-    return;
   m4_shipout_int (obs, m4_current_line);
 }
 
Index: modules/load.c
===================================================================
RCS file: /cvsroot/m4/m4/modules/load.c,v
retrieving revision 1.7
diff -u -p -u -r1.7 load.c
--- modules/load.c 2001/08/19 10:53:56 1.7
+++ modules/load.c 2001/10/12 19:52:37
@@ -32,15 +32,15 @@
 /* Maintain each of the builtins implemented in this modules along
    with their details in a single table for easy maintenance.
 
-               function        macros  blind */
+               function        macros  blind minargs maxargs */
 #define builtin_functions                      \
-       BUILTIN(modules,        FALSE,  FALSE ) \
-       BUILTIN(load,           FALSE,  TRUE  ) \
-       BUILTIN(unload,         FALSE,  TRUE  )
+       BUILTIN(modules,        FALSE,  FALSE,  1,      1  )    \
+       BUILTIN(load,           FALSE,  TRUE,   2,      2  )    \
+       BUILTIN(unload,         FALSE,  TRUE,   2,      2  )    \
 
 
 /* Generate prototypes for each builtin handler function. */
-#define BUILTIN(handler, macros,  blind)       M4BUILTIN(handler)
+#define BUILTIN(handler, macros,  blind, min, max) M4BUILTIN(handler)
   builtin_functions
 #undef BUILTIN
 
@@ -48,12 +48,12 @@
 /* Generate a table for mapping m4 symbol names to handler functions. */
 m4_builtin m4_builtin_table[] =
 {
-#define BUILTIN(handler, macros, blind)                \
-       { STR(handler), CONC(builtin_, handler), macros, blind },
+#define BUILTIN(handler, macros, blind, min, max)              \
+       { STR(handler), CONC(builtin_, handler), macros, blind, min, max },
   builtin_functions
 #undef BUILTIN
 
-  { 0, 0, FALSE, FALSE },
+  { 0, 0, FALSE, FALSE, 0, 0 },
 };
 
 
@@ -95,9 +95,6 @@ M4BUILTIN_HANDLER (modules)
      loaded modules.  */
   lt_dlhandle handle = lt_dlhandle_next (NULL);
 
-  if (m4_bad_argc (argv[0], argc, 1, 1))
-    return;
-
   if (handle)
     do
       {
@@ -114,9 +111,6 @@ M4BUILTIN_HANDLER (modules)
  **/
 M4BUILTIN_HANDLER (load)
 {
-  if (m4_bad_argc (argv[0], argc, 2, 2))
-    return;
-
   /* Load the named module and install the builtins and macros
      exported by that module.  */
   m4_module_load (M4ARG(1), obs);
@@ -127,9 +121,6 @@ M4BUILTIN_HANDLER (load)
  **/
 M4BUILTIN_HANDLER (unload)
 {
-  if (m4_bad_argc (argv[0], argc, 2, 2))
-    return;
-
   /* Remove all builtins and macros installed by the named module,
      and then unload the module from memory entirely.  */
   m4_module_unload (M4ARG(1), obs);
Index: modules/m4.c
===================================================================
RCS file: /cvsroot/m4/m4/modules/m4.c,v
retrieving revision 1.26
diff -u -p -u -r1.26 m4.c
--- modules/m4.c 2001/10/11 21:09:16 1.26
+++ modules/m4.c 2001/10/12 19:52:37
@@ -46,40 +46,40 @@ extern int errno;
 /* Maintain each of the builtins implemented in this modules along
    with their details in a single table for easy maintenance.
 
-               function        macros  blind */
+               function        macros  blind minargs maxargs */
 #define builtin_functions                      \
-       BUILTIN(changecom,      FALSE,  FALSE ) \
-       BUILTIN(changequote,    FALSE,  FALSE ) \
-       BUILTIN(decr,           FALSE,  TRUE  ) \
-       BUILTIN(define,         TRUE,   TRUE  ) \
-       BUILTIN(defn,           FALSE,  TRUE  ) \
-       BUILTIN(divert,         FALSE,  FALSE ) \
-       BUILTIN(divnum,         FALSE,  FALSE ) \
-       BUILTIN(dnl,            FALSE,  FALSE ) \
-       BUILTIN(dumpdef,        FALSE,  FALSE ) \
-       BUILTIN(errprint,       FALSE,  FALSE ) \
-       BUILTIN(eval,           FALSE,  TRUE  ) \
-       BUILTIN(ifdef,          FALSE,  TRUE  ) \
-       BUILTIN(ifelse,         FALSE,  TRUE  ) \
-       BUILTIN(include,        FALSE,  TRUE  ) \
-       BUILTIN(incr,           FALSE,  TRUE  ) \
-       BUILTIN(index,          FALSE,  TRUE  ) \
-       BUILTIN(len,            FALSE,  TRUE  ) \
-       BUILTIN(m4exit,         FALSE,  FALSE ) \
-       BUILTIN(m4wrap,         FALSE,  FALSE ) \
-       BUILTIN(maketemp,       FALSE,  TRUE  ) \
-       BUILTIN(popdef,         FALSE,  TRUE  ) \
-       BUILTIN(pushdef,        TRUE,   TRUE  ) \
-       BUILTIN(shift,          FALSE,  FALSE ) \
-       BUILTIN(sinclude,       FALSE,  TRUE  ) \
-       BUILTIN(substr,         FALSE,  TRUE  ) \
-       BUILTIN(syscmd,         FALSE,  TRUE  ) \
-       BUILTIN(sysval,         FALSE,  FALSE ) \
-       BUILTIN(traceoff,       FALSE,  FALSE ) \
-       BUILTIN(traceon,        FALSE,  FALSE ) \
-       BUILTIN(translit,       FALSE,  TRUE  ) \
-       BUILTIN(undefine,       FALSE,  TRUE  ) \
-       BUILTIN(undivert,       FALSE,  FALSE )
+       BUILTIN(changecom,      FALSE,  FALSE,  1,      3  )    \
+       BUILTIN(changequote,    FALSE,  FALSE,  1,      3  )    \
+       BUILTIN(decr,           FALSE,  TRUE,   2,      2  )    \
+       BUILTIN(define,         TRUE,   TRUE,   2,      3  )    \
+       BUILTIN(defn,           FALSE,  TRUE,   2,      2  )    \
+       BUILTIN(divert,         FALSE,  FALSE,  1,      2  )    \
+       BUILTIN(divnum,         FALSE,  FALSE,  1,      1  )    \
+       BUILTIN(dnl,            FALSE,  FALSE,  1,      1  )    \
+       BUILTIN(dumpdef,        FALSE,  FALSE,  0,      -1 )    \
+       BUILTIN(errprint,       FALSE,  FALSE,  0,      -1 )    \
+       BUILTIN(eval,           FALSE,  TRUE,   2,      4  )    \
+       BUILTIN(ifdef,          FALSE,  TRUE,   3,      4  )    \
+       BUILTIN(ifelse,         FALSE,  TRUE,   4,      -1 )    \
+       BUILTIN(include,        FALSE,  TRUE,   2,      2  )    \
+       BUILTIN(incr,           FALSE,  TRUE,   2,      2  )    \
+       BUILTIN(index,          FALSE,  TRUE,   3,      3  )    \
+       BUILTIN(len,            FALSE,  TRUE,   2,      2  )    \
+       BUILTIN(m4exit,         FALSE,  FALSE,  1,      2  )    \
+       BUILTIN(m4wrap,         FALSE,  FALSE,  0,      -1 )    \
+       BUILTIN(maketemp,       FALSE,  TRUE,   2,      2  )    \
+       BUILTIN(popdef,         FALSE,  TRUE,   2,      2  )    \
+       BUILTIN(pushdef,        TRUE,   TRUE,   2,      3  )    \
+       BUILTIN(shift,          FALSE,  FALSE,  0,      -1 )    \
+       BUILTIN(sinclude,       FALSE,  TRUE,   2,      2  )    \
+       BUILTIN(substr,         FALSE,  TRUE,   3,      4  )    \
+       BUILTIN(syscmd,         FALSE,  TRUE,   2,      2  )    \
+       BUILTIN(sysval,         FALSE,  FALSE,  0,      -1 )    \
+       BUILTIN(traceoff,       FALSE,  FALSE,  0,      -1 )    \
+       BUILTIN(traceon,        FALSE,  FALSE,  0,      -1 )    \
+       BUILTIN(translit,       FALSE,  TRUE,   3,      4  )    \
+       BUILTIN(undefine,       FALSE,  TRUE,   2,      2  )    \
+       BUILTIN(undivert,       FALSE,  FALSE,  0,      -1 )    \
 
 
 #if defined(SIZEOF_LONG_LONG_INT) && SIZEOF_LONG_LONG_INT > 0
@@ -102,7 +102,7 @@ static void numb_obstack    (struct obstack
 
 
 /* Generate prototypes for each builtin handler function. */
-#define BUILTIN(handler, macros,  blind)       M4BUILTIN(handler)
+#define BUILTIN(handler, macros,  blind, min, max) M4BUILTIN(handler)
   builtin_functions
 #undef BUILTIN
 
@@ -110,12 +110,12 @@ static void       numb_obstack    (struct obstack
 /* Generate a table for mapping m4 symbol names to handler functions. */
 m4_builtin m4_builtin_table[] =
 {
-#define BUILTIN(handler, macros, blind)                \
-       { STR(handler), CONC(builtin_, handler), macros, blind },
+#define BUILTIN(handler, macros, blind, min, max)              \
+       { STR(handler), CONC(builtin_, handler), macros, blind, min, max },
   builtin_functions
 #undef BUILTIN
 
-  { 0, 0, FALSE, FALSE },
+  { 0, 0, FALSE, FALSE, 0, 0 },
 };
 
 
@@ -148,15 +148,12 @@ M4INIT_HANDLER (m4)
 
 M4BUILTIN_HANDLER (define)
 {
-  if (m4_bad_argc (argv[0], argc, 2, 3))
-    return;
-
   if (TOKEN_TYPE (argv[1]) != M4_TOKEN_TEXT)
     return;
 
   if (argc == 2)
     {
-      m4_macro_define (M4ARG (1), NULL, "", 0);
+      m4_macro_define (M4ARG (1), NULL, "", 0, 0, -1);
       return;
     }
 
@@ -164,12 +161,14 @@ M4BUILTIN_HANDLER (define)
     {
     case M4_TOKEN_TEXT:
       m4_macro_define (M4ARG (1), TOKEN_HANDLE (argv[2]),
-                      TOKEN_TEXT (argv[2]), TOKEN_FLAGS (argv[2]));
+                      TOKEN_TEXT (argv[2]), TOKEN_FLAGS (argv[2]),
+                      TOKEN_MIN_ARGS (argv[2]), TOKEN_MAX_ARGS (argv[2]));
       return;
 
     case M4_TOKEN_FUNC:
       m4_builtin_define (M4ARG (1), TOKEN_HANDLE (argv[2]),
-                        TOKEN_FUNC (argv[2]), TOKEN_FLAGS (argv[2]));
+                        TOKEN_FUNC (argv[2]), TOKEN_FLAGS (argv[2]),
+                        TOKEN_MIN_ARGS (argv[2]), TOKEN_MAX_ARGS (argv[2]));
       return;
     }
 
@@ -179,9 +178,6 @@ M4BUILTIN_HANDLER (define)
 
 M4BUILTIN_HANDLER (undefine)
 {
-  if (m4_bad_argc (argv[0], argc, 2, 2))
-    return;
-
   if (!m4_symbol_lookup (M4ARG (1)))
     M4WARN ((warning_status, 0,
             _("Warning: %s: undefined name: %s"), M4ARG (0), M4ARG (1)));
@@ -191,15 +187,12 @@ M4BUILTIN_HANDLER (undefine)
 
 M4BUILTIN_HANDLER (pushdef)
 {
-  if (m4_bad_argc (argv[0], argc, 2, 3))
-    return;
-
   if (TOKEN_TYPE (argv[1]) != M4_TOKEN_TEXT)
     return;
 
   if (argc == 2)
     {
-      m4_macro_pushdef (M4ARG (1), NULL, "", 0);
+      m4_macro_pushdef (M4ARG (1), NULL, "", 0, 0, -1);
       return;
     }
 
@@ -207,12 +200,14 @@ M4BUILTIN_HANDLER (pushdef)
     {
     case M4_TOKEN_TEXT:
       m4_macro_pushdef (M4ARG (1), TOKEN_HANDLE (argv[2]),
-                       TOKEN_TEXT (argv[2]), TOKEN_FLAGS (argv[2]));
+                       TOKEN_TEXT (argv[2]), TOKEN_FLAGS (argv[2]),
+                       TOKEN_MIN_ARGS (argv[2]), TOKEN_MAX_ARGS (argv[2]));
       return;
 
     case M4_TOKEN_FUNC:
       m4_builtin_pushdef (M4ARG (1), TOKEN_HANDLE (argv[2]),
-                         TOKEN_FUNC (argv[2]), TOKEN_FLAGS (argv[2]));
+                         TOKEN_FUNC (argv[2]), TOKEN_FLAGS (argv[2]),
+                         TOKEN_MIN_ARGS (argv[2]), TOKEN_MAX_ARGS (argv[2]));
       return;
     }
 
@@ -222,8 +217,6 @@ M4BUILTIN_HANDLER (pushdef)
 
 M4BUILTIN_HANDLER (popdef)
 {
-  if (m4_bad_argc (argv[0], argc, 2, 2))
-    return;
   if (!m4_symbol_lookup (M4ARG (1)))
     M4WARN ((warning_status, 0,
             _("Warning: %s: undefined name: %s"), M4ARG (0), M4ARG (1)));
@@ -242,8 +235,6 @@ M4BUILTIN_HANDLER (ifdef)
   m4_symbol *symbol;
   const char *result;
 
-  if (m4_bad_argc (argv[0], argc, 3, 4))
-    return;
   symbol = m4_symbol_lookup (M4ARG (1));
 
   if (symbol)
@@ -264,8 +255,6 @@ M4BUILTIN_HANDLER (ifelse)
   if (argc == 2)
     return;
 
-  if (m4_bad_argc (argv[0], argc, 4, -1))
-    return;
   else
     /* Diagnose excess arguments if 5, 8, 11, etc., actual arguments.  */
     m4_bad_argc (argv[0], (argc + 2) % 3, -1, 1);
@@ -347,9 +336,6 @@ M4BUILTIN_HANDLER (defn)
 {
   m4_symbol *symbol;
 
-  if (m4_bad_argc (argv[0], argc, 2, 2))
-    return;
-
   symbol = m4_symbol_lookup (M4ARG (1));
   if (symbol == NULL)
     {
@@ -382,9 +368,6 @@ M4BUILTIN_HANDLER (defn)
    and "sysval".  */
 M4BUILTIN_HANDLER (syscmd)
 {
-  if (m4_bad_argc (argv[0], argc, 2, 2))
-    return;
-
   m4_debug_flush_files ();
   m4_sysval = system (M4ARG (1));
 }
@@ -400,9 +383,6 @@ M4BUILTIN_HANDLER (incr)
 {
   int value;
 
-  if (m4_bad_argc (argv[0], argc, 2, 2))
-    return;
-
   if (!m4_numeric_arg (argv[0], M4ARG (1), &value))
     return;
 
@@ -413,9 +393,6 @@ M4BUILTIN_HANDLER (decr)
 {
   int value;
 
-  if (m4_bad_argc (argv[0], argc, 2, 2))
-    return;
-
   if (!m4_numeric_arg (argv[0], M4ARG (1), &value))
     return;
 
@@ -432,9 +409,6 @@ M4BUILTIN_HANDLER (divert)
 {
   int i = 0;
 
-  if (m4_bad_argc (argv[0], argc, 1, 2))
-    return;
-
   if (argc == 2 && !m4_numeric_arg (argv[0], M4ARG (1), &i))
     return;
 
@@ -444,8 +418,6 @@ M4BUILTIN_HANDLER (divert)
 /* Expand to the current diversion number, -1 if none.  */
 M4BUILTIN_HANDLER (divnum)
 {
-  if (m4_bad_argc (argv[0], argc, 1, 1))
-    return;
   m4_shipout_int (obs, m4_current_diversion);
 }
 
@@ -490,9 +462,6 @@ M4BUILTIN_HANDLER (undivert)
    lives in input.c.  */
 M4BUILTIN_HANDLER (dnl)
 {
-  if (m4_bad_argc (argv[0], argc, 1, 1))
-    return;
-
   m4_skip_line ();
 }
 
@@ -506,9 +475,6 @@ M4BUILTIN_HANDLER (shift)
 /* Change the current quotes.  The function set_quotes () lives in input.c.  */
 M4BUILTIN_HANDLER (changequote)
 {
-  if (m4_bad_argc (argv[0], argc, 1, 3))
-    return;
-
   m4_set_quotes ((argc >= 2) ? M4ARG (1) : NULL,
                 (argc >= 3) ? M4ARG (2) : NULL);
 }
@@ -517,9 +483,6 @@ M4BUILTIN_HANDLER (changequote)
    lives in input.c.  */
 M4BUILTIN_HANDLER (changecom)
 {
-  if (m4_bad_argc (argv[0], argc, 1, 3))
-    return;
-
   if (argc == 1)
     m4_set_comment ("", "");   /* disable comments */
   else
@@ -539,9 +502,6 @@ include (int argc, m4_token **argv, bool
   FILE *fp;
   char *name = NULL;
 
-  if (m4_bad_argc (argv[0], argc, 2, 2))
-    return;
-
   fp = m4_path_search (M4ARG (1), &name);
   if (fp == NULL)
     {
@@ -574,8 +534,6 @@ M4BUILTIN_HANDLER (sinclude)
 /* Use the first argument as at template for a temporary file name.  */
 M4BUILTIN_HANDLER (maketemp)
 {
-  if (m4_bad_argc (argv[0], argc, 2, 2))
-    return;
   mktemp (M4ARG (1));
   m4_shipout_string (obs, M4ARG (1), 0, FALSE);
 }
@@ -600,8 +558,6 @@ M4BUILTIN_HANDLER (m4exit)
 {
   int exit_code = 0;
 
-  if (m4_bad_argc (argv[0], argc, 1, 2))
-    return;
   if (argc == 2  && !m4_numeric_arg (argv[0], M4ARG (1), &exit_code))
     exit_code = 0;
 
@@ -684,8 +640,6 @@ M4BUILTIN_HANDLER (traceoff)
 /* Expand to the length of the first argument.  */
 M4BUILTIN_HANDLER (len)
 {
-  if (m4_bad_argc (argv[0], argc, 2, 2))
-    return;
   m4_shipout_int (obs, strlen (M4ARG (1)));
 }
 
@@ -696,9 +650,6 @@ M4BUILTIN_HANDLER (index)
   const char *cp, *last;
   int l1, l2, retval;
 
-  if (m4_bad_argc (argv[0], argc, 3, 3))
-    return;
-
   l1 = strlen (M4ARG (1));
   l2 = strlen (M4ARG (2));
 
@@ -722,9 +673,6 @@ M4BUILTIN_HANDLER (substr)
 {
   int start, length, avail;
 
-  if (m4_bad_argc (argv[0], argc, 3, 4))
-    return;
-
   length = avail = strlen (M4ARG (1));
   if (!m4_numeric_arg (argv[0], M4ARG (2), &start))
     return;
@@ -751,9 +699,6 @@ M4BUILTIN_HANDLER (translit)
   register const char *data, *tmp;
   const char *from, *to;
   int tolen;
-
-  if (m4_bad_argc (argv[0], argc, 3, 4))
-    return;
 
   from = M4ARG (2);
   if (strchr (from, '-') != NULL)
Index: modules/modtest.c
===================================================================
RCS file: /cvsroot/m4/m4/modules/modtest.c,v
retrieving revision 1.6
diff -u -p -u -r1.6 modtest.c
--- modules/modtest.c 2001/10/04 07:47:45 1.6
+++ modules/modtest.c 2001/10/12 19:52:37
@@ -28,23 +28,23 @@
 #define m4_builtin_table       modtest_LTX_m4_builtin_table
 #define m4_macro_table         modtest_LTX_m4_macro_table
 
-/*             function        macros  blind */
-#define builtin_functions                      \
-       BUILTIN (test,          FALSE,  FALSE)
+/*             function        macros  blind minargs maxargs */
+#define builtin_functions                                      \
+       BUILTIN (test,          FALSE,  FALSE,  1,      1)
 
-#define BUILTIN(handler, macros,  blind)       M4BUILTIN(handler)
+#define BUILTIN(handler, macros,  blind, min, max) M4BUILTIN(handler)
   builtin_functions
 #undef BUILTIN
 
 m4_builtin m4_builtin_table[] =
 {
-#define BUILTIN(handler, macros, blind)                \
-       { STR(handler), CONC(builtin_, handler), macros, blind },
+#define BUILTIN(handler, macros, blind, min, max)              \
+       { STR(handler), CONC(builtin_, handler), macros, blind, min, max },
 
   builtin_functions
 #undef BUILTIN
 
-  { 0, 0, FALSE, FALSE },
+  { 0, 0, FALSE, FALSE, 0, 0 },
 };
 
 m4_macro m4_macro_table[] =
Index: modules/mpeval.c
===================================================================
RCS file: /cvsroot/m4/m4/modules/mpeval.c,v
retrieving revision 1.10
diff -u -p -u -r1.10 mpeval.c
--- modules/mpeval.c 2001/10/01 07:56:20 1.10
+++ modules/mpeval.c 2001/10/12 19:52:37
@@ -36,9 +36,9 @@
 /* Maintain each of the builtins implemented in this modules along
    with their details in a single table for easy maintenance.
 
-               function        macros  blind */
-#define builtin_functions                      \
-       BUILTIN(mpeval,         FALSE,  TRUE )
+               function        macros  blind minargs maxargs */
+#define builtin_functions                                      \
+       BUILTIN(mpeval,         FALSE,  TRUE,   2,      4  )    \
 
 
 
@@ -79,7 +79,7 @@
 #define numb_decr(n) numb_minus(n,numb_ONE)
 
 /* Generate prototypes for each builtin handler function. */
-#define BUILTIN(handler, macros,  blind)       M4BUILTIN(handler)
+#define BUILTIN(handler, macros,  blind, min, max)  M4BUILTIN(handler)
   builtin_functions
 #undef BUILTIN
 
@@ -87,12 +87,12 @@
 /* Generate a table for mapping m4 symbol names to handler functions. */
 m4_builtin m4_builtin_table[] =
 {
-#define BUILTIN(handler, macros, blind)                \
-       { STR(handler), CONC(builtin_, handler), macros, blind },
+#define BUILTIN(handler, macros, blind, min, max)              \
+       { STR(handler), CONC(builtin_, handler), macros, blind, min, max },
   builtin_functions
 #undef BUILTIN
 
-  { 0, 0, FALSE, FALSE },
+  { 0, 0, FALSE, FALSE, 0, 0 },
 };
 
 
Index: modules/perl.c
===================================================================
RCS file: /cvsroot/m4/m4/modules/perl.c,v
retrieving revision 1.7
diff -u -p -u -r1.7 perl.c
--- modules/perl.c 2001/08/19 10:53:56 1.7
+++ modules/perl.c 2001/10/12 19:52:37
@@ -30,23 +30,24 @@
 #define m4_builtin_table       perl_LTX_m4_builtin_table
 #define m4_macro_table         perl_LTX_m4_macro_table
 
-/*             function        macros  blind */
-#define builtin_functions                      \
-       BUILTIN (perleval,      FALSE,  FALSE)
+/*             function        macros  blind minargs maxargs */
+#define builtin_functions                                      \
+       BUILTIN (perleval,      FALSE,  FALSE,  0,      -1  )   \
 
-#define BUILTIN(handler, macros,  blind)       M4BUILTIN(handler)
+
+#define BUILTIN(handler, macros,  blind, min, max)  M4BUILTIN(handler)
   builtin_functions
 #undef BUILTIN
 
 m4_builtin m4_builtin_table[] =
 {
-#define BUILTIN(handler, macros, blind)                \
-       { STR(handler), CONC(builtin_, handler), macros, blind },
+#define BUILTIN(handler, macros, blind, min, max)              \
+       { STR(handler), CONC(builtin_, handler), macros, blind, min, max },
 
   builtin_functions
 #undef BUILTIN
 
-  { 0, 0, FALSE, FALSE },
+  { 0, 0, FALSE, FALSE, 0, 0 },
 };
 
 /* A table for mapping m4 symbol names to simple expansion text. */
Index: modules/shadow.c
===================================================================
RCS file: /cvsroot/m4/m4/modules/shadow.c,v
retrieving revision 1.7
diff -u -p -u -r1.7 shadow.c
--- modules/shadow.c 2001/09/21 00:13:30 1.7
+++ modules/shadow.c 2001/10/12 19:52:37
@@ -28,24 +28,25 @@
 #define m4_builtin_table       shadow_LTX_m4_builtin_table
 #define m4_macro_table         shadow_LTX_m4_macro_table
 
-/*             function        macros  blind */
+/*             function        macros  blind minargs maxargs */
 #define builtin_functions                      \
-       BUILTIN (shadow,        FALSE,  FALSE)  \
-       BUILTIN (test,          FALSE,  FALSE)
+       BUILTIN (shadow,        FALSE,  FALSE,  0,      -1 )    \
+       BUILTIN (test,          FALSE,  FALSE,  0,      -1 )    \
 
-#define BUILTIN(handler, macros,  blind)       M4BUILTIN(handler)
+
+#define BUILTIN(handler, macros,  blind, min, max) M4BUILTIN(handler)
   builtin_functions
 #undef BUILTIN
 
 m4_builtin m4_builtin_table[] =
 {
-#define BUILTIN(handler, macros, blind)                \
-       { STR(handler), CONC(builtin_, handler), macros, blind },
+#define BUILTIN(handler, macros, blind, min, max)              \
+       { STR(handler), CONC(builtin_, handler), macros, blind, min, max },
 
   builtin_functions
 #undef BUILTIN
 
-  { 0, 0, FALSE, FALSE },
+  { 0, 0, FALSE, FALSE, 0, 0 },
 };
 
 m4_macro m4_macro_table[] =
Index: modules/stdlib.c
===================================================================
RCS file: /cvsroot/m4/m4/modules/stdlib.c,v
retrieving revision 1.6
diff -u -p -u -r1.6 stdlib.c
--- modules/stdlib.c 2001/09/07 10:49:59 1.6
+++ modules/stdlib.c 2001/10/12 19:52:37
@@ -36,36 +36,37 @@
 
 #define m4_builtin_table       stdlib_LTX_m4_builtin_table
 
-/*             function        macros  blind */
-#define builtin_functions                      \
-       BUILTIN (getcwd,        FALSE,  FALSE)  \
-       BUILTIN (getenv,        FALSE,  TRUE)   \
-       BUILTIN (getlogin,      FALSE,  FALSE)  \
-       BUILTIN (getpid,        FALSE,  FALSE)  \
-       BUILTIN (getppid,       FALSE,  FALSE)  \
-       BUILTIN (getuid,        FALSE,  FALSE)  \
-       BUILTIN (getpwnam,      FALSE,  TRUE)   \
-       BUILTIN (getpwuid,      FALSE,  TRUE)   \
-       BUILTIN (hostname,      FALSE,  FALSE)  \
-       BUILTIN (rand,          FALSE,  FALSE)  \
-       BUILTIN (srand,         FALSE,  FALSE)  \
-       BUILTIN (setenv,        FALSE,  TRUE)   \
-       BUILTIN (unsetenv,      FALSE,  TRUE)   \
-       BUILTIN (uname,         FALSE,  FALSE)
+/*             function        macros  blind minargs maxargs */
+#define builtin_functions                                      \
+       BUILTIN (getcwd,        FALSE,  FALSE,  1,      1  )    \
+       BUILTIN (getenv,        FALSE,  TRUE,   2,      2  )    \
+       BUILTIN (getlogin,      FALSE,  FALSE,  1,      1  )    \
+       BUILTIN (getpid,        FALSE,  FALSE,  1,      1  )    \
+       BUILTIN (getppid,       FALSE,  FALSE,  1,      1  )    \
+       BUILTIN (getuid,        FALSE,  FALSE,  1,      1  )    \
+       BUILTIN (getpwnam,      FALSE,  TRUE,   2,      2  )    \
+       BUILTIN (getpwuid,      FALSE,  TRUE,   2,      2  )    \
+       BUILTIN (hostname,      FALSE,  FALSE,  1,      1  )    \
+       BUILTIN (rand,          FALSE,  FALSE,  1,      1  )    \
+       BUILTIN (srand,         FALSE,  FALSE,  1,      2  )    \
+       BUILTIN (setenv,        FALSE,  TRUE,   3,      4  )    \
+       BUILTIN (unsetenv,      FALSE,  TRUE,   2,      2  )    \
+       BUILTIN (uname,         FALSE,  FALSE,  1,      1  )    \
 
-#define BUILTIN(handler, macros,  blind)       M4BUILTIN(handler);
+
+#define BUILTIN(handler, macros,  blind, min, max) M4BUILTIN(handler);
   builtin_functions
 #undef BUILTIN
 
 m4_builtin m4_builtin_table[] =
 {
-#define BUILTIN(handler, macros, blind)                \
-       { STR(handler), CONC(builtin_, handler), macros, blind },
+#define BUILTIN(handler, macros, blind, min, max)              \
+       { STR(handler), CONC(builtin_, handler), macros, blind, min, max },
 
   builtin_functions
 #undef BUILTIN
 
-  { 0, 0, FALSE, FALSE },
+  { 0, 0, FALSE, FALSE, 0, 0 },
 };
 
 /**
@@ -76,9 +77,6 @@ M4BUILTIN_HANDLER (getcwd)
   char buf[1024];
   char *bp;
 
-  if (m4_bad_argc (argv[0], argc, 1, 1))
-    return;
-
   bp = getcwd (buf, sizeof buf);
 
   if (bp != NULL)              /* in case of error return null string */
@@ -92,9 +90,6 @@ M4BUILTIN_HANDLER (getenv)
 {
   char *env;
 
-  if (m4_bad_argc (argv[0], argc, 2, 2))
-    return;
-
   env = getenv (M4ARG (1));
 
   if (env != NULL)
@@ -108,9 +103,6 @@ M4BUILTIN_HANDLER (setenv)
 {
   int overwrite = 1;
 
-  if (m4_bad_argc (argv[0], argc, 3, 4))
-    return;
-
   if (argc == 4)
     if (!m4_numeric_arg (argv[0], M4ARG (3), &overwrite))
       return;
@@ -140,8 +132,6 @@ M4BUILTIN_HANDLER (setenv)
  **/
 M4BUILTIN_HANDLER (unsetenv)
 {
-  if (m4_bad_argc (argv[0], argc, 2, 2))
-    return;
 
 #if HAVE_UNSETENV
   unsetenv (M4ARG (1));
@@ -155,9 +145,6 @@ M4BUILTIN_HANDLER (getlogin)
 {
   char *login;
 
-  if (m4_bad_argc (argv[0], argc, 1, 1))
-    return;
-
   login = getlogin ();
 
   if (login != NULL)
@@ -169,9 +156,6 @@ M4BUILTIN_HANDLER (getlogin)
  **/
 M4BUILTIN_HANDLER (getpid)
 {
-  if (m4_bad_argc (argv[0], argc, 1, 1))
-    return;
-
   m4_shipout_int (obs, getpid ());
 }
 
@@ -180,9 +164,6 @@ M4BUILTIN_HANDLER (getpid)
  **/
 M4BUILTIN_HANDLER (getppid)
 {
-  if (m4_bad_argc (argv[0], argc, 1, 1))
-    return;
-
   m4_shipout_int (obs, getppid ());
 }
 
@@ -193,9 +174,6 @@ M4BUILTIN_HANDLER (getpwnam)
 {
   struct passwd *pw;
 
-  if (m4_bad_argc (argv[0], argc, 2, 2))
-    return;
-
   pw = getpwnam (M4ARG (1));
 
   if (pw != NULL)
@@ -224,9 +202,6 @@ M4BUILTIN_HANDLER (getpwuid)
   struct passwd *pw;
   int uid;
 
-  if (m4_bad_argc (argv[0], argc, 2, 2))
-    return;
-
   if (!m4_numeric_arg (argv[0], M4ARG (1), &uid))
     return;
 
@@ -257,9 +232,6 @@ M4BUILTIN_HANDLER (hostname)
 {
   char buf[1024];
 
-  if (m4_bad_argc (argv[0], argc, 1, 1))
-    return;
-
   if (gethostname (buf, sizeof buf) < 0)
     return;
 
@@ -271,9 +243,6 @@ M4BUILTIN_HANDLER (hostname)
  **/
 M4BUILTIN_HANDLER (rand)
 {
-  if (m4_bad_argc (argv[0], argc, 1, 1))
-    return;
-
   m4_shipout_int (obs, rand ());
 }
 
@@ -284,9 +253,6 @@ M4BUILTIN_HANDLER (srand)
 {
   int seed;
 
-  if (m4_bad_argc (argv[0], argc, 1, 2))
-    return;
-
   if (argc == 1)
     seed = time (0L) * getpid ();
   else
@@ -305,9 +271,6 @@ M4BUILTIN_HANDLER (uname)
 {
   struct utsname ut;
 
-  if (m4_bad_argc (argv[0], argc, 1, 1))
-    return;
-
   if (uname (&ut) == 0)
     {
       m4_shipout_string (obs, ut.sysname, 0, TRUE);
@@ -327,8 +290,5 @@ M4BUILTIN_HANDLER (uname)
  **/
 M4BUILTIN_HANDLER (getuid)
 {
-  if (m4_bad_argc (argv[0], argc, 1, 1))
-    return;
-
   m4_shipout_int (obs, getuid ());
 }
Index: modules/time.c
===================================================================
RCS file: /cvsroot/m4/m4/modules/time.c,v
retrieving revision 1.6
diff -u -p -u -r1.6 time.c
--- modules/time.c 2001/09/07 10:49:59 1.6
+++ modules/time.c 2001/10/12 19:52:41
@@ -33,20 +33,21 @@
 
 #define m4_builtin_table       time_LTX_m4_builtin_table
 
-/*             function        macros  blind */
-#define builtin_functions                      \
-       BUILTIN (currenttime,   FALSE,  FALSE)  \
-       BUILTIN (ctime,         FALSE,  FALSE)  \
-       BUILTIN (gmtime,        FALSE,  TRUE)   \
-       BUILTIN (localtime,     FALSE,  TRUE)
+/*             function        macros  blind minargs maxargs */
+#define builtin_functions                                      \
+       BUILTIN (currenttime,   FALSE,  FALSE,  1,      1  )    \
+       BUILTIN (ctime,         FALSE,  FALSE,  1,      2  )    \
+       BUILTIN (gmtime,        FALSE,  TRUE,   2,      2  )    \
+       BUILTIN (localtime,     FALSE,  TRUE,   2,      2  )    \
 
-#define mktime_functions                       \
-       BUILTIN (mktime,        FALSE,  TRUE)
+#define mktime_functions                                       \
+       BUILTIN (mktime,        FALSE,  TRUE,   7,      8  )    \
 
-#define strftime_functions                     \
-       BUILTIN (strftime,      FALSE,  TRUE)
+#define strftime_functions                                     \
+       BUILTIN (strftime,      FALSE,  TRUE,   3,      3  )    \
 
-#define BUILTIN(handler, macros,  blind)       M4BUILTIN(handler)
+
+#define BUILTIN(handler, macros,  blind, min, max)  M4BUILTIN(handler)
   builtin_functions
 # if HAVE_MKTIME
   mktime_functions
@@ -58,8 +59,8 @@
 
 m4_builtin m4_builtin_table[] =
 {
-#define BUILTIN(handler, macros, blind)                \
-       { STR(handler), CONC(builtin_, handler), macros, blind },
+#define BUILTIN(handler, macros, blind, min, max)              \
+       { STR(handler), CONC(builtin_, handler), macros, blind, min, max },
 
   builtin_functions
 # if HAVE_MKTIME
@@ -82,9 +83,6 @@ M4BUILTIN_HANDLER (currenttime)
   time_t now;
   int l;
 
-  if (m4_bad_argc (argv[0], argc, 1, 1))
-    return;
-
   now = time (0L);
   l = sprintf (buf, "%ld", now);
 
@@ -98,9 +96,6 @@ M4BUILTIN_HANDLER (ctime)
 {
   time_t t;
 
-  if (m4_bad_argc (argv[0], argc, 1, 2))
-    return;
-
   if (argc == 2)
     m4_numeric_arg (argv[0], M4ARG (1), (int *) &t);
   else
@@ -146,9 +141,6 @@ M4BUILTIN_HANDLER (gmtime)
 {
   time_t t;
 
-  if (m4_bad_argc (argv[0], argc, 2, 2))
-    return;
-
   if (!m4_numeric_arg (argv[0], M4ARG (1), (int *) &t))
     return;
 
@@ -162,9 +154,6 @@ M4BUILTIN_HANDLER (localtime)
 {
   time_t t;
 
-  if (m4_bad_argc (argv[0], argc, 2, 2))
-    return;
-
   if (!m4_numeric_arg (argv[0], M4ARG (1), (int *) &t))
     return;
 
@@ -180,9 +169,6 @@ M4BUILTIN_HANDLER (mktime)
   struct tm tm;
   time_t t;
 
-  if (m4_bad_argc (argv[0], argc, 7, 8))
-    return;
-
   if (!m4_numeric_arg (argv[0], M4ARG (1), &tm.tm_sec))
     return;
   if (!m4_numeric_arg (argv[0], M4ARG (2), &tm.tm_min))
@@ -214,9 +200,6 @@ M4BUILTIN_HANDLER (strftime)
   time_t t;
   char *buf;
   int l;
-
-  if (m4_bad_argc (argv[0], argc, 3, 3))
-    return;
 
   if (!m4_numeric_arg (argv[0], M4ARG (2), (int *) &t))
     return;
Index: src/freeze.c
===================================================================
RCS file: /cvsroot/m4/m4/src/freeze.c,v
retrieving revision 1.20
diff -u -p -u -r1.20 freeze.c
--- src/freeze.c 2001/10/11 21:09:16 1.20
+++ src/freeze.c 2001/10/12 19:52:41
@@ -480,7 +480,8 @@ reload_frozen_state (const char *name)
              if (bp->blind_if_no_args)
                BIT_SET (flags, TOKEN_BLIND_ARGS_BIT);
 
-             m4_builtin_pushdef (string[0], handle, bp->func, flags);
+             m4_builtin_pushdef (string[0], handle, bp->func, flags,
+                                 bp->min_args, bp->max_args);
            }
          else
            M4ERROR ((warning_status, 0,
@@ -656,7 +657,7 @@ reload_frozen_state (const char *name)
              if (strcmp (m4_module_name (handle), string[2]) == 0)
                break;
 
-         m4_macro_pushdef (string[0], handle, string[1], 0);
+         m4_macro_pushdef (string[0], handle, string[1], 0, 0, -1);
        }
        break;
 
Index: src/main.c
===================================================================
RCS file: /cvsroot/m4/m4/src/main.c,v
retrieving revision 1.29
diff -u -p -u -r1.29 main.c
--- src/main.c 2001/10/11 21:09:16 1.29
+++ src/main.c 2001/10/12 19:52:43
@@ -435,7 +435,7 @@ warranty; not even for MERCHANTABILITY o
            macro_value = "";
          else
            *macro_value++ = '\0';
-         m4_macro_define (defines->macro, NULL, macro_value, 0x0);
+         m4_macro_define (defines->macro, NULL, macro_value, 0x0, 0, -1);
          break;
 
        case 'U':

-- 
  ())_. Gary V. Vaughan     gary@(oranda.demon.co.uk|gnu.org)
  ( '/  Research Scientist  http://www.oranda.demon.co.uk       ,_())____
  / )=  GNU Hacker          http://www.gnu.org/software/libtool  \'      `&
`(_~)_  Tech' Author        http://sources.redhat.com/autobook   =`---d__/



reply via email to

[Prev in Thread] Current Thread [Next in Thread]