This is the mail archive of the gdb@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: GDB printf command


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
/* 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 <stddef.h>

/* Get wchar_t.  */
#ifdef HAVE_WCHAR_T
# include <stddef.h>
#endif

/* Get wint_t.  */
#ifdef HAVE_WINT_T
# include <wchar.h>
#endif

/* Get va_list.  */
#include <stdarg.h>


/* 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 */
/* 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 */

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]