1 /**************************************************************************** 2 * Copyright (c) 2001-2007,2008 Free Software Foundation, Inc. * 3 * * 4 * Permission is hereby granted, free of charge, to any person obtaining a * 5 * copy of this software and associated documentation files (the * 6 * "Software"), to deal in the Software without restriction, including * 7 * without limitation the rights to use, copy, modify, merge, publish, * 8 * distribute, distribute with modifications, sublicense, and/or sell * 9 * copies of the Software, and to permit persons to whom the Software is * 10 * furnished to do so, subject to the following conditions: * 11 * * 12 * The above copyright notice and this permission notice shall be included * 13 * in all copies or substantial portions of the Software. * 14 * * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * 16 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * 17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * 18 * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * 19 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * 20 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * 21 * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * 22 * * 23 * Except as contained in this notice, the name(s) of the above copyright * 24 * holders shall not be used in advertising or otherwise to promote the * 25 * sale, use or other dealings in this Software without prior written * 26 * authorization. * 27 ****************************************************************************/ 28 29 /**************************************************************************** 30 * Author: Thomas E. Dickey 2001 * 31 ****************************************************************************/ 32 33 #include <curses.priv.h> 34 35 #include <ctype.h> 36 37 MODULE_ID("$Id: varargs.c,v 1.8 2008/11/16 00:19:59 juergen Exp $") 38 39 #ifdef TRACE 40 41 #define MAX_PARMS 10 42 43 typedef enum { 44 atUnknown = 0, atInteger, atFloat, atPoint, atString 45 } ARGTYPE; 46 47 #define VA_INT(type) ival = (int) va_arg(ap, type) 48 #define VA_FLT(type) fval = va_arg(ap, type) 49 #define VA_PTR(type) pval = (char *)va_arg(ap, type) 50 #define VA_STR(type) sval = va_arg(ap, type) 51 52 #define MyBuffer _nc_globals.tracearg_buf 53 #define MyLength _nc_globals.tracearg_used 54 55 /* 56 * Returns a string that represents the parameter list of a printf-style call. 57 */ 58 NCURSES_EXPORT(char *) 59 _nc_varargs(const char *fmt, va_list ap) 60 { 61 static char dummy[] = ""; 62 63 char buffer[BUFSIZ]; 64 const char *param; 65 int n; 66 67 if (fmt == 0 || *fmt == '\0') 68 return dummy; 69 if (MyLength == 0) 70 MyBuffer = typeMalloc(char, MyLength = BUFSIZ); 71 if (MyBuffer == 0) 72 return dummy; 73 *MyBuffer = '\0'; 74 75 while (*fmt != '\0') { 76 if (*fmt == '%') { 77 char *pval = 0; /* avoid const-cast */ 78 const char *sval = ""; 79 double fval = 0.0; 80 int done = FALSE; 81 int ival = 0; 82 int type = 0; 83 ARGTYPE parm[MAX_PARMS]; 84 int parms = 0; 85 ARGTYPE used = atUnknown; 86 87 while (*++fmt != '\0' && !done) { 88 89 if (*fmt == '*') { 90 VA_INT(int); 91 if (parms < MAX_PARMS) 92 parm[parms++] = atInteger; 93 } else if (isalpha(UChar(*fmt))) { 94 done = TRUE; 95 switch (*fmt) { 96 case 'Z': /* FALLTHRU */ 97 case 'h': /* FALLTHRU */ 98 case 'l': /* FALLTHRU */ 99 done = FALSE; 100 type = *fmt; 101 break; 102 case 'i': /* FALLTHRU */ 103 case 'd': /* FALLTHRU */ 104 case 'u': /* FALLTHRU */ 105 case 'x': /* FALLTHRU */ 106 case 'X': /* FALLTHRU */ 107 if (type == 'l') 108 VA_INT(long); 109 else if (type == 'Z') 110 VA_INT(size_t); 111 else 112 VA_INT(int); 113 used = atInteger; 114 break; 115 case 'f': /* FALLTHRU */ 116 case 'e': /* FALLTHRU */ 117 case 'E': /* FALLTHRU */ 118 case 'g': /* FALLTHRU */ 119 case 'G': /* FALLTHRU */ 120 VA_FLT(double); 121 used = atFloat; 122 break; 123 case 'c': 124 VA_INT(int); 125 used = atInteger; 126 break; 127 case 's': 128 VA_STR(const char *); 129 used = atString; 130 break; 131 case 'p': 132 VA_PTR(void *); 133 used = atPoint; 134 break; 135 case 'n': 136 VA_PTR(int *); 137 used = atPoint; 138 break; 139 default: 140 break; 141 } 142 } else if (*fmt == '%') { 143 done = TRUE; 144 } 145 if (used != atUnknown && parms < MAX_PARMS) { 146 parm[parms++] = used; 147 for (n = 0; n < parms; ++n) { 148 used = parm[n]; 149 param = buffer; 150 switch (used) { 151 case atInteger: 152 sprintf(buffer, "%d", ival); 153 break; 154 case atFloat: 155 sprintf(buffer, "%f", fval); 156 break; 157 case atPoint: 158 sprintf(buffer, "%p", pval); 159 break; 160 case atString: 161 param = _nc_visbuf2(1, sval); 162 break; 163 case atUnknown: 164 default: 165 strcpy(buffer, "?"); 166 break; 167 } 168 MyLength += strlen(param) + 2; 169 MyBuffer = typeRealloc(char, MyLength, MyBuffer); 170 sprintf(MyBuffer + strlen(MyBuffer), ", %s", param); 171 } 172 } 173 used = atUnknown; 174 } 175 } else { 176 fmt++; 177 } 178 } 179 180 return (MyBuffer); 181 } 182 #else 183 EMPTY_MODULE(_nc_varargs) 184 #endif 185