1 /* @(#)varargs.h 1.8 14/01/06 Copyright 1998-2014 J. Schilling */ 2 /* 3 * Generic header for users of var args ... 4 * 5 * Includes a default definition for va_copy() 6 * and some magic know how about the SVr4 Power PC var args ABI 7 * to create a __va_arg_list() macro. 8 * 9 * The __va_arg_list() macro is needed to fetch a va_list type argument 10 * from a va_list. This is needed to implement a recursive "%r" printf. 11 * 12 * Copyright (c) 1998-2014 J. Schilling 13 */ 14 /* 15 * The contents of this file are subject to the terms of the 16 * Common Development and Distribution License, Version 1.0 only 17 * (the "License"). You may not use this file except in compliance 18 * with the License. 19 * 20 * See the file CDDL.Schily.txt in this distribution for details. 21 * A copy of the CDDL is also available via the Internet at 22 * http://www.opensource.org/licenses/cddl1.txt 23 * 24 * When distributing Covered Code, include this CDDL HEADER in each 25 * file and include the License file CDDL.Schily.txt from this distribution. 26 */ 27 28 #ifndef _SCHILY_VARARGS_H 29 #define _SCHILY_VARARGS_H 30 31 #ifndef _SCHILY_MCONFIG_H 32 #include <schily/mconfig.h> 33 #endif 34 35 #ifdef __cplusplus 36 extern "C" { 37 #endif 38 39 #ifdef PROTOTYPES 40 /* 41 * For ANSI C-compilers prefer stdarg.h 42 */ 43 # ifdef HAVE_STDARG_H 44 # ifndef _INCL_STDARG_H 45 # include <stdarg.h> 46 # define _INCL_STDARG_H 47 # endif 48 # else 49 # ifndef _INCL_VARARGS_H 50 # include <varargs.h> 51 # define _INCL_VARARGS_H 52 # endif 53 # endif 54 #else 55 /* 56 * For K&R C-compilers prefer varargs.h 57 */ 58 # ifdef HAVE_VARARGS_H 59 # ifndef _INCL_VARARGS_H 60 # include <varargs.h> 61 # define _INCL_VARARGS_H 62 # endif 63 # else 64 # ifndef _INCL_STDARG_H 65 # include <stdarg.h> 66 # define _INCL_STDARG_H 67 # endif 68 # endif 69 #endif 70 71 #if (defined(__linux__) || defined(__linux) || defined(sun)) && \ 72 (defined(__ppc) || defined(__PPC) || \ 73 defined(powerpc) || defined(__powerpc__)) 74 75 # ifndef VA_LIST_IS_ARRAY 76 # define VA_LIST_IS_ARRAY 77 # endif 78 #endif 79 80 81 /* 82 * __va_copy() is used by GCC 2.8 or newer until va_copy() becomes 83 * a final ISO standard. 84 */ 85 #if !defined(va_copy) && !defined(HAVE_VA_COPY) 86 # if defined(__va_copy) 87 # define va_copy(to, from) __va_copy(to, from) 88 # endif 89 #endif 90 91 /* 92 * va_copy() is a Solaris extension to provide a portable way to perform a 93 * variable argument list "bookmarking" function. 94 * If it is not available via stdarg.h, use a simple assignement for backward 95 * compatibility. 96 */ 97 #if !defined(va_copy) && !defined(HAVE_VA_COPY) 98 #ifdef VA_LIST_IS_ARRAY 99 # define va_copy(to, from) ((to)[0] = (from)[0]) 100 #else 101 # define va_copy(to, from) ((to) = (from)) 102 #endif 103 #endif 104 105 /* 106 * I don't know any portable way to get an arbitrary 107 * C object from a var arg list so I use a 108 * system-specific routine __va_arg_list() that knows 109 * if 'va_list' is an array. You will not be able to 110 * assign the value of __va_arg_list() but it works 111 * to be used as an argument of a function. 112 * It is a requirement for recursive printf to be able 113 * to use this function argument. If your system 114 * defines va_list to be an array you need to know this 115 * via autoconf or another mechanism. 116 * It would be nice to have something like 117 * __va_arg_list() in stdarg.h 118 */ 119 120 #ifdef VA_LIST_IS_ARRAY 121 # define __va_arg_list(list) va_arg(list, void *) 122 #else 123 # define __va_arg_list(list) va_arg(list, va_list) 124 #endif 125 126 /* 127 * This structure allows to work around the C limitation that a variable of 128 * type array cannot appear at the left side of an assignement operator. 129 * By putting va_list inside a struture, the assignement will work even in case 130 * that va_list is an array2. 131 */ 132 typedef struct { 133 va_list ap; 134 } va_lists_t; 135 136 #ifdef __cplusplus 137 } 138 #endif 139 140 #endif /* _SCHILY_VARARGS_H */ 141