ncurses 5.3
[ncurses.git] / ncurses / trace / varargs.c
1 /****************************************************************************
2  * Copyright (c) 2001,2002 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.3 2002/10/05 23:04:17 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 = (void *)va_arg(ap, type)
50 #define VA_STR(type) sval = va_arg(ap, type)
51
52 /*
53  * Returns a string that represents the parameter list of a printf-style call.
54  */
55 NCURSES_EXPORT(char *)
56 _nc_varargs(const char *fmt, va_list ap)
57 {
58     static char dummy[] = "";
59     static char *result_buf;
60     static size_t result_len;
61
62     char buffer[BUFSIZ];
63     const char *param;
64     int n;
65
66     if (fmt == 0 || *fmt == '\0')
67         return dummy;
68     if (result_len == 0)
69         result_buf = typeMalloc(char, result_len = BUFSIZ);
70     if (result_buf == 0)
71         return dummy;
72     *result_buf = '\0';
73
74     while (*fmt != '\0') {
75         if (*fmt == '%') {
76             char *pval = 0;     /* avoid const-cast */
77             const char *sval = "";
78             double fval = 0.0;
79             int done = FALSE;
80             int ival = 0;
81             int type = 0;
82             ARGTYPE parm[MAX_PARMS];
83             int parms = 0;
84             ARGTYPE used = atUnknown;
85
86             while (*++fmt != '\0' && !done) {
87
88                 if (*fmt == '*') {
89                     VA_INT(int);
90                     if (parms < MAX_PARMS)
91                         parm[parms++] = atInteger;
92                 } else if (isalpha(UChar(*fmt))) {
93                     done = TRUE;
94                     switch (*fmt) {
95                     case 'Z':   /* FALLTHRU */
96                     case 'h':   /* FALLTHRU */
97                     case 'l':   /* FALLTHRU */
98                         done = FALSE;
99                         type = *fmt;
100                         break;
101                     case 'i':   /* FALLTHRU */
102                     case 'd':   /* FALLTHRU */
103                     case 'u':   /* FALLTHRU */
104                     case 'x':   /* FALLTHRU */
105                     case 'X':   /* FALLTHRU */
106                         if (type == 'l')
107                             VA_INT(long);
108                         else if (type == 'Z')
109                             VA_INT(size_t);
110                         else
111                             VA_INT(int);
112                         used = atInteger;
113                         break;
114                     case 'f':   /* FALLTHRU */
115                     case 'e':   /* FALLTHRU */
116                     case 'E':   /* FALLTHRU */
117                     case 'g':   /* FALLTHRU */
118                     case 'G':   /* FALLTHRU */
119                         VA_FLT(double);
120                         used = atFloat;
121                         break;
122                     case 'c':
123                         VA_INT(int);
124                         used = atInteger;
125                         break;
126                     case 's':
127                         VA_STR(const char *);
128                         used = atString;
129                         break;
130                     case 'p':
131                         VA_PTR(void *);
132                         used = atPoint;
133                         break;
134                     case 'n':
135                         VA_PTR(int *);
136                         used = atPoint;
137                         break;
138                     default:
139                         break;
140                     }
141                 } else if (*fmt == '%') {
142                     done = TRUE;
143                 }
144                 if (used != atUnknown && parms < MAX_PARMS) {
145                     parm[parms++] = used;
146                     for (n = 0; n < parms; ++n) {
147                         used = parm[n];
148                         param = buffer;
149                         switch (used) {
150                         case atInteger:
151                             sprintf(buffer, "%d", ival);
152                             break;
153                         case atFloat:
154                             sprintf(buffer, "%f", fval);
155                             break;
156                         case atPoint:
157                             sprintf(buffer, "%p", pval);
158                             break;
159                         case atString:
160                             param = _nc_visbuf2(1, sval);
161                             break;
162                         default:
163                             strcpy(buffer, "?");
164                             break;
165                         }
166                         result_len += strlen(param) + 2;
167                         result_buf = typeRealloc(char, result_len, result_buf);
168                         sprintf(result_buf + strlen(result_buf), ", %s", param);
169                     }
170                 }
171                 used = atUnknown;
172             }
173         } else {
174             fmt++;
175         }
176     }
177
178     return (result_buf);
179 }
180 #else
181 empty_module(_nc_varargs)
182 #endif