1 /** @file
2     This header, <stdarg.h>, declares type va_list and defines macros: va_start, va_arg, va_end;
3     for advancing through a list of arguments whose number and types are not known to the
4     called function when it is translated.
5 
6     A function may be called with a variable number of arguments of varying types.
7     The rightmost argument plays a special role in the access mechanism, and will
8     be designated paramN in this and subsequent descriptions.
9 
10     The type va_list is a type suitable for holding information needed by the
11     macros va_start, va_arg, and va_end.  If access to the varying arguments
12     is desired, the called function shall declare an object (referred to as ap
13     in these descriptions) having type va_list.  The object ap may be passed as
14     an argument to another function; if the receiving function invokes the va_arg macro
15     with parameter ap, the value of ap in the calling function becomes indeterminate
16     and must be passed to the va_end macro prior to any further reference to ap.
17 
18     The va_start and va_arg macros must be implemented as macros, not as actual
19     functions.  The va_start and va_end macros must be invoked in the
20     function accepting a varying number of arguments, if access to the varying
21     arguments is desired.
22 
23     Copyright (c) 2010 - 2012, Intel Corporation. All rights reserved.<BR>
24     This program and the accompanying materials are licensed and made available under
25     the terms and conditions of the BSD License that accompanies this distribution.
26     The full text of the license may be found at
27     http://opensource.org/licenses/bsd-license.
28 
29     THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
30     WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
31 **/
32 #ifndef _STDARG_H
33 #define _STDARG_H
34 #include  <sys/EfiCdefs.h>
35 
36 /** @{
37     The type va_list is a type suitable for holding information needed by the
38     macros va_start, va_arg, and va_end.
39 
40     Depending upon compiler or CPU architecture, different definitions are required.
41 **/
42 #if defined(__GNUC__)
43 typedef __builtin_va_list   va_list;
44 #else
45 #define va_list   VA_LIST
46 #endif
47 /*@}*/
48 
49 /** @{
50     The va_start macro must be invoked before any access to the unnamed arguments.
51     The va_start macro initializes ap for subsequent use by va_arg and va_end.
52 
53     Synopsys: void va_start(va_list ap, paramN);
54 
55     @param  ap      An object of type va_list that is to be initialized such
56                     that subsequent successive invocations of va_arg will
57                     return the values of the parameters following paramN.
58 
59     @param  paramN  The parameter paramN is the identifier of the rightmost
60                     parameter in the variable parameter list in the function
61                     definition (the one just before the ,...).  If the
62                     parameter parmN is declared with the register storage
63                     class, with a function of array type, or with a type that
64                     is not compatible with the type that results after
65                     application of the default argument promotions, the
66                     behavior is undefined.
67 **/
68 #if defined(__GNUC__)
69 #define va_start    __builtin_va_start
70 #else
71 #define va_start    VA_START
72 #endif
73 /*@}*/
74 
75 /** @{
76     The va_arg macro expands to an expression that has the type and value of
77     the next argument in the call.  The parameter ap shall be the same as the
78     va_list ap initialized by va_start.  Each invocation of va_arg modifies ap
79     so that the values of successive arguments are returned in turn.  The
80     parameter type is a type name specified such that the type of a pointer to
81     an object that has the specified type can be obtained simply by postfixing
82     a * to type.  If there is no actual next argument, or if type is not
83     compatible with the type of the actual next argument (as promoted
84     according to the default argument promotions), the behavior is undefined.
85 
86     Synopsys: type va_arg(va_list ap, type);
87 
88     @param  ap    An object of type va_list that was initialized by a prior
89                   invocation of va_start.
90 
91     @param  type  A type name specifying the type of the parameter to be retrieved.
92 
93     @return       The first invocation of the va_arg macro after that of the
94                   va_start macro returns the value of the argument after that
95                   specified by paramN.  Successive invocations return the values
96                   of the remaining arguments in succession.
97 **/
98 #if defined(__GNUC__)
99 #define va_arg        __builtin_va_arg
100 #else
101 #define va_arg        VA_ARG
102 #endif
103 /*@}*/
104 
105 /** @{
106     The va_end macro facillitates a normal return from the function whose
107     variable argument list was referred to by the expansion of va_start that
108     initialized the va_list ap.
109 
110     Synopsys: void va_end(va_list ap);
111 
112     The va_end macro may modify ap so that it is no longer usable (without an
113     intervening invocation of va_start).  If there is no corresponding
114     invocation of the va_start macro, or if the va_end macro is not invoked
115     before the return, the behavior is undefined.
116 
117     @param  ap    An object of type va_list, initialized by a prior
118                   invocation of va_start, that will no longer be referenced.
119 **/
120 #if defined(__GNUC__)
121 #define va_end              __builtin_va_end
122 #else
123 #define va_end              VA_END
124 #endif
125 /*@}*/
126 
127 /** @{
128     For BSD compatibility.
129 **/
130 #if defined(__GNUC__)
131 #define va_copy         __builtin_va_copy
132 #else
133 #define va_copy(s,d)      (s) = (d)
134 #endif
135 /*@}*/
136 
137 /** Provide a generic version of the compiler-dependent __va_copy macro.
138     Some software, such as Python 2.7.2, relies upon the existence of __va_copy.
139     If this macro is not defined, it just assigns one va_list item to another.
140     This breaks for compiler environments that define va_list as an array or structure.
141 **/
142 #ifndef __va_copy
143   #define __va_copy       va_copy
144 #endif
145 
146 #endif  /* _STDARG_H */
147