]> granicus.if.org Git - nethack/commitdiff
revisit variable arguments in new lev_comp
authorPatR <rankin@nethack.org>
Fri, 10 Apr 2015 08:39:55 +0000 (01:39 -0700)
committerPatR <rankin@nethack.org>
Fri, 10 Apr 2015 08:39:55 +0000 (01:39 -0700)
The previous USE_OLDARGS worked with gcc on Intel, but was inherently
unsafe.  This method is completely safe, just obnoxiously intrusive.
It you disliked debugpline*(), you're bound to hate this....

include/sp_lev.h
include/tradstdc.h
util/lev_comp.y
util/lev_main.c

index 05c7ea6c6eb0a6d53c1ffe421e4f4082444cd28e..badc3e97c5355a953ae8774816cecf9cd2cf77fc 100644 (file)
@@ -1,4 +1,4 @@
-/* NetHack 3.5 sp_lev.h        $NHDT-Date$  $NHDT-Branch$:$NHDT-Revision$ */
+/* NetHack 3.5 sp_lev.h        $NHDT-Date: 1428655166 2015/04/10 08:39:26 $  $NHDT-Branch: master $:$NHDT-Revision: 1.10 $ */
 /* NetHack 3.5 sp_lev.h        $Date: 2009/05/06 10:45:06 $  $Revision: 1.5 $ */
 /*     SCCS Id: @(#)sp_lev.h   3.5     2007/08/01      */
 /* Copyright (c) 1989 by Jean-Christophe Collet                          */
@@ -471,4 +471,82 @@ struct lc_breakdef {
     int break_depth;
 };
 
