2005-04-21 16:53:53 +02:00
|
|
|
/* The <stdarg.h> header is ANSI's way to handle variable numbers of params.
|
|
|
|
* Some programming languages require a function that is declared with n
|
|
|
|
* parameters to be called with n parameters. C does not. A function may
|
|
|
|
* called with more parameters than it is declared with. The well-known
|
|
|
|
* printf function, for example, may have arbitrarily many parameters.
|
|
|
|
* The question arises how one can access all the parameters in a portable
|
|
|
|
* way. The C standard defines three macros that programs can use to
|
|
|
|
* advance through the parameter list. The definition of these macros for
|
|
|
|
* MINIX are given in this file. The three macros are:
|
|
|
|
*
|
|
|
|
* va_start(ap, parmN) prepare to access parameters
|
|
|
|
* va_arg(ap, type) get next parameter value and type
|
|
|
|
* va_end(ap) access is finished
|
|
|
|
*
|
|
|
|
* Ken Thompson's famous line from V6 UNIX is equally applicable to this file:
|
|
|
|
*
|
|
|
|
* "You are not expected to understand this"
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef _STDARG_H
|
|
|
|
#define _STDARG_H
|
|
|
|
|
|
|
|
#ifdef __GNUC__
|
|
|
|
/* The GNU C-compiler uses its own, but similar varargs mechanism. */
|
|
|
|
|
|
|
|
typedef char *va_list;
|
|
|
|
|
|
|
|
/* Amount of space required in an argument list for an arg of type TYPE.
|
|
|
|
* TYPE may alternatively be an expression whose type is used.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#define __va_rounded_size(TYPE) \
|
|
|
|
(((sizeof (TYPE) + sizeof (int) - 1) / sizeof (int)) * sizeof (int))
|
|
|
|
|
|
|
|
#if __GNUC__ < 2
|
|
|
|
|
|
|
|
#ifndef __sparc__
|
|
|
|
#define va_start(AP, LASTARG) \
|
|
|
|
(AP = ((char *) &(LASTARG) + __va_rounded_size (LASTARG)))
|
|
|
|
#else
|
|
|
|
#define va_start(AP, LASTARG) \
|
|
|
|
(__builtin_saveregs (), \
|
|
|
|
AP = ((char *) &(LASTARG) + __va_rounded_size (LASTARG)))
|
|
|
|
#endif
|
|
|
|
|
|
|
|
void va_end (va_list); /* Defined in gnulib */
|
|
|
|
#define va_end(AP)
|
|
|
|
|
|
|
|
#define va_arg(AP, TYPE) \
|
|
|
|
(AP += __va_rounded_size (TYPE), \
|
|
|
|
*((TYPE *) (AP - __va_rounded_size (TYPE))))
|
|
|
|
|
|
|
|
#else /* __GNUC__ >= 2 */
|
|
|
|
|
2010-03-30 11:36:46 +02:00
|
|
|
#define va_start(ap, last) __builtin_va_start((ap), (last))
|
|
|
|
#define va_arg(ap, type) __builtin_va_arg((ap), type)
|
|
|
|
#define va_end(ap) __builtin_va_end(ap)
|
|
|
|
#define va_copy(dest, src) __builtin_va_copy((dest), (src))
|
2005-04-21 16:53:53 +02:00
|
|
|
|
|
|
|
#endif /* __GNUC__ >= 2 */
|
|
|
|
|
|
|
|
#else /* not __GNUC__ */
|
|
|
|
|
|
|
|
typedef char *va_list;
|
|
|
|
|
|
|
|
#define __vasz(x) ((sizeof(x)+sizeof(int)-1) & ~(sizeof(int) -1))
|
|
|
|
|
|
|
|
#define va_start(ap, parmN) ((ap) = (va_list)&parmN + __vasz(parmN))
|
|
|
|
#define va_arg(ap, type) \
|
|
|
|
(*((type *)((va_list)((ap) = (void *)((va_list)(ap) + __vasz(type))) \
|
|
|
|
- __vasz(type))))
|
2008-12-11 15:10:56 +01:00
|
|
|
#define va_copy(ap2, ap) (ap2) = (ap)
|
2005-04-21 16:53:53 +02:00
|
|
|
#define va_end(ap)
|
|
|
|
|
|
|
|
#endif /* __GNUC__ */
|
|
|
|
|
|
|
|
#endif /* _STDARG_H */
|