From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 22915 invoked by alias); 17 Oct 2006 14:54:24 -0000 Received: (qmail 22900 invoked by uid 22791); 17 Oct 2006 14:54:22 -0000 X-Spam-Check-By: sourceware.org Received: from nevyn.them.org (HELO nevyn.them.org) (66.93.172.17) by sourceware.org (qpsmtpd/0.31.1) with ESMTP; Tue, 17 Oct 2006 14:54:14 +0000 Received: from drow by nevyn.them.org with local (Exim 4.54) id 1GZqKZ-0008FO-AV for gdb@sourceware.org; Tue, 17 Oct 2006 10:54:11 -0400 Date: Tue, 17 Oct 2006 14:54:00 -0000 From: Daniel Jacobowitz To: gdb@sourceware.org Subject: Re: GDB printf command Message-ID: <20061017145411.GA31447@nevyn.them.org> Mail-Followup-To: gdb@sourceware.org References: <4534C695.2050206@st.com> <20061017132426.GA28323@nevyn.them.org> <4534E3FF.9030505@st.com> <20061017142451.GA30620@nevyn.them.org> <4534EC06.3050200@st.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="3V7upXqbjpZ4EhLz" Content-Disposition: inline In-Reply-To: <4534EC06.3050200@st.com> User-Agent: Mutt/1.5.13 (2006-08-11) X-IsSubscribed: yes Mailing-List: contact gdb-help@sourceware.org; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-owner@sourceware.org X-SW-Source: 2006-10/txt/msg00126.txt.bz2 --3V7upXqbjpZ4EhLz Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-length: 1638 On Tue, Oct 17, 2006 at 03:43:18PM +0100, Andrew STUBBS wrote: > I'm not really sure what you are suggesting I do exactly. What do you > think ought to be done and where? I think we ought to run a format string parser to break up the string, then look at what arguments we've got and their types, and squeeze the two together. This sounds like a fairly complicated solution, and I'd agree, except that we can steal most of the code for it from this "gnulib" project I keep talking about: a collection of GPL and LGPL utility routines, designed to be imported into other projects. For example, I've attached the headers which handle the parsing. There's no "take this argument and format set and print it" function; it's all wrapped up in a vasnprintf implementation. However, we could trivially split that out, and ask the gnulib maintainers to accept such a change; I bet they would accept such a patch. Once we have the structure in place, we could basically replace printf_fetchargs (which uses va_arg) with something that operated on our list of values and did appropriate type checking / casts, then hand it back to the gnulib printf routine. > How much effort do you think it will take? Like everyone else I don't > have enormous amounts of time for projects I wasn't expecting. This I can not predict, I'm afraid. > Assuming it isn't a big task I am certainly interested in getting it > done right. Whatever that is, hopefully it does include the same target > working the same on all hosts (or at least all the same features > working, for some definition of 'work'). Precisely. -- Daniel Jacobowitz CodeSourcery --3V7upXqbjpZ4EhLz Content-Type: text/x-chdr; charset=us-ascii Content-Disposition: attachment; filename="printf-args.h" Content-length: 2859 /* Decomposed printf argument list. Copyright (C) 1999, 2002-2003 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef _PRINTF_ARGS_H #define _PRINTF_ARGS_H /* Get size_t. */ #include /* Get wchar_t. */ #ifdef HAVE_WCHAR_T # include #endif /* Get wint_t. */ #ifdef HAVE_WINT_T # include #endif /* Get va_list. */ #include /* Argument types */ typedef enum { TYPE_NONE, TYPE_SCHAR, TYPE_UCHAR, TYPE_SHORT, TYPE_USHORT, TYPE_INT, TYPE_UINT, TYPE_LONGINT, TYPE_ULONGINT, #ifdef HAVE_LONG_LONG TYPE_LONGLONGINT, TYPE_ULONGLONGINT, #endif TYPE_DOUBLE, #ifdef HAVE_LONG_DOUBLE TYPE_LONGDOUBLE, #endif TYPE_CHAR, #ifdef HAVE_WINT_T TYPE_WIDE_CHAR, #endif TYPE_STRING, #ifdef HAVE_WCHAR_T TYPE_WIDE_STRING, #endif TYPE_POINTER, TYPE_COUNT_SCHAR_POINTER, TYPE_COUNT_SHORT_POINTER, TYPE_COUNT_INT_POINTER, TYPE_COUNT_LONGINT_POINTER #ifdef HAVE_LONG_LONG , TYPE_COUNT_LONGLONGINT_POINTER #endif } arg_type; /* Polymorphic argument */ typedef struct { arg_type type; union { signed char a_schar; unsigned char a_uchar; short a_short; unsigned short a_ushort; int a_int; unsigned int a_uint; long int a_longint; unsigned long int a_ulongint; #ifdef HAVE_LONG_LONG long long int a_longlongint; unsigned long long int a_ulonglongint; #endif float a_float; double a_double; #ifdef HAVE_LONG_DOUBLE long double a_longdouble; #endif int a_char; #ifdef HAVE_WINT_T wint_t a_wide_char; #endif const char* a_string; #ifdef HAVE_WCHAR_T const wchar_t* a_wide_string; #endif void* a_pointer; signed char * a_count_schar_pointer; short * a_count_short_pointer; int * a_count_int_pointer; long int * a_count_longint_pointer; #ifdef HAVE_LONG_LONG long long int * a_count_longlongint_pointer; #endif } a; } argument; typedef struct { size_t count; argument *arg; } arguments; /* Fetch the arguments, putting them into a. */ #ifdef STATIC STATIC #else extern #endif int printf_fetchargs (va_list args, arguments *a); #endif /* _PRINTF_ARGS_H */ --3V7upXqbjpZ4EhLz Content-Type: text/x-chdr; charset=us-ascii Content-Disposition: attachment; filename="printf-parse.h" Content-length: 2160 /* Parse printf format string. Copyright (C) 1999, 2002-2003 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef _PRINTF_PARSE_H #define _PRINTF_PARSE_H #include "printf-args.h" /* Flags */ #define FLAG_GROUP 1 /* ' flag */ #define FLAG_LEFT 2 /* - flag */ #define FLAG_SHOWSIGN 4 /* + flag */ #define FLAG_SPACE 8 /* space flag */ #define FLAG_ALT 16 /* # flag */ #define FLAG_ZERO 32 /* arg_index value indicating that no argument is consumed. */ #define ARG_NONE (~(size_t)0) /* A parsed directive. */ typedef struct { const char* dir_start; const char* dir_end; int flags; const char* width_start; const char* width_end; size_t width_arg_index; const char* precision_start; const char* precision_end; size_t precision_arg_index; char conversion; /* d i o u x X f e E g G c s p n U % but not C S */ size_t arg_index; } char_directive; /* A parsed format string. */ typedef struct { size_t count; char_directive *dir; size_t max_width_length; size_t max_precision_length; } char_directives; /* Parses the format string. Fills in the number N of directives, and fills in directives[0], ..., directives[N-1], and sets directives[N].dir_start to the end of the format string. Also fills in the arg_type fields of the arguments and the needed count of arguments. */ #ifdef STATIC STATIC #else extern #endif int printf_parse (const char *format, char_directives *d, arguments *a); #endif /* _PRINTF_PARSE_H */ --3V7upXqbjpZ4EhLz--