91 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			91 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
| /* 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 */
 | |
| 
 | |
| #ifndef __sparc__
 | |
| #define va_start(AP, LASTARG) 						\
 | |
|  (AP = ((char *) __builtin_next_arg ()))
 | |
| #else
 | |
| #define va_start(AP, LASTARG)					\
 | |
|   (__builtin_saveregs (), AP = ((char *) __builtin_next_arg ()))
 | |
| #endif
 | |
| 
 | |
| void va_end (va_list);		/* Defined in libgcc.a */
 | |
| #define va_end(AP)
 | |
| 
 | |
| #define va_arg(AP, TYPE)						\
 | |
|  (AP = ((char *) (AP)) += __va_rounded_size (TYPE),			\
 | |
|   *((TYPE *) ((char *) (AP) - __va_rounded_size (TYPE))))
 | |
| 
 | |
| #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))))
 | |
| #define va_end(ap)
 | |
| 
 | |
| 
 | |
| #endif /* __GNUC__ */
 | |
| 
 | |
| #endif /* _STDARG_H */
 | 
