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