]> pd.if.org Git - pdclib/blobdiff - includes/stdarg.h
Re-import from Subversion.
[pdclib] / includes / stdarg.h
index e0943329010533346d95ddca7865444bf57ac07b..62d0e404e36dbc80d1e0fdfb51e6f7edc04836ff 100644 (file)
@@ -1,34 +1,80 @@
-// ----------------------------------------------------------------------------
-// $Id$
-// ----------------------------------------------------------------------------
-// Public Domain C Library - http://pdclib.sourceforge.net
-// This code is Public Domain. Use, modify, and redistribute at will.
-// ----------------------------------------------------------------------------
-// Variable arguments
-// ----------------------------------------------------------------------------
+/* ----------------------------------------------------------------------------
+ * $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
+#ifndef _STDARG_H
+#define _STDARG_H _STDARG_H
 
-// ----------------------------------------------------------------------------
-// TYPEDEFS
+/* 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.
+ */
 
-typedef do-type va_list;
+/* ----------------------------------------------------------------------------
+ * TYPEDEFS
+ * --------------------------------------------------------------------------*/
 
-// ----------------------------------------------------------------------------
-// MACROS
+typedef char * va_list;
 
-#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
+/* ----------------------------------------------------------------------------
+ * MACROS
+ * --------------------------------------------------------------------------*/
 
-/*
-From PDPClib:
+/** 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)             \
+   )
 
-#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
-*/
+/** 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                                                                 \
+   )
 
-#endif // __STDARG_H
+/** 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 */