+/*
+ * Quick! Avert your eyes while you still have a chance!
+ */
+#ifdef SPEC_LEV
+/* compiling lev_comp rather than nethack */
+# ifdef USE_OLDARGS
+#  undef VA_ARGS
+#  undef VA_DECL
+#  undef VA_DECL2
+#  undef VA_SHIFT
+#  define VA_ARGS      arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,\
+                       arg10,arg11,arg12,arg13,arg14
+#  define VA_DECL(typ1,var1)  (var1,VA_ARGS) \
+       typ1 var1; \
+       char *arg1,*arg2,*arg3,*arg4,*arg5,*arg6,*arg7,*arg8,*arg9,\
+            *arg10,*arg11,*arg12,*arg13,*arg14; {
+#  define VA_DECL2(typ1,var1,typ2,var2)  (var1,var2,VA_ARGS) \
+       typ1 var1; typ2 var2; \
+       char *arg1,*arg2,*arg3,*arg4,*arg5,*arg6,*arg7,*arg8,*arg9,\
+            *arg10,*arg11,*arg12,*arg13,*arg14; {
+   /* unlike in the core, lev_comp's VA_SHIFT is completely safe,
+      because callers always pass all these arguments */
+#  define VA_SHIFT()   (arg1=arg2, arg2=arg3, arg3=arg4, arg4=arg5,\
+                        arg5=arg6, arg6=arg7, arg7=arg8, arg8=arg9,\
+                        arg9=arg10, arg10=arg11, arg11=arg12,\
+                        arg12=arg13, arg13=arg14, arg14=0)
+   /* standard NULL may be either (void *)0 or plain 0, both of
+      which would need to be explicitly cast to (char *) here */
+typedef char *Va;
+#  define VA_PASS1(a1)         (Va)a1, (Va)0,(Va)0,(Va)0,(Va)0,\
+                               (Va)0,(Va)0,(Va)0,(Va)0,(Va)0,\
+                               (Va)0,(Va)0,(Va)0,(Va)0
+#  define VA_PASS2(a1,a2)      (Va)a1, (Va)a2, (Va)0,(Va)0,(Va)0,\
+                               (Va)0,(Va)0,(Va)0,(Va)0,(Va)0,\
+                               (Va)0,(Va)0,(Va)0,(Va)0
+#  define VA_PASS3(a1,a2,a3)   (Va)a1, (Va)a2, (Va)a3, (Va)0,(Va)0,\
+                               (Va)0,(Va)0,(Va)0,(Va)0,(Va)0,\
+                               (Va)0,(Va)0,(Va)0,(Va)0
+#  define VA_PASS4(a1,a2,a3,a4)        (Va)a1, (Va)a2, (Va)a3, (Va)a4, (Va)0,\
+                               (Va)0,(Va)0,(Va)0,(Va)0,(Va)0,\
+                               (Va)0,(Va)0,(Va)0,(Va)0
+#  define VA_PASS5(a1,a2,a3,a4,a5) \
+                               (Va)a1, (Va)a2, (Va)a3, (Va)a4, (Va)a5,\
+                               (Va)0,(Va)0,(Va)0,(Va)0,(Va)0,\
+                               (Va)0,(Va)0,(Va)0,(Va)0
+#  define VA_PASS7(a1,a2,a3,a4,a5,a6,a7) \
+                               (Va)a1, (Va)a2, (Va)a3, (Va)a4, (Va)a5,\
+                               (Va)a6, (Va)a7, (Va)0,(Va)0,(Va)0,\
+                               (Va)0,(Va)0,(Va)0,(Va)0
+#  define VA_PASS8(a1,a2,a3,a4,a5,a6,a7,a8) \
+                               (Va)a1, (Va)a2, (Va)a3, (Va)a4, (Va)a5,\
+                               (Va)a6, (Va)a7, (Va)a8, (Va)0,(Va)0,\
+                               (Va)0,(Va)0,(Va)0,(Va)0
+#  define VA_PASS9(a1,a2,a3,a4,a5,a6,a7,a8,a9) \
+                               (Va)a1, (Va)a2, (Va)a3, (Va)a4, (Va)a5,\
+                               (Va)a6, (Va)a7, (Va)a8, (Va)a9, (Va)0,\
+                               (Va)0,(Va)0,(Va)0,(Va)0
+#  define VA_PASS14(a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14)    \
+                               (Va)a1, (Va)a2, (Va)a3, (Va)a4, (Va)a5,\
+                               (Va)a6, (Va)a7, (Va)a8, (Va)a9, (Va)a10,\
+                               (Va)a11, (Va)a12, (Va)a13, (Va)a14
+# else /*!USE_OLDARGS*/
+   /* USE_STDARG and USE_VARARGS don't need to pass dummy arguments
+      or cast real ones */
+#  define VA_PASS1(a1)         a1
+#  define VA_PASS2(a1,a2)      a1,a2
+#  define VA_PASS3(a1,a2,a3)   a1,a2,a3
+#  define VA_PASS4(a1,a2,a3,a4)        a1,a2,a3,a4
+#  define VA_PASS5(a1,a2,a3,a4,a5) a1,a2,a3,a4,a5
+#  define VA_PASS7(a1,a2,a3,a4,a5,a6,a7) a1,a2,a3,a4,a5,a6,a7
+#  define VA_PASS8(a1,a2,a3,a4,a5,a6,a7,a8) a1,a2,a3,a4,a5,a6,a7,a8
+#  define VA_PASS9(a1,a2,a3,a4,a5,a6,a7,a8,a9) a1,a2,a3,a4,a5,a6,a7,a8,a9
+#  define VA_PASS14(a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14) \
+                               a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14
+# endif /*?USE_OLDARGS*/
+/* You were warned to avert your eyes.... */
+#endif /*SPEC_LEV*/
+
 #endif /* SP_LEV_H */
index 82ffe996dc3d592e4c7374c0610fc3bb2aab7dc3..83b07f7caa0277f8a2e6b70317462687c39f5037 100644 (file)
@@ -1,4 +1,4 @@
-/* NetHack 3.5 tradstdc.h      $NHDT-Date: 1428574130 2015/04/09 10:08:50 $  $NHDT-Branch: master $:$NHDT-Revision: 1.18 $ */
+/* NetHack 3.5 tradstdc.h      $NHDT-Date: 1428655166 2015/04/10 08:39:26 $  $NHDT-Branch: master $:$NHDT-Revision: 1.19 $ */
 /* NetHack 3.5 tradstdc.h      $Date: 2012/01/11 18:23:26 $  $Revision: 1.15 $ */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /* NetHack may be freely redistributed.  See license for details. */
 #  define VA_NEXT(var1,typ1)   var1 = va_arg(the_args,typ1)
 #  define VA_END()             va_end(the_args)
 # else
-    /* the core never uses this many arguments, but lev_comp does */
-#   define VA_ARGS     arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,\
-                       arg10,arg11,arg12,arg13,arg14
+#   define VA_ARGS     arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9
 #   define VA_DECL(typ1,var1)  (var1,VA_ARGS) typ1 var1; \
-       char *arg1,*arg2,*arg3,*arg4,*arg5,*arg6,*arg7,*arg8,*arg9,\
-            *arg10,*arg11,*arg12,*arg13,*arg14; {
+       char *arg1,*arg2,*arg3,*arg4,*arg5,*arg6,*arg7,*arg8,*arg9; {
 #   define VA_DECL2(typ1,var1,typ2,var2)  (var1,var2,VA_ARGS) \
        typ1 var1; typ2 var2; \
-       char *arg1,*arg2,*arg3,*arg4,*arg5,*arg6,*arg7,*arg8,*arg9,\
-            *arg10,*arg11,*arg12,*arg13,*arg14; {
+       char *arg1,*arg2,*arg3,*arg4,*arg5,*arg6,*arg7,*arg8,*arg9; {
 #   define VA_START(x)
 #   define VA_INIT(var1,typ1)
+    /* this is inherently risky, and should only be attempted as a
+       very last resort; manipulating arguments which haven't actually
+       been passed may or may not cause severe trouble depending on
+       the function-calling/argument-passing mechanism being used */
 #   define VA_SHIFT()  (arg1=arg2, arg2=arg3, arg3=arg4, arg4=arg5,\
-                        arg5=arg6, arg6=arg7, arg7=arg8, arg8=arg9,\
-                        arg9=arg10, arg10=arg11, arg11=arg12,\
-                        arg12=arg13, arg13=arg14, arg14=0)
+                        arg5=arg6, arg6=arg7, arg7=arg8, arg8=arg9)
 #   define VA_NEXT(var1,typ1)  ((var1 = (typ1)arg1), VA_SHIFT(), var1)
 #   define VA_END()
 # endif
index 281bd3fcf5a672fae3991ec6de88f7ee220cbb80..0a153bef2bb92d66ef3d90e3f677baf4762715f4 100644 (file)
@@ -1,5 +1,5 @@
 %{
-/* NetHack 3.5  lev_comp.y     $NHDT-Date: 1428574134 2015/04/09 10:08:54 $  $NHDT-Branch: master $:$NHDT-Revision: 1.10 $ */
+/* NetHack 3.5  lev_comp.y     $NHDT-Date: 1428655167 2015/04/10 08:39:27 $  $NHDT-Branch: master $:$NHDT-Revision: 1.11 $ */
 /* NetHack 3.5  lev_comp.y     $Date: 2009/05/06 10:54:31 $  $Revision: 1.8 $ */
 /*     SCCS Id: @(#)lev_yacc.c 3.5     2007/08/01      */
 /*     Copyright (c) 1989 by Jean-Christophe Collet */
@@ -23,6 +23,7 @@
  #pragma alloca                /* keep leading space! */
 #endif
 
+#define SPEC_LEV    /* for USE_OLDARGS (sp_lev.h) */
 #include "hack.h"
 #include "sp_lev.h"
 
@@ -311,12 +312,17 @@ level_def : LEVEL_ID ':' STRING
                  {
                      start_level_def(&splev, $3);
                      if ($5 == -1) {
-                         add_opvars(splev, "iiiiiiiio", LVLINIT_MAZEGRID,HWALL,0,0, 0,0,0,0, SPO_INITLEVEL);
+                         add_opvars(splev, "iiiiiiiio",
+                                    VA_PASS9(LVLINIT_MAZEGRID,HWALL,0,0,
+                                             0,0,0,0, SPO_INITLEVEL));
                      } else {
                          long bg = what_map_char((char) $5);
-                         add_opvars(splev, "iiiiiiiio", LVLINIT_SOLIDFILL, bg, 0,0, 0,0,0,0, SPO_INITLEVEL);
+                         add_opvars(splev, "iiiiiiiio",
+                                    VA_PASS9(LVLINIT_SOLIDFILL, bg, 0,0,
+                                             0,0,0,0, SPO_INITLEVEL));
                      }
-                     add_opvars(splev, "io", MAZELEVEL, SPO_LEVEL_FLAGS);
+                     add_opvars(splev, "io",
+                                VA_PASS2(MAZELEVEL, SPO_LEVEL_FLAGS));
                      max_x_map = COLNO-1;
                      max_y_map = ROWNO;
                      $$ = $3;
@@ -338,7 +344,8 @@ lev_init    : LEV_INIT_ID ':' SOLID_FILL_ID ',' terrain_type
                      long filling = $5.ter;
                      if (filling == INVALID_TYPE || filling >= MAX_TYPE)
                          lc_error("INIT_MAP: Invalid fill char type.");
-                     add_opvars(splev, "iiiiiiiio", LVLINIT_SOLIDFILL,filling,0,(long)$5.lit, 0,0,0,0, SPO_INITLEVEL);
+                     add_opvars(splev, "iiiiiiiio",
+                                LVLINIT_SOLIDFILL,filling,0,(long)$5.lit, 0,0,0,0, SPO_INITLEVEL);
                      max_x_map = COLNO-1;
                      max_y_map = ROWNO;
                  }
@@ -347,13 +354,17 @@ lev_init  : LEV_INIT_ID ':' SOLID_FILL_ID ',' terrain_type
                      long filling = what_map_char((char) $5);
                      if (filling == INVALID_TYPE || filling >= MAX_TYPE)
                          lc_error("INIT_MAP: Invalid fill char type.");
-                     add_opvars(splev, "iiiiiiiio", LVLINIT_MAZEGRID,filling,0,0, 0,0,0,0, SPO_INITLEVEL);
+                     add_opvars(splev, "iiiiiiiio",
+                                VA_PASS9(LVLINIT_MAZEGRID,filling,0,0,
+                                         0,0,0,0, SPO_INITLEVEL));
                      max_x_map = COLNO-1;
                      max_y_map = ROWNO;
                  }
                | LEV_INIT_ID ':' ROGUELEV_ID
                  {
-                     add_opvars(splev, "iiiiiiiio", LVLINIT_ROGUE,0,0,0,0,0,0,0, SPO_INITLEVEL);
+                     add_opvars(splev, "iiiiiiiio",
+                                VA_PASS9(LVLINIT_ROGUE,0,0,0,
+                                         0,0,0,0, SPO_INITLEVEL));
                  }
                | LEV_INIT_ID ':' MINES_ID ',' CHAR ',' CHAR ',' BOOLEAN ',' BOOLEAN ',' light_state ',' walled opt_fillchar
                  {
@@ -374,7 +385,10 @@ lev_init   : LEV_INIT_ID ':' SOLID_FILL_ID ',' terrain_type
                      if (filling == INVALID_TYPE)
                          lc_error("INIT_MAP: Invalid fill char type.");
 
-                     add_opvars(splev, "iiiiiiiio", LVLINIT_MINES,filling,walled,lit, joined,smoothed,bg,fg, SPO_INITLEVEL);
+                     add_opvars(splev, "iiiiiiiio",
+                                VA_PASS9(LVLINIT_MINES,filling,walled,lit,
+                                         joined,smoothed,bg,fg,
+                                         SPO_INITLEVEL));
                        max_x_map = COLNO-1;
                        max_y_map = ROWNO;
                  }
@@ -392,7 +406,7 @@ opt_limited : /* nothing */
 
 opt_coord_or_var       : /* nothing */
                  {
-                     add_opvars(splev, "o", SPO_COPY);
+                     add_opvars(splev, "o", VA_PASS1(SPO_COPY));
                      $$ = 0;
                  }
                | ',' coord_or_var
@@ -418,11 +432,11 @@ walled            : BOOLEAN
 
 flags          : /* nothing */
                  {
-                     add_opvars(splev, "io", 0, SPO_LEVEL_FLAGS);
+                     add_opvars(splev, "io", VA_PASS2(0, SPO_LEVEL_FLAGS));
                  }
                | FLAGS_ID ':' flag_list
                  {
-                     add_opvars(splev, "io", $3, SPO_LEVEL_FLAGS);
+                     add_opvars(splev, "io", VA_PASS2($3, SPO_LEVEL_FLAGS));
                  }
                ;
 
@@ -536,7 +550,7 @@ shuffle_detail      : SHUFFLE_ID ':' any_var_array
                          if (!(vd->var_type & SPOVAR_ARRAY))
                              lc_error("Trying to shuffle non-array variable '%s'", $3);
                      } else lc_error("Trying to shuffle undefined variable '%s'", $3);
-                     add_opvars(splev, "so", $3, SPO_SHUFFLE_ARRAY);
+                     add_opvars(splev, "so", VA_PASS2($3, SPO_SHUFFLE_ARRAY));
                      Free($3);
                  }
                ;
@@ -544,134 +558,141 @@ shuffle_detail  : SHUFFLE_ID ':' any_var_array
 variable_define        : any_var_or_arr '=' math_expr_var
                  {
                      variable_definitions = add_vardef_type(variable_definitions, $1, SPOVAR_INT);
-                     add_opvars(splev, "iso", 0, $1, SPO_VAR_INIT);
+                     add_opvars(splev, "iso", VA_PASS3(0, $1, SPO_VAR_INIT));
                      Free($1);
                  }
                | any_var_or_arr '=' selection_ID ':' ter_selection
                  {
                      variable_definitions = add_vardef_type(variable_definitions, $1, SPOVAR_SEL);
-                     add_opvars(splev, "iso", 0, $1, SPO_VAR_INIT);
+                     add_opvars(splev, "iso", VA_PASS3(0, $1, SPO_VAR_INIT));
                      Free($1);
                  }
                | any_var_or_arr '=' string_expr
                  {
                      variable_definitions = add_vardef_type(variable_definitions, $1, SPOVAR_STRING);
-                     add_opvars(splev, "iso", 0, $1, SPO_VAR_INIT);
+                     add_opvars(splev, "iso", VA_PASS3(0, $1, SPO_VAR_INIT));
                      Free($1);
                  }
                | any_var_or_arr '=' terrainid ':' mapchar_or_var
                  {
                      variable_definitions = add_vardef_type(variable_definitions, $1, SPOVAR_MAPCHAR);
-                     add_opvars(splev, "iso", 0, $1, SPO_VAR_INIT);
+                     add_opvars(splev, "iso", VA_PASS3(0, $1, SPO_VAR_INIT));
                      Free($1);
                  }
                | any_var_or_arr '=' monsterid ':' monster_or_var
                  {
                      variable_definitions = add_vardef_type(variable_definitions, $1, SPOVAR_MONST);
-                     add_opvars(splev, "iso", 0, $1, SPO_VAR_INIT);
+                     add_opvars(splev, "iso", VA_PASS3(0, $1, SPO_VAR_INIT));
                      Free($1);
                  }
                | any_var_or_arr '=' objectid ':' object_or_var
                  {
                      variable_definitions = add_vardef_type(variable_definitions, $1, SPOVAR_OBJ);
-                     add_opvars(splev, "iso", 0, $1, SPO_VAR_INIT);
+                     add_opvars(splev, "iso", VA_PASS3(0, $1, SPO_VAR_INIT));
                      Free($1);
                  }
                | any_var_or_arr '=' coord_or_var
                  {
                      variable_definitions = add_vardef_type(variable_definitions, $1, SPOVAR_COORD);
-                     add_opvars(splev, "iso", 0, $1, SPO_VAR_INIT);
+                     add_opvars(splev, "iso", VA_PASS3(0, $1, SPO_VAR_INIT));
                      Free($1);
                  }
                | any_var_or_arr '=' region_or_var
                  {
                      variable_definitions = add_vardef_type(variable_definitions, $1, SPOVAR_REGION);
-                     add_opvars(splev, "iso", 0, $1, SPO_VAR_INIT);
+                     add_opvars(splev, "iso", VA_PASS3(0, $1, SPO_VAR_INIT));
                      Free($1);
                  }
                | any_var_or_arr '=' '{' integer_list '}'
                  {
                      long n_items = $4;
                      variable_definitions = add_vardef_type(variable_definitions, $1, SPOVAR_INT|SPOVAR_ARRAY);
-                     add_opvars(splev, "iso", n_items, $1, SPO_VAR_INIT);
+                     add_opvars(splev, "iso",
+                                VA_PASS3(n_items, $1, SPO_VAR_INIT));
                      Free($1);
                  }
                | any_var_or_arr '=' '{' encodecoord_list '}'
                  {
                      long n_items = $4;
                      variable_definitions = add_vardef_type(variable_definitions, $1, SPOVAR_COORD|SPOVAR_ARRAY);
-                     add_opvars(splev, "iso", n_items, $1, SPO_VAR_INIT);
+                     add_opvars(splev, "iso",
+                                VA_PASS3(n_items, $1, SPO_VAR_INIT));
                      Free($1);
                  }
                | any_var_or_arr '=' '{' encoderegion_list '}'
                  {
                      long n_items = $4;
                      variable_definitions = add_vardef_type(variable_definitions, $1, SPOVAR_REGION|SPOVAR_ARRAY);
-                     add_opvars(splev, "iso", n_items, $1, SPO_VAR_INIT);
+                     add_opvars(splev, "iso",
+                                VA_PASS3(n_items, $1, SPO_VAR_INIT));
                      Free($1);
                  }
                | any_var_or_arr '=' terrainid ':' '{' mapchar_list '}'
                  {
                      long n_items = $6;
                      variable_definitions = add_vardef_type(variable_definitions, $1, SPOVAR_MAPCHAR|SPOVAR_ARRAY);
-                     add_opvars(splev, "iso", n_items, $1, SPO_VAR_INIT);
+                     add_opvars(splev, "iso",
+                                VA_PASS3(n_items, $1, SPO_VAR_INIT));
                      Free($1);
                  }
                | any_var_or_arr '=' monsterid ':' '{' encodemonster_list '}'
                  {
                      long n_items = $6;
                      variable_definitions = add_vardef_type(variable_definitions, $1, SPOVAR_MONST|SPOVAR_ARRAY);
-                     add_opvars(splev, "iso", n_items, $1, SPO_VAR_INIT);
+                     add_opvars(splev, "iso",
+                                VA_PASS3(n_items, $1, SPO_VAR_INIT));
                      Free($1);
                  }
                | any_var_or_arr '=' objectid ':' '{' encodeobj_list '}'
                  {
                      long n_items = $6;
                      variable_definitions = add_vardef_type(variable_definitions, $1, SPOVAR_OBJ|SPOVAR_ARRAY);
-                     add_opvars(splev, "iso", n_items, $1, SPO_VAR_INIT);
+                     add_opvars(splev, "iso",
+                                VA_PASS3(n_items, $1, SPO_VAR_INIT));
                      Free($1);
                  }
                | any_var_or_arr '=' '{' string_list '}'
                  {
                      long n_items = $4;
                      variable_definitions = add_vardef_type(variable_definitions, $1, SPOVAR_STRING|SPOVAR_ARRAY);
-                     add_opvars(splev, "iso", n_items, $1, SPO_VAR_INIT);
+                     add_opvars(splev, "iso",
+                                VA_PASS3(n_items, $1, SPO_VAR_INIT));
                      Free($1);
                  }
                ;
 
 encodeobj_list : encodeobj
                  {
-                     add_opvars(splev, "O", $1);
+                     add_opvars(splev, "O", VA_PASS1($1));
                      $$ = 1;
                  }
                | encodeobj_list ',' encodeobj
                  {
-                     add_opvars(splev, "O", $3);
+                     add_opvars(splev, "O", VA_PASS1($3));
                      $$ = 1 + $1;
                  }
                ;
 
 encodemonster_list     : encodemonster
                  {
-                     add_opvars(splev, "M", $1);
+                     add_opvars(splev, "M", VA_PASS1($1));
                      $$ = 1;
                  }
                | encodemonster_list ',' encodemonster
                  {
-                     add_opvars(splev, "M", $3);
+                     add_opvars(splev, "M", VA_PASS1($3));
                      $$ = 1 + $1;
                  }
                ;
 
 mapchar_list   : mapchar
                  {
-                     add_opvars(splev, "m", $1);
+                     add_opvars(splev, "m", VA_PASS1($1));
                      $$ = 1;
                  }
                | mapchar_list ',' mapchar
                  {
-                     add_opvars(splev, "m", $3);
+                     add_opvars(splev, "m", VA_PASS1($3));
                      $$ = 1 + $1;
                  }
                ;
@@ -688,12 +709,12 @@ encoderegion_list : encoderegion
 
 encodecoord_list       : encodecoord
                  {
-                     add_opvars(splev, "c", $1);
+                     add_opvars(splev, "c", VA_PASS1($1));
                      $$ = 1;
                  }
                | encodecoord_list ',' encodecoord
                  {
-                     add_opvars(splev, "c", $3);
+                     add_opvars(splev, "c", VA_PASS1($3));
                      $$ = 1 + $1;
                  }
                ;
@@ -746,7 +767,7 @@ function_define     : FUNCTION_ID NQSTRING '('
                  }
                stmt_block
                  {
-                     add_opvars(splev, "io", 0, SPO_RETURN);
+                     add_opvars(splev, "io", VA_PASS2(0, SPO_RETURN));
                      splev = function_splev_backup;
                      in_function_definition--;
                      curr_function = NULL;
@@ -782,7 +803,9 @@ function_call       : NQSTRING '(' func_call_params_list ')'
                              { /* init function parameter variables */
                                  struct lc_funcdefs_parm *tfp = tmpfunc->params;
                                  while (tfp) {
-                                     add_opvars(splev, "iso", 0, tfp->name, SPO_VAR_INIT);
+                                     add_opvars(splev, "iso",
+                                                VA_PASS3(0, tfp->name,
+                                                         SPO_VAR_INIT));
                                      tfp = tfp->next;
                                  }
                              }
@@ -791,7 +814,8 @@ function_call       : NQSTRING '(' func_call_params_list ')'
                              set_opvar_int(jmp, splev->n_opcodes - jmp->vardata.l);
                          }
                          l = tmpfunc->addr - splev->n_opcodes - 2;
