diff --git a/include/ChangeLog b/include/ChangeLog index f264b27501f..1d5f7013321 100644 --- a/include/ChangeLog +++ b/include/ChangeLog @@ -1,3 +1,9 @@ +2014-12-11 Uros Bizjak + Ben Elliston + Manuel Lopez-Ibanez + + * libiberty.h (xvasprintf): Declare. + 2014-12-09 Trevor Saunders * hashtab.h, splay-tree.h: Remove GTY markers. diff --git a/include/libiberty.h b/include/libiberty.h index 571e85f1e9e..b9694f0f093 100644 --- a/include/libiberty.h +++ b/include/libiberty.h @@ -636,6 +636,11 @@ extern int asprintf (char **, const char *, ...) ATTRIBUTE_PRINTF_2; extern int vasprintf (char **, const char *, va_list) ATTRIBUTE_PRINTF(2,0); #endif +/* Like vasprintf but allocates memory without fail. This works like + xmalloc. */ + +extern char *xvasprintf (const char *, va_list) ATTRIBUTE_MALLOC ATTRIBUTE_PRINTF(1,0); + #if defined(HAVE_DECL_SNPRINTF) && !HAVE_DECL_SNPRINTF /* Like sprintf but prints at most N characters. */ extern int snprintf (char *, size_t, const char *, ...) ATTRIBUTE_PRINTF_3; diff --git a/libcpp/ChangeLog b/libcpp/ChangeLog index e26c8c9b599..df71ac2597a 100644 --- a/libcpp/ChangeLog +++ b/libcpp/ChangeLog @@ -1,3 +1,7 @@ +2014-12-11 Uros Bizjak + + * directives.c (cpp_define_formatted): Use xvasprintf. + 2014-12-05 Manuel López-Ibáñez * line-map.c (linemap_position_for_loc_and_offset): Add new diff --git a/libcpp/directives.c b/libcpp/directives.c index ba92ec2a6e4..c9be4122511 100644 --- a/libcpp/directives.c +++ b/libcpp/directives.c @@ -2404,11 +2404,11 @@ cpp_define (cpp_reader *pfile, const char *str) void cpp_define_formatted (cpp_reader *pfile, const char *fmt, ...) { - char *ptr = NULL; + char *ptr; va_list ap; va_start (ap, fmt); - vasprintf (&ptr, fmt, ap); + ptr = xvasprintf (fmt, ap); va_end (ap); cpp_define (pfile, ptr); diff --git a/libiberty/ChangeLog b/libiberty/ChangeLog index 66018b33717..e4a8ce81b25 100644 --- a/libiberty/ChangeLog +++ b/libiberty/ChangeLog @@ -1,3 +1,17 @@ +2014-12-11 Uros Bizjak + Ben Elliston + Manuel Lopez-Ibanez + + * xvasprintf.c: New file. + * vprintf-support.h: Likewise. + * vprintf-support.c: Likewise. + * Makefile.in (CFILES): Add vprintf-support.c, xvasprintf.c. + (REQUIRED_OFILES): Add vprintf-support.$(objext), xvasprintf.$(objext). + (vprintf-support.$(objext), xvasprintf.$(objext)): New targets. + (vasprintf.$(objext)): Depend on $(srcdir)/vprintf-support.h. + * functions.texi: Regenerate. + * vasprintf.c (int_vasprintf): Use libiberty_vprintf_buffer_size. + 2014-11-22 John David Anglin PR other/63694 diff --git a/libiberty/Makefile.in b/libiberty/Makefile.in index 1b0d8ae782b..e7e17af226c 100644 --- a/libiberty/Makefile.in +++ b/libiberty/Makefile.in @@ -155,10 +155,11 @@ CFILES = alloca.c argv.c asprintf.c atexit.c \ strtoll.c strtoul.c strtoull.c strndup.c strnlen.c \ strverscmp.c timeval-utils.c tmpnam.c \ unlink-if-ordinary.c \ - vasprintf.c vfork.c vfprintf.c vprintf.c vsnprintf.c vsprintf.c \ + vasprintf.c vfork.c vfprintf.c vprintf.c vprintf-support.c \ + vsnprintf.c vsprintf.c \ waitpid.c \ xatexit.c xexit.c xmalloc.c xmemdup.c xstrdup.c xstrerror.c \ - xstrndup.c + xstrndup.c xvasprintf.c # These are always included in the library. The first four are listed # first and by compile time to optimize parallel builds. @@ -180,7 +181,7 @@ REQUIRED_OFILES = \ ./obstack.$(objext) \ ./partition.$(objext) ./pexecute.$(objext) ./physmem.$(objext) \ ./pex-common.$(objext) ./pex-one.$(objext) \ - ./@pexecute@.$(objext) \ + ./@pexecute@.$(objext) ./vprintf-support.$(objext) \ ./safe-ctype.$(objext) \ ./simple-object.$(objext) ./simple-object-coff.$(objext) \ ./simple-object-elf.$(objext) ./simple-object-mach-o.$(objext) \ @@ -191,7 +192,7 @@ REQUIRED_OFILES = \ ./timeval-utils.$(objext) ./unlink-if-ordinary.$(objext) \ ./xatexit.$(objext) ./xexit.$(objext) ./xmalloc.$(objext) \ ./xmemdup.$(objext) ./xstrdup.$(objext) ./xstrerror.$(objext) \ - ./xstrndup.$(objext) + ./xstrndup.$(objext) ./xvasprintf.$(objext) # These are all the objects that configure may add to the library via # $funcs or EXTRA_OFILES. This list exists here only for "make @@ -1543,7 +1544,7 @@ $(CONFIGURED_OFILES): stamp-picdir stamp-noasandir $(COMPILE.c) $(srcdir)/unlink-if-ordinary.c $(OUTPUT_OPTION) ./vasprintf.$(objext): $(srcdir)/vasprintf.c config.h $(INCDIR)/ansidecl.h \ - $(INCDIR)/libiberty.h + $(INCDIR)/libiberty.h $(srcdir)/vprintf-support.h if [ x"$(PICFLAG)" != x ]; then \ $(COMPILE.c) $(PICFLAG) $(srcdir)/vasprintf.c -o pic/$@; \ else true; fi @@ -1570,6 +1571,16 @@ $(CONFIGURED_OFILES): stamp-picdir stamp-noasandir else true; fi $(COMPILE.c) $(srcdir)/vfprintf.c $(OUTPUT_OPTION) +./vprintf-support.$(objext): $(srcdir)/vprintf-support.c config.h \ + $(INCDIR)/ansidecl.h $(INCDIR)/libiberty.h + if [ x"$(PICFLAG)" != x ]; then \ + $(COMPILE.c) $(PICFLAG) $(srcdir)/vprintf-support.c -o pic/$@; \ + else true; fi + if [ x"$(NOASANFLAG)" != x ]; then \ + $(COMPILE.c) $(PICFLAG) $(NOASANFLAG) $(srcdir)/vprintf-support.c -o noasan/$@; \ + else true; fi + $(COMPILE.c) $(srcdir)/vprintf-support.c $(OUTPUT_OPTION) + ./vprintf.$(objext): $(srcdir)/vprintf.c $(INCDIR)/ansidecl.h if [ x"$(PICFLAG)" != x ]; then \ $(COMPILE.c) $(PICFLAG) $(srcdir)/vprintf.c -o pic/$@; \ @@ -1677,3 +1688,12 @@ $(CONFIGURED_OFILES): stamp-picdir stamp-noasandir else true; fi $(COMPILE.c) $(srcdir)/xstrndup.c $(OUTPUT_OPTION) +./xvasprintf.$(objext): $(srcdir)/xvasprintf.c config.h $(INCDIR)/ansidecl.h \ + $(INCDIR)/libiberty.h $(srcdir)/vprintf-support.h + if [ x"$(PICFLAG)" != x ]; then \ + $(COMPILE.c) $(PICFLAG) $(srcdir)/xvasprintf.c -o pic/$@; \ + else true; fi + if [ x"$(NOASANFLAG)" != x ]; then \ + $(COMPILE.c) $(PICFLAG) $(NOASANFLAG) $(srcdir)/xvasprintf.c -o noasan/$@; \ + else true; fi + $(COMPILE.c) $(srcdir)/xvasprintf.c $(OUTPUT_OPTION) diff --git a/libiberty/functions.texi b/libiberty/functions.texi index 9ed9ff03438..39064b4166c 100644 --- a/libiberty/functions.texi +++ b/libiberty/functions.texi @@ -2022,4 +2022,13 @@ always NUL terminated. @end deftypefn +@c xvasprintf.c:38 +@deftypefn Replacement char* xvasprintf (const char *@var{format}, va_list @var{args}) + +Print to allocated string without fail. If @code{xvasprintf} fails, +this will print a message to @code{stderr} (using the name set by +@code{xmalloc_set_program_name}, if any) and then call @code{xexit}. + +@end deftypefn + diff --git a/libiberty/vasprintf.c b/libiberty/vasprintf.c index 492506037da..6ffe2dd7516 100644 --- a/libiberty/vasprintf.c +++ b/libiberty/vasprintf.c @@ -14,9 +14,9 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public -License along with libiberty; see the file COPYING.LIB. If -not, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, -Boston, MA 02110-1301, USA. */ +License along with libiberty; see the file COPYING.LIB. If not, write +to the Free Software Foundation, Inc., 51 Franklin Street - Fifth +Floor, Boston, MA 02110-1301, USA. */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -33,10 +33,10 @@ Boston, MA 02110-1301, USA. */ #ifdef HAVE_STDLIB_H #include #else -extern unsigned long strtoul (); extern PTR malloc (); #endif #include "libiberty.h" +#include "vprintf-support.h" #ifdef TEST int global_total_width; @@ -64,81 +64,7 @@ static int int_vasprintf (char **, const char *, va_list); static int int_vasprintf (char **result, const char *format, va_list args) { - const char *p = format; - /* Add one to make sure that it is never zero, which might cause malloc - to return NULL. */ - int total_width = strlen (format) + 1; - va_list ap; - -#ifdef va_copy - va_copy (ap, args); -#else - memcpy ((PTR) &ap, (PTR) &args, sizeof (va_list)); -#endif - - while (*p != '\0') - { - if (*p++ == '%') - { - while (strchr ("-+ #0", *p)) - ++p; - if (*p == '*') - { - ++p; - total_width += abs (va_arg (ap, int)); - } - else - total_width += strtoul (p, (char **) &p, 10); - if (*p == '.') - { - ++p; - if (*p == '*') - { - ++p; - total_width += abs (va_arg (ap, int)); - } - else - total_width += strtoul (p, (char **) &p, 10); - } - while (strchr ("hlL", *p)) - ++p; - /* Should be big enough for any format specifier except %s and floats. */ - total_width += 30; - switch (*p) - { - case 'd': - case 'i': - case 'o': - case 'u': - case 'x': - case 'X': - case 'c': - (void) va_arg (ap, int); - break; - case 'f': - case 'e': - case 'E': - case 'g': - case 'G': - (void) va_arg (ap, double); - /* Since an ieee double can have an exponent of 307, we'll - make the buffer wide enough to cover the gross case. */ - total_width += 307; - break; - case 's': - total_width += strlen (va_arg (ap, char *)); - break; - case 'p': - case 'n': - (void) va_arg (ap, char *); - break; - } - p++; - } - } -#ifdef va_copy - va_end (ap); -#endif + int total_width = libiberty_vprintf_buffer_size (format, args); #ifdef TEST global_total_width = total_width; #endif diff --git a/libiberty/vprintf-support.c b/libiberty/vprintf-support.c new file mode 100644 index 00000000000..171232f1b0f --- /dev/null +++ b/libiberty/vprintf-support.c @@ -0,0 +1,119 @@ +/* Estimate the length of the string generated by a vprintf-like + function. Used by vasprintf and xvasprintf. + Copyright (C) 1994, 2003, 2011, 2013, 2014 Free Software Foundation, Inc. + +This file is part of the libiberty library. +Libiberty is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +Libiberty 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with libiberty; see the file COPYING.LIB. If not, write +to the Free Software Foundation, Inc., 51 Franklin Street - Fifth +Floor, Boston, MA 02110-1301, USA. */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +#include +#include +#if !defined (va_copy) && defined (__va_copy) +# define va_copy(d,s) __va_copy((d),(s)) +#endif +#include +#ifdef HAVE_STRING_H +#include +#endif +#ifdef HAVE_STDLIB_H +#include +#else +extern unsigned long strtoul (); +#endif +#include "libiberty.h" + +int +libiberty_vprintf_buffer_size (const char *format, va_list args) +{ + const char *p = format; + /* Add one to make sure that it is never zero, which might cause malloc + to return NULL. */ + int total_width = strlen (format) + 1; + va_list ap; + +#ifdef va_copy + va_copy (ap, args); +#else + memcpy ((PTR) &ap, (PTR) &args, sizeof (va_list)); +#endif + + while (*p != '\0') + { + if (*p++ == '%') + { + while (strchr ("-+ #0", *p)) + ++p; + if (*p == '*') + { + ++p; + total_width += abs (va_arg (ap, int)); + } + else + total_width += strtoul (p, (char **) &p, 10); + if (*p == '.') + { + ++p; + if (*p == '*') + { + ++p; + total_width += abs (va_arg (ap, int)); + } + else + total_width += strtoul (p, (char **) &p, 10); + } + while (strchr ("hlL", *p)) + ++p; + /* Should be big enough for any format specifier except %s and floats. */ + total_width += 30; + switch (*p) + { + case 'd': + case 'i': + case 'o': + case 'u': + case 'x': + case 'X': + case 'c': + (void) va_arg (ap, int); + break; + case 'f': + case 'e': + case 'E': + case 'g': + case 'G': + (void) va_arg (ap, double); + /* Since an ieee double can have an exponent of 307, we'll + make the buffer wide enough to cover the gross case. */ + total_width += 307; + break; + case 's': + total_width += strlen (va_arg (ap, char *)); + break; + case 'p': + case 'n': + (void) va_arg (ap, char *); + break; + } + p++; + } + } +#ifdef va_copy + va_end (ap); +#endif + return total_width; +} diff --git a/libiberty/vprintf-support.h b/libiberty/vprintf-support.h new file mode 100644 index 00000000000..9d2680aac89 --- /dev/null +++ b/libiberty/vprintf-support.h @@ -0,0 +1,22 @@ +/* Estimate the length of the string generated by a vprintf-like + function. Use by vasprintf and xvasprintf. + Copyright (C) 1994, 2003, 2011, 2013, 2014 Free Software Foundation, Inc. + +This file is part of the libiberty library. +Libiberty is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +Libiberty 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with libiberty; see the file COPYING.LIB. If not, write +to the Free Software Foundation, Inc., 51 Franklin Street - Fifth +Floor, Boston, MA 02110-1301, USA. */ + + +extern int libiberty_vprintf_buffer_size (const char *, va_list); diff --git a/libiberty/xvasprintf.c b/libiberty/xvasprintf.c new file mode 100644 index 00000000000..9e9a9d39e11 --- /dev/null +++ b/libiberty/xvasprintf.c @@ -0,0 +1,61 @@ +/* Implement the xvasprintf function. + Copyright (C) 2014 Free Software Foundation, Inc. + Contributed by Manuel Lopez-Ibanez. + +This file is part of the libiberty library. +Libiberty is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +Libiberty 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with libiberty; see the file COPYING.LIB. If not, write +to the Free Software Foundation, Inc., 51 Franklin Street - Fifth +Floor, Boston, MA 02110-1301, USA. */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +#include +#include +#if !defined (va_copy) && defined (__va_copy) +# define va_copy(d,s) __va_copy((d),(s)) +#endif +#include +#ifdef HAVE_STRING_H +#include +#endif +#include "libiberty.h" +#include "vprintf-support.h" + +/* + +@deftypefn Replacement char* xvasprintf (const char *@var{format}, va_list @var{args}) + +Print to allocated string without fail. If @code{xvasprintf} fails, +this will print a message to @code{stderr} (using the name set by +@code{xmalloc_set_program_name}, if any) and then call @code{xexit}. + +@end deftypefn + +*/ + +char * +xvasprintf (const char *format, +#if defined (_BSD_VA_LIST_) && defined (__FreeBSD__) + _BSD_VA_LIST_ args) +#else + va_list args) +#endif +{ + char *result; + int total_width = libiberty_vprintf_buffer_size (format, args); + result = (char *) xmalloc (total_width); + vsprintf (result, format, args); + return result; +}