diff options
Diffstat (limited to 'dbug/vargs.h')
-rw-r--r-- | dbug/vargs.h | 139 |
1 files changed, 139 insertions, 0 deletions
diff --git a/dbug/vargs.h b/dbug/vargs.h new file mode 100644 index 00000000000..4609c8301bb --- /dev/null +++ b/dbug/vargs.h @@ -0,0 +1,139 @@ +/****************************************************************************** + * * + * N O T I C E * + * * + * Copyright Abandoned, 1987, Fred Fish * + * * + * * + * This previously copyrighted work has been placed into the public * + * domain by the author and may be freely used for any purpose, * + * private or commercial. * + * * + * Because of the number of inquiries I was receiving about the use * + * of this product in commercially developed works I have decided to * + * simply make it public domain to further its unrestricted use. I * + * specifically would be most happy to see this material become a * + * part of the standard Unix distributions by AT&T and the Berkeley * + * Computer Science Research Group, and a standard part of the GNU * + * system from the Free Software Foundation. * + * * + * I would appreciate it, as a courtesy, if this notice is left in * + * all copies and derivative works. Thank you. * + * * + * The author makes no warranty of any kind with respect to this * + * product and explicitly disclaims any implied warranties of mer- * + * chantability or fitness for any particular purpose. * + * * + ****************************************************************************** + */ + + +/* + * FILE + * + * vargs.h include file for environments without varargs.h + * + * SCCS + * + * @(#)vargs.h 1.2 5/8/88 + * + * SYNOPSIS + * + * #include "vargs.h" + * + * DESCRIPTION + * + * This file implements a varargs macro set for use in those + * environments where there is no system supplied varargs. This + * generally works because systems which don't supply a varargs + * package are precisely those which don't strictly need a varargs + * package. Using this one then allows us to minimize source + * code changes. So in some sense, this is a "portable" varargs + * since it is only used for convenience, when it is not strictly + * needed. + * + */ + +/* + * These macros allow us to rebuild an argument list on the stack + * given only a va_list. We can use these to fake a function like + * vfprintf, which gets a fixed number of arguments, the last of + * which is a va_list, by rebuilding a stack and calling the variable + * argument form fprintf. Of course this only works when vfprintf + * is not available in the host environment, and thus is not available + * for fprintf to call (which would give us an infinite loop). + * + * Note that ARGS_TYPE is a long, which lets us get several bytes + * at a time while also preventing lots of "possible pointer alignment + * problem" messages from lint. The messages are valid, because this + * IS nonportable, but then we should only be using it in very + * nonrestrictive environments, and using the real varargs where it + * really counts. + * + */ + +#define ARG0 a0 +#define ARG1 a1 +#define ARG2 a2 +#define ARG3 a3 +#define ARG4 a4 +#define ARG5 a5 +#define ARG6 a6 +#define ARG7 a7 +#define ARG8 a8 +#define ARG9 a9 + +#define ARGS_TYPE long +#define ARGS_LIST ARG0,ARG1,ARG2,ARG3,ARG4,ARG5,ARG6,ARG7,ARG8,ARG9 +#define ARGS_DCL auto ARGS_TYPE ARGS_LIST + +/* + * A pointer of type "va_list" points to a section of memory + * containing an array of variable sized arguments of unknown + * number. This pointer is initialized by the va_start + * macro to point to the first byte of the first argument. + * We can then use it to walk through the argument list by + * incrementing it by the size of the argument being referenced. + */ + +typedef char *va_list; + +/* + * The first variable argument overlays va_alist, which is + * nothing more than a "handle" which allows us to get the + * address of the first argument on the stack. Note that + * by definition, the va_dcl macro includes the terminating + * semicolon, which makes use of va_dcl in the source code + * appear to be missing a semicolon. + */ + +#define va_dcl ARGS_TYPE va_alist; + +/* + * The va_start macro takes a variable of type "va_list" and + * initializes it. In our case, it initializes a local variable + * of type "pointer to char" to point to the first argument on + * the stack. + */ + +#define va_start(list) list = (char *) &va_alist + +/* + * The va_end macro is a null operation for our use. + */ + +#define va_end(list) + +/* + * The va_arg macro is the tricky one. This one takes + * a va_list as the first argument, and a type as the second + * argument, and returns a value of the appropriate type + * while advancing the va_list to the following argument. + * For our case, we first increment the va_list arg by the + * size of the type being recovered, cast the result to + * a pointer of the appropriate type, and then dereference + * that pointer as an array to get the previous arg (which + * is the one we wanted. + */ + +#define va_arg(list,type) ((type *) (list += sizeof (type)))[-1] |