2 * This file is part of ltrace.
3 * Copyright (C) 2011,2012,2013 Petr Machata, Red Hat Inc.
4 * Copyright (C) 1998,2004,2007,2008,2009 Juan Cespedes
5 * Copyright (C) 2006 Steve Fink
6 * Copyright (C) 2006 Ian Wienand
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of the
11 * License, or (at your option) any later version.
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
35 #include "lens_default.h"
40 size_t *future_length;
47 static struct param_enum *
48 param_printf_init(struct value *cb_args, size_t nargs,
49 struct value_dict *arguments)
53 struct process *proc = cb_args[0].inferior;
56 /* We expect a pointer to array. */
57 if (cb_args->type->type != ARGTYPE_POINTER
58 || cb_args->type->u.ptr_info.info->type != ARGTYPE_ARRAY)
61 /* The element type should be either character (for narrow
62 * strings) or an integral type (for wide strings). */
63 struct arg_type_info *et
64 = cb_args->type->u.ptr_info.info->u.array_info.elt_type;
78 struct param_enum *self = malloc(sizeof(*self));
84 self->width = type_sizeof(proc, et);
85 if (self->width == (size_t) -1)
88 if (value_init_deref(&self->array, cb_args) < 0)
90 assert(self->array.type->type == ARGTYPE_ARRAY);
92 self->format = (char *)value_get_data(&self->array, arguments);
93 if (self->format == NULL) {
94 value_destroy(&self->array);
98 size_t size = value_size(&self->array, arguments);
99 if (size == (size_t)-1) {
100 value_destroy(&self->array);
105 self->ptr = self->format;
106 self->end = self->format + size;
107 self->future_length = NULL;
112 drop_future_length(struct param_enum *self)
114 if (self->future_length != NULL) {
115 free(self->future_length);
116 self->future_length = NULL;
121 form_next_param(struct param_enum *self,
122 enum arg_type format_type, enum arg_type elt_type,
123 unsigned hlf, unsigned lng, char *len_buf, size_t len_buf_len,
124 struct arg_type_info *infop)
126 /* XXX note: Some types are wrong because we lack
127 ARGTYPE_LONGLONG, ARGTYPE_UCHAR and ARGTYPE_SCHAR. */
130 static enum arg_type ints[] =
131 { ARGTYPE_CHAR, ARGTYPE_SHORT, ARGTYPE_INT,
132 ARGTYPE_LONG, ARGTYPE_ULONG };
133 static enum arg_type uints[] =
134 { ARGTYPE_CHAR, ARGTYPE_USHORT, ARGTYPE_UINT,
135 ARGTYPE_ULONG, ARGTYPE_ULONG };
137 struct arg_type_info *elt_info = NULL;
138 if (format_type == ARGTYPE_ARRAY || format_type == ARGTYPE_POINTER)
139 elt_info = type_get_simple(elt_type);
140 else if (format_type == ARGTYPE_INT)
141 format_type = ints[2 + lng - hlf];
142 else if (format_type == ARGTYPE_UINT)
143 format_type = uints[2 + lng - hlf];
146 if (format_type == ARGTYPE_ARRAY) {
147 struct arg_type_info *array = malloc(sizeof(*array));
151 struct expr_node *node = NULL;
154 || self->future_length != NULL) {
156 struct expr_node node;
157 struct arg_type_info type;
159 struct tmp *len = malloc(sizeof(*len));
167 len->type = *type_get_simple(ARGTYPE_LONG);
170 if (self->future_length != NULL) {
171 l = *self->future_length;
172 drop_future_length(self);
177 expr_init_const_word(&len->node, l, &len->type, 0);
179 node = build_zero_w_arg(&len->node, 1);
185 node = expr_node_zero();
188 assert(node != NULL);
190 type_init_array(array, elt_info, 0, node, own_node);
191 type_init_pointer(infop, array, 1);
193 } else if (format_type == ARGTYPE_POINTER) {
194 type_init_pointer(infop, elt_info, 0);
197 *infop = *type_get_simple(format_type);
204 param_printf_next(struct param_enum *self, struct arg_type_info *infop,
209 enum arg_type format_type = ARGTYPE_VOID;
210 enum arg_type elt_type = ARGTYPE_VOID;
211 char len_buf[25] = {};
212 size_t len_buf_len = 0;
213 struct lens *lens = NULL;
215 for (; self->ptr < self->end; self->ptr += self->width) {
223 memcpy(u.buf, self->ptr, self->width);
224 switch (self->width) {
225 case 1: u.u64 = u.u8; break;
226 case 2: u.u64 = u.u16; break;
227 case 4: u.u64 = u.u32; break;
231 if (!self->percent) {
238 case '#': case ' ': case '-':
239 case '+': case 'I': case '\'':
240 /* These are only important for formatting,
241 * not for interpreting the type. */
245 /* Length parameter given in the next
247 if (self->future_length == NULL)
248 /* This should really be an assert,
249 * but we can't just fail on invalid
252 = malloc(sizeof(*self->future_length));
254 if (self->future_length != NULL) {
255 self->ptr += self->width;
256 format_type = ARGTYPE_INT;
261 case '1': case '2': case '3':
262 case '4': case '5': case '6':
263 case '7': case '8': case '9':
264 /* Field length likewise, but we need to parse
265 * this to attach the appropriate string
266 * length expression. */
267 if (len_buf_len < sizeof(len_buf) - 1)
268 len_buf[len_buf_len++] = c;
285 case 'L': /* long double */
289 case 'j': /* intmax_t */
290 /* XXX ABI should know */
294 case 't': /* ptrdiff_t */
295 case 'Z': case 'z': /* size_t */
296 lng = 1; /* XXX ABI should tell */
301 format_type = ARGTYPE_INT;
314 format_type = ARGTYPE_UINT;
322 format_type = ARGTYPE_DOUBLE;
326 case 'C': /* like "lc" */
330 /* XXX "lc" means wchar_t string. */
331 format_type = ARGTYPE_CHAR;
335 case 'S': /* like "ls" */
339 format_type = ARGTYPE_ARRAY;
340 elt_type = lng == 0 ? ARGTYPE_CHAR : ARGTYPE_INT;
346 case 'n': /* int* where to store no. of printed chars. */
347 format_type = ARGTYPE_POINTER;
348 elt_type = ARGTYPE_VOID;
352 case 'm': /* (glibc) print argument of errno */
363 /* If we got here, the type must have been set. */
364 assert(format_type != ARGTYPE_VOID);
366 if (form_next_param(self, format_type, elt_type, hlf, lng,
367 len_buf, len_buf_len, infop) < 0)
376 *infop = *type_get_simple(ARGTYPE_VOID);
380 static enum param_status
381 param_printf_stop(struct param_enum *self, struct value *value)
383 if (self->future_length != NULL
384 && value_extract_word(value, (long *)self->future_length, NULL) < 0)
385 drop_future_length(self);
391 param_printf_done(struct param_enum *context)
393 value_destroy(&context->array);
398 param_pack_init_printf(struct param *param, struct expr_node *arg, int own_arg)
400 param_init_pack(param, PARAM_PACK_VARARGS, arg, 1, own_arg,
401 ¶m_printf_init, ¶m_printf_next,
402 ¶m_printf_stop, ¶m_printf_done);