-                         add_opvars(splev, "iio", nparams, l, SPO_CALL);
+                         add_opvars(splev, "iio",
+                                    VA_PASS3(nparams, l, SPO_CALL));
                          tmpfunc->n_called++;
                      } else {
                          lc_error("Function '%s' not defined.", $1);
@@ -819,7 +843,8 @@ opt_percent : /* nothing */
 comparestmt     : PERCENT
                   {
                      /* val > rn2(100) */
-                     add_opvars(splev, "iio", (long)$1, 100, SPO_RN2);
+                     add_opvars(splev, "iio",
+                                VA_PASS3((long)$1, 100, SPO_RN2));
                      $$ = SPO_JG;
                   }
                | '[' math_expr_var COMPARE_TYPE math_expr_var ']'
@@ -829,7 +854,7 @@ comparestmt     : PERCENT
                | '[' math_expr_var ']'
                   {
                      /* boolean, explicit foo != 0 */
-                     add_opvars(splev, "i", 0);
+                     add_opvars(splev, "i", VA_PASS1(0));
                      $$ = SPO_JNE;
                   }
                ;
@@ -850,7 +875,7 @@ switchstatement     : SWITCH_ID
                      switch_default_case = NULL;
 
                      if (!is_inconstant_number)
-                         add_opvars(splev, "o", SPO_RN2);
+                         add_opvars(splev, "o", VA_PASS1(SPO_RN2));
                      is_inconstant_number = 0;
 
                      chkjmp = New(struct opvar);
@@ -870,17 +895,22 @@ switchstatement   : SWITCH_ID
                      add_opcode(splev, SPO_PUSH, endjump);
                      add_opcode(splev, SPO_JMP, NULL);
 
-                     set_opvar_int(switch_check_jump, splev->n_opcodes - switch_check_jump->vardata.l);
+                     set_opvar_int(switch_check_jump,
+                            splev->n_opcodes - switch_check_jump->vardata.l);
 
                      for (i = 0; i < n_switch_case_list; i++) {
-                         add_opvars(splev, "oio", SPO_COPY, switch_case_value[i], SPO_CMP);
-                         set_opvar_int(switch_case_list[i], switch_case_list[i]->vardata.l - splev->n_opcodes-1);
+                         add_opvars(splev, "oio",
+                                    VA_PASS3(SPO_COPY,
+                                             switch_case_value[i], SPO_CMP));
+                         set_opvar_int(switch_case_list[i],
+                        switch_case_list[i]->vardata.l - splev->n_opcodes-1);
                          add_opcode(splev, SPO_PUSH, switch_case_list[i]);
                          add_opcode(splev, SPO_JE, NULL);
                      }
 
                      if (switch_default_case) {
-                         set_opvar_int(switch_default_case, switch_default_case->vardata.l - splev->n_opcodes-1);
+                         set_opvar_int(switch_default_case,
+                        switch_default_case->vardata.l - splev->n_opcodes-1);
                          add_opcode(splev, SPO_PUSH, switch_default_case);
                          add_opcode(splev, SPO_JMP, NULL);
                      }
@@ -953,17 +983,23 @@ forstmt_start     : FOR_ID any_var_or_unk '=' math_expr_var for_to_span math_expr_va
                      /* first, define a variable for the for-loop end value */
                      snprintf(buf, 255, "%s end", $2);
                      /* the value of which is already in stack (the 2nd math_expr) */
-                     add_opvars(splev, "iso", 0, buf, SPO_VAR_INIT);
+                     add_opvars(splev, "iso", VA_PASS3(0, buf, SPO_VAR_INIT));
 
-                     variable_definitions = add_vardef_type(variable_definitions, $2, SPOVAR_INT);
+                     variable_definitions = add_vardef_type(variable_definitions,
+                                                            $2, SPOVAR_INT);
                      /* define the for-loop variable. value is in stack (1st math_expr) */
-                     add_opvars(splev, "iso", 0, $2, SPO_VAR_INIT);
+                     add_opvars(splev, "iso", VA_PASS3(0, $2, SPO_VAR_INIT));
 
                      /* calculate value for the loop "step" variable */
                      snprintf(buf2, 255, "%s step", $2);
-                     add_opvars(splev, "vvo", buf, $2, SPO_MATH_SUB); /* end - start */
-                     add_opvars(splev, "o", SPO_MATH_SIGN); /* sign of that */
-                     add_opvars(splev, "iso", 0, buf2, SPO_VAR_INIT); /* save the sign into the step var */
+                     /* end - start */
+                     add_opvars(splev, "vvo",
+                                VA_PASS3(buf, $2, SPO_MATH_SUB));
+                     /* sign of that */
+                     add_opvars(splev, "o", VA_PASS1(SPO_MATH_SIGN));
+                     /* save the sign into the step var */
+                     add_opvars(splev, "iso",
+                                VA_PASS3(0, buf2, SPO_VAR_INIT));
 
                      forloop_list[n_forloops].varname = strdup($2);
                      forloop_list[n_forloops].jmp_point = splev->n_opcodes;
@@ -985,14 +1021,22 @@ forstatement     : forstmt_start
                      snprintf(buf, 255, "%s step", forloop_list[n_forloops].varname);
                      snprintf(buf2, 255, "%s end", forloop_list[n_forloops].varname);
                      /* compare for-loop var to end value */
-                     add_opvars(splev, "vvo", forloop_list[n_forloops].varname, buf2, SPO_CMP);
+                     add_opvars(splev, "vvo",
+                                VA_PASS3(forloop_list[n_forloops].varname,
+                                         buf2, SPO_CMP));
                      /* var + step */
-                     add_opvars(splev, "vvo", buf,
-                                forloop_list[n_forloops].varname, SPO_MATH_ADD);
+                     add_opvars(splev, "vvo",
+                               VA_PASS3(buf, forloop_list[n_forloops].varname,
+                                        SPO_MATH_ADD));
                      /* for-loop var = (for-loop var + step) */
-                     add_opvars(splev, "iso", 0, forloop_list[n_forloops].varname, SPO_VAR_INIT);
+                     add_opvars(splev, "iso",
+                                VA_PASS3(0, forloop_list[n_forloops].varname,
+                                         SPO_VAR_INIT));
                      /* jump back if compared values were not equal */
-                     add_opvars(splev, "io", forloop_list[n_forloops].jmp_point - splev->n_opcodes - 1, SPO_JNE);
+                     add_opvars(splev, "io",
+                                VA_PASS2(
+                   forloop_list[n_forloops].jmp_point - splev->n_opcodes - 1,
+                                         SPO_JNE));
                      Free(forloop_list[n_forloops].varname);
                      break_stmt_end(splev);
                  }
