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
37MODULE_ID("$Id: varargs.c,v 1.7 2008/08/03 15:42:49 tom Exp $")
38
39#ifdef TRACE
40
41#define MAX_PARMS 10
42
43typedef enum {
44    atUnknown = 0, atInteger, atFloat, atPoint, atString
45} ARGTYPE;
46
47#define VA_INT(type) ival = 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 */
58NCURSES_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
183EMPTY_MODULE(_nc_varargs)
184#endif
185