stdarg.h

Go to the documentation of this file.
00001 /* The <stdarg.h> header is ANSI's way to handle variable numbers of params.
00002  * Some programming languages require a function that is declared with n
00003  * parameters to be called with n parameters.  C does not.  A function may
00004  * called with more parameters than it is declared with.  The well-known
00005  * printf function, for example, may have arbitrarily many parameters.
00006  * The question arises how one can access all the parameters in a portable
00007  * way.  The C standard defines three macros that programs can use to
00008  * advance through the parameter list.  The definition of these macros for
00009  * MINIX are given in this file.  The three macros are:
00010  *
00011  *      va_start(ap, parmN)     prepare to access parameters
00012  *      va_arg(ap, type)        get next parameter value and type
00013  *      va_end(ap)              access is finished
00014  *
00015  * Ken Thompson's famous line from V6 UNIX is equally applicable to this file:
00016  *
00017  *      "You are not expected to understand this"
00018  *
00019  */
00020 
00021 #ifndef _STDARG_H
00022 #define _STDARG_H
00023 
00024 #ifdef __GNUC__
00025 /* The GNU C-compiler uses its own, but similar varargs mechanism. */
00026 
00027 typedef char *va_list;
00028 
00029 /* Amount of space required in an argument list for an arg of type TYPE.
00030  * TYPE may alternatively be an expression whose type is used.
00031  */
00032 
00033 #define __va_rounded_size(TYPE)  \
00034   (((sizeof (TYPE) + sizeof (int) - 1) / sizeof (int)) * sizeof (int))
00035 
00036 #if __GNUC__ < 2
00037 
00038 #ifndef __sparc__
00039 #define va_start(AP, LASTARG)                                           \
00040  (AP = ((char *) &(LASTARG) + __va_rounded_size (LASTARG)))
00041 #else
00042 #define va_start(AP, LASTARG)                                           \
00043  (__builtin_saveregs (),                                                \
00044   AP = ((char *) &(LASTARG) + __va_rounded_size (LASTARG)))
00045 #endif
00046 
00047 void va_end (va_list);          /* Defined in gnulib */
00048 #define va_end(AP)
00049 
00050 #define va_arg(AP, TYPE)                                                \
00051  (AP += __va_rounded_size (TYPE),                                       \
00052   *((TYPE *) (AP - __va_rounded_size (TYPE))))
00053 
00054 #else   /* __GNUC__ >= 2 */
00055 
00056 #ifndef __sparc__
00057 #define va_start(AP, LASTARG)                                           \
00058  (AP = ((char *) __builtin_next_arg ()))
00059 #else
00060 #define va_start(AP, LASTARG)                                   \
00061   (__builtin_saveregs (), AP = ((char *) __builtin_next_arg ()))
00062 #endif
00063 
00064 void va_end (va_list);          /* Defined in libgcc.a */
00065 #define va_end(AP)
00066 
00067 #define va_arg(AP, TYPE)                                                \
00068  (AP = ((char *) (AP)) += __va_rounded_size (TYPE),                     \
00069   *((TYPE *) ((char *) (AP) - __va_rounded_size (TYPE))))
00070 
00071 #endif  /* __GNUC__ >= 2 */
00072 
00073 #else   /* not __GNUC__ */
00074 
00075 typedef char *va_list;
00076 
00077 #define __vasz(x)               ((sizeof(x)+sizeof(int)-1) & ~(sizeof(int) -1))
00078 
00079 #define va_start(ap, parmN)     ((ap) = (va_list)&parmN + __vasz(parmN))
00080 #define va_arg(ap, type)      \
00081   (*((type *)((va_list)((ap) = (void *)((va_list)(ap) + __vasz(type))) \
00082                                                     - __vasz(type))))
00083 #define va_end(ap)
00084 
00085 #endif /* __GNUC__ */
00086 
00087 #endif /* _STDARG_H */

Generated on Fri Apr 14 22:57:21 2006 for minix by  doxygen 1.4.6