@@ -1009,14 +1053,14 @@ loopstatement   : LOOP_ID '[' integer_or_var ']'
                      set_opvar_int(tmppush, splev->n_opcodes);
                      if_list[n_if_list++] = tmppush;
 
-                     add_opvars(splev, "o", SPO_DEC);
+                     add_opvars(splev, "o", VA_PASS1(SPO_DEC));
                      break_stmt_start();
                  }
                 stmt_block
                  {
                      struct opvar *tmppush;
 
-                     add_opvars(splev, "oio", SPO_COPY, 0, SPO_CMP);
+                     add_opvars(splev, "oio", VA_PASS3(SPO_COPY, 0, SPO_CMP));
 
                      tmppush = (struct opvar *) if_list[--n_if_list];
                      set_opvar_int(tmppush, tmppush->vardata.l - splev->n_opcodes-1);
@@ -1120,37 +1164,40 @@ if_ending       : stmt_block
 
 message                : MESSAGE_ID ':' string_expr
                  {
-                     add_opvars(splev, "o", SPO_MESSAGE);
+                     add_opvars(splev, "o", VA_PASS1(SPO_MESSAGE));
                  }
                ;
 
 random_corridors: RAND_CORRIDOR_ID
                  {
-                     add_opvars(splev, "iiiiiio", -1,  0, -1, -1, -1, -1, SPO_CORRIDOR);
+                     add_opvars(splev, "iiiiiio",
+                             VA_PASS7(-1,  0, -1, -1, -1, -1, SPO_CORRIDOR));
                  }
                | RAND_CORRIDOR_ID ':' all_integers
                  {
-                     add_opvars(splev, "iiiiiio", -1, $3, -1, -1, -1, -1, SPO_CORRIDOR);
+                     add_opvars(splev, "iiiiiio",
+                             VA_PASS7(-1, $3, -1, -1, -1, -1, SPO_CORRIDOR));
                  }
                | RAND_CORRIDOR_ID ':' RANDOM_TYPE
                  {
-                     add_opvars(splev, "iiiiiio", -1, -1, -1, -1, -1, -1, SPO_CORRIDOR);
+                     add_opvars(splev, "iiiiiio",
+                             VA_PASS7(-1, -1, -1, -1, -1, -1, SPO_CORRIDOR));
                  }
                ;
 
 corridor       : CORRIDOR_ID ':' corr_spec ',' corr_spec
                  {
                      add_opvars(splev, "iiiiiio",
-                                $3.room, $3.door, $3.wall,
-                                $5.room, $5.door, $5.wall,
-                                SPO_CORRIDOR);
+                                VA_PASS7($3.room, $3.door, $3.wall,
+                                         $5.room, $5.door, $5.wall,
+                                         SPO_CORRIDOR));
                  }
                | CORRIDOR_ID ':' corr_spec ',' all_integers
                  {
                      add_opvars(splev, "iiiiiio",
-                                $3.room, $3.door, $3.wall,
-                                -1, -1, (long)$5,
-                                SPO_CORRIDOR);
+                                VA_PASS7($3.room, $3.door, $3.wall,
+                                         -1, -1, (long)$5,
+                                         SPO_CORRIDOR));
                  }
                ;
 
@@ -1167,7 +1214,8 @@ room_begin      : room_type opt_percent ',' light_state
                      if (($2 < 100) && ($1 == OROOM))
                          lc_error("Only typed rooms can have a chance.");
                      else {
-                         add_opvars(splev, "iii", (long)$1, (long)$2, (long)$4);
+                         add_opvars(splev, "iii",
+                                    VA_PASS3((long)$1, (long)$2, (long)$4));
                      }
                   }
                 ;
@@ -1177,8 +1225,10 @@ subroom_def      : SUBROOM_ID ':' room_begin ',' subroom_pos ',' room_size optroomreg
                      long rflags = $8;
 
                      if (rflags == -1) rflags = (1 << 0);
-                     add_opvars(splev, "iiiiiiio", rflags, ERR, ERR,
-                                $5.x, $5.y, $7.width, $7.height, SPO_SUBROOM);
+                     add_opvars(splev, "iiiiiiio",
+                                VA_PASS8(rflags, ERR, ERR,
+                                         $5.x, $5.y, $7.width, $7.height,
+                                         SPO_SUBROOM));
                      break_stmt_start();
                  }
                  stmt_block
@@ -1193,9 +1243,10 @@ room_def : ROOM_ID ':' room_begin ',' room_pos ',' room_align ',' room_size optr
                      long rflags = $8;
 
                      if (rflags == -1) rflags = (1 << 0);
-                     add_opvars(splev, "iiiiiiio", rflags,
-                                $7.x, $7.y, $5.x, $5.y,
-                                $9.width, $9.height, SPO_ROOM);
+                     add_opvars(splev, "iiiiiiio",
+                                VA_PASS8(rflags,
+                                         $7.x, $7.y, $5.x, $5.y,
+                                         $9.width, $9.height, SPO_ROOM));
                      break_stmt_start();
                  }
                  stmt_block
@@ -1274,12 +1325,14 @@ door_detail     : ROOMDOOR_ID ':' secret ',' door_state ',' door_wall ',' door_pos
                        if ($7 == ERR && $9 != ERR) {
                            lc_error("If the door wall is random, so must be its pos!");
                        } else {
-                           add_opvars(splev, "iiiio", (long)$9, (long)$5, (long)$3, (long)$7, SPO_ROOM_DOOR);
+                           add_opvars(splev, "iiiio",
+                                      VA_PASS5((long)$9, (long)$5, (long)$3,
+                                               (long)$7, SPO_ROOM_DOOR));
                        }
                  }
                | DOOR_ID ':' door_state ',' ter_selection
                  {
-                     add_opvars(splev, "io", (long)$3, SPO_DOOR);
+                     add_opvars(splev, "io", VA_PASS2((long)$3, SPO_DOOR));
                  }
                ;
 
@@ -1307,19 +1360,22 @@ door_pos        : INTEGER
 
 map_definition : NOMAP_ID
                  {
-                     add_opvars(splev, "ciisiio", 0, 0, 1, (char *)0, 0, 0, SPO_MAP);
+                     add_opvars(splev, "ciisiio",
+                                VA_PASS7(0, 0, 1, (char *)0, 0, 0, SPO_MAP));
                      max_x_map = COLNO-1;
                      max_y_map = ROWNO;
                  }
                | GEOMETRY_ID ':' h_justif ',' v_justif roomfill MAP_ID
                  {
-                     add_opvars(splev, "cii", SP_COORD_PACK(($3),($5)), 1, (long)$6);
+                     add_opvars(splev, "cii",
+                                VA_PASS3(SP_COORD_PACK(($3),($5)),
+                                         1, (long)$6));
                      scan_map($7, splev);
                      Free($7);
                  }
                | GEOMETRY_ID ':' coord_or_var roomfill MAP_ID
                  {
-                     add_opvars(splev, "ii", 2, (long)$4);
+                     add_opvars(splev, "ii", VA_PASS2(2, (long)$4));
                      scan_map($5, splev);
                      Free($5);
                  }
@@ -1335,11 +1391,11 @@ v_justif        : TOP_OR_BOT
 
 monster_detail : MONSTER_ID ':' monster_desc
                  {
-                     add_opvars(splev, "io", 0, SPO_MONSTER);
+                     add_opvars(splev, "io", VA_PASS2(0, SPO_MONSTER));
                  }
                | MONSTER_ID ':' monster_desc
                  {
-                     add_opvars(splev, "io", 1, SPO_MONSTER);
+                     add_opvars(splev, "io", VA_PASS2(1, SPO_MONSTER));
                      in_container_obj++;
                      break_stmt_start();
                  }
@@ -1347,7 +1403,7 @@ monster_detail    : MONSTER_ID ':' monster_desc
                 {
                     break_stmt_end(splev);
                     in_container_obj--;
-                    add_opvars(splev, "o", SPO_END_MONINVENT);
+                    add_opvars(splev, "o", VA_PASS1(SPO_END_MONINVENT));
                 }
                ;
 
