ncurses 5.7 - patch 20090117
[ncurses.git] / ncurses / trace / varargs.c
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.7 2008/08/03 15:42:49 tom 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 = 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