]> ncurses.scripts.mit.edu Git - ncurses.git/blob - ncurses/trace/varargs.c
ncurses 6.4 - patch 20230624
[ncurses.git] / ncurses / trace / varargs.c
1 /****************************************************************************
2  * Copyright 2020,2023 Thomas E. Dickey                                     *
3  * Copyright 2001-2008,2012 Free Software Foundation, Inc.                  *
4  *                                                                          *
5  * Permission is hereby granted, free of charge, to any person obtaining a  *
6  * copy of this software and associated documentation files (the            *
7  * "Software"), to deal in the Software without restriction, including      *
8  * without limitation the rights to use, copy, modify, merge, publish,      *
9  * distribute, distribute with modifications, sublicense, and/or sell       *
10  * copies of the Software, and to permit persons to whom the Software is    *
11  * furnished to do so, subject to the following conditions:                 *
12  *                                                                          *
13  * The above copyright notice and this permission notice shall be included  *
14  * in all copies or substantial portions of the Software.                   *
15  *                                                                          *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
17  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
19  * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
20  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
21  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
22  * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
23  *                                                                          *
24  * Except as contained in this notice, the name(s) of the above copyright   *
25  * holders shall not be used in advertising or otherwise to promote the     *
26  * sale, use or other dealings in this Software without prior written       *
27  * authorization.                                                           *
28  ****************************************************************************/
29
30 /****************************************************************************
31  *  Author: Thomas E. Dickey 2001                                           *
32  ****************************************************************************/
33
34 #include <curses.priv.h>
35
36 #include <ctype.h>
37
38 MODULE_ID("$Id: varargs.c,v 1.13 2023/06/24 13:41:46 tom Exp $")
39
40 #ifdef TRACE
41
42 #define MAX_PARMS 10
43
44 typedef enum {
45     atUnknown = 0, atInteger, atFloat, atPoint, atString
46 } ARGTYPE;
47
48 #define VA_INT(type) ival = (int) va_arg(ap, type)
49 #define VA_FLT(type) fval = va_arg(ap, type)
50 #define VA_PTR(type) pval = (char *)va_arg(ap, type)
51 #define VA_STR(type) sval = va_arg(ap, type)
52
53 #define MyBuffer _nc_globals.tracearg_buf
54 #define MyLength _nc_globals.tracearg_used
55
56 /*
57  * Returns a string that represents the parameter list of a printf-style call.
58  */
59 NCURSES_EXPORT(char *)
60 _nc_varargs(const char *fmt, va_list ap)
61 {
62     char buffer[BUFSIZ];
63     const char *param;
64     int n;
65
66     if (fmt == 0 || *fmt == '\0')
67         return NULL;
68     if (MyLength == 0)
69         MyBuffer = typeMalloc(char, MyLength = BUFSIZ);
70     if (MyBuffer == 0)
71         return NULL;
72     *MyBuffer = '\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                             _nc_SPRINTF(buffer, _nc_SLIMIT(sizeof(buffer))
152                                         "%d", ival);
153                             break;
154                         case atFloat:
155                             _nc_SPRINTF(buffer, _nc_SLIMIT(sizeof(buffer))
156                                         "%f", fval);
157                             break;
158                         case atPoint:
159                             _nc_SPRINTF(buffer, _nc_SLIMIT(sizeof(buffer))
160                                         "%p", pval);
161                             break;
162                         case atString:
163                             param = _nc_visbuf2(1, sval);
164                             break;
165                         case atUnknown:
166                         default:
167                             _nc_STRCPY(buffer, "?", sizeof(buffer));
168                             break;
169                         }
170                         MyLength += strlen(param) + 2;
171                         MyBuffer = typeRealloc(char, MyLength, MyBuffer);
172                         if (MyBuffer != 0) {
173                             _nc_SPRINTF(MyBuffer + strlen(MyBuffer),
174                                         _nc_SLIMIT(MyLength - strlen(MyBuffer))
175                                         ", %s", param);
176                         }
177                     }
178                 }
179                 used = atUnknown;
180             }
181         } else {
182             fmt++;
183         }
184     }
185
186     return (MyBuffer ? MyBuffer : NULL);
187 }
188 #else
189 EMPTY_MODULE(_nc_varargs)
190 #endif