@@ -1374,82 +1430,87 @@ monster_infos   : /* nothing */
 
 monster_info   : string_expr
                  {
-                     add_opvars(splev, "i", SP_M_V_NAME);
+                     add_opvars(splev, "i", VA_PASS1(SP_M_V_NAME));
                      $$ = 0x0001;
                  }
                | MON_ATTITUDE
                  {
-                     add_opvars(splev, "ii", (long)$<i>1, SP_M_V_PEACEFUL);
+                     add_opvars(splev, "ii",
+                                VA_PASS2((long)$<i>1, SP_M_V_PEACEFUL));
                      $$ = 0x0002;
                  }
                | MON_ALERTNESS
                  {
-                     add_opvars(splev, "ii", (long)$<i>1, SP_M_V_ASLEEP);
+                     add_opvars(splev, "ii",
+                                VA_PASS2((long)$<i>1, SP_M_V_ASLEEP));
                      $$ = 0x0004;
                  }
                | alignment_prfx
                  {
-                     add_opvars(splev, "ii", (long)$1, SP_M_V_ALIGN);
+                     add_opvars(splev, "ii",
+                                VA_PASS2((long)$1, SP_M_V_ALIGN));
                      $$ = 0x0008;
                  }
                | MON_APPEARANCE string_expr
                  {
-                     add_opvars(splev, "ii", (long)$<i>1, SP_M_V_APPEAR);
+                     add_opvars(splev, "ii",
+                                VA_PASS2((long)$<i>1, SP_M_V_APPEAR));
                      $$ = 0x0010;
                  }
                | FEMALE_ID
                  {
-                     add_opvars(splev, "ii", 1, SP_M_V_FEMALE);
+                     add_opvars(splev, "ii", VA_PASS2(1, SP_M_V_FEMALE));
                      $$ = 0x0020;
                  }
                | INVIS_ID
                  {
-                     add_opvars(splev, "ii", 1, SP_M_V_INVIS);
+                     add_opvars(splev, "ii", VA_PASS2(1, SP_M_V_INVIS));
                      $$ = 0x0040;
                  }
                | CANCELLED_ID
                  {
-                     add_opvars(splev, "ii", 1, SP_M_V_CANCELLED);
+                     add_opvars(splev, "ii", VA_PASS2(1, SP_M_V_CANCELLED));
                      $$ = 0x0080;
                  }
                | REVIVED_ID
                  {
-                     add_opvars(splev, "ii", 1, SP_M_V_REVIVED);
+                     add_opvars(splev, "ii", VA_PASS2(1, SP_M_V_REVIVED));
                      $$ = 0x0100;
                  }
                | AVENGE_ID
                  {
-                     add_opvars(splev, "ii", 1, SP_M_V_AVENGE);
+                     add_opvars(splev, "ii", VA_PASS2(1, SP_M_V_AVENGE));
                      $$ = 0x0200;
                  }
                | FLEEING_ID ':' integer_or_var
                  {
-                     add_opvars(splev, "i", SP_M_V_FLEEING);
+                     add_opvars(splev, "i", VA_PASS1(SP_M_V_FLEEING));
                      $$ = 0x0400;
                  }
                | BLINDED_ID ':' integer_or_var
                  {
-                     add_opvars(splev, "i", SP_M_V_BLINDED);
+                     add_opvars(splev, "i", VA_PASS1(SP_M_V_BLINDED));
                      $$ = 0x0800;
                  }
                | PARALYZED_ID ':' integer_or_var
                  {
-                     add_opvars(splev, "i", SP_M_V_PARALYZED);
+                     add_opvars(splev, "i", VA_PASS1(SP_M_V_PARALYZED));
                      $$ = 0x1000;
                  }
                | STUNNED_ID
                  {
-                     add_opvars(splev, "ii", 1, SP_M_V_STUNNED);
+                     add_opvars(splev, "ii", VA_PASS2(1, SP_M_V_STUNNED));
                      $$ = 0x2000;
                  }
                | CONFUSED_ID
                  {
-                     add_opvars(splev, "ii", 1, SP_M_V_CONFUSED);
+                     add_opvars(splev, "ii", VA_PASS2(1, SP_M_V_CONFUSED));
                      $$ = 0x4000;
                  }
                | SEENTRAPS_ID ':' seen_trap_mask
                  {
-                     add_opvars(splev, "ii", (long)$3, SP_M_V_SEENTRAPS);
+                     add_opvars(splev, "ii",
+                                VA_PASS2((long)$3, SP_M_V_SEENTRAPS));
                      $$ = 0x8000;
                  }
                ;
@@ -1482,13 +1543,13 @@ object_detail   : OBJECT_ID ':' object_desc
                  {
                      long cnt = 0;
                      if (in_container_obj) cnt |= SP_OBJ_CONTENT;
-                     add_opvars(splev, "io", cnt, SPO_OBJECT);
+                     add_opvars(splev, "io", VA_PASS2(cnt, SPO_OBJECT));
                  }
                | COBJECT_ID ':' object_desc
                  {
                      long cnt = SP_OBJ_CONTAINER;
                      if (in_container_obj) cnt |= SP_OBJ_CONTENT;
-                     add_opvars(splev, "io", cnt, SPO_OBJECT);
+                     add_opvars(splev, "io", VA_PASS2(cnt, SPO_OBJECT));
                      in_container_obj++;
                      break_stmt_start();
                  }
@@ -1524,90 +1585,91 @@ object_infos    : /* nothing */
 
 object_info    : CURSE_TYPE
                  {
-                     add_opvars(splev, "ii", (long)$1, SP_O_V_CURSE);
+                     add_opvars(splev, "ii",
+                                VA_PASS2((long)$1, SP_O_V_CURSE));
                      $$ = 0x0001;
                  }
                | MONTYPE_ID ':' monster_or_var
                  {
-                     add_opvars(splev, "i", SP_O_V_CORPSENM);
+                     add_opvars(splev, "i", VA_PASS1(SP_O_V_CORPSENM));
                      $$ = 0x0002;
                  }
                | all_ints_push
                  {
-                     add_opvars(splev, "i", SP_O_V_SPE);
+                     add_opvars(splev, "i", VA_PASS1(SP_O_V_SPE));
                      $$ = 0x0004;
                  }
                | NAME_ID ':' string_expr
                  {
-                     add_opvars(splev, "i", SP_O_V_NAME);
+                     add_opvars(splev, "i", VA_PASS1(SP_O_V_NAME));
                      $$ = 0x0008;
                  }
                | QUANTITY_ID ':' integer_or_var
                  {
-                     add_opvars(splev, "i", SP_O_V_QUAN);
+                     add_opvars(splev, "i", VA_PASS1(SP_O_V_QUAN));
                      $$ = 0x0010;
                  }
                | BURIED_ID
                  {
-                     add_opvars(splev, "ii", 1, SP_O_V_BURIED);
+                     add_opvars(splev, "ii", VA_PASS2(1, SP_O_V_BURIED));
                      $$ = 0x0020;
                  }
                | LIGHT_STATE
                  {
-                     add_opvars(splev, "ii", (long)$1, SP_O_V_LIT);
+                     add_opvars(splev, "ii", VA_PASS2((long)$1, SP_O_V_LIT));
                      $$ = 0x0040;
                  }
                | ERODED_ID ':' integer_or_var
                  {
-                     add_opvars(splev, "i", SP_O_V_ERODED);
+                     add_opvars(splev, "i", VA_PASS1(SP_O_V_ERODED));
                      $$ = 0x0080;
                  }
                | ERODEPROOF_ID
                  {
-                     add_opvars(splev, "ii", -1, SP_O_V_ERODED);
+                     add_opvars(splev, "ii", VA_PASS2(-1, SP_O_V_ERODED));
                      $$ = 0x0080;
                  }
                | DOOR_STATE
                  {
                      if ($1 == D_LOCKED) {
-                         add_opvars(splev, "ii", 1, SP_O_V_LOCKED);
+                         add_opvars(splev, "ii", VA_PASS2(1, SP_O_V_LOCKED));
                          $$ = 0x0100;
                      } else if ($1 == D_BROKEN) {
-                         add_opvars(splev, "ii", 1, SP_O_V_BROKEN);
+                         add_opvars(splev, "ii", VA_PASS2(1, SP_O_V_BROKEN));
                          $$ = 0x0200;
                      } else
-                         lc_error("OBJECT state can only be locked or broken.");
+                         lc_error("DOOR state can only be locked or broken.");
                  }
                | TRAPPED_ID
                  {
-                     add_opvars(splev, "ii", 1, SP_O_V_TRAPPED);
+                     add_opvars(splev, "ii", VA_PASS2(1, SP_O_V_TRAPPED));
                      $$ = 0x0400;
                  }
                | RECHARGED_ID ':' integer_or_var
                  {
-                     add_opvars(splev, "i", SP_O_V_RECHARGED);
+                     add_opvars(splev, "i", VA_PASS1(SP_O_V_RECHARGED));
                      $$ = 0x0800;
                  }
                | INVIS_ID
                  {
-                     add_opvars(splev, "ii", 1, SP_O_V_INVIS);
+                     add_opvars(splev, "ii", VA_PASS2(1, SP_O_V_INVIS));
                      $$ = 0x1000;
                  }
                | GREASED_ID
                  {
-                     add_opvars(splev, "ii", 1, SP_O_V_GREASED);
+                     add_opvars(splev, "ii", VA_PASS2(1, SP_O_V_GREASED));
                      $$ = 0x2000;
                  }
                | coord_or_var
                  {
-                     add_opvars(splev, "i", SP_O_V_COORD);
+                     add_opvars(splev, "i", VA_PASS1(SP_O_V_COORD));
                      $$ = 0x4000;
                  }
                ;
 
 trap_detail    : TRAP_ID ':' trap_name ',' coord_or_var
                  {
-                     add_opvars(splev, "io", (long)$3, SPO_TRAP);
+                     add_opvars(splev, "io", VA_PASS2((long)$3, SPO_TRAP));
                  }
                ;
 
@@ -1635,85 +1697,92 @@ drawbridge_detail: DRAWBRIDGE_ID ':' coord_or_var ',' DIRECTION ',' door_state
                           state = -1;
                       else
                           lc_error("A drawbridge can only be open, closed or random!");
