Ne.app NeANT
The Ne.app NeANT User module of the NeANT distribution.
VA_LIST.cpp
Go to the documentation of this file.
1// checking the type of va_list
2
3
25#include "config.h"
26
27#include <stddef.h>
28#include <stdarg.h>
29#include <stdio.h>
30#include <string.h>
31
32
33// determine the underlying pointer type of a typedef
34#define GET_TYPE_NAME(T) \
35 const char* get_type_name (T) { return # T; } \
36 const char* get_type_name (T*) { return # T "*"; } \
37 typedef void unused_type
38
40GET_TYPE_NAME (signed char);
41GET_TYPE_NAME (unsigned char);
43GET_TYPE_NAME (unsigned short);
45GET_TYPE_NAME (unsigned int);
47GET_TYPE_NAME (unsigned long);
48
49#ifndef _RWSTD_NO_LONG_LONG
50
51GET_TYPE_NAME (long long);
52GET_TYPE_NAME (unsigned long long);
53
54#elif defined (_MSC_VER)
55
56GET_TYPE_NAME (__int64);
57GET_TYPE_NAME (unsigned __int64);
58
59#endif // _RWSTD_NO_LONG_LONG, _MSC_VER
60
63
64#ifndef _RWSTD_NO_LONG_DOUBLE
65
66GET_TYPE_NAME (long double);
67
68#endif // _RWSTD_NO_LONG_DOUBLE
69
71
72const char* get_type_name (...) { return 0; }
73
74#ifndef _RWSTD_NO_CLASS_PARTIAL_SPEC
75
76template <class T>
77struct Type {
78 enum { array_size = 0 };
79 static const char* type_name () { return get_type_name (T ()); }
80};
81
82template <class T, int N>
83struct Type<T [N]> {
84 enum { array_size = N };
85 static const char* type_name () { return get_type_name (T ()); }
86};
87
88
89int va_list_array_size (va_list)
90{
92}
93
94const char* va_list_type_name (va_list)
95{
97}
98
99
100#else // if defined (_RWSTD_NO_CLASS_PARTIAL_SPEC)
101
102#ifndef _RWSTD_NO_PART_SPEC_OVERLOAD
103
104template <class T>
105int va_list_array_size_imp (T *va)
106{
107 return 0;
108}
109
110template <class T>
111int va_list_array_size_imp (T **va)
112{
113 return sizeof (va_list) / sizeof **va;
114}
115
116int va_list_array_size (va_list va)
117{
118 return va_list_array_size_imp (&va);
119}
120
121#else // if defined (_RWSTD_NO_PART_SPEC_OVERLOAD)
122
123template <class T>
124class is_array
125{
126 class yes {};
127
128 class no { yes yes_ [2]; };
129
130 template <class U> struct Type {};
131
132 template <class U, size_t N>
133 static yes test (Type<U[N]>);
134 static no test (...);
135
136public:
137 enum { value = sizeof (test (Type<T> ())) == sizeof (yes) };
138};
139
140template <class T>
141int va_list_array_size_imp (T **va)
142{
143 return sizeof (va_list) / sizeof **va;
144}
145
146int va_list_array_size (va_list va)
147{
148 return is_array<va_list>::value ? va_list_array_size_imp (&va) : 0;
149}
150
151#endif // _RWSTD_NO_PART_SPEC_OVERLOAD
152
153template <class T>
154const char* va_list_type (T *va)
155{
156 return get_type_name (*va);
157}
158
159const char* va_list_type_name (va_list va)
160{
161 va_list va2;
162 memset (&va2, 0, sizeof va2);
163
164 const int array_size = va_list_array_size (va2);
165
166 return array_size ? va_list_type (va2) : get_type_name (va);
167}
168
169#endif // _RWSTD_NO_CLASS_PARTIAL_SPEC
170
171
172int main ()
173{
174#if defined (va_copy)
175
176 // comment out the macro #defined below when va_copy() exists
177 printf ("%s ", "//");
178
179#endif // va_copy
180
181 printf ("#define _RWSTD_NO_VA_COPY\n");
182
183 va_list va;
184 memset (&va, 0, sizeof va);
185
186 const int array_size = va_list_array_size (va);
187
188 const char* type_name = va_list_type_name (va);
189
190 if (0 == type_name) {
191 puts ("typedef struct {");
192
193 int elem_size = sizeof va;
194 if (array_size)
195 elem_size /= array_size;
196
197 if (1 < elem_size / sizeof (void*))
198 printf (" void* _C_data [%u];\n", elem_size / sizeof (void*));
199 else if (1 == elem_size / sizeof (void*))
200 puts (" void* _C_data;");
201 else if (1 < elem_size % sizeof (void*))
202 printf (" char _C_data [%u]\n", elem_size % sizeof (void*));
203 else if (1 == elem_size % sizeof (void*))
204 puts (" char _C_data;");
205
206 puts ("} __rw_va_elem;");
207 type_name = "__rw_va_elem";
208 }
209
210 if (array_size) {
211 printf ("typedef %s __rw_va_list [%d];\n"
212 "// #define _RWSTD_NO_VA_LIST_ARRAY // va_list is an array\n",
213 type_name, array_size);
214 }
215 else {
216 printf ("typedef %s __rw_va_list;\n"
217 "#define _RWSTD_NO_VA_LIST_ARRAY // va_list is object type\n",
218 type_name);
219 }
220
221 puts ("#define _RWSTD_VA_LIST __rw_va_list");
222
223 return 0;
224}
#define N
Definition 17.names.cpp:157
#define T
Definition 17.names.cpp:163
#define U
Definition 17.names.cpp:164
T value(const T &val)
const char * type_name()
IMPORT_C SInt32 printf(const Char *,...)
#define GET_TYPE_NAME(T)
Definition VA_LIST.cpp:34
const char * get_type_name(...)
Definition VA_LIST.cpp:72
int va_list_array_size(va_list)
Definition VA_LIST.cpp:89
const char * va_list_type_name(va_list)
Definition VA_LIST.cpp:94
int main()
Definition VA_LIST.cpp:172
constexpr bool is_array
Metafunction for determining if a type is, or is a reference to, a toml::array.
static const char * type_name()
Definition VA_LIST.cpp:85
static const char * type_name()
Definition VA_LIST.cpp:79
@ array_size
Definition VA_LIST.cpp:78