]>
Commit | Line | Data |
---|---|---|
1eee94d3 GM |
1 | /* do not edit automatically generated by mc from varargs. */ |
2 | /* varargs.mod provides a basic vararg facility for GNU Modula-2. | |
3 | ||
83ffe9cd | 4 | Copyright (C) 2015-2023 Free Software Foundation, Inc. |
1eee94d3 GM |
5 | Contributed by Gaius Mulley <gaius@glam.ac.uk>. |
6 | ||
7 | This file is part of GNU Modula-2. | |
8 | ||
9 | GNU Modula-2 is free software; you can redistribute it and/or modify | |
10 | it under the terms of the GNU General Public License as published by | |
11 | the Free Software Foundation; either version 3, or (at your option) | |
12 | any later version. | |
13 | ||
14 | GNU Modula-2 is distributed in the hope that it will be useful, but | |
15 | WITHOUT ANY WARRANTY; without even the implied warranty of | |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
17 | General Public License for more details. | |
18 | ||
19 | You should have received a copy of the GNU General Public License | |
20 | along with GNU Modula-2; see the file COPYING3. If not see | |
21 | <http://www.gnu.org/licenses/>. */ | |
22 | ||
23 | #include "config.h" | |
24 | #include "system.h" | |
25 | # if !defined (PROC_D) | |
26 | # define PROC_D | |
27 | typedef void (*PROC_t) (void); | |
28 | typedef struct { PROC_t proc; } PROC; | |
29 | # endif | |
30 | ||
31 | # include "GStorage.h" | |
32 | #if defined(__cplusplus) | |
33 | # undef NULL | |
34 | # define NULL 0 | |
35 | #endif | |
36 | #define _varargs_H | |
37 | #define _varargs_C | |
38 | ||
39 | # include "GStorage.h" | |
40 | # include "Glibc.h" | |
41 | # include "GSYSTEM.h" | |
42 | # include "GM2RTS.h" | |
43 | ||
44 | # define MaxArg 4 | |
45 | typedef struct varargs_argDesc_r varargs_argDesc; | |
46 | ||
47 | typedef struct varargs__T6_r varargs__T6; | |
48 | ||
49 | typedef unsigned char *varargs_ptrToByte; | |
50 | ||
51 | typedef struct varargs__T7_a varargs__T7; | |
52 | ||
53 | typedef varargs__T6 *varargs_vararg; | |
54 | ||
55 | struct varargs_argDesc_r { | |
56 | void *ptr; | |
57 | unsigned int len; | |
58 | }; | |
59 | ||
60 | struct varargs__T7_a { varargs_argDesc array[MaxArg+1]; }; | |
61 | struct varargs__T6_r { | |
62 | unsigned int nArgs; | |
63 | unsigned int i; | |
64 | void *contents; | |
65 | unsigned int size; | |
66 | varargs__T7 arg; | |
67 | }; | |
68 | ||
69 | ||
70 | /* | |
71 | nargs - returns the number of arguments wrapped in, v. | |
72 | */ | |
73 | ||
74 | extern "C" unsigned int varargs_nargs (varargs_vararg v); | |
75 | ||
76 | /* | |
77 | arg - fills in, a, with the next argument. The size of, a, must be an exact | |
78 | match with the original vararg parameter. | |
79 | */ | |
80 | ||
81 | extern "C" void varargs_arg (varargs_vararg v, unsigned char *a, unsigned int _a_high); | |
82 | ||
83 | /* | |
84 | next - assigns the next arg to be collected as, i. | |
85 | */ | |
86 | ||
87 | extern "C" void varargs_next (varargs_vararg v, unsigned int i); | |
88 | ||
89 | /* | |
90 | copy - returns a copy of, v. | |
91 | */ | |
92 | ||
93 | extern "C" varargs_vararg varargs_copy (varargs_vararg v); | |
94 | ||
95 | /* | |
96 | replace - fills the next argument with, a. The size of, a, | |
97 | must be an exact match with the original vararg | |
98 | parameter. | |
99 | */ | |
100 | ||
101 | extern "C" void varargs_replace (varargs_vararg v, unsigned char *a, unsigned int _a_high); | |
102 | ||
103 | /* | |
104 | end - destructor for vararg, v. | |
105 | */ | |
106 | ||
107 | extern "C" void varargs_end (varargs_vararg *v); | |
108 | ||
109 | /* | |
110 | start1 - wraps up argument, a, into a vararg. | |
111 | */ | |
112 | ||
113 | extern "C" varargs_vararg varargs_start1 (const unsigned char *a_, unsigned int _a_high); | |
114 | ||
115 | /* | |
116 | start2 - wraps up arguments, a, b, into a vararg. | |
117 | */ | |
118 | ||
119 | extern "C" varargs_vararg varargs_start2 (const unsigned char *a_, unsigned int _a_high, const unsigned char *b_, unsigned int _b_high); | |
120 | ||
121 | /* | |
122 | start3 - wraps up arguments, a, b, c, into a vararg. | |
123 | */ | |
124 | ||
125 | extern "C" varargs_vararg varargs_start3 (const unsigned char *a_, unsigned int _a_high, const unsigned char *b_, unsigned int _b_high, const unsigned char *c_, unsigned int _c_high); | |
126 | ||
127 | /* | |
128 | start4 - wraps up arguments, a, b, c, d, into a vararg. | |
129 | */ | |
130 | ||
131 | extern "C" varargs_vararg varargs_start4 (const unsigned char *a_, unsigned int _a_high, const unsigned char *b_, unsigned int _b_high, const unsigned char *c_, unsigned int _c_high, const unsigned char *d_, unsigned int _d_high); | |
132 | ||
133 | ||
134 | /* | |
135 | nargs - returns the number of arguments wrapped in, v. | |
136 | */ | |
137 | ||
138 | extern "C" unsigned int varargs_nargs (varargs_vararg v) | |
139 | { | |
140 | return v->nArgs; | |
141 | /* static analysis guarentees a RETURN statement will be used before here. */ | |
142 | __builtin_unreachable (); | |
143 | } | |
144 | ||
145 | ||
146 | /* | |
147 | arg - fills in, a, with the next argument. The size of, a, must be an exact | |
148 | match with the original vararg parameter. | |
149 | */ | |
150 | ||
151 | extern "C" void varargs_arg (varargs_vararg v, unsigned char *a, unsigned int _a_high) | |
152 | { | |
153 | typedef unsigned char *arg__T1; | |
154 | ||
155 | arg__T1 p; | |
156 | unsigned int j; | |
157 | ||
158 | if (v->i == v->nArgs) | |
159 | { | |
160 | M2RTS_HALT (-1); /* too many calls to arg. */ | |
161 | __builtin_unreachable (); | |
162 | } | |
163 | else | |
164 | { | |
165 | if ((_a_high+1) == v->arg.array[v->i].len) | |
166 | { | |
167 | p = static_cast<arg__T1> (v->arg.array[v->i].ptr); | |
168 | j = 0; | |
169 | while (j <= _a_high) | |
170 | { | |
171 | a[j] = (*p); | |
172 | p += 1; | |
173 | j += 1; | |
174 | } | |
175 | } | |
176 | else | |
177 | { | |
178 | M2RTS_HALT (-1); /* parameter mismatch. */ | |
179 | __builtin_unreachable (); | |
180 | } | |
181 | v->i += 1; | |
182 | } | |
183 | } | |
184 | ||
185 | ||
186 | /* | |
187 | next - assigns the next arg to be collected as, i. | |
188 | */ | |
189 | ||
190 | extern "C" void varargs_next (varargs_vararg v, unsigned int i) | |
191 | { | |
192 | v->i = i; | |
193 | } | |
194 | ||
195 | ||
196 | /* | |
197 | copy - returns a copy of, v. | |
198 | */ | |
199 | ||
200 | extern "C" varargs_vararg varargs_copy (varargs_vararg v) | |
201 | { | |
202 | varargs_vararg c; | |
203 | unsigned int j; | |
204 | unsigned int offset; | |
205 | ||
206 | Storage_ALLOCATE ((void **) &c, sizeof (varargs__T6)); | |
207 | c->i = v->i; | |
208 | c->nArgs = v->nArgs; | |
209 | c->size = v->size; | |
210 | Storage_ALLOCATE (&c->contents, c->size); | |
211 | c->contents = libc_memcpy (c->contents, v->contents, static_cast<size_t> (c->size)); | |
212 | for (j=0; j<=c->nArgs; j++) | |
213 | { | |
214 | offset = (unsigned int ) (((varargs_ptrToByte) (v->contents))-((varargs_ptrToByte) (v->arg.array[j].ptr))); | |
215 | c->arg.array[j].ptr = reinterpret_cast<void *> ((varargs_ptrToByte) (((varargs_ptrToByte) (c->contents))+offset)); | |
216 | c->arg.array[j].len = v->arg.array[j].len; | |
217 | } | |
218 | return c; | |
219 | /* static analysis guarentees a RETURN statement will be used before here. */ | |
220 | __builtin_unreachable (); | |
221 | } | |
222 | ||
223 | ||
224 | /* | |
225 | replace - fills the next argument with, a. The size of, a, | |
226 | must be an exact match with the original vararg | |
227 | parameter. | |
228 | */ | |
229 | ||
230 | extern "C" void varargs_replace (varargs_vararg v, unsigned char *a, unsigned int _a_high) | |
231 | { | |
232 | typedef unsigned char *replace__T2; | |
233 | ||
234 | replace__T2 p; | |
235 | unsigned int j; | |
236 | ||
237 | if (v->i == v->nArgs) | |
238 | { | |
239 | M2RTS_HALT (-1); /* too many calls to arg. */ | |
240 | __builtin_unreachable (); | |
241 | } | |
242 | else | |
243 | { | |
244 | if ((_a_high+1) == v->arg.array[v->i].len) | |
245 | { | |
246 | p = static_cast<replace__T2> (v->arg.array[v->i].ptr); | |
247 | j = 0; | |
248 | while (j <= _a_high) | |
249 | { | |
250 | (*p) = a[j]; | |
251 | p += 1; | |
252 | j += 1; | |
253 | } | |
254 | } | |
255 | else | |
256 | { | |
257 | M2RTS_HALT (-1); /* parameter mismatch. */ | |
258 | __builtin_unreachable (); | |
259 | } | |
260 | } | |
261 | } | |
262 | ||
263 | ||
264 | /* | |
265 | end - destructor for vararg, v. | |
266 | */ | |
267 | ||
268 | extern "C" void varargs_end (varargs_vararg *v) | |
269 | { | |
270 | if ((*v) != NULL) | |
271 | { | |
272 | Storage_DEALLOCATE (&(*v)->contents, sizeof (varargs_vararg)); | |
273 | Storage_DEALLOCATE ((void **) &(*v), sizeof (varargs__T6)); | |
274 | } | |
275 | } | |
276 | ||
277 | ||
278 | /* | |
279 | start1 - wraps up argument, a, into a vararg. | |
280 | */ | |
281 | ||
282 | extern "C" varargs_vararg varargs_start1 (const unsigned char *a_, unsigned int _a_high) | |
283 | { | |
284 | varargs_vararg v; | |
285 | unsigned char a[_a_high+1]; | |
286 | ||
287 | /* make a local copy of each unbounded array. */ | |
288 | memcpy (a, a_, _a_high+1); | |
289 | ||
290 | Storage_ALLOCATE ((void **) &v, sizeof (varargs__T6)); | |
291 | v->i = 0; | |
292 | v->nArgs = 1; | |
293 | v->size = _a_high+1; | |
294 | Storage_ALLOCATE (&v->contents, v->size); | |
295 | v->contents = libc_memcpy (v->contents, &a, static_cast<size_t> (v->size)); | |
296 | v->arg.array[0].ptr = v->contents; | |
297 | v->arg.array[0].len = v->size; | |
298 | return v; | |
299 | /* static analysis guarentees a RETURN statement will be used before here. */ | |
300 | __builtin_unreachable (); | |
301 | } | |
302 | ||
303 | ||
304 | /* | |
305 | start2 - wraps up arguments, a, b, into a vararg. | |
306 | */ | |
307 | ||
308 | extern "C" varargs_vararg varargs_start2 (const unsigned char *a_, unsigned int _a_high, const unsigned char *b_, unsigned int _b_high) | |
309 | { | |
310 | typedef unsigned char *start2__T3; | |
311 | ||
312 | varargs_vararg v; | |
313 | start2__T3 p; | |
314 | unsigned char a[_a_high+1]; | |
315 | unsigned char b[_b_high+1]; | |
316 | ||
317 | /* make a local copy of each unbounded array. */ | |
318 | memcpy (a, a_, _a_high+1); | |
319 | memcpy (b, b_, _b_high+1); | |
320 | ||
321 | Storage_ALLOCATE ((void **) &v, sizeof (varargs__T6)); | |
322 | v->i = 0; | |
323 | v->nArgs = 2; | |
324 | v->size = (_a_high+_b_high)+2; | |
325 | Storage_ALLOCATE (&v->contents, v->size); | |
326 | p = static_cast<start2__T3> (libc_memcpy (v->contents, &a, static_cast<size_t> (_a_high+1))); | |
327 | v->arg.array[0].ptr = reinterpret_cast<void *> (p); | |
328 | v->arg.array[0].len = _a_high+1; | |
329 | p += v->arg.array[0].len; | |
330 | p = static_cast<start2__T3> (libc_memcpy (reinterpret_cast<void *> (p), &b, static_cast<size_t> (_b_high+1))); | |
331 | v->arg.array[1].ptr = reinterpret_cast<void *> (p); | |
332 | v->arg.array[1].len = _b_high+1; | |
333 | return v; | |
334 | /* static analysis guarentees a RETURN statement will be used before here. */ | |
335 | __builtin_unreachable (); | |
336 | } | |
337 | ||
338 | ||
339 | /* | |
340 | start3 - wraps up arguments, a, b, c, into a vararg. | |
341 | */ | |
342 | ||
343 | extern "C" varargs_vararg varargs_start3 (const unsigned char *a_, unsigned int _a_high, const unsigned char *b_, unsigned int _b_high, const unsigned char *c_, unsigned int _c_high) | |
344 | { | |
345 | typedef unsigned char *start3__T4; | |
346 | ||
347 | varargs_vararg v; | |
348 | start3__T4 p; | |
349 | unsigned char a[_a_high+1]; | |
350 | unsigned char b[_b_high+1]; | |
351 | unsigned char c[_c_high+1]; | |
352 | ||
353 | /* make a local copy of each unbounded array. */ | |
354 | memcpy (a, a_, _a_high+1); | |
355 | memcpy (b, b_, _b_high+1); | |
356 | memcpy (c, c_, _c_high+1); | |
357 | ||
358 | Storage_ALLOCATE ((void **) &v, sizeof (varargs__T6)); | |
359 | v->i = 0; | |
360 | v->nArgs = 3; | |
361 | v->size = ((_a_high+_b_high)+_c_high)+3; | |
362 | Storage_ALLOCATE (&v->contents, v->size); | |
363 | p = static_cast<start3__T4> (libc_memcpy (v->contents, &a, static_cast<size_t> (_a_high+1))); | |
364 | v->arg.array[0].ptr = reinterpret_cast<void *> (p); | |
365 | v->arg.array[0].len = _a_high+1; | |
366 | p += v->arg.array[0].len; | |
367 | p = static_cast<start3__T4> (libc_memcpy (reinterpret_cast<void *> (p), &b, static_cast<size_t> (_b_high+1))); | |
368 | v->arg.array[1].ptr = reinterpret_cast<void *> (p); | |
369 | v->arg.array[1].len = _b_high+1; | |
370 | p += v->arg.array[1].len; | |
371 | p = static_cast<start3__T4> (libc_memcpy (reinterpret_cast<void *> (p), &c, static_cast<size_t> (_c_high+1))); | |
372 | v->arg.array[2].ptr = reinterpret_cast<void *> (p); | |
373 | v->arg.array[2].len = _c_high+1; | |
374 | return v; | |
375 | /* static analysis guarentees a RETURN statement will be used before here. */ | |
376 | __builtin_unreachable (); | |
377 | } | |
378 | ||
379 | ||
380 | /* | |
381 | start4 - wraps up arguments, a, b, c, d, into a vararg. | |
382 | */ | |
383 | ||
384 | extern "C" varargs_vararg varargs_start4 (const unsigned char *a_, unsigned int _a_high, const unsigned char *b_, unsigned int _b_high, const unsigned char *c_, unsigned int _c_high, const unsigned char *d_, unsigned int _d_high) | |
385 | { | |
386 | typedef unsigned char *start4__T5; | |
387 | ||
388 | varargs_vararg v; | |
389 | start4__T5 p; | |
390 | unsigned char a[_a_high+1]; | |
391 | unsigned char b[_b_high+1]; | |
392 | unsigned char c[_c_high+1]; | |
393 | unsigned char d[_d_high+1]; | |
394 | ||
395 | /* make a local copy of each unbounded array. */ | |
396 | memcpy (a, a_, _a_high+1); | |
397 | memcpy (b, b_, _b_high+1); | |
398 | memcpy (c, c_, _c_high+1); | |
399 | memcpy (d, d_, _d_high+1); | |
400 | ||
401 | Storage_ALLOCATE ((void **) &v, sizeof (varargs__T6)); | |
402 | v->i = 0; | |
403 | v->nArgs = 4; | |
404 | v->size = (((_a_high+_b_high)+_c_high)+_d_high)+4; | |
405 | Storage_ALLOCATE (&v->contents, v->size); | |
406 | p = static_cast<start4__T5> (libc_memcpy (v->contents, &a, static_cast<size_t> (_a_high+1))); | |
407 | v->arg.array[0].len = _a_high+1; | |
408 | p += v->arg.array[0].len; | |
409 | p = static_cast<start4__T5> (libc_memcpy (reinterpret_cast<void *> (p), &b, static_cast<size_t> (_b_high+1))); | |
410 | v->arg.array[1].ptr = reinterpret_cast<void *> (p); | |
411 | v->arg.array[1].len = _b_high+1; | |
412 | p += v->arg.array[1].len; | |
413 | p = static_cast<start4__T5> (libc_memcpy (reinterpret_cast<void *> (p), &c, static_cast<size_t> (_c_high+1))); | |
414 | v->arg.array[2].ptr = reinterpret_cast<void *> (p); | |
415 | v->arg.array[2].len = _c_high+1; | |
416 | p += v->arg.array[2].len; | |
417 | p = static_cast<start4__T5> (libc_memcpy (reinterpret_cast<void *> (p), &c, static_cast<size_t> (_c_high+1))); | |
418 | v->arg.array[3].ptr = reinterpret_cast<void *> (p); | |
419 | v->arg.array[3].len = _c_high+1; | |
420 | return v; | |
421 | /* static analysis guarentees a RETURN statement will be used before here. */ | |
422 | __builtin_unreachable (); | |
423 | } | |
424 | ||
425 | extern "C" void _M2_varargs_init (__attribute__((unused)) int argc,__attribute__((unused)) char *argv[],__attribute__((unused)) char *envp[]) | |
426 | { | |
427 | } | |
428 | ||
429 | extern "C" void _M2_varargs_finish (__attribute__((unused)) int argc,__attribute__((unused)) char *argv[],__attribute__((unused)) char *envp[]) | |
430 | { | |
431 | } |