-                      add_opvars(splev, "iio", state, dir, SPO_DRAWBRIDGE);
+                      add_opvars(splev, "iio",
+                                 VA_PASS3(state, dir, SPO_DRAWBRIDGE));
                   }
                ;
 
 mazewalk_detail : MAZEWALK_ID ':' coord_or_var ',' DIRECTION
                  {
                      add_opvars(splev, "iiio",
-                                (long)$5, 1, 0, SPO_MAZEWALK);
+                                VA_PASS4((long)$5, 1, 0, SPO_MAZEWALK));
                  }
                | MAZEWALK_ID ':' coord_or_var ',' DIRECTION ',' BOOLEAN opt_fillchar
                  {
                      add_opvars(splev, "iiio",
-                                (long)$5, (long)$<i>7, (long)$8, SPO_MAZEWALK);
+                                VA_PASS4((long)$5, (long)$<i>7,
+                                         (long)$8, SPO_MAZEWALK));
                  }
                ;
 
 wallify_detail : WALLIFY_ID
                  {
-                     add_opvars(splev, "rio", SP_REGION_PACK(-1,-1,-1,-1), 0, SPO_WALLIFY);
+                     add_opvars(splev, "rio",
+                                VA_PASS3(SP_REGION_PACK(-1,-1,-1,-1),
+                                         0, SPO_WALLIFY));
                  }
                | WALLIFY_ID ':' ter_selection
                  {
-                     add_opvars(splev, "io", 1, SPO_WALLIFY);
+                     add_opvars(splev, "io", VA_PASS2(1, SPO_WALLIFY));
                  }
                ;
 
 ladder_detail  : LADDER_ID ':' coord_or_var ',' UP_OR_DOWN
                  {
-                     add_opvars(splev, "io", (long)$<i>5, SPO_LADDER);
+                     add_opvars(splev, "io",
+                                VA_PASS2((long)$<i>5, SPO_LADDER));
                  }
                ;
 
 stair_detail   : STAIR_ID ':' coord_or_var ',' UP_OR_DOWN
                  {
-                     add_opvars(splev, "io", (long)$<i>5, SPO_STAIR);
+                     add_opvars(splev, "io",
+                                VA_PASS2((long)$<i>5, SPO_STAIR));
                  }
                ;
 
 stair_region   : STAIR_ID ':' lev_region ',' lev_region ',' UP_OR_DOWN
                  {
                      add_opvars(splev, "iiiii iiiii iiso",
-                                $3.x1, $3.y1, $3.x2, $3.y2, $3.area,
-                                $5.x1, $5.y1, $5.x2, $5.y2, $5.area,
-                                (long)(($7) ? LR_UPSTAIR : LR_DOWNSTAIR),
-                                0, (char *)0, SPO_LEVREGION);
+                                VA_PASS14($3.x1, $3.y1, $3.x2, $3.y2, $3.area,
+                                          $5.x1, $5.y1, $5.x2, $5.y2, $5.area,
+                                     (long)(($7) ? LR_UPSTAIR : LR_DOWNSTAIR),
+                                          0, (char *)0, SPO_LEVREGION));
                  }
                ;
 
 portal_region  : PORTAL_ID ':' lev_region ',' lev_region ',' STRING
                  {
                      add_opvars(splev, "iiiii iiiii iiso",
-                                $3.x1, $3.y1, $3.x2, $3.y2, $3.area,
-                                $5.x1, $5.y1, $5.x2, $5.y2, $5.area,
-                                LR_PORTAL, 0, $7, SPO_LEVREGION);
+                                VA_PASS14($3.x1, $3.y1, $3.x2, $3.y2, $3.area,
+                                          $5.x1, $5.y1, $5.x2, $5.y2, $5.area,
+                                          LR_PORTAL, 0, $7, SPO_LEVREGION));
                      Free($7);
                  }
                ;
 
 teleprt_region : TELEPRT_ID ':' lev_region ',' lev_region teleprt_detail
                  {
-                     long rtype = 0;
+                     long rtyp = 0;
                      switch($6) {
-                     case -1: rtype = LR_TELE; break;
-                     case  0: rtype = LR_DOWNTELE; break;
-                     case  1: rtype = LR_UPTELE; break;
+                     case -1: rtyp = LR_TELE; break;
+                     case  0: rtyp = LR_DOWNTELE; break;
+                     case  1: rtyp = LR_UPTELE; break;
                      }
                      add_opvars(splev, "iiiii iiiii iiso",
-                                $3.x1, $3.y1, $3.x2, $3.y2, $3.area,
-                                $5.x1, $5.y1, $5.x2, $5.y2, $5.area,
-                                rtype, 0, (char *)0, SPO_LEVREGION);
+                                VA_PASS14($3.x1, $3.y1, $3.x2, $3.y2, $3.area,
+                                          $5.x1, $5.y1, $5.x2, $5.y2, $5.area,
+                                          rtyp, 0, (char *)0, SPO_LEVREGION));
                  }
                ;
 
 branch_region  : BRANCH_ID ':' lev_region ',' lev_region
                  {
                      add_opvars(splev, "iiiii iiiii iiso",
-                                $3.x1, $3.y1, $3.x2, $3.y2, $3.area,
-                                $5.x1, $5.y1, $5.x2, $5.y2, $5.area,
-                                (long)LR_BRANCH, 0, (char *)0, SPO_LEVREGION);
+                                VA_PASS14($3.x1, $3.y1, $3.x2, $3.y2, $3.area,
+                                          $5.x1, $5.y1, $5.x2, $5.y2, $5.area,
+                                          (long)LR_BRANCH, 0,
+                                          (char *)0, SPO_LEVREGION));
                  }
                ;
 
@@ -1729,19 +1798,19 @@ teleprt_detail  : /* empty */
 
 fountain_detail : FOUNTAIN_ID ':' ter_selection
                  {
-                     add_opvars(splev, "o", SPO_FOUNTAIN);
+                     add_opvars(splev, "o", VA_PASS1(SPO_FOUNTAIN));
                  }
                ;
 
 sink_detail : SINK_ID ':' ter_selection
                  {
-                     add_opvars(splev, "o", SPO_SINK);
+                     add_opvars(splev, "o", VA_PASS1(SPO_SINK));
                  }
                ;
 
 pool_detail : POOL_ID ':' ter_selection
                  {
-                     add_opvars(splev, "o", SPO_POOL);
+                     add_opvars(splev, "o", VA_PASS1(SPO_POOL));
                  }
                ;
 
@@ -1759,25 +1828,26 @@ terrain_type    : CHAR
 
 replace_terrain_detail : REPLACE_TERRAIN_ID ':' region_or_var ',' mapchar_or_var ',' mapchar_or_var ',' SPERCENT
                  {
-                     add_opvars(splev, "io", $9, SPO_REPLACETERRAIN);
+                     add_opvars(splev, "io",
+                                VA_PASS2($9, SPO_REPLACETERRAIN));
                  }
                ;
 
 terrain_detail : TERRAIN_ID ':' ter_selection ',' mapchar_or_var
                 {
-                    add_opvars(splev, "o", SPO_TERRAIN);
+                    add_opvars(splev, "o", VA_PASS1(SPO_TERRAIN));
                 }
               ;
 
 diggable_detail : NON_DIGGABLE_ID ':' region_or_var
                  {
-                    add_opvars(splev, "o", SPO_NON_DIGGABLE);
+                     add_opvars(splev, "o", VA_PASS1(SPO_NON_DIGGABLE));
                  }
                ;
 
 passwall_detail : NON_PASSWALL_ID ':' region_or_var
                  {
-                    add_opvars(splev, "o", SPO_NON_PASSWALL);
+                     add_opvars(splev, "o", VA_PASS1(SPO_NON_PASSWALL));
                  }
                ;
 
@@ -1791,7 +1861,7 @@ region_detail     : REGION_ID ':' region_or_var ',' light_state ',' room_type optroo
                      if (!(rflags & 1)) rt += MAXRTYPE+1;
                      irr = ((rflags & 2) != 0);
                      add_opvars(splev, "iiio",
-                                (long)$5, rt, rflags, SPO_REGION);
+                                VA_PASS4((long)$5, rt, rflags, SPO_REGION));
                      $<i>$ = (irr || (rflags & 1) || rt != OROOM);
                      break_stmt_start();
                  }
@@ -1817,46 +1887,48 @@ region_detail_end : /* nothing */
 
 altar_detail   : ALTAR_ID ':' coord_or_var ',' alignment ',' altar_type
                  {
-                     add_opvars(splev, "iio", (long)$7, (long)$5, SPO_ALTAR);
+                     add_opvars(splev, "iio",
+                                VA_PASS3((long)$7, (long)$5, SPO_ALTAR));
                  }
                ;
 
 grave_detail   : GRAVE_ID ':' coord_or_var ',' string_expr
                  {
-                     add_opvars(splev, "io", 2, SPO_GRAVE);
+                     add_opvars(splev, "io", VA_PASS2(2, SPO_GRAVE));
                  }
                | GRAVE_ID ':' coord_or_var ',' RANDOM_TYPE
                  {
                      add_opvars(splev, "sio",
-                                (char *)0, 1, SPO_GRAVE);
+                                VA_PASS3((char *)0, 1, SPO_GRAVE));
                  }
                | GRAVE_ID ':' coord_or_var
                  {
                      add_opvars(splev, "sio",
-                                (char *)0, 0, SPO_GRAVE);
+                                VA_PASS3((char *)0, 0, SPO_GRAVE));
                  }
                ;
 
 gold_detail    : GOLD_ID ':' math_expr_var ',' coord_or_var
                  {
-                     add_opvars(splev, "o", SPO_GOLD);
+                     add_opvars(splev, "o", VA_PASS1(SPO_GOLD));
                  }
                ;
 
 engraving_detail: ENGRAVING_ID ':' coord_or_var ',' engraving_type ',' string_expr
                  {
                      add_opvars(splev, "io",
-                                (long)$5, SPO_ENGRAVING);
+                                VA_PASS2((long)$5, SPO_ENGRAVING));
                  }
                ;
 
 mineralize     : MINERALIZE_ID ':' integer_or_var ',' integer_or_var ',' integer_or_var ',' integer_or_var
                  {
-                     add_opvars(splev, "o", SPO_MINERALIZE);
+                     add_opvars(splev, "o", VA_PASS1(SPO_MINERALIZE));
                  }
                | MINERALIZE_ID
                  {
-                     add_opvars(splev, "iiiio", -1L, -1L, -1L, -1L, SPO_MINERALIZE);
+                     add_opvars(splev, "iiiio",
+                                VA_PASS5(-1L, -1L, -1L, -1L, SPO_MINERALIZE));
                  }
                ;
 
