blob: e8b20e1a56b50b9006badf024a5922092fbf0a6c [file] [log] [blame]
Juan Cespedesd44c6b81998-09-25 14:48:42 +02001#if HAVE_CONFIG_H
2#include "config.h"
3#endif
4
Steve Fink7bafff02006-08-07 04:50:42 +02005#include <ctype.h>
Juan Cespedes5e01f651998-03-08 22:31:44 +01006#include <stdio.h>
7#include <stdlib.h>
Juan Cespedesd914a202004-11-10 00:15:33 +01008#include <string.h>
Juan Cespedes2c4a8cb1998-03-11 23:33:18 +01009#include <limits.h>
Juan Cespedes5e01f651998-03-08 22:31:44 +010010
11#include "ltrace.h"
12#include "options.h"
13
Juan Cespedesac3db291998-04-25 14:31:58 +020014static int display_char(int what);
Steve Fink6a48a6d2006-08-07 04:29:06 +020015static int display_string(enum tof type, struct process *proc,
Steve Fink7bafff02006-08-07 04:50:42 +020016 void* addr, size_t maxlen);
17static int display_value(enum tof type, struct process *proc,
Steve Finke4b32632006-08-07 06:10:08 +020018 long value, arg_type_info *info,
19 void *st, arg_type_info* st_info);
Steve Fink7bafff02006-08-07 04:50:42 +020020static int display_unknown(enum tof type, struct process *proc, long value);
Ian Wienand2d45b1a2006-02-20 22:48:07 +010021static int display_format(enum tof type, struct process *proc, int arg_num);
Juan Cespedes5e01f651998-03-08 22:31:44 +010022
Steve Fink6a48a6d2006-08-07 04:29:06 +020023static int string_maxlength = INT_MAX;
Steve Fink1150bc42006-08-07 06:04:43 +020024static int array_maxlength = INT_MAX;
Steve Fink6a48a6d2006-08-07 04:29:06 +020025
Steve Finke4b32632006-08-07 06:10:08 +020026static long get_length(enum tof type, struct process *proc, int len_spec,
27 void *st, arg_type_info* st_info)
Steve Fink6a48a6d2006-08-07 04:29:06 +020028{
Steve Finke4b32632006-08-07 06:10:08 +020029 long len;
Steve Fink6a48a6d2006-08-07 04:29:06 +020030 if (len_spec > 0)
31 return len_spec;
Steve Finke4b32632006-08-07 06:10:08 +020032 if (type == LT_TOF_STRUCT) {
33 umovelong(proc, st + st_info->u.struct_info.offset[-len_spec-1], &len);
34 return len;
35 }
Steve Fink6a48a6d2006-08-07 04:29:06 +020036 return gimme_arg(type, proc, -len_spec - 1);
37}
38
Steve Fink1150bc42006-08-07 06:04:43 +020039static int display_ptrto(enum tof type, struct process *proc, long item,
Steve Finke4b32632006-08-07 06:10:08 +020040 arg_type_info * info,
41 void *st, arg_type_info* st_info)
Steve Fink1150bc42006-08-07 06:04:43 +020042{
43 arg_type_info temp;
44 temp.type = ARGTYPE_POINTER;
45 temp.u.ptr_info.info = info;
Steve Finke4b32632006-08-07 06:10:08 +020046 return display_value(type, proc, item, &temp, st, st_info);
Steve Fink1150bc42006-08-07 06:04:43 +020047}
48
49/*
50 * addr - A pointer to the first element of the array
51 *
52 * The function name is used to indicate that we're not actually
53 * looking at an 'array', which is a contiguous region of memory
54 * containing a sequence of elements of some type; instead, we have a
55 * pointer to that region of memory.
56 */
57static int display_arrayptr(enum tof type, struct process *proc,
Steve Finke4b32632006-08-07 06:10:08 +020058 void *addr, arg_type_info * info,
59 void *st, arg_type_info* st_info)
Steve Fink1150bc42006-08-07 06:04:43 +020060{
61 int len = 0;
62 int i;
63 int array_len;
64
65 if (addr == NULL)
66 return fprintf(output, "NULL");
67
Steve Finke4b32632006-08-07 06:10:08 +020068 array_len = get_length(type, proc, info->u.array_info.len_spec,
69 st, st_info);
Steve Fink1150bc42006-08-07 06:04:43 +020070 len += fprintf(output, "[ ");
71 for (i = 0; i < opt_A && i < array_maxlength && i < array_len; i++) {
72 arg_type_info *elt_type = info->u.array_info.elt_type;
73 size_t elt_size = info->u.array_info.elt_size;
74 if (i != 0)
75 len += fprintf(output, ", ");
76 if (opt_d)
77 len += fprintf(output, "%p=", addr);
78 len +=
Steve Finke4b32632006-08-07 06:10:08 +020079 display_ptrto(type, proc, (long) addr, elt_type, st, st_info);
Steve Fink1150bc42006-08-07 06:04:43 +020080 addr += elt_size;
81 }
82 if (i < array_len)
83 len += fprintf(output, "...");
84 len += fprintf(output, " ]");
85 return len;
86}
87
Steve Finke4b32632006-08-07 06:10:08 +020088/* addr - A pointer to the beginning of the memory region occupied by
89 * the struct (aka a pointer to the struct)
90 */
91static int display_structptr(enum tof type, struct process *proc,
92 void *addr, arg_type_info * info)
93{
94 int i;
95 arg_type_info *field;
96 int len = 0;
97
98 if (addr == NULL)
99 return fprintf(output, "NULL");
100
101 len += fprintf(output, "{ ");
102 for (i = 0; (field = info->u.struct_info.fields[i]) != NULL; i++) {
103 if (i != 0)
104 len += fprintf(output, ", ");
105 if (opt_d)
106 len +=
107 fprintf(output, "%p=",
108 addr + info->u.struct_info.offset[i]);
109 len +=
110 display_ptrto(LT_TOF_STRUCT, proc,
111 (long) addr + info->u.struct_info.offset[i],
112 field, addr, info);
113 }
114 len += fprintf(output, " }");
115
116 return len;
117}
118
Steve Fink7bafff02006-08-07 04:50:42 +0200119static int display_pointer(enum tof type, struct process *proc, long value,
Steve Finke4b32632006-08-07 06:10:08 +0200120 arg_type_info * info,
121 void *st, arg_type_info* st_info)
Steve Fink7bafff02006-08-07 04:50:42 +0200122{
123 long pointed_to;
124 arg_type_info *inner = info->u.ptr_info.info;
125
Steve Fink1150bc42006-08-07 06:04:43 +0200126 if (inner->type == ARGTYPE_ARRAY) {
Steve Finke4b32632006-08-07 06:10:08 +0200127 return display_arrayptr(type, proc, (void*) value, inner,
128 st, st_info);
129 } else if (inner->type == ARGTYPE_STRUCT) {
130 return display_structptr(type, proc, (void *) value, inner);
Steve Fink1150bc42006-08-07 06:04:43 +0200131 } else {
132 if (value == 0)
133 return fprintf(output, "NULL");
134 else if (umovelong(proc, (void *) value, &pointed_to) < 0)
135 return fprintf(output, "?");
136 else
Steve Finke4b32632006-08-07 06:10:08 +0200137 return display_value(type, proc, pointed_to, inner,
138 st, st_info);
Steve Fink1150bc42006-08-07 06:04:43 +0200139 }
Steve Fink7bafff02006-08-07 04:50:42 +0200140}
141
Steve Fink6a3e24d2006-08-07 05:53:19 +0200142static int display_enum(enum tof type, struct process *proc,
143 arg_type_info* info, long value)
144{
145 int ii;
146 for (ii = 0; ii < info->u.enum_info.entries; ++ii) {
147 if (info->u.enum_info.values[ii] == value)
148 return fprintf(output, "%s", info->u.enum_info.keys[ii]);
149 }
150
151 return display_unknown(type, proc, value);
152}
153
Steve Fink7bafff02006-08-07 04:50:42 +0200154/* Args:
155 type - syscall or shared library function or memory
156 proc - information about the traced process
157 value - the value to display
158 info - the description of the type to display
Steve Finke4b32632006-08-07 06:10:08 +0200159 st - if the current value is a struct member, the address of the struct
160 st_info - type of the above struct
161
162 Those last two parameters are used for structs containing arrays or
163 strings whose length is given by another structure element.
Steve Fink7bafff02006-08-07 04:50:42 +0200164*/
165int display_value(enum tof type, struct process *proc,
Steve Finke4b32632006-08-07 06:10:08 +0200166 long value, arg_type_info *info,
167 void *st, arg_type_info* st_info)
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100168{
Juan Cespedes5e01f651998-03-08 22:31:44 +0100169 int tmp;
Juan Cespedes5e01f651998-03-08 22:31:44 +0100170
Steve Fink6a48a6d2006-08-07 04:29:06 +0200171 switch (info->type) {
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100172 case ARGTYPE_VOID:
173 return 0;
Steve Fink6b175832006-08-07 04:37:33 +0200174 case ARGTYPE_IGNORE:
175 return 0; /* Empty gap between commas */
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100176 case ARGTYPE_INT:
Steve Fink7bafff02006-08-07 04:50:42 +0200177 return fprintf(output, "%d", (int) value);
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100178 case ARGTYPE_UINT:
Steve Fink7bafff02006-08-07 04:50:42 +0200179 return fprintf(output, "%u", (unsigned) value);
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100180 case ARGTYPE_LONG:
181 if (proc->mask_32bit)
Steve Fink7bafff02006-08-07 04:50:42 +0200182 return fprintf(output, "%d", (int) value);
183 else
184 return fprintf(output, "%ld", value);
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100185 case ARGTYPE_ULONG:
186 if (proc->mask_32bit)
Steve Fink7bafff02006-08-07 04:50:42 +0200187 return fprintf(output, "%u", (unsigned) value);
188 else
189 return fprintf(output, "%lu", (unsigned long) value);
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100190 case ARGTYPE_OCTAL:
Steve Fink7bafff02006-08-07 04:50:42 +0200191 return fprintf(output, "0%o", (unsigned) value);
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100192 case ARGTYPE_CHAR:
193 tmp = fprintf(output, "'");
Steve Fink7bafff02006-08-07 04:50:42 +0200194 tmp += display_char(value == -1 ? value : (char) value);
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100195 tmp += fprintf(output, "'");
196 return tmp;
Steve Fink6fa27c32006-08-07 05:56:56 +0200197 case ARGTYPE_SHORT:
198 return fprintf(output, "%hd", (short) value);
199 case ARGTYPE_USHORT:
200 return fprintf(output, "%hu", (unsigned short) value);
201 case ARGTYPE_FLOAT: {
202 union { long l; float f; } cvt;
203 cvt.l = value;
204 return fprintf(output, "%f", cvt.f);
205 }
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100206 case ARGTYPE_ADDR:
Steve Fink7bafff02006-08-07 04:50:42 +0200207 if (!value)
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100208 return fprintf(output, "NULL");
Steve Fink7bafff02006-08-07 04:50:42 +0200209 else
210 return fprintf(output, "0x%08lx", value);
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100211 case ARGTYPE_FORMAT:
Steve Fink7bafff02006-08-07 04:50:42 +0200212 fprintf(stderr, "Should never encounter a format anywhere but at the top level (for now?)\n");
213 exit(1);
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100214 case ARGTYPE_STRING:
Steve Fink7bafff02006-08-07 04:50:42 +0200215 return display_string(type, proc, (void*) value,
Steve Fink6a48a6d2006-08-07 04:29:06 +0200216 string_maxlength);
217 case ARGTYPE_STRING_N:
Steve Fink7bafff02006-08-07 04:50:42 +0200218 return display_string(type, proc, (void*) value,
Steve Fink6a48a6d2006-08-07 04:29:06 +0200219 get_length(type, proc,
Steve Finke4b32632006-08-07 06:10:08 +0200220 info->u.string_n_info.size_spec, st, st_info));
Steve Fink1150bc42006-08-07 06:04:43 +0200221 case ARGTYPE_ARRAY:
222 return fprintf(output, "<array without address>");
Steve Fink6a3e24d2006-08-07 05:53:19 +0200223 case ARGTYPE_ENUM:
224 return display_enum(type, proc, info, value);
Steve Finke4b32632006-08-07 06:10:08 +0200225 case ARGTYPE_STRUCT:
226 return fprintf(output, "<struct without address>");
Steve Fink7bafff02006-08-07 04:50:42 +0200227 case ARGTYPE_POINTER:
Steve Finke4b32632006-08-07 06:10:08 +0200228 return display_pointer(type, proc, value, info,
229 st, st_info);
Steve Fink7bafff02006-08-07 04:50:42 +0200230 case ARGTYPE_UNKNOWN:
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100231 default:
Steve Fink7bafff02006-08-07 04:50:42 +0200232 return display_unknown(type, proc, value);
Juan Cespedes5e01f651998-03-08 22:31:44 +0100233 }
Steve Fink7bafff02006-08-07 04:50:42 +0200234}
235
236int display_arg(enum tof type, struct process *proc, int arg_num,
237 arg_type_info * info)
238{
239 long arg;
240
241 if (info->type == ARGTYPE_VOID) {
242 return 0;
243 } else if (info->type == ARGTYPE_FORMAT) {
244 return display_format(type, proc, arg_num);
245 } else {
246 arg = gimme_arg(type, proc, arg_num);
Steve Finke4b32632006-08-07 06:10:08 +0200247 return display_value(type, proc, arg, info, NULL, NULL);
Steve Fink7bafff02006-08-07 04:50:42 +0200248 }
Juan Cespedes5e01f651998-03-08 22:31:44 +0100249}
250
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100251static int display_char(int what)
252{
253 switch (what) {
254 case -1:
255 return fprintf(output, "EOF");
256 case '\r':
257 return fprintf(output, "\\r");
258 case '\n':
259 return fprintf(output, "\\n");
260 case '\t':
261 return fprintf(output, "\\t");
262 case '\b':
263 return fprintf(output, "\\b");
264 case '\\':
265 return fprintf(output, "\\\\");
266 default:
Steve Fink7bafff02006-08-07 04:50:42 +0200267 if (isprint(what)) {
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100268 return fprintf(output, "%c", what);
Steve Fink7bafff02006-08-07 04:50:42 +0200269 } else {
270 return fprintf(output, "\\%03o", (unsigned char)what);
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100271 }
Juan Cespedes5e01f651998-03-08 22:31:44 +0100272 }
273}
274
Juan Cespedes2c4a8cb1998-03-11 23:33:18 +0100275#define MIN(a,b) (((a)<(b)) ? (a) : (b))
276
Steve Fink7bafff02006-08-07 04:50:42 +0200277static int display_string(enum tof type, struct process *proc, void *addr,
278 size_t maxlength)
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100279{
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100280 unsigned char *str1;
Juan Cespedes5e01f651998-03-08 22:31:44 +0100281 int i;
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100282 int len = 0;
Juan Cespedes5e01f651998-03-08 22:31:44 +0100283
Juan Cespedes5e01f651998-03-08 22:31:44 +0100284 if (!addr) {
285 return fprintf(output, "NULL");
286 }
287
Steve Fink6a48a6d2006-08-07 04:29:06 +0200288 str1 = malloc(MIN(opt_s, maxlength) + 3);
Juan Cespedes5e01f651998-03-08 22:31:44 +0100289 if (!str1) {
290 return fprintf(output, "???");
291 }
Steve Fink6a48a6d2006-08-07 04:29:06 +0200292 umovestr(proc, addr, MIN(opt_s, maxlength) + 1, str1);
Juan Cespedes5e01f651998-03-08 22:31:44 +0100293 len = fprintf(output, "\"");
Steve Fink6a48a6d2006-08-07 04:29:06 +0200294 for (i = 0; i < MIN(opt_s, maxlength); i++) {
Juan Cespedes5e01f651998-03-08 22:31:44 +0100295 if (str1[i]) {
296 len += display_char(str1[i]);
297 } else {
298 break;
299 }
300 }
301 len += fprintf(output, "\"");
Steve Fink6a48a6d2006-08-07 04:29:06 +0200302 if (str1[i] && (opt_s <= maxlength)) {
Juan Cespedes5e01f651998-03-08 22:31:44 +0100303 len += fprintf(output, "...");
304 }
305 free(str1);
306 return len;
307}
308
Steve Fink7bafff02006-08-07 04:50:42 +0200309static int display_unknown(enum tof type, struct process *proc, long value)
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100310{
Ian Wienand9a2ad352006-02-20 22:44:45 +0100311 if (proc->mask_32bit) {
Steve Fink7bafff02006-08-07 04:50:42 +0200312 if ((int)value < 1000000 && (int)value > -1000000)
313 return fprintf(output, "%d", (int)value);
Ian Wienand9a2ad352006-02-20 22:44:45 +0100314 else
Steve Fink7bafff02006-08-07 04:50:42 +0200315 return fprintf(output, "%p", (void *)value);
316 } else if (value < 1000000 && value > -1000000) {
317 return fprintf(output, "%ld", value);
Juan Cespedes5e01f651998-03-08 22:31:44 +0100318 } else {
Steve Fink7bafff02006-08-07 04:50:42 +0200319 return fprintf(output, "%p", (void *)value);
Juan Cespedes5e01f651998-03-08 22:31:44 +0100320 }
321}
Juan Cespedesac3db291998-04-25 14:31:58 +0200322
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100323static int display_format(enum tof type, struct process *proc, int arg_num)
324{
325 void *addr;
326 unsigned char *str1;
Juan Cespedesac3db291998-04-25 14:31:58 +0200327 int i;
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100328 int len = 0;
Juan Cespedesac3db291998-04-25 14:31:58 +0200329
330 addr = (void *)gimme_arg(type, proc, arg_num);
331 if (!addr) {
332 return fprintf(output, "NULL");
333 }
334
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100335 str1 = malloc(MIN(opt_s, string_maxlength) + 3);
Juan Cespedesac3db291998-04-25 14:31:58 +0200336 if (!str1) {
337 return fprintf(output, "???");
338 }
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100339 umovestr(proc, addr, MIN(opt_s, string_maxlength) + 1, str1);
Juan Cespedesac3db291998-04-25 14:31:58 +0200340 len = fprintf(output, "\"");
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100341 for (i = 0; len < MIN(opt_s, string_maxlength) + 1; i++) {
Juan Cespedesac3db291998-04-25 14:31:58 +0200342 if (str1[i]) {
343 len += display_char(str1[i]);
344 } else {
345 break;
346 }
347 }
348 len += fprintf(output, "\"");
349 if (str1[i] && (opt_s <= string_maxlength)) {
350 len += fprintf(output, "...");
351 }
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100352 for (i = 0; str1[i]; i++) {
353 if (str1[i] == '%') {
Juan Cespedesd914a202004-11-10 00:15:33 +0100354 int is_long = 0;
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100355 while (1) {
Juan Cespedes5c3fe062004-06-14 18:08:37 +0200356 unsigned char c = str1[++i];
Juan Cespedesac3db291998-04-25 14:31:58 +0200357 if (c == '%') {
358 break;
359 } else if (!c) {
360 break;
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100361 } else if (strchr("lzZtj", c)) {
Juan Cespedesd914a202004-11-10 00:15:33 +0100362 is_long++;
363 if (c == 'j')
364 is_long++;
Ian Wienand3219f322006-02-16 06:00:00 +0100365 if (is_long > 1
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100366 && (sizeof(long) < sizeof(long long)
367 || proc->mask_32bit)) {
Juan Cespedesd914a202004-11-10 00:15:33 +0100368 len += fprintf(output, ", ...");
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100369 str1[i + 1] = '\0';
Juan Cespedesd914a202004-11-10 00:15:33 +0100370 break;
371 }
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100372 } else if (c == 'd' || c == 'i') {
Ian Wienand9a2ad352006-02-20 22:44:45 +0100373 if (!is_long || proc->mask_32bit)
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100374 len +=
375 fprintf(output, ", %d",
376 (int)gimme_arg(type,
377 proc,
378 ++arg_num));
Juan Cespedesd914a202004-11-10 00:15:33 +0100379 else
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100380 len +=
381 fprintf(output, ", %ld",
382 gimme_arg(type,
383 proc,
384 ++arg_num));
Juan Cespedesac3db291998-04-25 14:31:58 +0200385 break;
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100386 } else if (c == 'u') {
Ian Wienand9a2ad352006-02-20 22:44:45 +0100387 if (!is_long || proc->mask_32bit)
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100388 len +=
389 fprintf(output, ", %u",
390 (int)gimme_arg(type,
391 proc,
392 ++arg_num));
Juan Cespedesd914a202004-11-10 00:15:33 +0100393 else
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100394 len +=
395 fprintf(output, ", %lu",
396 gimme_arg(type,
397 proc,
398 ++arg_num));
Juan Cespedesac3db291998-04-25 14:31:58 +0200399 break;
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100400 } else if (c == 'o') {
Ian Wienand9a2ad352006-02-20 22:44:45 +0100401 if (!is_long || proc->mask_32bit)
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100402 len +=
403 fprintf(output, ", 0%o",
404 (int)gimme_arg(type,
405 proc,
406 ++arg_num));
Juan Cespedesd914a202004-11-10 00:15:33 +0100407 else
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100408 len +=
409 fprintf(output, ", 0%lo",
410 gimme_arg(type,
411 proc,
412 ++arg_num));
Juan Cespedesac3db291998-04-25 14:31:58 +0200413 break;
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100414 } else if (c == 'x' || c == 'X') {
Ian Wienand9a2ad352006-02-20 22:44:45 +0100415 if (!is_long || proc->mask_32bit)
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100416 len +=
417 fprintf(output, ", %#x",
418 (int)gimme_arg(type,
419 proc,
420 ++arg_num));
Juan Cespedesd914a202004-11-10 00:15:33 +0100421 else
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100422 len +=
423 fprintf(output, ", %#lx",
424 gimme_arg(type,
425 proc,
426 ++arg_num));
Juan Cespedesd914a202004-11-10 00:15:33 +0100427 break;
428 } else if (strchr("eEfFgGaACS", c)
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100429 || (is_long
430 && (c == 'c' || c == 's'))) {
Juan Cespedesd914a202004-11-10 00:15:33 +0100431 len += fprintf(output, ", ...");
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100432 str1[i + 1] = '\0';
Juan Cespedesac3db291998-04-25 14:31:58 +0200433 break;
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100434 } else if (c == 'c') {
Juan Cespedesac3db291998-04-25 14:31:58 +0200435 len += fprintf(output, ", '");
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100436 len +=
437 display_char((int)
438 gimme_arg(type, proc,
439 ++arg_num));
Juan Cespedesac3db291998-04-25 14:31:58 +0200440 len += fprintf(output, "'");
441 break;
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100442 } else if (c == 's') {
Juan Cespedesac3db291998-04-25 14:31:58 +0200443 len += fprintf(output, ", ");
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100444 len +=
445 display_string(type, proc,
Steve Fink7bafff02006-08-07 04:50:42 +0200446 (void *)gimme_arg(type,
447 proc,
448 ++arg_num),
Steve Fink6a48a6d2006-08-07 04:29:06 +0200449 string_maxlength);
Juan Cespedesac3db291998-04-25 14:31:58 +0200450 break;
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100451 } else if (c == 'p' || c == 'n') {
452 len +=
453 fprintf(output, ", %p",
454 (void *)gimme_arg(type,
455 proc,
456 ++arg_num));
Juan Cespedesac3db291998-04-25 14:31:58 +0200457 break;
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100458 } else if (c == '*') {
459 len +=
460 fprintf(output, ", %d",
461 (int)gimme_arg(type, proc,
462 ++arg_num));
Juan Cespedesac3db291998-04-25 14:31:58 +0200463 }
464 }
465 }
466 }
467 free(str1);
468 return len;
469}