6d3d12ebef
This commit includes string.h in common-defs.h and removes all other inclusions. gdb/ 2014-08-07 Gary Benson <gbenson@redhat.com> * common/common-defs.h: Include string.h. * aarch64-tdep.c: Do not include string.h. * ada-exp.y: Likewise. * ada-lang.c: Likewise. * ada-lex.l: Likewise. * ada-typeprint.c: Likewise. * ada-valprint.c: Likewise. * aix-thread.c: Likewise. * alpha-linux-tdep.c: Likewise. * alpha-mdebug-tdep.c: Likewise. * alpha-nat.c: Likewise. * alpha-osf1-tdep.c: Likewise. * alpha-tdep.c: Likewise. * alphanbsd-tdep.c: Likewise. * amd64-dicos-tdep.c: Likewise. * amd64-linux-tdep.c: Likewise. * amd64-nat.c: Likewise. * amd64-sol2-tdep.c: Likewise. * amd64fbsd-tdep.c: Likewise. * amd64obsd-tdep.c: Likewise. * arch-utils.c: Likewise. * arm-linux-nat.c: Likewise. * arm-linux-tdep.c: Likewise. * arm-tdep.c: Likewise. * arm-wince-tdep.c: Likewise. * armbsd-tdep.c: Likewise. * armnbsd-nat.c: Likewise. * armnbsd-tdep.c: Likewise. * armobsd-tdep.c: Likewise. * avr-tdep.c: Likewise. * ax-gdb.c: Likewise. * ax-general.c: Likewise. * bcache.c: Likewise. * bfin-tdep.c: Likewise. * breakpoint.c: Likewise. * build-id.c: Likewise. * buildsym.c: Likewise. * c-exp.y: Likewise. * c-lang.c: Likewise. * c-typeprint.c: Likewise. * c-valprint.c: Likewise. * charset.c: Likewise. * cli-out.c: Likewise. * cli/cli-cmds.c: Likewise. * cli/cli-decode.c: Likewise. * cli/cli-dump.c: Likewise. * cli/cli-interp.c: Likewise. * cli/cli-logging.c: Likewise. * cli/cli-script.c: Likewise. * cli/cli-setshow.c: Likewise. * cli/cli-utils.c: Likewise. * coffread.c: Likewise. * common/agent.c: Likewise. * common/buffer.c: Likewise. * common/buffer.h: Likewise. * common/common-utils.c: Likewise. * common/filestuff.c: Likewise. * common/filestuff.c: Likewise. * common/format.c: Likewise. * common/print-utils.c: Likewise. * common/rsp-low.c: Likewise. * common/signals.c: Likewise. * common/vec.h: Likewise. * common/xml-utils.c: Likewise. * core-regset.c: Likewise. * corefile.c: Likewise. * corelow.c: Likewise. * cp-abi.c: Likewise. * cp-name-parser.y: Likewise. * cp-support.c: Likewise. * cp-valprint.c: Likewise. * cris-tdep.c: Likewise. * d-exp.y: Likewise. * darwin-nat.c: Likewise. * dbxread.c: Likewise. * dcache.c: Likewise. * demangle.c: Likewise. * dicos-tdep.c: Likewise. * disasm.c: Likewise. * doublest.c: Likewise. * dsrec.c: Likewise. * dummy-frame.c: Likewise. * dwarf2-frame.c: Likewise. * dwarf2loc.c: Likewise. * dwarf2read.c: Likewise. * elfread.c: Likewise. * environ.c: Likewise. * eval.c: Likewise. * event-loop.c: Likewise. * exceptions.c: Likewise. * exec.c: Likewise. * expprint.c: Likewise. * f-exp.y: Likewise. * f-lang.c: Likewise. * f-typeprint.c: Likewise. * f-valprint.c: Likewise. * fbsd-nat.c: Likewise. * findcmd.c: Likewise. * findvar.c: Likewise. * fork-child.c: Likewise. * frame.c: Likewise. * frv-linux-tdep.c: Likewise. * frv-tdep.c: Likewise. * gdb.c: Likewise. * gdb_bfd.c: Likewise. * gdbarch.c: Likewise. * gdbarch.sh: Likewise. * gdbtypes.c: Likewise. * gnu-nat.c: Likewise. * gnu-v2-abi.c: Likewise. * gnu-v3-abi.c: Likewise. * go-exp.y: Likewise. * go-lang.c: Likewise. * go32-nat.c: Likewise. * guile/guile.c: Likewise. * guile/scm-auto-load.c: Likewise. * hppa-hpux-tdep.c: Likewise. * hppa-linux-nat.c: Likewise. * hppanbsd-tdep.c: Likewise. * hppaobsd-tdep.c: Likewise. * i386-cygwin-tdep.c: Likewise. * i386-dicos-tdep.c: Likewise. * i386-linux-tdep.c: Likewise. * i386-nto-tdep.c: Likewise. * i386-sol2-tdep.c: Likewise. * i386-tdep.c: Likewise. * i386bsd-tdep.c: Likewise. * i386gnu-nat.c: Likewise. * i386nbsd-tdep.c: Likewise. * i386obsd-tdep.c: Likewise. * i387-tdep.c: Likewise. * ia64-libunwind-tdep.c: Likewise. * ia64-linux-nat.c: Likewise. * inf-child.c: Likewise. * inf-ptrace.c: Likewise. * inf-ttrace.c: Likewise. * infcall.c: Likewise. * infcmd.c: Likewise. * inflow.c: Likewise. * infrun.c: Likewise. * interps.c: Likewise. * iq2000-tdep.c: Likewise. * irix5-nat.c: Likewise. * jv-exp.y: Likewise. * jv-lang.c: Likewise. * jv-typeprint.c: Likewise. * jv-valprint.c: Likewise. * language.c: Likewise. * linux-fork.c: Likewise. * linux-nat.c: Likewise. * lm32-tdep.c: Likewise. * m2-exp.y: Likewise. * m2-typeprint.c: Likewise. * m32c-tdep.c: Likewise. * m32r-linux-nat.c: Likewise. * m32r-linux-tdep.c: Likewise. * m32r-rom.c: Likewise. * m32r-tdep.c: Likewise. * m68hc11-tdep.c: Likewise. * m68k-tdep.c: Likewise. * m68kbsd-tdep.c: Likewise. * m68klinux-nat.c: Likewise. * m68klinux-tdep.c: Likewise. * m88k-tdep.c: Likewise. * machoread.c: Likewise. * macrocmd.c: Likewise. * main.c: Likewise. * mdebugread.c: Likewise. * mem-break.c: Likewise. * memattr.c: Likewise. * memory-map.c: Likewise. * mep-tdep.c: Likewise. * mi/mi-cmd-break.c: Likewise. * mi/mi-cmd-disas.c: Likewise. * mi/mi-cmd-env.c: Likewise. * mi/mi-cmd-stack.c: Likewise. * mi/mi-cmd-var.c: Likewise. * mi/mi-cmds.c: Likewise. * mi/mi-console.c: Likewise. * mi/mi-getopt.c: Likewise. * mi/mi-interp.c: Likewise. * mi/mi-main.c: Likewise. * mi/mi-parse.c: Likewise. * microblaze-rom.c: Likewise. * microblaze-tdep.c: Likewise. * mingw-hdep.c: Likewise. * minidebug.c: Likewise. * minsyms.c: Likewise. * mips-irix-tdep.c: Likewise. * mips-linux-tdep.c: Likewise. * mips-tdep.c: Likewise. * mips64obsd-tdep.c: Likewise. * mipsnbsd-tdep.c: Likewise. * mipsread.c: Likewise. * mn10300-linux-tdep.c: Likewise. * mn10300-tdep.c: Likewise. * monitor.c: Likewise. * moxie-tdep.c: Likewise. * mt-tdep.c: Likewise. * nat/linux-btrace.c: Likewise. * nat/linux-osdata.c: Likewise. * nat/linux-procfs.c: Likewise. * nat/linux-ptrace.c: Likewise. * nat/linux-waitpid.c: Likewise. * nbsd-tdep.c: Likewise. * nios2-linux-tdep.c: Likewise. * nto-procfs.c: Likewise. * nto-tdep.c: Likewise. * objc-lang.c: Likewise. * objfiles.c: Likewise. * opencl-lang.c: Likewise. * osabi.c: Likewise. * osdata.c: Likewise. * p-exp.y: Likewise. * p-lang.c: Likewise. * p-typeprint.c: Likewise. * parse.c: Likewise. * posix-hdep.c: Likewise. * ppc-linux-nat.c: Likewise. * ppc-sysv-tdep.c: Likewise. * ppcfbsd-tdep.c: Likewise. * ppcnbsd-tdep.c: Likewise. * ppcobsd-tdep.c: Likewise. * printcmd.c: Likewise. * procfs.c: Likewise. * prologue-value.c: Likewise. * python/py-auto-load.c: Likewise. * python/py-gdb-readline.c: Likewise. * ravenscar-thread.c: Likewise. * regcache.c: Likewise. * registry.c: Likewise. * remote-fileio.c: Likewise. * remote-m32r-sdi.c: Likewise. * remote-mips.c: Likewise. * remote-notif.c: Likewise. * remote-sim.c: Likewise. * remote.c: Likewise. * reverse.c: Likewise. * rs6000-aix-tdep.c: Likewise. * ser-base.c: Likewise. * ser-go32.c: Likewise. * ser-mingw.c: Likewise. * ser-pipe.c: Likewise. * ser-tcp.c: Likewise. * ser-unix.c: Likewise. * serial.c: Likewise. * sh-tdep.c: Likewise. * sh64-tdep.c: Likewise. * shnbsd-tdep.c: Likewise. * skip.c: Likewise. * sol-thread.c: Likewise. * solib-dsbt.c: Likewise. * solib-frv.c: Likewise. * solib-osf.c: Likewise. * solib-som.c: Likewise. * solib-spu.c: Likewise. * solib-target.c: Likewise. * solib.c: Likewise. * somread.c: Likewise. * source.c: Likewise. * sparc-nat.c: Likewise. * sparc-sol2-tdep.c: Likewise. * sparc-tdep.c: Likewise. * sparc64-tdep.c: Likewise. * sparc64fbsd-tdep.c: Likewise. * sparc64nbsd-tdep.c: Likewise. * sparcnbsd-tdep.c: Likewise. * spu-linux-nat.c: Likewise. * spu-multiarch.c: Likewise. * spu-tdep.c: Likewise. * stabsread.c: Likewise. * stack.c: Likewise. * std-regs.c: Likewise. * symfile.c: Likewise. * symmisc.c: Likewise. * symtab.c: Likewise. * target.c: Likewise. * thread.c: Likewise. * tilegx-linux-nat.c: Likewise. * tilegx-tdep.c: Likewise. * top.c: Likewise. * tracepoint.c: Likewise. * tui/tui-command.c: Likewise. * tui/tui-data.c: Likewise. * tui/tui-disasm.c: Likewise. * tui/tui-file.c: Likewise. * tui/tui-layout.c: Likewise. * tui/tui-out.c: Likewise. * tui/tui-regs.c: Likewise. * tui/tui-source.c: Likewise. * tui/tui-stack.c: Likewise. * tui/tui-win.c: Likewise. * tui/tui-windata.c: Likewise. * tui/tui-winsource.c: Likewise. * typeprint.c: Likewise. * ui-file.c: Likewise. * ui-out.c: Likewise. * user-regs.c: Likewise. * utils.c: Likewise. * v850-tdep.c: Likewise. * valarith.c: Likewise. * valops.c: Likewise. * valprint.c: Likewise. * value.c: Likewise. * varobj.c: Likewise. * vax-tdep.c: Likewise. * vaxnbsd-tdep.c: Likewise. * vaxobsd-tdep.c: Likewise. * windows-nat.c: Likewise. * xcoffread.c: Likewise. * xml-support.c: Likewise. * xstormy16-tdep.c: Likewise. * xtensa-linux-nat.c: Likewise. gdb/gdbserver/ 2014-08-07 Gary Benson <gbenson@redhat.com> * server.h: Do not include string.h. * event-loop.c: Likewise. * linux-low.c: Likewise. * regcache.c: Likewise. * remote-utils.c: Likewise. * spu-low.c: Likewise. * utils.c: Likewise.
402 lines
8.7 KiB
C
402 lines
8.7 KiB
C
/* Parse a printf-style format string.
|
|
|
|
Copyright (C) 1986-2014 Free Software Foundation, Inc.
|
|
|
|
This file is part of GDB.
|
|
|
|
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 3 of the License, 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, see <http://www.gnu.org/licenses/>. */
|
|
|
|
#ifdef GDBSERVER
|
|
#include "server.h"
|
|
#else
|
|
#include "defs.h"
|
|
#endif
|
|
|
|
#include "format.h"
|
|
|
|
struct format_piece *
|
|
parse_format_string (const char **arg)
|
|
{
|
|
const char *s;
|
|
char *f, *string;
|
|
const char *prev_start;
|
|
const char *percent_loc;
|
|
char *sub_start, *current_substring;
|
|
struct format_piece *pieces;
|
|
int next_frag;
|
|
int max_pieces;
|
|
enum argclass this_argclass;
|
|
|
|
s = *arg;
|
|
|
|
/* Parse the format-control string and copy it into the string STRING,
|
|
processing some kinds of escape sequence. */
|
|
|
|
f = string = (char *) alloca (strlen (s) + 1);
|
|
|
|
while (*s != '"' && *s != '\0')
|
|
{
|
|
int c = *s++;
|
|
switch (c)
|
|
{
|
|
case '\0':
|
|
continue;
|
|
|
|
case '\\':
|
|
switch (c = *s++)
|
|
{
|
|
case '\\':
|
|
*f++ = '\\';
|
|
break;
|
|
case 'a':
|
|
*f++ = '\a';
|
|
break;
|
|
case 'b':
|
|
*f++ = '\b';
|
|
break;
|
|
case 'f':
|
|
*f++ = '\f';
|
|
break;
|
|
case 'n':
|
|
*f++ = '\n';
|
|
break;
|
|
case 'r':
|
|
*f++ = '\r';
|
|
break;
|
|
case 't':
|
|
*f++ = '\t';
|
|
break;
|
|
case 'v':
|
|
*f++ = '\v';
|
|
break;
|
|
case '"':
|
|
*f++ = '"';
|
|
break;
|
|
default:
|
|
/* ??? TODO: handle other escape sequences. */
|
|
error (_("Unrecognized escape character \\%c in format string."),
|
|
c);
|
|
}
|
|
break;
|
|
|
|
default:
|
|
*f++ = c;
|
|
}
|
|
}
|
|
|
|
/* Terminate our escape-processed copy. */
|
|
*f++ = '\0';
|
|
|
|
/* Whether the format string ended with double-quote or zero, we're
|
|
done with it; it's up to callers to complain about syntax. */
|
|
*arg = s;
|
|
|
|
/* Need extra space for the '\0's. Doubling the size is sufficient. */
|
|
|
|
current_substring = xmalloc (strlen (string) * 2 + 1000);
|
|
|
|
max_pieces = strlen (string) + 2;
|
|
|
|
pieces = (struct format_piece *)
|
|
xmalloc (max_pieces * sizeof (struct format_piece));
|
|
|
|
next_frag = 0;
|
|
|
|
/* Now scan the string for %-specs and see what kinds of args they want.
|
|
argclass classifies the %-specs so we can give printf-type functions
|
|
something of the right size. */
|
|
|
|
f = string;
|
|
prev_start = string;
|
|
while (*f)
|
|
if (*f++ == '%')
|
|
{
|
|
int seen_hash = 0, seen_zero = 0, lcount = 0, seen_prec = 0;
|
|
int seen_space = 0, seen_plus = 0;
|
|
int seen_big_l = 0, seen_h = 0, seen_big_h = 0;
|
|
int seen_big_d = 0, seen_double_big_d = 0;
|
|
int bad = 0;
|
|
|
|
/* Skip over "%%", it will become part of a literal piece. */
|
|
if (*f == '%')
|
|
{
|
|
f++;
|
|
continue;
|
|
}
|
|
|
|
sub_start = current_substring;
|
|
|
|
strncpy (current_substring, prev_start, f - 1 - prev_start);
|
|
current_substring += f - 1 - prev_start;
|
|
*current_substring++ = '\0';
|
|
|
|
pieces[next_frag].string = sub_start;
|
|
pieces[next_frag].argclass = literal_piece;
|
|
next_frag++;
|
|
|
|
percent_loc = f - 1;
|
|
|
|
/* Check the validity of the format specifier, and work
|
|
out what argument it expects. We only accept C89
|
|
format strings, with the exception of long long (which
|
|
we autoconf for). */
|
|
|
|
/* The first part of a format specifier is a set of flag
|
|
characters. */
|
|
while (*f != '\0' && strchr ("0-+ #", *f))
|
|
{
|
|
if (*f == '#')
|
|
seen_hash = 1;
|
|
else if (*f == '0')
|
|
seen_zero = 1;
|
|
else if (*f == ' ')
|
|
seen_space = 1;
|
|
else if (*f == '+')
|
|
seen_plus = 1;
|
|
f++;
|
|
}
|
|
|
|
/* The next part of a format specifier is a width. */
|
|
while (*f != '\0' && strchr ("0123456789", *f))
|
|
f++;
|
|
|
|
/* The next part of a format specifier is a precision. */
|
|
if (*f == '.')
|
|
{
|
|
seen_prec = 1;
|
|
f++;
|
|
while (*f != '\0' && strchr ("0123456789", *f))
|
|
f++;
|
|
}
|
|
|
|
/* The next part of a format specifier is a length modifier. */
|
|
if (*f == 'h')
|
|
{
|
|
seen_h = 1;
|
|
f++;
|
|
}
|
|
else if (*f == 'l')
|
|
{
|
|
f++;
|
|
lcount++;
|
|
if (*f == 'l')
|
|
{
|
|
f++;
|
|
lcount++;
|
|
}
|
|
}
|
|
else if (*f == 'L')
|
|
{
|
|
seen_big_l = 1;
|
|
f++;
|
|
}
|
|
/* Decimal32 modifier. */
|
|
else if (*f == 'H')
|
|
{
|
|
seen_big_h = 1;
|
|
f++;
|
|
}
|
|
/* Decimal64 and Decimal128 modifiers. */
|
|
else if (*f == 'D')
|
|
{
|
|
f++;
|
|
|
|
/* Check for a Decimal128. */
|
|
if (*f == 'D')
|
|
{
|
|
f++;
|
|
seen_double_big_d = 1;
|
|
}
|
|
else
|
|
seen_big_d = 1;
|
|
}
|
|
|
|
switch (*f)
|
|
{
|
|
case 'u':
|
|
if (seen_hash)
|
|
bad = 1;
|
|
/* FALLTHROUGH */
|
|
|
|
case 'o':
|
|
case 'x':
|
|
case 'X':
|
|
if (seen_space || seen_plus)
|
|
bad = 1;
|
|
/* FALLTHROUGH */
|
|
|
|
case 'd':
|
|
case 'i':
|
|
if (lcount == 0)
|
|
this_argclass = int_arg;
|
|
else if (lcount == 1)
|
|
this_argclass = long_arg;
|
|
else
|
|
this_argclass = long_long_arg;
|
|
|
|
if (seen_big_l)
|
|
bad = 1;
|
|
break;
|
|
|
|
case 'c':
|
|
this_argclass = lcount == 0 ? int_arg : wide_char_arg;
|
|
if (lcount > 1 || seen_h || seen_big_l)
|
|
bad = 1;
|
|
if (seen_prec || seen_zero || seen_space || seen_plus)
|
|
bad = 1;
|
|
break;
|
|
|
|
case 'p':
|
|
this_argclass = ptr_arg;
|
|
if (lcount || seen_h || seen_big_l)
|
|
bad = 1;
|
|
if (seen_prec)
|
|
bad = 1;
|
|
if (seen_hash || seen_zero || seen_space || seen_plus)
|
|
bad = 1;
|
|
break;
|
|
|
|
case 's':
|
|
this_argclass = lcount == 0 ? string_arg : wide_string_arg;
|
|
if (lcount > 1 || seen_h || seen_big_l)
|
|
bad = 1;
|
|
if (seen_zero || seen_space || seen_plus)
|
|
bad = 1;
|
|
break;
|
|
|
|
case 'e':
|
|
case 'f':
|
|
case 'g':
|
|
case 'E':
|
|
case 'G':
|
|
if (seen_big_h || seen_big_d || seen_double_big_d)
|
|
this_argclass = decfloat_arg;
|
|
else if (seen_big_l)
|
|
this_argclass = long_double_arg;
|
|
else
|
|
this_argclass = double_arg;
|
|
|
|
if (lcount || seen_h)
|
|
bad = 1;
|
|
break;
|
|
|
|
case '*':
|
|
error (_("`*' not supported for precision or width in printf"));
|
|
|
|
case 'n':
|
|
error (_("Format specifier `n' not supported in printf"));
|
|
|
|
case '\0':
|
|
error (_("Incomplete format specifier at end of format string"));
|
|
|
|
default:
|
|
error (_("Unrecognized format specifier '%c' in printf"), *f);
|
|
}
|
|
|
|
if (bad)
|
|
error (_("Inappropriate modifiers to "
|
|
"format specifier '%c' in printf"),
|
|
*f);
|
|
|
|
f++;
|
|
|
|
sub_start = current_substring;
|
|
|
|
if (lcount > 1 && USE_PRINTF_I64)
|
|
{
|
|
/* Windows' printf does support long long, but not the usual way.
|
|
Convert %lld to %I64d. */
|
|
int length_before_ll = f - percent_loc - 1 - lcount;
|
|
|
|
strncpy (current_substring, percent_loc, length_before_ll);
|
|
strcpy (current_substring + length_before_ll, "I64");
|
|
current_substring[length_before_ll + 3] =
|
|
percent_loc[length_before_ll + lcount];
|
|
current_substring += length_before_ll + 4;
|
|
}
|
|
else if (this_argclass == wide_string_arg
|
|
|| this_argclass == wide_char_arg)
|
|
{
|
|
/* Convert %ls or %lc to %s. */
|
|
int length_before_ls = f - percent_loc - 2;
|
|
|
|
strncpy (current_substring, percent_loc, length_before_ls);
|
|
strcpy (current_substring + length_before_ls, "s");
|
|
current_substring += length_before_ls + 2;
|
|
}
|
|
else
|
|
{
|
|
strncpy (current_substring, percent_loc, f - percent_loc);
|
|
current_substring += f - percent_loc;
|
|
}
|
|
|
|
*current_substring++ = '\0';
|
|
|
|
prev_start = f;
|
|
|
|
pieces[next_frag].string = sub_start;
|
|
pieces[next_frag].argclass = this_argclass;
|
|
next_frag++;
|
|
}
|
|
|
|
/* Record the remainder of the string. */
|
|
|
|
sub_start = current_substring;
|
|
|
|
strncpy (current_substring, prev_start, f - prev_start);
|
|
current_substring += f - prev_start;
|
|
*current_substring++ = '\0';
|
|
|
|
pieces[next_frag].string = sub_start;
|
|
pieces[next_frag].argclass = literal_piece;
|
|
next_frag++;
|
|
|
|
/* Record an end-of-array marker. */
|
|
|
|
pieces[next_frag].string = NULL;
|
|
pieces[next_frag].argclass = literal_piece;
|
|
|
|
return pieces;
|
|
}
|
|
|
|
void
|
|
free_format_pieces (struct format_piece *pieces)
|
|
{
|
|
if (!pieces)
|
|
return;
|
|
|
|
/* We happen to know that all the string pieces are in the block
|
|
pointed to by the first string piece. */
|
|
if (pieces[0].string)
|
|
xfree (pieces[0].string);
|
|
|
|
xfree (pieces);
|
|
}
|
|
|
|
void
|
|
free_format_pieces_cleanup (void *ptr)
|
|
{
|
|
void **location = ptr;
|
|
|
|
if (location == NULL)
|
|
return;
|
|
|
|
if (*location != NULL)
|
|
{
|
|
free_format_pieces (*location);
|
|
*location = NULL;
|
|
}
|
|
}
|
|
|