@@ -1958,21 +2030,21 @@ a_register      : A_REGISTER '[' INTEGER ']'
 
 string_or_var  : STRING
                  {
-                     add_opvars(splev, "s", $1);
+                     add_opvars(splev, "s", VA_PASS1($1));
                      Free($1);
                  }
                | VARSTRING_STRING
                  {
                      check_vardef_type(variable_definitions, $1, SPOVAR_STRING);
                      vardef_used(variable_definitions, $1);
-                     add_opvars(splev, "v", $1);
+                     add_opvars(splev, "v", VA_PASS1($1));
                      Free($1);
                  }
                | VARSTRING_STRING_ARRAY '[' math_expr_var ']'
                  {
                      check_vardef_type(variable_definitions, $1, SPOVAR_STRING|SPOVAR_ARRAY);
                      vardef_used(variable_definitions, $1);
-                     add_opvars(splev, "v", $1);
+                     add_opvars(splev, "v", VA_PASS1($1));
                      Free($1);
                  }
                ;
@@ -1986,24 +2058,24 @@ integer_or_var  : math_expr_var
 
 coord_or_var   : encodecoord
                  {
-                     add_opvars(splev, "c", $1);
+                     add_opvars(splev, "c", VA_PASS1($1));
                  }
                | rndcoord_ID '(' ter_selection ')'
                  {
-                     add_opvars(splev, "o", SPO_SEL_RNDCOORD);
+                     add_opvars(splev, "o", VA_PASS1(SPO_SEL_RNDCOORD));
                  }
                | VARSTRING_COORD
                  {
                      check_vardef_type(variable_definitions, $1, SPOVAR_COORD);
                      vardef_used(variable_definitions, $1);
-                     add_opvars(splev, "v", $1);
+                     add_opvars(splev, "v", VA_PASS1($1));
                      Free($1);
                  }
                | VARSTRING_COORD_ARRAY '[' math_expr_var ']'
                  {
                      check_vardef_type(variable_definitions, $1, SPOVAR_COORD|SPOVAR_ARRAY);
                      vardef_used(variable_definitions, $1);
-                     add_opvars(splev, "v", $1);
+                     add_opvars(splev, "v", VA_PASS1($1));
                      Free($1);
                  }
                ;
@@ -2044,14 +2116,14 @@ region_or_var   : encoderegion
                  {
                      check_vardef_type(variable_definitions, $1, SPOVAR_REGION);
                      vardef_used(variable_definitions, $1);
-                     add_opvars(splev, "v", $1);
+                     add_opvars(splev, "v", VA_PASS1($1));
                      Free($1);
                  }
                | VARSTRING_REGION_ARRAY '[' math_expr_var ']'
                  {
                      check_vardef_type(variable_definitions, $1, SPOVAR_REGION|SPOVAR_ARRAY);
                      vardef_used(variable_definitions, $1);
-                     add_opvars(splev, "v", $1);
+                     add_opvars(splev, "v", VA_PASS1($1));
                      Free($1);
                  }
                ;
@@ -2062,27 +2134,27 @@ encoderegion    : '(' INTEGER ',' INTEGER ',' INTEGER ',' INTEGER ')'
                      if ( $2 > $6 || $4 > $8 )
                          lc_error("Region start > end: (%li,%li,%li,%li)!", $2, $4, $6, $8);
 
-                     add_opvars(splev, "r", r);
+                     add_opvars(splev, "r", VA_PASS1(r));
                      $$ = r;
                  }
                ;
 
 mapchar_or_var : mapchar
                  {
-                     add_opvars(splev, "m", $1);
+                     add_opvars(splev, "m", VA_PASS1($1));
                  }
                | VARSTRING_MAPCHAR
                  {
                      check_vardef_type(variable_definitions, $1, SPOVAR_MAPCHAR);
                      vardef_used(variable_definitions, $1);
-                     add_opvars(splev, "v", $1);
+                     add_opvars(splev, "v", VA_PASS1($1));
                      Free($1);
                  }
                | VARSTRING_MAPCHAR_ARRAY '[' math_expr_var ']'
                  {
                      check_vardef_type(variable_definitions, $1, SPOVAR_MAPCHAR|SPOVAR_ARRAY);
                      vardef_used(variable_definitions, $1);
-                     add_opvars(splev, "v", $1);
+                     add_opvars(splev, "v", VA_PASS1($1));
                      Free($1);
                  }
                ;
@@ -2109,20 +2181,20 @@ mapchar         : CHAR
 
 monster_or_var : encodemonster
                  {
-                     add_opvars(splev, "M", $1);
+                     add_opvars(splev, "M", VA_PASS1($1));
                  }
                | VARSTRING_MONST
                  {
                      check_vardef_type(variable_definitions, $1, SPOVAR_MONST);
                      vardef_used(variable_definitions, $1);
-                     add_opvars(splev, "v", $1);
+                     add_opvars(splev, "v", VA_PASS1($1));
                      Free($1);
                  }
                | VARSTRING_MONST_ARRAY '[' math_expr_var ']'
                  {
                      check_vardef_type(variable_definitions, $1, SPOVAR_MONST|SPOVAR_ARRAY);
                      vardef_used(variable_definitions, $1);
-                     add_opvars(splev, "v", $1);
+                     add_opvars(splev, "v", VA_PASS1($1));
                      Free($1);
                  }
                ;
@@ -2162,20 +2234,20 @@ encodemonster   : STRING
 
 object_or_var  : encodeobj
                  {
-                     add_opvars(splev, "O", $1);
+                     add_opvars(splev, "O", VA_PASS1($1));
                  }
                | VARSTRING_OBJ
                  {
                      check_vardef_type(variable_definitions, $1, SPOVAR_OBJ);
                      vardef_used(variable_definitions, $1);
-                     add_opvars(splev, "v", $1);
+                     add_opvars(splev, "v", VA_PASS1($1));
                      Free($1);
                  }
                | VARSTRING_OBJ_ARRAY '[' math_expr_var ']'
                  {
                      check_vardef_type(variable_definitions, $1, SPOVAR_OBJ|SPOVAR_ARRAY);
                      vardef_used(variable_definitions, $1);
-                     add_opvars(splev, "v", $1);
+                     add_opvars(splev, "v", VA_PASS1($1));
                      Free($1);
                  }
                ;
@@ -2218,79 +2290,105 @@ encodeobj      : STRING
 string_expr    : string_or_var                 { }
                | string_expr '.' string_or_var
                  {
-                     add_opvars(splev, "o", SPO_MATH_ADD);
+                     add_opvars(splev, "o", VA_PASS1(SPO_MATH_ADD));
                  }
                ;
 
-math_expr_var  : INTEGER                       { add_opvars(splev, "i", $1 ); }
-               | dice                          { is_inconstant_number = 1; }
-               | '(' MINUS_INTEGER ')'         { add_opvars(splev, "i", $2 ); }
+math_expr_var  : INTEGER
+                 {
+                     add_opvars(splev, "i", VA_PASS1($1));
+                 }
+               | dice
+                 {
+                     is_inconstant_number = 1;
+                 }
+               | '(' MINUS_INTEGER ')'
+                 {
+                     add_opvars(splev, "i", VA_PASS1($2));
+                 }
                | VARSTRING_INT
                  {
                      check_vardef_type(variable_definitions, $1, SPOVAR_INT);
                      vardef_used(variable_definitions, $1);
-                     add_opvars(splev, "v", $1);
+                     add_opvars(splev, "v", VA_PASS1($1));
                      Free($1);
                      is_inconstant_number = 1;
                  }
                | VARSTRING_INT_ARRAY '[' math_expr_var ']'
                  {
-                     check_vardef_type(variable_definitions, $1, SPOVAR_INT|SPOVAR_ARRAY);
+                     check_vardef_type(variable_definitions,
+                                       $1, SPOVAR_INT|SPOVAR_ARRAY);
                      vardef_used(variable_definitions, $1);
-                     add_opvars(splev, "v", $1);
+                     add_opvars(splev, "v", VA_PASS1($1));
                      Free($1);
                      is_inconstant_number = 1;
                  }
-               | math_expr_var '+' math_expr_var       { add_opvars(splev, "o", SPO_MATH_ADD); }
-               | math_expr_var '-' math_expr_var       { add_opvars(splev, "o", SPO_MATH_SUB); }
-               | math_expr_var '*' math_expr_var       { add_opvars(splev, "o", SPO_MATH_MUL); }
-               | math_expr_var '/' math_expr_var       { add_opvars(splev, "o", SPO_MATH_DIV); }
-               | math_expr_var '%' math_expr_var       { add_opvars(splev, "o", SPO_MATH_MOD); }
+               | math_expr_var '+' math_expr_var
+                 {
+                     add_opvars(splev, "o", VA_PASS1(SPO_MATH_ADD));
+                 }
+               | math_expr_var '-' math_expr_var
+                 {
+                     add_opvars(splev, "o", VA_PASS1(SPO_MATH_SUB));
+                 }
+               | math_expr_var '*' math_expr_var
+                 {
+                     add_opvars(splev, "o", VA_PASS1(SPO_MATH_MUL));
+                 }
+               | math_expr_var '/' math_expr_var
+                 {
+                     add_opvars(splev, "o", VA_PASS1(SPO_MATH_DIV));
+                 }
+               | math_expr_var '%' math_expr_var
+                 {
+                     add_opvars(splev, "o", VA_PASS1(SPO_MATH_MOD));
+                 }
                | '(' math_expr_var ')'             { }
                ;
 
-func_param_type                : CFUNC_INT
-                         {
-                             if (!strcmp("int", $1) || !strcmp("integer", $1)) {
-                                 $$ = (int)'i';
-                             } else lc_error("Unknown function parameter type '%s'", $1);
-                         }
-                       | CFUNC_STR
-                         {
-                             if (!strcmp("str", $1) || !strcmp("string", $1)) {
-                                 $$ = (int)'s';
-                             } else lc_error("Unknown function parameter type '%s'", $1);
-                         }
-                       ;
+func_param_type        : CFUNC_INT
+                 {
+                     if (!strcmp("int", $1) || !strcmp("integer", $1)) {
+                         $$ = (int)'i';
+                     } else
+                         lc_error("Unknown function parameter type '%s'", $1);
+                 }
+               | CFUNC_STR
+                 {
+                     if (!strcmp("str", $1) || !strcmp("string", $1)) {
+                         $$ = (int)'s';
+                     } else
+                         lc_error("Unknown function parameter type '%s'", $1);
+                 }
+               ;
 
