vargs.h
上传用户:romrleung
上传日期:2022-05-23
资源大小:18897k
文件大小:5k
- /******************************************************************************
- * *
- * 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]