| /* do not edit automatically generated by mc from varargs. */ |
| /* varargs.mod provides a basic vararg facility for GNU Modula-2. |
| |
| Copyright (C) 2015-2025 Free Software Foundation, Inc. |
| Contributed by Gaius Mulley <gaius@glam.ac.uk>. |
| |
| This file is part of GNU Modula-2. |
| |
| GNU Modula-2 is free software; you can redistribute it and/or modify |
| it under the terms of the GNU General Public License as published by |
| the Free Software Foundation; either version 3, or (at your option) |
| any later version. |
| |
| GNU Modula-2 is distributed in the hope that it will be useful, but |
| WITHOUT ANY WARRANTY; without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| General Public License for more details. |
| |
| You should have received a copy of the GNU General Public License |
| along with GNU Modula-2; see the file COPYING3. If not see |
| <http://www.gnu.org/licenses/>. */ |
| |
| #include "config.h" |
| #include "system.h" |
| #include <stdbool.h> |
| # if !defined (PROC_D) |
| # define PROC_D |
| typedef void (*PROC_t) (void); |
| typedef struct { PROC_t proc; } PROC; |
| # endif |
| |
| # include "GStorage.h" |
| #if defined(__cplusplus) |
| # undef NULL |
| # define NULL 0 |
| #endif |
| #define _varargs_C |
| |
| #include "Gvarargs.h" |
| # include "GStorage.h" |
| # include "Glibc.h" |
| # include "GSYSTEM.h" |
| # include "GM2RTS.h" |
| |
| # define MaxArg 4 |
| typedef struct varargs_argDesc_r varargs_argDesc; |
| |
| typedef struct varargs__T6_r varargs__T6; |
| |
| typedef unsigned char *varargs_ptrToByte; |
| |
| typedef struct varargs__T7_a varargs__T7; |
| |
| typedef varargs__T6 *varargs_vararg__opaque; |
| |
| struct varargs_argDesc_r { |
| void * ptr; |
| unsigned int len; |
| }; |
| |
| struct varargs__T7_a { varargs_argDesc array[MaxArg+1]; }; |
| struct varargs__T6_r { |
| unsigned int nArgs; |
| unsigned int i; |
| void * contents; |
| unsigned int size; |
| varargs__T7 arg; |
| }; |
| |
| |
| /* |
| nargs - returns the number of arguments wrapped in, v. |
| */ |
| |
| extern "C" unsigned int varargs_nargs (varargs_vararg v); |
| |
| /* |
| arg - fills in, a, with the next argument. The size of, a, must be an exact |
| match with the original vararg parameter. |
| */ |
| |
| extern "C" void varargs_arg (varargs_vararg v, unsigned char *a, unsigned int _a_high); |
| |
| /* |
| next - assigns the next arg to be collected as, i. |
| */ |
| |
| extern "C" void varargs_next (varargs_vararg v, unsigned int i); |
| |
| /* |
| copy - returns a copy of, v. |
| */ |
| |
| extern "C" varargs_vararg varargs_copy (varargs_vararg v); |
| |
| /* |
| replace - fills the next argument with, a. The size of, a, |
| must be an exact match with the original vararg |
| parameter. |
| */ |
| |
| extern "C" void varargs_replace (varargs_vararg v, unsigned char *a, unsigned int _a_high); |
| |
| /* |
| end - destructor for vararg, v. |
| */ |
| |
| extern "C" void varargs_end (varargs_vararg *v); |
| |
| /* |
| start1 - wraps up argument, a, into a vararg. |
| */ |
| |
| extern "C" varargs_vararg varargs_start1 (const unsigned char *a_, unsigned int _a_high); |
| |
| /* |
| start2 - wraps up arguments, a, b, into a vararg. |
| */ |
| |
| extern "C" varargs_vararg varargs_start2 (const unsigned char *a_, unsigned int _a_high, const unsigned char *b_, unsigned int _b_high); |
| |
| /* |
| start3 - wraps up arguments, a, b, c, into a vararg. |
| */ |
| |
| 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); |
| |
| /* |
| start4 - wraps up arguments, a, b, c, d, into a vararg. |
| */ |
| |
| 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); |
| |
| |
| /* |
| nargs - returns the number of arguments wrapped in, v. |
| */ |
| |
| extern "C" unsigned int varargs_nargs (varargs_vararg v) |
| { |
| return static_cast<varargs_vararg__opaque> (v)->nArgs; |
| /* static analysis guarentees a RETURN statement will be used before here. */ |
| __builtin_unreachable (); |
| } |
| |
| |
| /* |
| arg - fills in, a, with the next argument. The size of, a, must be an exact |
| match with the original vararg parameter. |
| */ |
| |
| extern "C" void varargs_arg (varargs_vararg v, unsigned char *a, unsigned int _a_high) |
| { |
| typedef unsigned char *arg__T1; |
| |
| arg__T1 p; |
| unsigned int j; |
| |
| if (static_cast<varargs_vararg__opaque> (v)->i == static_cast<varargs_vararg__opaque> (v)->nArgs) |
| { |
| M2RTS_HALT (-1); /* too many calls to arg. */ |
| __builtin_unreachable (); |
| } |
| else |
| { |
| if ((_a_high+1) == static_cast<varargs_vararg__opaque> (v)->arg.array[static_cast<varargs_vararg__opaque> (v)->i].len) |
| { |
| p = static_cast<arg__T1> (static_cast<varargs_vararg__opaque> (v)->arg.array[static_cast<varargs_vararg__opaque> (v)->i].ptr); |
| j = 0; |
| while (j <= _a_high) |
| { |
| const_cast<unsigned char *>(a)[j] = (*p); |
| p += 1; |
| j += 1; |
| } |
| } |
| else |
| { |
| M2RTS_HALT (-1); /* parameter mismatch. */ |
| __builtin_unreachable (); |
| } |
| static_cast<varargs_vararg__opaque> (v)->i += 1; |
| } |
| } |
| |
| |
| /* |
| next - assigns the next arg to be collected as, i. |
| */ |
| |
| extern "C" void varargs_next (varargs_vararg v, unsigned int i) |
| { |
| static_cast<varargs_vararg__opaque> (v)->i = i; |
| } |
| |
| |
| /* |
| copy - returns a copy of, v. |
| */ |
| |
| extern "C" varargs_vararg varargs_copy (varargs_vararg v) |
| { |
| varargs_vararg__opaque c; |
| unsigned int j; |
| unsigned int offset; |
| |
| Storage_ALLOCATE ((void **) &c, sizeof (varargs__T6)); |
| c->i = static_cast<varargs_vararg__opaque> (v)->i; |
| c->nArgs = static_cast<varargs_vararg__opaque> (v)->nArgs; |
| c->size = static_cast<varargs_vararg__opaque> (v)->size; |
| Storage_ALLOCATE (&c->contents, c->size); |
| c->contents = libc_memcpy (c->contents, static_cast<varargs_vararg__opaque> (v)->contents, static_cast<size_t> (c->size)); |
| for (j=0; j<=c->nArgs; j++) |
| { |
| offset = (unsigned int ) (((varargs_ptrToByte) (static_cast<varargs_vararg__opaque> (v)->contents))-((varargs_ptrToByte) (static_cast<varargs_vararg__opaque> (v)->arg.array[j].ptr))); |
| c->arg.array[j].ptr = static_cast<void *> ((varargs_ptrToByte) (c->contents)); |
| c->arg.array[j].ptr = reinterpret_cast<void *> (reinterpret_cast<char *> (c->arg.array[j].ptr)+offset); |
| c->arg.array[j].len = static_cast<varargs_vararg__opaque> (v)->arg.array[j].len; |
| } |
| return static_cast<varargs_vararg> (c); |
| /* static analysis guarentees a RETURN statement will be used before here. */ |
| __builtin_unreachable (); |
| } |
| |
| |
| /* |
| replace - fills the next argument with, a. The size of, a, |
| must be an exact match with the original vararg |
| parameter. |
| */ |
| |
| extern "C" void varargs_replace (varargs_vararg v, unsigned char *a, unsigned int _a_high) |
| { |
| typedef unsigned char *replace__T2; |
| |
| replace__T2 p; |
| unsigned int j; |
| |
| if (static_cast<varargs_vararg__opaque> (v)->i == static_cast<varargs_vararg__opaque> (v)->nArgs) |
| { |
| M2RTS_HALT (-1); /* too many calls to arg. */ |
| __builtin_unreachable (); |
| } |
| else |
| { |
| if ((_a_high+1) == static_cast<varargs_vararg__opaque> (v)->arg.array[static_cast<varargs_vararg__opaque> (v)->i].len) |
| { |
| p = static_cast<replace__T2> (static_cast<varargs_vararg__opaque> (v)->arg.array[static_cast<varargs_vararg__opaque> (v)->i].ptr); |
| j = 0; |
| while (j <= _a_high) |
| { |
| (*p) = a[j]; |
| p += 1; |
| j += 1; |
| } |
| } |
| else |
| { |
| M2RTS_HALT (-1); /* parameter mismatch. */ |
| __builtin_unreachable (); |
| } |
| } |
| } |
| |
| |
| /* |
| end - destructor for vararg, v. |
| */ |
| |
| extern "C" void varargs_end (varargs_vararg *v) |
| { |
| if ((*v) != NULL) |
| { |
| Storage_DEALLOCATE (&static_cast<varargs_vararg__opaque> ((*v))->contents, sizeof (varargs_vararg)); |
| Storage_DEALLOCATE ((void **) &(*v), sizeof (varargs__T6)); |
| } |
| } |
| |
| |
| /* |
| start1 - wraps up argument, a, into a vararg. |
| */ |
| |
| extern "C" varargs_vararg varargs_start1 (const unsigned char *a_, unsigned int _a_high) |
| { |
| varargs_vararg__opaque v; |
| unsigned char a[_a_high+1]; |
| |
| /* make a local copy of each unbounded array. */ |
| memcpy (a, a_, _a_high+1); |
| |
| Storage_ALLOCATE ((void **) &v, sizeof (varargs__T6)); |
| v->i = 0; |
| v->nArgs = 1; |
| v->size = _a_high+1; |
| Storage_ALLOCATE (&v->contents, v->size); |
| v->contents = libc_memcpy (v->contents, const_cast<void*> (static_cast<const void*>(a)), static_cast<size_t> (v->size)); |
| v->arg.array[0].ptr = v->contents; |
| v->arg.array[0].len = v->size; |
| return static_cast<varargs_vararg> (v); |
| /* static analysis guarentees a RETURN statement will be used before here. */ |
| __builtin_unreachable (); |
| } |
| |
| |
| /* |
| start2 - wraps up arguments, a, b, into a vararg. |
| */ |
| |
| extern "C" varargs_vararg varargs_start2 (const unsigned char *a_, unsigned int _a_high, const unsigned char *b_, unsigned int _b_high) |
| { |
| typedef unsigned char *start2__T3; |
| |
| varargs_vararg__opaque v; |
| start2__T3 p; |
| unsigned char a[_a_high+1]; |
| unsigned char b[_b_high+1]; |
| |
| /* make a local copy of each unbounded array. */ |
| memcpy (a, a_, _a_high+1); |
| memcpy (b, b_, _b_high+1); |
| |
| Storage_ALLOCATE ((void **) &v, sizeof (varargs__T6)); |
| v->i = 0; |
| v->nArgs = 2; |
| v->size = (_a_high+_b_high)+2; |
| Storage_ALLOCATE (&v->contents, v->size); |
| p = static_cast<start2__T3> (libc_memcpy (v->contents, const_cast<void*> (static_cast<const void*>(a)), static_cast<size_t> (_a_high+1))); |
| v->arg.array[0].ptr = static_cast<void *> (p); |
| v->arg.array[0].len = _a_high+1; |
| p += v->arg.array[0].len; |
| p = static_cast<start2__T3> (libc_memcpy (reinterpret_cast <void *> (p), const_cast<void*> (static_cast<const void*>(b)), static_cast<size_t> (_b_high+1))); |
| v->arg.array[1].ptr = static_cast<void *> (p); |
| v->arg.array[1].len = _b_high+1; |
| return static_cast<varargs_vararg> (v); |
| /* static analysis guarentees a RETURN statement will be used before here. */ |
| __builtin_unreachable (); |
| } |
| |
| |
| /* |
| start3 - wraps up arguments, a, b, c, into a vararg. |
| */ |
| |
| 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) |
| { |
| typedef unsigned char *start3__T4; |
| |
| varargs_vararg__opaque v; |
| start3__T4 p; |
| unsigned char a[_a_high+1]; |
| unsigned char b[_b_high+1]; |
| unsigned char c[_c_high+1]; |
| |
| /* make a local copy of each unbounded array. */ |
| memcpy (a, a_, _a_high+1); |
| memcpy (b, b_, _b_high+1); |
| memcpy (c, c_, _c_high+1); |
| |
| Storage_ALLOCATE ((void **) &v, sizeof (varargs__T6)); |
| v->i = 0; |
| v->nArgs = 3; |
| v->size = ((_a_high+_b_high)+_c_high)+3; |
| Storage_ALLOCATE (&v->contents, v->size); |
| p = static_cast<start3__T4> (libc_memcpy (v->contents, const_cast<void*> (static_cast<const void*>(a)), static_cast<size_t> (_a_high+1))); |
| v->arg.array[0].ptr = static_cast<void *> (p); |
| v->arg.array[0].len = _a_high+1; |
| p += v->arg.array[0].len; |
| p = static_cast<start3__T4> (libc_memcpy (reinterpret_cast <void *> (p), const_cast<void*> (static_cast<const void*>(b)), static_cast<size_t> (_b_high+1))); |
| v->arg.array[1].ptr = static_cast<void *> (p); |
| v->arg.array[1].len = _b_high+1; |
| p += v->arg.array[1].len; |
| p = static_cast<start3__T4> (libc_memcpy (reinterpret_cast <void *> (p), const_cast<void*> (static_cast<const void*>(c)), static_cast<size_t> (_c_high+1))); |
| v->arg.array[2].ptr = static_cast<void *> (p); |
| v->arg.array[2].len = _c_high+1; |
| return static_cast<varargs_vararg> (v); |
| /* static analysis guarentees a RETURN statement will be used before here. */ |
| __builtin_unreachable (); |
| } |
| |
| |
| /* |
| start4 - wraps up arguments, a, b, c, d, into a vararg. |
| */ |
| |
| 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) |
| { |
| typedef unsigned char *start4__T5; |
| |
| varargs_vararg__opaque v; |
| start4__T5 p; |
| unsigned char a[_a_high+1]; |
| unsigned char b[_b_high+1]; |
| unsigned char c[_c_high+1]; |
| unsigned char d[_d_high+1]; |
| |
| /* make a local copy of each unbounded array. */ |
| memcpy (a, a_, _a_high+1); |
| memcpy (b, b_, _b_high+1); |
| memcpy (c, c_, _c_high+1); |
| memcpy (d, d_, _d_high+1); |
| |
| Storage_ALLOCATE ((void **) &v, sizeof (varargs__T6)); |
| v->i = 0; |
| v->nArgs = 4; |
| v->size = (((_a_high+_b_high)+_c_high)+_d_high)+4; |
| Storage_ALLOCATE (&v->contents, v->size); |
| p = static_cast<start4__T5> (libc_memcpy (v->contents, const_cast<void*> (static_cast<const void*>(a)), static_cast<size_t> (_a_high+1))); |
| v->arg.array[0].len = _a_high+1; |
| p += v->arg.array[0].len; |
| p = static_cast<start4__T5> (libc_memcpy (reinterpret_cast <void *> (p), const_cast<void*> (static_cast<const void*>(b)), static_cast<size_t> (_b_high+1))); |
| v->arg.array[1].ptr = static_cast<void *> (p); |
| v->arg.array[1].len = _b_high+1; |
| p += v->arg.array[1].len; |
| p = static_cast<start4__T5> (libc_memcpy (reinterpret_cast <void *> (p), const_cast<void*> (static_cast<const void*>(c)), static_cast<size_t> (_c_high+1))); |
| v->arg.array[2].ptr = static_cast<void *> (p); |
| v->arg.array[2].len = _c_high+1; |
| p += v->arg.array[2].len; |
| p = static_cast<start4__T5> (libc_memcpy (reinterpret_cast <void *> (p), const_cast<void*> (static_cast<const void*>(c)), static_cast<size_t> (_c_high+1))); |
| v->arg.array[3].ptr = static_cast<void *> (p); |
| v->arg.array[3].len = _c_high+1; |
| return static_cast<varargs_vararg> (v); |
| /* static analysis guarentees a RETURN statement will be used before here. */ |
| __builtin_unreachable (); |
| } |
| |
| extern "C" void _M2_varargs_init (__attribute__((unused)) int argc, __attribute__((unused)) char *argv[], __attribute__((unused)) char *envp[]) |
| { |
| } |
| |
| extern "C" void _M2_varargs_fini (__attribute__((unused)) int argc, __attribute__((unused)) char *argv[], __attribute__((unused)) char *envp[]) |
| { |
| } |