X-Git-Url: https://pd.if.org/git/?p=pdclib;a=blobdiff_plain;f=includes%2Fstdarg.h;h=62d0e404e36dbc80d1e0fdfb51e6f7edc04836ff;hp=5d2270535968835b6d685a56cde6011d40adce93;hb=refs%2Ftags%2FOLD;hpb=8c8750c2826684c2420571a8007b9606f72c9040 diff --git a/includes/stdarg.h b/includes/stdarg.h index 5d22705..62d0e40 100644 --- a/includes/stdarg.h +++ b/includes/stdarg.h @@ -1,32 +1,80 @@ -// ---------------------------------------------------------------------------- -// $Id$ -// ---------------------------------------------------------------------------- -// Public Domain C Library - http://pdclib.sourceforge.net -// This code is Public Domain. Use, modify, and redistribute at will. -// ---------------------------------------------------------------------------- -// Variable arguments -// ---------------------------------------------------------------------------- - -#ifndef __STDARG_H -#define __STDARG_H __STDARG_H - -// ---------------------------------------------------------------------------- -// TYPEDEFS - -typedef do-type va_list; // TODO - -// ---------------------------------------------------------------------------- -// MACROS - -#define va_arg( va_list ap, Ty ) // TODO -#define va_copy( va_list dest, va_list src ) // TODO -#define va_end( va_list ap ) // TODO -#define va_start( va_list ap, last-par ) // TODO - -/* PDPC code - unreviewed -#define va_start(ap, parmN) ap = (char *)&parmN + 4 -#define va_arg(ap, type) *(type *)(ap += sizeof(type), ap - sizeof(type)) -#define va_end(ap) ap = 0 -*/ - -#endif // __STDARG_H +/* ---------------------------------------------------------------------------- + * $Id$ + * ---------------------------------------------------------------------------- + * Public Domain C Library - http://pdclib.sourceforge.net + * This code is Public Domain. Use, modify, and redistribute at will. + * ---------------------------------------------------------------------------- + * Variable arguments + * ---------------------------------------------------------------------------- + * This header is part of a freestanding implementation + * --------------------------------------------------------------------------*/ + +#ifndef _STDARG_H +#define _STDARG_H _STDARG_H + +/* TODO: This code was contributed by Michael Moody, who added: + * "As always with my code it's not guaranteed bug-free (In fact I know for a + * fact it won't work properly on certain archs)." + * Code assumes that: + * - arguments are passed on the stack; + * - arguments are alligned to pointer size. + */ + +/* ---------------------------------------------------------------------------- + * TYPEDEFS + * --------------------------------------------------------------------------*/ + +typedef char * va_list; + +/* ---------------------------------------------------------------------------- + * MACROS + * --------------------------------------------------------------------------*/ + +/** Returns the size of 'type' rounded up to the nearest multiple of the size + * of a pointer. This macro is just here for clarity. + */ +#define __va_round(type) \ + ( \ + (sizeof(type) + sizeof(void *) - 1) & ~(sizeof(void *) - 1) \ + ) + +/** Initialises ap for use by va_arg by setting ap to point at the first + * argument in the ellipsis. parmN is the last known parameter in the function + * definition (ie the one before the ellipsis). + */ +#define va_start(ap, parmN) \ + ( \ + (ap) = (char *)&parmN + (__va_round(parmN)) \ + , \ + (void)0 \ + ) + +/** Returns the next argument, assumed variable type is 'type', in the + * ellipsis. + */ +#define va_arg(ap, type) \ + ( \ + (ap) += (__va_round(type)) \ + , \ + (*(type*)((ap) - (__va_round(type)))) \ + ) + +/** Cleans up ap. + */ +#define va_end(ap) \ + ( \ + (ap) = (void *)0 \ + , \ + (void)0 \ + ) + +/** Makes the va_list dest be a copy of the va_list src. + */ +#define va_copy(dest, src) \ + ( \ + (dest) = (src) \ + , \ + (void)0 \ + ) + +#endif /* _STDARG_H */