source: branches/minix3-book/include/stdarg.h@ 15

Last change on this file since 15 was 4, checked in by Mattia Monga, 14 years ago

Importazione sorgenti libro

File size: 2.8 KB
RevLine 
[4]1/* The <stdarg.h> header is ANSI's way to handle variable numbers of params.
2 * Some programming languages require a function that is declared with n
3 * parameters to be called with n parameters. C does not. A function may
4 * called with more parameters than it is declared with. The well-known
5 * printf function, for example, may have arbitrarily many parameters.
6 * The question arises how one can access all the parameters in a portable
7 * way. The C standard defines three macros that programs can use to
8 * advance through the parameter list. The definition of these macros for
9 * MINIX are given in this file. The three macros are:
10 *
11 * va_start(ap, parmN) prepare to access parameters
12 * va_arg(ap, type) get next parameter value and type
13 * va_end(ap) access is finished
14 *
15 * Ken Thompson's famous line from V6 UNIX is equally applicable to this file:
16 *
17 * "You are not expected to understand this"
18 *
19 */
20
21#ifndef _STDARG_H
22#define _STDARG_H
23
24#ifdef __GNUC__
25/* The GNU C-compiler uses its own, but similar varargs mechanism. */
26
27typedef char *va_list;
28
29/* Amount of space required in an argument list for an arg of type TYPE.
30 * TYPE may alternatively be an expression whose type is used.
31 */
32
33#define __va_rounded_size(TYPE) \
34 (((sizeof (TYPE) + sizeof (int) - 1) / sizeof (int)) * sizeof (int))
35
36#if __GNUC__ < 2
37
38#ifndef __sparc__
39#define va_start(AP, LASTARG) \
40 (AP = ((char *) &(LASTARG) + __va_rounded_size (LASTARG)))
41#else
42#define va_start(AP, LASTARG) \
43 (__builtin_saveregs (), \
44 AP = ((char *) &(LASTARG) + __va_rounded_size (LASTARG)))
45#endif
46
47void va_end (va_list); /* Defined in gnulib */
48#define va_end(AP)
49
50#define va_arg(AP, TYPE) \
51 (AP += __va_rounded_size (TYPE), \
52 *((TYPE *) (AP - __va_rounded_size (TYPE))))
53
54#else /* __GNUC__ >= 2 */
55
56#ifndef __sparc__
57#define va_start(AP, LASTARG) \
58 (AP = ((char *) __builtin_next_arg ()))
59#else
60#define va_start(AP, LASTARG) \
61 (__builtin_saveregs (), AP = ((char *) __builtin_next_arg ()))
62#endif
63
64void va_end (va_list); /* Defined in libgcc.a */
65#define va_end(AP)
66
67#define va_arg(AP, TYPE) \
68 (AP = ((char *) (AP)) += __va_rounded_size (TYPE), \
69 *((TYPE *) ((char *) (AP) - __va_rounded_size (TYPE))))
70
71#endif /* __GNUC__ >= 2 */
72
73#else /* not __GNUC__ */
74
75typedef char *va_list;
76
77#define __vasz(x) ((sizeof(x)+sizeof(int)-1) & ~(sizeof(int) -1))
78
79#define va_start(ap, parmN) ((ap) = (va_list)&parmN + __vasz(parmN))
80#define va_arg(ap, type) \
81 (*((type *)((va_list)((ap) = (void *)((va_list)(ap) + __vasz(type))) \
82 - __vasz(type))))
83#define va_end(ap)
84
85#endif /* __GNUC__ */
86
87#endif /* _STDARG_H */
Note: See TracBrowser for help on using the repository browser.