-func_param_part                : any_var_or_arr ':' func_param_type
-                         {
-                             struct lc_funcdefs_parm *tmp = New(struct lc_funcdefs_parm);
-
-                             if (!curr_function)
-                                 lc_error("Function parameters outside function definition.");
-                             else if (!tmp)
-                                 lc_error("Could not alloc function params.");
-                             else {
-                                 tmp->name = strdup($1);
-                                 tmp->parmtype = (char) $3;
-                                 tmp->next = curr_function->params;
-                                 curr_function->params = tmp;
-                                 curr_function->n_params++;
-                                 {
-                                     long vt;
-                                     switch (tmp->parmtype) {
-                                     case 'i': vt = SPOVAR_INT; break;
-                                     case 's': vt = SPOVAR_STRING; break;
-                                     default: lc_error("Unknown func param conversion."); break;
-                                     }
-                                     variable_definitions = add_vardef_type(variable_definitions, $1, vt);
-                                 }
-                             }
-                             Free($1);
-                         }
-                       ;
+func_param_part        : any_var_or_arr ':' func_param_type
+                 {
+                     struct lc_funcdefs_parm *tmp = New(struct lc_funcdefs_parm);
 
+                     if (!curr_function) {
+                         lc_error("Function parameters outside function definition.");
+                     } else if (!tmp) {
+                         lc_error("Could not alloc function params.");
+                     } else {
+                         long vt;
+                         tmp->name = strdup($1);
+                         tmp->parmtype = (char) $3;
+                         tmp->next = curr_function->params;
+                         curr_function->params = tmp;
+                         curr_function->n_params++;
+                         switch (tmp->parmtype) {
+                         case 'i': vt = SPOVAR_INT; break;
+                         case 's': vt = SPOVAR_STRING; break;
+                         default: lc_error("Unknown func param conversion."); break;
+                         }
+                         variable_definitions = add_vardef_type(
+                                                        variable_definitions,
+                                                                $1, vt);
+                     }
+                     Free($1);
+                 }
+               ;
 
 func_param_list                : func_param_part
                        | func_param_list ',' func_param_part
@@ -2342,78 +2440,84 @@ func_call_params_list   : /* nothing */
 
 ter_selection_x        : coord_or_var
                  {
-                     add_opvars(splev, "o", SPO_SEL_POINT);
+                     add_opvars(splev, "o", VA_PASS1(SPO_SEL_POINT));
                  }
                | rect_ID region_or_var
                  {
-                     add_opvars(splev, "o", SPO_SEL_RECT);
+                     add_opvars(splev, "o", VA_PASS1(SPO_SEL_RECT));
                  }
                | fillrect_ID region_or_var
                  {
-                     add_opvars(splev, "o", SPO_SEL_FILLRECT);
+                     add_opvars(splev, "o", VA_PASS1(SPO_SEL_FILLRECT));
                  }
                | line_ID coord_or_var '-' coord_or_var
                  {
-                     add_opvars(splev, "o", SPO_SEL_LINE);
+                     add_opvars(splev, "o", VA_PASS1(SPO_SEL_LINE));
                  }
                | randline_ID coord_or_var '-' coord_or_var ',' math_expr_var
                  {
                      /* randline (x1,y1),(x2,y2), roughness */
-                     add_opvars(splev, "o", SPO_SEL_RNDLINE);
+                     add_opvars(splev, "o", VA_PASS1(SPO_SEL_RNDLINE));
                  }
                | grow_ID '(' ter_selection ')'
                  {
-                     add_opvars(splev, "io", W_ANY, SPO_SEL_GROW);
+                     add_opvars(splev, "io", VA_PASS2(W_ANY, SPO_SEL_GROW));
                  }
                | grow_ID '(' dir_list ',' ter_selection ')'
                  {
-                     add_opvars(splev, "io", $3, SPO_SEL_GROW);
+                     add_opvars(splev, "io", VA_PASS2($3, SPO_SEL_GROW));
                  }
                | filter_ID '(' SPERCENT ',' ter_selection ')'
                  {
-                     add_opvars(splev, "iio", $3, SPOFILTER_PERCENT, SPO_SEL_FILTER);
+                     add_opvars(splev, "iio",
+                            VA_PASS3($3, SPOFILTER_PERCENT, SPO_SEL_FILTER));
                  }
                | filter_ID '(' ter_selection ',' ter_selection ')'
                  {
-                     add_opvars(splev, "io", SPOFILTER_SELECTION, SPO_SEL_FILTER);
+                     add_opvars(splev, "io",
+                              VA_PASS2(SPOFILTER_SELECTION, SPO_SEL_FILTER));
                  }
                | filter_ID '(' mapchar_or_var ',' ter_selection ')'
                  {
-                     add_opvars(splev, "io", SPOFILTER_MAPCHAR, SPO_SEL_FILTER);
+                     add_opvars(splev, "io",
+                                VA_PASS2(SPOFILTER_MAPCHAR, SPO_SEL_FILTER));
                  }
                | flood_ID coord_or_var
                  {
-                     add_opvars(splev, "o", SPO_SEL_FLOOD);
+                     add_opvars(splev, "o", VA_PASS1(SPO_SEL_FLOOD));
                  }
                | circle_ID '(' coord_or_var ',' math_expr_var ')'
                  {
-                     add_opvars(splev, "oio", SPO_COPY, 1, SPO_SEL_ELLIPSE);
+                     add_opvars(splev, "oio",
+                                VA_PASS3(SPO_COPY, 1, SPO_SEL_ELLIPSE));
                  }
                | circle_ID '(' coord_or_var ',' math_expr_var ',' FILLING ')'
                  {
-                     add_opvars(splev, "oio", SPO_COPY, $7, SPO_SEL_ELLIPSE);
+                     add_opvars(splev, "oio",
+                                VA_PASS3(SPO_COPY, $7, SPO_SEL_ELLIPSE));
                  }
                | ellipse_ID '(' coord_or_var ',' math_expr_var ',' math_expr_var ')'
                  {
-                     add_opvars(splev, "io", 1, SPO_SEL_ELLIPSE);
+                     add_opvars(splev, "io", VA_PASS2(1, SPO_SEL_ELLIPSE));
                  }
                | ellipse_ID '(' coord_or_var ',' math_expr_var ',' math_expr_var ',' FILLING ')'
                  {
-                     add_opvars(splev, "io", $9, SPO_SEL_ELLIPSE);
+                     add_opvars(splev, "io", VA_PASS2($9, SPO_SEL_ELLIPSE));
                  }
                | gradient_ID '(' GRADIENT_TYPE ',' '(' math_expr_var '-' math_expr_var opt_limited ')' ',' coord_or_var opt_coord_or_var ')'
                  {
-                     add_opvars(splev, "iio", $9, $3, SPO_SEL_GRADIENT);
+                     add_opvars(splev, "iio",
+                                VA_PASS3($9, $3, SPO_SEL_GRADIENT));
                  }
                | complement_ID ter_selection_x
                  {
-                     add_opvars(splev, "o", SPO_SEL_COMPLEMENT);
+                     add_opvars(splev, "o", VA_PASS1(SPO_SEL_COMPLEMENT));
                  }
                | VARSTRING_SEL
                  {
                      check_vardef_type(variable_definitions, $1, SPOVAR_SEL);
                      vardef_used(variable_definitions, $1);
-                     add_opvars(splev, "v", $1);
+                     add_opvars(splev, "v", VA_PASS1($1));
                      Free($1);
                  }
                | '(' ter_selection ')'
@@ -2428,13 +2532,14 @@ ter_selection   : ter_selection_x
                  }
                | ter_selection_x '&' ter_selection
                  {
-                     add_opvars(splev, "o", SPO_SEL_ADD);
+                     add_opvars(splev, "o", VA_PASS1(SPO_SEL_ADD));
                  }
                ;
 
 dice           : DICE
                  {
-                     add_opvars(splev, "iio", $1.num, $1.die, SPO_DICE);
+                     add_opvars(splev, "iio",
+                                VA_PASS3($1.num, $1.die, SPO_DICE));
                  }
                ;
 
@@ -2445,15 +2550,15 @@ all_integers    : MINUS_INTEGER
 
 all_ints_push  : MINUS_INTEGER
                  {
-                     add_opvars(splev, "i", $1 );
+                     add_opvars(splev, "i", VA_PASS1($1));
                  }
                | PLUS_INTEGER
                  {
-                     add_opvars(splev, "i", $1 );
+                     add_opvars(splev, "i", VA_PASS1($1));
                  }
                | INTEGER
                  {
-                     add_opvars(splev, "i", $1 );
+                     add_opvars(splev, "i", VA_PASS1($1));
                  }
                | dice
                  {
index 8cb335057053d62ba7dfd4101d6eda28288d0887..edd16c021bcf16c1396ad153d05c22d3d036dc22 100644 (file)
@@ -1,4 +1,4 @@
-/* NetHack 3.5 lev_main.c      $NHDT-Date: 1428574133 2015/04/09 10:08:53 $  $NHDT-Branch: master $:$NHDT-Revision: 1.33 $ */
+/* NetHack 3.5 lev_main.c      $NHDT-Date: 1428655166 2015/04/10 08:39:26 $  $NHDT-Branch: master $:$NHDT-Revision: 1.34 $ */
 /* NetHack 3.5 lev_main.c      $Date: 2012/01/12 04:48:12 $  $Revision: 1.20 $ */
 /*     SCCS Id: @(#)lev_main.c 3.5     2007/01/17      */
 /*     Copyright (c) 1989 by Jean-Christophe Collet */
@@ -8,8 +8,7 @@
  * This file contains the main function for the parser
  * and some useful functions needed by yacc
  */
-#define SPEC_LEV       /* for MPW */
-/* although, why don't we move those special defines here.. and in dgn_main? */
+#define SPEC_LEV    /* for USE_OLDARGS (sp_lev.h) and for MPW (macconf.h) */
 
 #define NEED_VARARGS
 #include "hack.h"
@@ -1303,7 +1302,7 @@ sp_lev *sp;
 
        mbuf[((max_hig-1) * max_len) + (max_len-1) + 1] = '\0';
 
-       add_opvars(sp, "siio", mbuf, max_hig, max_len, SPO_MAP);
+       add_opvars(sp, "siio", VA_PASS4(mbuf, max_hig, max_len, SPO_MAP));
 
        for (dy = 0; dy < max_hig; dy++)
            Free(tmpmap[dy]);