| 2875 |
dpurdie |
1 |
#pragma force_top_level
|
|
|
2 |
#pragma include_only_once
|
|
|
3 |
|
|
|
4 |
/* stdarg.h: ANSI 'C' (X3J11 Oct 88) library header, section 4.8 */
|
|
|
5 |
/* Copyright (C) Codemist Ltd., 1988 */
|
|
|
6 |
/* Copyright (C) Advanced Risc Machines Ltd., 1991 */
|
|
|
7 |
/* version 3 */
|
|
|
8 |
|
|
|
9 |
#ifndef __stdarg_h
|
|
|
10 |
#define __stdarg_h
|
|
|
11 |
|
|
|
12 |
/*
|
|
|
13 |
* stdarg.h declares a type and defines three macros, for advancing through a
|
|
|
14 |
* list of arguments whose number and types are not known to the called
|
|
|
15 |
* function when it is translated. A function may be called with a variable
|
|
|
16 |
* number of arguments of differing types. Its parameter list contains one or
|
|
|
17 |
* more parameters. The rightmost parameter plays a special role in the access
|
|
|
18 |
* mechanism, and will be called parmN in this description.
|
|
|
19 |
*/
|
|
|
20 |
|
|
|
21 |
/* N.B. <stdio.h> is required to declare vfprintf() without defining */
|
|
|
22 |
/* va_list. Clearly the type __va_list there must keep in step. */
|
|
|
23 |
typedef char *va_list[1]; /* see <stdio.h> */
|
|
|
24 |
/*
|
|
|
25 |
* an array type suitable for holding information needed by the macro va_arg
|
|
|
26 |
* and the function va_end. The called function shall declare a variable
|
|
|
27 |
* (referred to as ap) having type va_list. The variable ap may be passed as
|
|
|
28 |
* an argument to another function.
|
|
|
29 |
* Note: va_list is an array type so that when an object of that type
|
|
|
30 |
* is passed as an argument it gets passed by reference.
|
|
|
31 |
*/
|
|
|
32 |
|
|
|
33 |
/* Note that ___type is a syntactic item a bit like the type qualifiers */
|
|
|
34 |
/* 'static', 'register', 'const' etc except that it has no effect! Its */
|
|
|
35 |
/* purpose is to indicate when a type is being introduced and thus */
|
|
|
36 |
/* help (a bit) when the user gets the args to va_arg the wrong way round */
|
|
|
37 |
#define __alignof(type) \
|
|
|
38 |
((char *)&(((struct{char __member1; \
|
|
|
39 |
___type type __member2;}*) 0)->__member2) - \
|
|
|
40 |
(char *)0)
|
|
|
41 |
#define __alignuptotype(ptr,type) \
|
|
|
42 |
((char *)((int)(ptr) + (__alignof(type)-1) & ~(__alignof(type)-1)))
|
|
|
43 |
|
|
|
44 |
|
|
|
45 |
#define va_start(ap,parmN) \
|
|
|
46 |
(___assert((___typeof(parmN) & 0x481) == 0, \
|
|
|
47 |
"Illegal type of 2nd argument to va_start"), \
|
|
|
48 |
(void)(*(ap) = (char *)&(parmN) + sizeof(parmN)))
|
|
|
49 |
/*
|
|
|
50 |
* The va_start macro shall be executed before any access to the unnamed
|
|
|
51 |
* arguments. The parameter ap points to an object that has type va_list.
|
|
|
52 |
* The va_start macro initialises ap for subsequent use by va_arg and
|
|
|
53 |
* va_end. The parameter parmN is the identifier of the rightmost parameter
|
|
|
54 |
* in the variable parameter list in the function definition (the one just
|
|
|
55 |
* before the , ...). If the parameter parmN is declared with the register
|
|
|
56 |
* storage class the behaviour is undefined (Norcroft C gives diagnostic).
|
|
|
57 |
* parmN shall not be affected by default argument conversions (Norcroft
|
|
|
58 |
* C gives a diagnostic and would (July 1990) generate 'wrong' code).
|
|
|
59 |
* Returns: no value.
|
|
|
60 |
*/
|
|
|
61 |
|
|
|
62 |
#define va_arg(ap,type) \
|
|
|
63 |
(___assert((___typeof(___type type) & 0x481) == 0, \
|
|
|
64 |
"Illegal type used with va_arg"), \
|
|
|
65 |
*(___type type *)((*(ap)=__alignuptotype(*(ap),type)+sizeof(___type type))-\
|
|
|
66 |
sizeof(___type type)))
|
|
|
67 |
/*
|
|
|
68 |
* The va_arg macro expands to an expression that has the type and value of
|
|
|
69 |
* the next argument in the call. The parameter ap shall be the same as the
|
|
|
70 |
* va_list ap initialised by va_start. Each invocation of va_arg modifies
|
|
|
71 |
* ap so that successive arguments are returned in turn. The parameter
|
|
|
72 |
* 'type' is a type name such that the type of a pointer to an object that
|
|
|
73 |
* has the specified type can be obtained simply by postfixing a * to
|
|
|
74 |
* 'type'. If 'type' disagrees with the type of the actual next argument
|
|
|
75 |
* (as promoted according to the default argument promotions), the behaviour
|
|
|
76 |
* is undefined.
|
|
|
77 |
* Returns: The first invocation of the va_arg macro after that of the
|
|
|
78 |
* va_start macro returns the value of the argument after that
|
|
|
79 |
* specified by parmN. Successive invocations return the values of
|
|
|
80 |
* the remaining arguments in succession.
|
|
|
81 |
* Note: care is taken in va_arg so that illegal things like va_arg(ap,char)
|
|
|
82 |
* which may seem natural but are illegal are caught. The special Norcroft
|
|
|
83 |
* C keywords ___assert and ___typeof are used to do this: these keywords
|
|
|
84 |
* are not intended for use by ordinary users.
|
|
|
85 |
*/
|
|
|
86 |
|
|
|
87 |
#define va_end(ap) ((void)(*(ap) = (char *)-256))
|
|
|
88 |
/*
|
|
|
89 |
* The va_end macro facilitates a normal return from the function whose
|
|
|
90 |
* variable argument list was referenced by the expansion of va_start that
|
|
|
91 |
* initialised the va_list ap. If the va_end macro is not invoked before
|
|
|
92 |
* the return, the behaviour is undefined.
|
|
|
93 |
* Returns: no value.
|
|
|
94 |
* Note: this macro is careful to avoid compiler warning messages and uses
|
|
|
95 |
* a -ve address to ensure address trap.
|
|
|
96 |
*/
|
|
|
97 |
|
|
|
98 |
#endif
|
|
|
99 |
|
|
|
100 |
/* end of stdarg.h */
|