about summary refs log tree commit diff
path: root/Src
diff options
context:
space:
mode:
Diffstat (limited to 'Src')
-rw-r--r--Src/makepro.awk103
-rw-r--r--Src/system.h40
-rw-r--r--Src/utils.c64
3 files changed, 146 insertions, 61 deletions
diff --git a/Src/makepro.awk b/Src/makepro.awk
index 158510d33..5def40203 100644
--- a/Src/makepro.awk
+++ b/Src/makepro.awk
@@ -49,15 +49,17 @@ BEGIN {
 	if(line ~ /\/\*/)
 	    continue
 	# If it is a function definition, note so.
-	if(line ~ /\) *[{].*$/) #}
+	if(line ~ /\) *(VA_DCL )*[{].*$/) #}
 	    isfunc = 1
 	if(sub(/ *[{;].*$/, "", line)) #}
 	    break
     }
-    # Put spaces around each identifier.
-    while(match(line, /[^_0-9A-Za-z ][_0-9A-Za-z]/) ||
-	    match(line, /[_0-9A-Za-z][^_0-9A-Za-z ]/))
-	line = substr(line, 1, RSTART) " " substr(line, RSTART+1)
+    if (!match(line, /VA_ALIST/)) {
+	# Put spaces around each identifier.
+	while(match(line, /[^_0-9A-Za-z ][_0-9A-Za-z]/) ||
+	      match(line, /[_0-9A-Za-z][^_0-9A-Za-z ]/))
+	    line = substr(line, 1, RSTART) " " substr(line, RSTART+1)
+    }
     # Separate declarations into a type and a list of declarators.
     # In each declarator, "@{" and "@}" are used in place of parens to
     # mark function parameter lists, and "@!" is used in place of commas
@@ -87,45 +89,64 @@ BEGIN {
     exported = " " dtype " " ~ / mod_export /
     line = substr(line, RLENGTH+1) ","
     # Handle each declarator.
-    while(match(line, /^[^,]*,/)) {
-	# Separate out the name from the declarator.  Use "@+" and "@-"
-	# to bracket the name within the declarator.  Strip off any
-	# initialiser.
-	dcltor = substr(line, 1, RLENGTH-1)
-	line = substr(line, RLENGTH+1)
-	sub(/\=.*$/, "", dcltor)
-	match(dcltor, /^([^_0-9A-Za-z]| const )*/)
-	dcltor = substr(dcltor, 1, RLENGTH) "@+" substr(dcltor, RLENGTH+1)
-	match(dcltor, /^.*@\+[_0-9A-Za-z]+/)
-	dcltor = substr(dcltor, 1, RLENGTH) "@-" substr(dcltor, RLENGTH+1)
-	dnam = dcltor
-	sub(/^.*@\+/, "", dnam)
-	sub(/@-.*$/, "", dnam)
-
+    if (match(line, /VA_ALIST/)) {
+	# Already has VARARGS handling.
 	# Put parens etc. back
-	gsub(/@[{]/, " _((", dcltor)
-	gsub(/@}/, "))", dcltor)
-	gsub(/@</, "(", dcltor)
-	gsub(/@>/, ")", dcltor)
-	gsub(/@!/, ",", dcltor)
-
-	# If this is exported, add it to the exported symbol list.
-	if(exported)
-	    printf "X%s\n", dnam
+	gsub(/@[{]/, "((", line)
+	gsub(/@}/, "))", line)
+	gsub(/@</, "(", line)
+	gsub(/@>/, ")", line)
+	gsub(/@!/, ",", line)
+	sub(/,$/, ";", line)
+	gsub(/mod_export/, "mod_import_function", dtype)
+	gsub(/VA_ALIST/, "VA_ALIST_PROTO", line)
+	sub(/ VA_DCL/, "", line)
 
-	# Format the declaration for output
-	dcl = dtype " " dcltor ";"
 	if(locality ~ /E/)
-	    dcl = "extern " dcl
-	if(isfunc)
-	    gsub(/ mod_export /, " mod_import_function ", dcl)
-	else
-	    gsub(/ mod_export /, " mod_import_variable ", dcl)
-	gsub(/@[+-]/, "", dcl)
-	gsub(/ +/, " ", dcl)
-	while(match(dcl, /[^_0-9A-Za-z] ./) || match(dcl, /. [^_0-9A-Za-z]/))
-	    dcl = substr(dcl, 1, RSTART) substr(dcl, RSTART+2)
-	printf "%s%s\n", locality, dcl
+	    dtype = "extern " dtype
+
+	printf "%s%s %s\n", locality, dtype, line
+    } else {
+	while(match(line, /^[^,]*,/)) {
+		# Separate out the name from the declarator.  Use "@+" and "@-"
+		# to bracket the name within the declarator.  Strip off any
+		# initialiser.
+		dcltor = substr(line, 1, RLENGTH-1)
+		line = substr(line, RLENGTH+1)
+		sub(/\=.*$/, "", dcltor)
+		match(dcltor, /^([^_0-9A-Za-z]| const )*/)
+		dcltor = substr(dcltor, 1, RLENGTH) "@+" substr(dcltor, RLENGTH+1)
+		match(dcltor, /^.*@\+[_0-9A-Za-z]+/)
+		dcltor = substr(dcltor, 1, RLENGTH) "@-" substr(dcltor, RLENGTH+1)
+		dnam = dcltor
+		sub(/^.*@\+/, "", dnam)
+		sub(/@-.*$/, "", dnam)
+
+		# Put parens etc. back
+		gsub(/@[{]/, " _((", dcltor)
+		gsub(/@}/, "))", dcltor)
+		gsub(/@</, "(", dcltor)
+		gsub(/@>/, ")", dcltor)
+		gsub(/@!/, ",", dcltor)
+
+		# If this is exported, add it to the exported symbol list.
+		if(exported)
+		    printf "X%s\n", dnam
+
+		# Format the declaration for output
+		dcl = dtype " " dcltor ";"
+		if(locality ~ /E/)
+		    dcl = "extern " dcl
+		if(isfunc)
+		    gsub(/ mod_export /, " mod_import_function ", dcl)
+		else
+		    gsub(/ mod_export /, " mod_import_variable ", dcl)
+		gsub(/@[+-]/, "", dcl)
+		gsub(/ +/, " ", dcl)
+		while(match(dcl, /[^_0-9A-Za-z] ./) || match(dcl, /. [^_0-9A-Za-z]/))
+		    dcl = substr(dcl, 1, RSTART) substr(dcl, RSTART+2)
+		printf "%s%s\n", locality, dcl
+	}
     }
 }
 
diff --git a/Src/system.h b/Src/system.h
index 340f4693b..2f3dcd32a 100644
--- a/Src/system.h
+++ b/Src/system.h
@@ -153,8 +153,48 @@ char *alloca _((size_t));
 # include <stdlib.h>
 #endif
 
+/*
+ * Stuff with variable arguments.  We use definitions to make the
+ * same code work with varargs (the original K&R-style, just to
+ * be maximally compatible) and stdarg (which all modern systems
+ * should have).
+ *
+ * Ideally this should somehow be merged with the tricks performed
+ * with "_" in makepro.awk, but I don't understand makepro.awk.
+ * Currently we simply rely on the fact that makepro.awk has been
+ * hacked to leave alone argument lists that already contains VA_ALIST
+ * except for removing the VA_DCL and turning VA_ALIST into VA_ALIST_PROTO.
+ */
 #ifdef HAVE_STDARG_H
 # include <stdarg.h>
+# define VA_ALIST1(x)		x, ...
+# define VA_ALIST2(x,y)		x, y, ...
+# define VA_ALIST_PROTO1(x)	VA_ALIST1(x)
+# define VA_ALIST_PROTO2(x,y)	VA_ALIST2(x,y)
+# define VA_DCL
+# define VA_DEF_ARG(x)
+# define VA_START(ap,x)		va_start(ap, x)
+# define VA_GET_ARG(ap,x,t)
+#else
+# if HAVE_VARARGS_H
+#  include <varargs.h>
+#  define VA_ALIST1(x)		va_alist
+#  define VA_ALIST2(x,y)	va_alist
+/*
+ * In prototypes, assume K&R form and remove the variable list.
+ * This is about the best we can do without second-guessing the way
+ * varargs works on this system.  The _ trick should be able to
+ * do this for us but we've turned it off here.
+ */
+#  define VA_ALIST_PROTO1(x)
+#  define VA_ALIST_PROTO2(x,y)
+#  define VA_DCL		va_dcl
+#  define VA_DEF_ARG(x)		x
+#  define VA_START(ap,x)	va_start(ap);
+#  define VA_GET_ARG(ap,x,t)	(x = va_arg(ap, t))
+# else
+#  error "Your system has neither stdarg.h or varargs.h."
+# endif
 #endif
 
 #ifdef HAVE_ERRNO_H
diff --git a/Src/utils.c b/Src/utils.c
index bb814a41b..2d7bf2ec6 100644
--- a/Src/utils.c
+++ b/Src/utils.c
@@ -78,11 +78,14 @@ zwarning(const char *cmd, const char *fmt, va_list ap)
     zerrmsg(fmt, ap);
 }
 
+
 /**/
 mod_export void
-zerr(const char *fmt, ...)
+zerr(VA_ALIST1(const char *fmt))
+VA_DCL
 {
     va_list ap;
+    VA_DEF_ARG(const char *fmt);
 
     if (errflag || noerrs) {
 	if (noerrs < 2)
@@ -90,7 +93,8 @@ zerr(const char *fmt, ...)
 	return;
     }
 
-    va_start(ap, fmt);
+    VA_START(ap, fmt);
+    VA_GET_ARG(ap, fmt, const char *);
     zwarning(NULL, fmt, ap);
     va_end(ap);
     errflag = 1;
@@ -98,14 +102,19 @@ zerr(const char *fmt, ...)
 
 /**/
 mod_export void
-zerrnam(const char *cmd, const char *fmt, ...)
+zerrnam(VA_ALIST2(const char *cmd, const char *fmt))
+VA_DCL
 {
     va_list ap;
+    VA_DEF_ARG(const char *cmd);
+    VA_DEF_ARG(const char *fmt);
 
     if (errflag || noerrs)
 	return;
 
-    va_start(ap, fmt);
+    VA_START(ap, fmt);
+    VA_GET_ARG(ap, cmd, const char *);
+    VA_GET_ARG(ap, fmt, const char *);
     zwarning(cmd, fmt, ap);
     va_end(ap);
     errflag = 1;
@@ -113,33 +122,60 @@ zerrnam(const char *cmd, const char *fmt, ...)
 
 /**/
 mod_export void
-zwarn(const char *fmt, ...)
+zwarn(VA_ALIST1(const char *fmt))
+VA_DCL
 {
     va_list ap;
+    VA_DEF_ARG(const char *fmt);
 
     if (errflag || noerrs)
 	return;
 
-    va_start(ap, fmt);
+    VA_START(ap, fmt);
+    VA_GET_ARG(ap, fmt, const char *);
     zwarning(NULL, fmt, ap);
     va_end(ap);
 }
 
 /**/
 mod_export void
-zwarnnam(const char *cmd, const char *fmt, ...)
+zwarnnam(VA_ALIST2(const char *cmd, const char *fmt))
+VA_DCL
 {
     va_list ap;
+    VA_DEF_ARG(const char *cmd);
+    VA_DEF_ARG(const char *fmt);
 
     if (errflag || noerrs)
 	return;
 
-    va_start(ap, fmt);
+    VA_START(ap, fmt);
+    VA_GET_ARG(ap, cmd, const char *);
+    VA_GET_ARG(ap, fmt, const char *);
     zwarning(cmd, fmt, ap);
     va_end(ap);
 }
 
 
+#ifdef DEBUG
+
+/**/
+mod_export void
+dputs(VA_ALIST1(const char *message))
+VA_DCL
+{
+    va_list ap;
+    VA_DEF_ARG(const char *message);
+
+    VA_START(ap, message);
+    VA_GET_ARG(ap, message, const char *);
+    zerrmsg(message, ap);
+    va_end(ap);
+    fflush(stderr);
+}
+
+#endif /* DEBUG */
+
 #ifdef __CYGWIN__
 /*
  * This works around an occasional problem with dllwrap on Cygwin, seen
@@ -4536,18 +4572,6 @@ privasserted(void)
     return 0;
 }
 
-#ifdef DEBUG
-
-/**/
-mod_export void
-dputs(char *message)
-{
-    fprintf(stderr, "%s\n", message);
-    fflush(stderr);
-}
-
-#endif /* DEBUG */
-
 /**/
 mod_export int
 mode_to_octal(mode_t mode)