summaryrefslogtreecommitdiff
path: root/libiberty/vprintf-support.c
diff options
context:
space:
mode:
authorUros Bizjak <ubizjak@gmail.com>2014-12-11 09:15:37 +0100
committerUros Bizjak <uros@gcc.gnu.org>2014-12-11 09:15:37 +0100
commit01ca36af914385acfc864adfae6923768581888a (patch)
tree73160bf616558a6ddfc1ac73519216a81c9d0e8a /libiberty/vprintf-support.c
parentc168eab92cc42d3c995cc0a1188e1554ebbcd63a (diff)
downloadgcc-01ca36af914385acfc864adfae6923768581888a.tar.gz
xvasprintf.c: New file.
* 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. include/ChangeLog: * libiberty.h (xvasprintf): Declare. libcpp/ChangeLog: * directives.c (cpp_define_formatted): Use xvasprintf. Co-Authored-By: Ben Elliston <bje@au.ibm.com> Co-Authored-By: Manuel López-Ibáñez <manu@gcc.gnu.org> From-SVN: r218618
Diffstat (limited to 'libiberty/vprintf-support.c')
-rw-r--r--libiberty/vprintf-support.c119
1 files changed, 119 insertions, 0 deletions
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 <ansidecl.h>
+#include <stdarg.h>
+#if !defined (va_copy) && defined (__va_copy)
+# define va_copy(d,s) __va_copy((d),(s))
+#endif
+#include <stdio.h>
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#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;
+}