diff options
author | Peter Stephenson <pws@users.sourceforge.net> | 2006-06-05 16:55:38 +0000 |
---|---|---|
committer | Peter Stephenson <pws@users.sourceforge.net> | 2006-06-05 16:55:38 +0000 |
commit | 11836eb5e32085f9808d35ca6e7dc23d61a5090b (patch) | |
tree | 52168c0739ffb9f0f00f92d5a8b9ccf5890ecee3 /Src | |
parent | 8346a5e8d28899f88c92ea3cd772012ad4a50e49 (diff) | |
download | zsh-11836eb5e32085f9808d35ca6e7dc23d61a5090b.tar.gz zsh-11836eb5e32085f9808d35ca6e7dc23d61a5090b.tar.xz zsh-11836eb5e32085f9808d35ca6e7dc23d61a5090b.zip |
22484: support varargs.h in addition to stdarg.h
Diffstat (limited to 'Src')
-rw-r--r-- | Src/makepro.awk | 103 | ||||
-rw-r--r-- | Src/system.h | 40 | ||||
-rw-r--r-- | Src/utils.c | 64 |
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) |