diff options
author | Karl Berry <karl@freefriends.org> | 2021-02-25 19:22:25 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2021-02-25 19:22:25 +0000 |
commit | ad547a6b5986815fda458221149728d9d9ab1d87 (patch) | |
tree | 16296910eb3eca724371474ea9aea3994dc69614 /Build/source/libs/gmp/gmp-src/printf | |
parent | 947b43de3dd21d58ccc2ffadefc4441ea1c2a813 (diff) |
restore Build,TODO from r57911
git-svn-id: svn://tug.org/texlive/trunk@57915 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/libs/gmp/gmp-src/printf')
22 files changed, 2718 insertions, 0 deletions
diff --git a/Build/source/libs/gmp/gmp-src/printf/Makefile.am b/Build/source/libs/gmp/gmp-src/printf/Makefile.am new file mode 100644 index 00000000000..bcbf55dbd75 --- /dev/null +++ b/Build/source/libs/gmp/gmp-src/printf/Makefile.am @@ -0,0 +1,41 @@ +## Process this file with automake to generate Makefile.in + +# Copyright 2001, 2002 Free Software Foundation, Inc. +# +# This file is part of the GNU MP Library. +# +# The GNU MP Library is free software; you can redistribute it and/or modify +# it under the terms of either: +# +# * the GNU Lesser General Public License as published by the Free +# Software Foundation; either version 3 of the License, or (at your +# option) any later version. +# +# or +# +# * the GNU General Public License as published by the Free Software +# Foundation; either version 2 of the License, or (at your option) any +# later version. +# +# or both in parallel, as here. +# +# The GNU MP Library 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 copies of the GNU General Public License and the +# GNU Lesser General Public License along with the GNU MP Library. If not, +# see https://www.gnu.org/licenses/. + + +AM_CPPFLAGS = -D__GMP_WITHIN_GMP -I$(top_srcdir) + +noinst_LTLIBRARIES = libprintf.la + +libprintf_la_SOURCES = \ + asprintf.c asprntffuns.c doprnt.c doprntf.c doprnti.c \ + fprintf.c obprintf.c obvprintf.c obprntffuns.c \ + printf.c printffuns.c snprintf.c snprntffuns.c sprintf.c sprintffuns.c \ + vasprintf.c vfprintf.c vprintf.c vsnprintf.c vsprintf.c \ + repl-vsnprintf.c diff --git a/Build/source/libs/gmp/gmp-src/printf/asprintf.c b/Build/source/libs/gmp/gmp-src/printf/asprintf.c new file mode 100644 index 00000000000..da87b755dd0 --- /dev/null +++ b/Build/source/libs/gmp/gmp-src/printf/asprintf.c @@ -0,0 +1,47 @@ +/* gmp_asprintf -- formatted output to an allocated space. + +Copyright 2001 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library 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 copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include <stdarg.h> + +#include "gmp-impl.h" + + +int +gmp_asprintf (char **result, const char *fmt, ...) +{ + va_list ap; + int ret; + + va_start (ap, fmt); + + ret = gmp_vasprintf (result, fmt, ap); + va_end (ap); + return ret; +} diff --git a/Build/source/libs/gmp/gmp-src/printf/asprntffuns.c b/Build/source/libs/gmp/gmp-src/printf/asprntffuns.c new file mode 100644 index 00000000000..022a80ca772 --- /dev/null +++ b/Build/source/libs/gmp/gmp-src/printf/asprntffuns.c @@ -0,0 +1,71 @@ +/* __gmp_asprintf_memory etc -- formatted output to allocated space. + +Copyright 2001, 2002 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library 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 copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + + +/* These routines are in a separate file so that the mpz_t, mpq_t and mpf_t + operator<< routines can avoid dragging vsnprintf into the link (via + __gmp_asprintf_format). */ + +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "gmp-impl.h" + + +int +__gmp_asprintf_memory (struct gmp_asprintf_t *d, const char *str, size_t len) +{ + GMP_ASPRINTF_T_NEED (d, len); + memcpy (d->buf + d->size, str, len); + d->size += len; + return len; +} + +int +__gmp_asprintf_reps (struct gmp_asprintf_t *d, int c, int reps) +{ + GMP_ASPRINTF_T_NEED (d, reps); + memset (d->buf + d->size, c, reps); + d->size += reps; + return reps; +} + +int +__gmp_asprintf_final (struct gmp_asprintf_t *d) +{ + char *buf = d->buf; + ASSERT (d->alloc >= d->size + 1); + buf[d->size] = '\0'; + __GMP_REALLOCATE_FUNC_MAYBE_TYPE (buf, d->alloc, d->size+1, char); + *d->result = buf; + return 0; +} diff --git a/Build/source/libs/gmp/gmp-src/printf/doprnt.c b/Build/source/libs/gmp/gmp-src/printf/doprnt.c new file mode 100644 index 00000000000..fa3f3029f95 --- /dev/null +++ b/Build/source/libs/gmp/gmp-src/printf/doprnt.c @@ -0,0 +1,626 @@ +/* __gmp_doprnt -- printf style formatted output. + + THE FUNCTIONS IN THIS FILE ARE FOR INTERNAL USE ONLY. THEY'RE ALMOST + CERTAIN TO BE SUBJECT TO INCOMPATIBLE CHANGES OR DISAPPEAR COMPLETELY IN + FUTURE GNU MP RELEASES. + +Copyright 2001-2003 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library 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 copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#define _GNU_SOURCE /* for DECIMAL_POINT in glibc langinfo.h */ + +#include "config.h" /* needed for the HAVE_, could also move gmp incls */ + +#include <stdarg.h> +#include <ctype.h> /* for isdigit */ +#include <stddef.h> /* for ptrdiff_t */ +#include <string.h> +#include <stdio.h> /* for NULL */ +#include <stdlib.h> + +#if HAVE_INTTYPES_H +# include <inttypes.h> /* for intmax_t */ +#else +# if HAVE_STDINT_H +# include <stdint.h> +# endif +#endif + +#if HAVE_LANGINFO_H +#include <langinfo.h> /* for nl_langinfo */ +#endif + +#if HAVE_LOCALE_H +#include <locale.h> /* for localeconv */ +#endif + +#if HAVE_SYS_TYPES_H +#include <sys/types.h> /* for quad_t */ +#endif + +#include "gmp-impl.h" + + +/* change this to "#define TRACE(x) x" for diagnostics */ +#define TRACE(x) + + +/* Should be portable, but in any case this is only used under some ASSERTs. */ +#define va_equal(x, y) \ + (memcmp (&(x), &(y), sizeof(va_list)) == 0) + + +/* printf is convenient because it allows various types to be printed in one + fairly compact call, so having gmp_printf support the standard types as + well as the gmp ones is important. This ends up meaning all the standard + parsing must be duplicated, to get a new routine recognising the gmp + extras. + + With the currently favoured handling of mpz etc as Z, Q and F type + markers, it's not possible to use glibc register_printf_function since + that only accepts new conversion characters, not new types. If Z was a + conversion there'd be no way to specify hex, decimal or octal, or + similarly with F no way to specify fixed point or scientific format. + + It seems wisest to pass conversions %f, %e and %g of float, double and + long double over to the standard printf. It'd be hard to be sure of + getting the right handling for NaNs, rounding, etc. Integer conversions + %d etc and string conversions %s on the other hand could be easily enough + handled within gmp_doprnt, but if floats are going to libc then it's just + as easy to send all non-gmp types there. + + "Z" was a type marker for size_t in old glibc, but there seems no need to + provide access to that now "z" is standard. + + In GMP 4.1.1 we documented "ll" and "L" as being equivalent, but in C99 + in fact "ll" is just for long long and "L" just for long double. + Apparently GLIBC allows "L" for long long though. This doesn't affect + us as such, since both are passed through to the C library. To be + consistent with what we said before, the two are treated equivalently + here, and it's left to the C library to do what it thinks with them. + + Possibilities: + + "b" might be nice for binary output, and could even be supported for the + standard C types too if desired. + + POSIX style "%n$" parameter numbering would be possible, but would need + to be handled completely within gmp_doprnt, since the numbering will be + all different once the format string it cut into pieces. + + Some options for mpq formatting would be good. Perhaps a non-zero + precision field could give a width for the denominator and mean always + put a "/". A form "n+p/q" might interesting too, though perhaps that's + better left to applications. + + Right now there's no way for an application to know whether types like + intmax_t are supported here. If configure is doing its job and the same + compiler is used for gmp as for the application then there shouldn't be + any problem, but perhaps gmp.h should have some preprocessor symbols to + say what libgmp can do. */ + + + +/* If a gmp format is the very first thing or there are two gmp formats with + nothing in between then we'll reach here with this_fmt == last_fmt and we + can do nothing in that case. + + last_ap is always replaced after a FLUSH, so it doesn't matter if va_list + is a call-by-reference and the funs->format routine modifies it. */ + +#define FLUSH() \ + do { \ + if (this_fmt == last_fmt) \ + { \ + TRACE (printf ("nothing to flush\n")); \ + ASSERT (va_equal (this_ap, last_ap)); \ + } \ + else \ + { \ + ASSERT (*this_fmt == '%'); \ + *this_fmt = '\0'; \ + TRACE (printf ("flush \"%s\"\n", last_fmt)); \ + DOPRNT_FORMAT (last_fmt, last_ap); \ + } \ + } while (0) + + +/* Parse up the given format string and do the appropriate output using the + given "funs" routines. The data parameter is passed through to those + routines. */ + +int +__gmp_doprnt (const struct doprnt_funs_t *funs, void *data, + const char *orig_fmt, va_list orig_ap) +{ + va_list ap, this_ap, last_ap; + size_t alloc_fmt_size, orig_fmt_size; + char *fmt, *alloc_fmt, *last_fmt, *this_fmt, *gmp_str; + int retval = 0; + int type, fchar, *value, seen_precision; + struct doprnt_params_t param; + + TRACE (printf ("gmp_doprnt \"%s\"\n", orig_fmt)); + + /* Don't modify orig_ap, if va_list is actually an array and hence call by + reference. It could be argued that it'd be more efficient to leave the + caller to make a copy if it cared, but doing so here is going to be a + very small part of the total work, and we may as well keep applications + out of trouble. */ + va_copy (ap, orig_ap); + + /* The format string is chopped up into pieces to be passed to + funs->format. Unfortunately that means it has to be copied so each + piece can be null-terminated. We're not going to be very fast here, so + use __gmp_allocate_func rather than TMP_ALLOC, to avoid overflowing the + stack if a long output string is given. */ + alloc_fmt_size = orig_fmt_size = strlen (orig_fmt) + 1; +#if _LONG_LONG_LIMB + /* for a long long limb we change %Mx to %llx, so could need an extra 1 + char for every 3 existing */ + alloc_fmt_size += alloc_fmt_size / 3; +#endif + alloc_fmt = __GMP_ALLOCATE_FUNC_TYPE (alloc_fmt_size, char); + fmt = alloc_fmt; + memcpy (fmt, orig_fmt, orig_fmt_size); + + /* last_fmt and last_ap are just after the last output, and hence where + the next output will begin, when that's done */ + last_fmt = fmt; + va_copy (last_ap, ap); + + for (;;) + { + TRACE (printf ("next: \"%s\"\n", fmt)); + + fmt = strchr (fmt, '%'); + if (fmt == NULL) + break; + + /* this_fmt and this_ap are the current '%' sequence being considered */ + this_fmt = fmt; + va_copy (this_ap, ap); + fmt++; /* skip the '%' */ + + TRACE (printf ("considering\n"); + printf (" last: \"%s\"\n", last_fmt); + printf (" this: \"%s\"\n", this_fmt)); + + type = '\0'; + value = ¶m.width; + + param.base = 10; + param.conv = 0; + param.expfmt = "e%c%02ld"; + param.exptimes4 = 0; + param.fill = ' '; + param.justify = DOPRNT_JUSTIFY_RIGHT; + param.prec = 6; + param.showbase = DOPRNT_SHOWBASE_NO; + param.showpoint = 0; + param.showtrailing = 1; + param.sign = '\0'; + param.width = 0; + seen_precision = 0; + + /* This loop parses a single % sequence. "break" from the switch + means continue with this %, "goto next" means the conversion + character has been seen and a new % should be sought. */ + for (;;) + { + fchar = *fmt++; + if (fchar == '\0') + break; + + switch (fchar) { + + case 'a': + /* %a behaves like %e, but defaults to all significant digits, + and there's no leading zeros on the exponent (which is in + fact bit-based) */ + param.base = 16; + param.expfmt = "p%c%ld"; + goto conv_a; + case 'A': + param.base = -16; + param.expfmt = "P%c%ld"; + conv_a: + param.conv = DOPRNT_CONV_SCIENTIFIC; + param.exptimes4 = 1; + if (! seen_precision) + param.prec = -1; /* default to all digits */ + param.showbase = DOPRNT_SHOWBASE_YES; + param.showtrailing = 1; + goto floating_a; + + case 'c': + /* Let's assume wchar_t will be promoted to "int" in the call, + the same as char will be. */ + (void) va_arg (ap, int); + goto next; + + case 'd': + case 'i': + case 'u': + integer: + TRACE (printf ("integer, base=%d\n", param.base)); + if (! seen_precision) + param.prec = -1; + switch (type) { + case 'j': + /* Let's assume uintmax_t is the same size as intmax_t. */ +#if HAVE_INTMAX_T + (void) va_arg (ap, intmax_t); +#else + ASSERT_FAIL (intmax_t not available); +#endif + break; + case 'l': + (void) va_arg (ap, long); + break; + case 'L': +#if HAVE_LONG_LONG + (void) va_arg (ap, long long); +#else + ASSERT_FAIL (long long not available); +#endif + break; + case 'N': + { + mp_ptr xp; + mp_size_t xsize, abs_xsize; + mpz_t z; + FLUSH (); + xp = va_arg (ap, mp_ptr); + PTR(z) = xp; + xsize = (int) va_arg (ap, mp_size_t); + abs_xsize = ABS (xsize); + MPN_NORMALIZE (xp, abs_xsize); + SIZ(z) = (xsize >= 0 ? abs_xsize : -abs_xsize); + ASSERT_CODE (ALLOC(z) = abs_xsize); + gmp_str = mpz_get_str (NULL, param.base, z); + goto gmp_integer; + } + /* break; */ + case 'q': + /* quad_t is probably the same as long long, but let's treat + it separately just to be sure. Also let's assume u_quad_t + will be the same size as quad_t. */ +#if HAVE_QUAD_T + (void) va_arg (ap, quad_t); +#else + ASSERT_FAIL (quad_t not available); +#endif + break; + case 'Q': + FLUSH (); + gmp_str = mpq_get_str (NULL, param.base, va_arg(ap, mpq_srcptr)); + goto gmp_integer; + case 't': +#if HAVE_PTRDIFF_T + (void) va_arg (ap, ptrdiff_t); +#else + ASSERT_FAIL (ptrdiff_t not available); +#endif + break; + case 'z': + (void) va_arg (ap, size_t); + break; + case 'Z': + { + int ret; + FLUSH (); + gmp_str = mpz_get_str (NULL, param.base, + va_arg (ap, mpz_srcptr)); + gmp_integer: + ret = __gmp_doprnt_integer (funs, data, ¶m, gmp_str); + __GMP_FREE_FUNC_TYPE (gmp_str, strlen(gmp_str)+1, char); + DOPRNT_ACCUMULATE (ret); + va_copy (last_ap, ap); + last_fmt = fmt; + } + break; + default: + /* default is an "int", and this includes h=short and hh=char + since they're promoted to int in a function call */ + (void) va_arg (ap, int); + break; + } + goto next; + + case 'E': + param.base = -10; + param.expfmt = "E%c%02ld"; + /*FALLTHRU*/ + case 'e': + param.conv = DOPRNT_CONV_SCIENTIFIC; + floating: + if (param.showbase == DOPRNT_SHOWBASE_NONZERO) + { + /* # in %e, %f and %g */ + param.showpoint = 1; + param.showtrailing = 1; + } + floating_a: + switch (type) { + case 'F': + FLUSH (); + DOPRNT_ACCUMULATE (__gmp_doprnt_mpf (funs, data, ¶m, + GMP_DECIMAL_POINT, + va_arg (ap, mpf_srcptr))); + va_copy (last_ap, ap); + last_fmt = fmt; + break; + case 'L': +#if HAVE_LONG_DOUBLE + (void) va_arg (ap, long double); +#else + ASSERT_FAIL (long double not available); +#endif + break; + default: + (void) va_arg (ap, double); + break; + } + goto next; + + case 'f': + param.conv = DOPRNT_CONV_FIXED; + goto floating; + + case 'F': /* mpf_t */ + case 'j': /* intmax_t */ + case 'L': /* long long */ + case 'N': /* mpn */ + case 'q': /* quad_t */ + case 'Q': /* mpq_t */ + case 't': /* ptrdiff_t */ + case 'z': /* size_t */ + case 'Z': /* mpz_t */ + set_type: + type = fchar; + break; + + case 'G': + param.base = -10; + param.expfmt = "E%c%02ld"; + /*FALLTHRU*/ + case 'g': + param.conv = DOPRNT_CONV_GENERAL; + param.showtrailing = 0; + goto floating; + + case 'h': + if (type != 'h') + goto set_type; + type = 'H'; /* internal code for "hh" */ + break; + + case 'l': + if (type != 'l') + goto set_type; + type = 'L'; /* "ll" means "L" */ + break; + + case 'm': + /* glibc strerror(errno), no argument */ + goto next; + + case 'M': /* mp_limb_t */ + /* mung format string to l or ll and let plain printf handle it */ +#if _LONG_LONG_LIMB + memmove (fmt+1, fmt, strlen (fmt)+1); + fmt[-1] = 'l'; + fmt[0] = 'l'; + fmt++; + type = 'L'; +#else + fmt[-1] = 'l'; + type = 'l'; +#endif + break; + + case 'n': + { + void *p; + FLUSH (); + p = va_arg (ap, void *); + switch (type) { + case '\0': * (int *) p = retval; break; + case 'F': mpf_set_si ((mpf_ptr) p, (long) retval); break; + case 'H': * (char *) p = retval; break; + case 'h': * (short *) p = retval; break; +#if HAVE_INTMAX_T + case 'j': * (intmax_t *) p = retval; break; +#else + case 'j': ASSERT_FAIL (intmax_t not available); break; +#endif + case 'l': * (long *) p = retval; break; +#if HAVE_QUAD_T && HAVE_LONG_LONG + case 'q': + ASSERT_ALWAYS (sizeof (quad_t) == sizeof (long long)); + /*FALLTHRU*/ +#else + case 'q': ASSERT_FAIL (quad_t not available); break; +#endif +#if HAVE_LONG_LONG + case 'L': * (long long *) p = retval; break; +#else + case 'L': ASSERT_FAIL (long long not available); break; +#endif + case 'N': + { + mp_size_t n; + n = va_arg (ap, mp_size_t); + n = ABS (n); + if (n != 0) + { + * (mp_ptr) p = retval; + MPN_ZERO ((mp_ptr) p + 1, n - 1); + } + } + break; + case 'Q': mpq_set_si ((mpq_ptr) p, (long) retval, 1L); break; +#if HAVE_PTRDIFF_T + case 't': * (ptrdiff_t *) p = retval; break; +#else + case 't': ASSERT_FAIL (ptrdiff_t not available); break; +#endif + case 'z': * (size_t *) p = retval; break; + case 'Z': mpz_set_si ((mpz_ptr) p, (long) retval); break; + } + } + va_copy (last_ap, ap); + last_fmt = fmt; + goto next; + + case 'o': + param.base = 8; + goto integer; + + case 'p': + case 's': + /* "void *" will be good enough for "char *" or "wchar_t *", no + need for separate code. */ + (void) va_arg (ap, const void *); + goto next; + + case 'x': + param.base = 16; + goto integer; + case 'X': + param.base = -16; + goto integer; + + case '%': + goto next; + + case '#': + param.showbase = DOPRNT_SHOWBASE_NONZERO; + break; + + case '\'': + /* glibc digit grouping, just pass it through, no support for it + on gmp types */ + break; + + case '+': + case ' ': + param.sign = fchar; + break; + + case '-': + param.justify = DOPRNT_JUSTIFY_LEFT; + break; + case '.': + seen_precision = 1; + param.prec = -1; /* "." alone means all necessary digits */ + value = ¶m.prec; + break; + + case '*': + { + int n = va_arg (ap, int); + + if (value == ¶m.width) + { + /* negative width means left justify */ + if (n < 0) + { + param.justify = DOPRNT_JUSTIFY_LEFT; + n = -n; + } + param.width = n; + } + else + { + /* don't allow negative precision */ + param.prec = MAX (0, n); + } + } + break; + + case '0': + if (value == ¶m.width) + { + /* in width field, set fill */ + param.fill = '0'; + + /* for right justify, put the fill after any minus sign */ + if (param.justify == DOPRNT_JUSTIFY_RIGHT) + param.justify = DOPRNT_JUSTIFY_INTERNAL; + } + else + { + /* in precision field, set value */ + *value = 0; + } + break; + + case '1': case '2': case '3': case '4': case '5': + case '6': case '7': case '8': case '9': + /* process all digits to form a value */ + { + int n = 0; + do { + n = n * 10 + (fchar-'0'); + fchar = *fmt++; + } while (isascii (fchar) && isdigit (fchar)); + fmt--; /* unget the non-digit */ + *value = n; + } + break; + + default: + /* something invalid */ + ASSERT (0); + goto next; + } + } + + next: + /* Stop parsing the current "%" format, look for a new one. */ + ; + } + + TRACE (printf ("remainder: \"%s\"\n", last_fmt)); + if (*last_fmt != '\0') + DOPRNT_FORMAT (last_fmt, last_ap); + + if (funs->final != NULL) + if ((*funs->final) (data) == -1) + goto error; + + done: + __GMP_FREE_FUNC_TYPE (alloc_fmt, alloc_fmt_size, char); + return retval; + + error: + retval = -1; + goto done; +} diff --git a/Build/source/libs/gmp/gmp-src/printf/doprntf.c b/Build/source/libs/gmp/gmp-src/printf/doprntf.c new file mode 100644 index 00000000000..2a7e0d234fc --- /dev/null +++ b/Build/source/libs/gmp/gmp-src/printf/doprntf.c @@ -0,0 +1,389 @@ +/* __gmp_doprnt_mpf -- mpf formatted output. + + THE FUNCTIONS IN THIS FILE ARE FOR INTERNAL USE ONLY. THEY'RE ALMOST + CERTAIN TO BE SUBJECT TO INCOMPATIBLE CHANGES OR DISAPPEAR COMPLETELY IN + FUTURE GNU MP RELEASES. + +Copyright 2001, 2002, 2011 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library 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 copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include <stdarg.h> /* for va_list and hence doprnt_funs_t */ +#include <ctype.h> +#include <string.h> +#include <stdio.h> +#include <stdlib.h> + +#include "gmp-impl.h" +#include "longlong.h" + + +/* change this to "#define TRACE(x) x" for diagnostics */ +#define TRACE(x) + + +/* The separate of __gmp_doprnt_float_digits and __gmp_doprnt_float is so + some C++ can do the mpf_get_str and release it in case of an exception */ + +#define DIGIT_VALUE(c) \ + (isdigit (c) ? (c) - '0' \ + : islower (c) ? (c) - 'a' + 10 \ + : (c) - 'A' + 10) + +int +__gmp_doprnt_mpf (const struct doprnt_funs_t *funs, + void *data, + const struct doprnt_params_t *p, + const char *point, + mpf_srcptr f) +{ + int prec, ndigits, free_size, len, newlen, justify, justlen, explen; + int showbaselen, sign, signlen, intlen, intzeros, pointlen; + int fraczeros, fraclen, preczeros; + char *s, *free_ptr; + mp_exp_t exp; + char exponent[GMP_LIMB_BITS + 10]; + const char *showbase; + int retval = 0; + + TRACE (printf ("__gmp_doprnt_float\n"); + printf (" conv=%d prec=%d\n", p->conv, p->prec)); + + prec = p->prec; + if (prec <= -1) + { + /* all digits */ + ndigits = 0; + + /* arrange the fixed/scientific decision on a "prec" implied by how + many significant digits there are */ + if (p->conv == DOPRNT_CONV_GENERAL) + MPF_SIGNIFICANT_DIGITS (prec, PREC(f), ABS(p->base)); + } + else + { + switch (p->conv) { + case DOPRNT_CONV_FIXED: + /* Precision is digits after the radix point. Try not to generate + too many more than will actually be required. If f>=1 then + overestimate the integer part, and add prec. If f<1 then + underestimate the zeros between the radix point and the first + digit and subtract that from prec. In either case add 2 so the + round to nearest can be applied accurately. Finally, we add 1 to + handle the case of 1-eps where EXP(f) = 0 but mpf_get_str returns + exp as 1. */ + ndigits = prec + 2 + 1 + + EXP(f) * (mp_bases[ABS(p->base)].chars_per_limb + (EXP(f)>=0)); + ndigits = MAX (ndigits, 1); + break; + + case DOPRNT_CONV_SCIENTIFIC: + /* precision is digits after the radix point, and there's one digit + before */ + ndigits = prec + 1; + break; + + default: + ASSERT (0); + /*FALLTHRU*/ + + case DOPRNT_CONV_GENERAL: + /* precision is total digits, but be sure to ask mpf_get_str for at + least 1, not 0 */ + ndigits = MAX (prec, 1); + break; + } + } + TRACE (printf (" ndigits %d\n", ndigits)); + + s = mpf_get_str (NULL, &exp, p->base, ndigits, f); + len = strlen (s); + free_ptr = s; + free_size = len + 1; + TRACE (printf (" s %s\n", s); + printf (" exp %ld\n", exp); + printf (" len %d\n", len)); + + /* For fixed mode check the ndigits formed above was in fact enough for + the integer part plus p->prec after the radix point. */ + ASSERT ((p->conv == DOPRNT_CONV_FIXED && p->prec > -1) + ? ndigits >= MAX (1, exp + p->prec + 2) : 1); + + sign = p->sign; + if (s[0] == '-') + { + sign = s[0]; + s++, len--; + } + signlen = (sign != '\0'); + TRACE (printf (" sign %c signlen %d\n", sign, signlen)); + + switch (p->conv) { + case DOPRNT_CONV_FIXED: + if (prec <= -1) + prec = MAX (0, len-exp); /* retain all digits */ + + /* Truncate if necessary so fraction will be at most prec digits. */ + ASSERT (prec >= 0); + newlen = exp + prec; + if (newlen < 0) + { + /* first non-zero digit is below target prec, and at least one zero + digit in between, so print zero */ + len = 0; + exp = 0; + } + else if (len <= newlen) + { + /* already got few enough digits */ + } + else + { + /* discard excess digits and round to nearest */ + + const char *num_to_text = (p->base >= 0 + ? "0123456789abcdefghijklmnopqrstuvwxyz" + : "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"); + int base = ABS(p->base); + int n; + + ASSERT (base <= 36); + + len = newlen; + n = DIGIT_VALUE (s[len]); + TRACE (printf (" rounding with %d\n", n)); + if (n >= (base + 1) / 2) + { + /* propagate a carry */ + for (;;) + { + if (len == 0) + { + s[0] = '1'; + len = 1; + exp++; + break; + } + n = DIGIT_VALUE (s[len-1]); + ASSERT (n >= 0 && n < base); + n++; + if (n != base) + { + TRACE (printf (" storing now %d\n", n)); + s[len-1] = num_to_text[n]; + break; + } + len--; + } + } + else + { + /* truncate only, strip any trailing zeros now exposed */ + while (len > 0 && s[len-1] == '0') + len--; + } + + /* Can have newlen==0, in which case the truncate was just to check + for a carry turning it into "1". If we're left with len==0 then + adjust exp to match. */ + if (len == 0) + exp = 0; + } + + fixed: + ASSERT (len == 0 ? exp == 0 : 1); + if (exp <= 0) + { + TRACE (printf (" fixed 0.000sss\n")); + intlen = 0; + intzeros = 1; + fraczeros = -exp; + fraclen = len; + } + else + { + TRACE (printf (" fixed sss.sss or sss000\n")); + intlen = MIN (len, exp); + intzeros = exp - intlen; + fraczeros = 0; + fraclen = len - intlen; + } + explen = 0; + break; + + case DOPRNT_CONV_SCIENTIFIC: + { + long int expval; + char expsign; + + if (prec <= -1) + prec = MAX (0, len-1); /* retain all digits */ + + scientific: + TRACE (printf (" scientific s.sss\n")); + + intlen = MIN (1, len); + intzeros = (intlen == 0 ? 1 : 0); + fraczeros = 0; + fraclen = len - intlen; + + expval = (exp-intlen); + if (p->exptimes4) + expval <<= 2; + + /* Split out the sign since %o or %x in expfmt give negatives as twos + complement, not with a sign. */ + expsign = (expval >= 0 ? '+' : '-'); + expval = ABS (expval); + +#if HAVE_VSNPRINTF + explen = snprintf (exponent, sizeof(exponent), + p->expfmt, expsign, expval); + /* test for < sizeof-1 since a glibc 2.0.x return of sizeof-1 might + mean truncation */ + ASSERT (explen >= 0 && explen < sizeof(exponent)-1); +#else + sprintf (exponent, p->expfmt, expsign, expval); + explen = strlen (exponent); + ASSERT (explen < sizeof(exponent)); +#endif + TRACE (printf (" expfmt %s gives %s\n", p->expfmt, exponent)); + } + break; + + default: + ASSERT (0); + /*FALLTHRU*/ /* to stop variables looking uninitialized */ + + case DOPRNT_CONV_GENERAL: + /* The exponent for "scientific" will be exp-1, choose scientific if + this is < -4 or >= prec (and minimum 1 for prec). For f==0 will have + exp==0 and get the desired "fixed". This rule follows glibc. For + fixed there's no need to truncate, the desired ndigits will already + be as required. */ + if (exp-1 < -4 || exp-1 >= MAX (1, prec)) + goto scientific; + else + goto fixed; + } + + TRACE (printf (" intlen %d intzeros %d fraczeros %d fraclen %d\n", + intlen, intzeros, fraczeros, fraclen)); + ASSERT (p->prec <= -1 + ? intlen + fraclen == strlen (s) + : intlen + fraclen <= strlen (s)); + + if (p->showtrailing) + { + /* Pad to requested precision with trailing zeros, for general this is + all digits, for fixed and scientific just the fraction. */ + preczeros = prec - (fraczeros + fraclen + + (p->conv == DOPRNT_CONV_GENERAL + ? intlen + intzeros : 0)); + preczeros = MAX (0, preczeros); + } + else + preczeros = 0; + TRACE (printf (" prec=%d showtrailing=%d, pad with preczeros %d\n", + prec, p->showtrailing, preczeros)); + + /* radix point if needed, or if forced */ + pointlen = ((fraczeros + fraclen + preczeros) != 0 || p->showpoint != 0) + ? strlen (point) : 0; + TRACE (printf (" point |%s| pointlen %d\n", point, pointlen)); + + /* Notice the test for a non-zero value is done after any truncation for + DOPRNT_CONV_FIXED. */ + showbase = NULL; + showbaselen = 0; + switch (p->showbase) { + default: + ASSERT (0); + /*FALLTHRU*/ + case DOPRNT_SHOWBASE_NO: + break; + case DOPRNT_SHOWBASE_NONZERO: + if (intlen == 0 && fraclen == 0) + break; + /*FALLTHRU*/ + case DOPRNT_SHOWBASE_YES: + switch (p->base) { + case 16: showbase = "0x"; showbaselen = 2; break; + case -16: showbase = "0X"; showbaselen = 2; break; + case 8: showbase = "0"; showbaselen = 1; break; + } + break; + } + TRACE (printf (" showbase %s showbaselen %d\n", + showbase == NULL ? "" : showbase, showbaselen)); + + /* left over field width */ + justlen = p->width - (signlen + showbaselen + intlen + intzeros + pointlen + + fraczeros + fraclen + preczeros + explen); + TRACE (printf (" justlen %d fill 0x%X\n", justlen, p->fill)); + + justify = p->justify; + if (justlen <= 0) /* no justifying if exceed width */ + justify = DOPRNT_JUSTIFY_NONE; + + TRACE (printf (" justify type %d intlen %d pointlen %d fraclen %d\n", + justify, intlen, pointlen, fraclen)); + + if (justify == DOPRNT_JUSTIFY_RIGHT) /* pad for right */ + DOPRNT_REPS (p->fill, justlen); + + if (signlen) /* sign */ + DOPRNT_REPS (sign, 1); + + DOPRNT_MEMORY_MAYBE (showbase, showbaselen); /* base */ + + if (justify == DOPRNT_JUSTIFY_INTERNAL) /* pad for internal */ + DOPRNT_REPS (p->fill, justlen); + + DOPRNT_MEMORY (s, intlen); /* integer */ + DOPRNT_REPS_MAYBE ('0', intzeros); + + DOPRNT_MEMORY_MAYBE (point, pointlen); /* point */ + + DOPRNT_REPS_MAYBE ('0', fraczeros); /* frac */ + DOPRNT_MEMORY_MAYBE (s+intlen, fraclen); + + DOPRNT_REPS_MAYBE ('0', preczeros); /* prec */ + + DOPRNT_MEMORY_MAYBE (exponent, explen); /* exp */ + + if (justify == DOPRNT_JUSTIFY_LEFT) /* pad for left */ + DOPRNT_REPS (p->fill, justlen); + + done: + __GMP_FREE_FUNC_TYPE (free_ptr, free_size, char); + return retval; + + error: + retval = -1; + goto done; +} diff --git a/Build/source/libs/gmp/gmp-src/printf/doprnti.c b/Build/source/libs/gmp/gmp-src/printf/doprnti.c new file mode 100644 index 00000000000..61ff64326eb --- /dev/null +++ b/Build/source/libs/gmp/gmp-src/printf/doprnti.c @@ -0,0 +1,136 @@ +/* __gmp_doprnt_integer -- integer style formatted output. + + THE FUNCTIONS IN THIS FILE ARE FOR INTERNAL USE ONLY. THEY'RE ALMOST + CERTAIN TO BE SUBJECT TO INCOMPATIBLE CHANGES OR DISAPPEAR COMPLETELY IN + FUTURE GNU MP RELEASES. + +Copyright 2001 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library 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 copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include <stdarg.h> /* for va_list and hence doprnt_funs_t */ +#include <string.h> +#include <stdio.h> +#include <stdlib.h> + +#include "gmp-impl.h" + + +int +__gmp_doprnt_integer (const struct doprnt_funs_t *funs, + void *data, + const struct doprnt_params_t *p, + const char *s) +{ + int retval = 0; + int slen, justlen, showbaselen, sign, signlen, slashlen, zeros; + int justify, den_showbaselen; + const char *slash, *showbase; + + /* '+' or ' ' if wanted, and don't already have '-' */ + sign = p->sign; + if (s[0] == '-') + { + sign = s[0]; + s++; + } + signlen = (sign != '\0'); + + /* if the precision was explicitly 0, print nothing for a 0 value */ + if (*s == '0' && p->prec == 0) + s++; + + slen = strlen (s); + slash = strchr (s, '/'); + + showbase = NULL; + showbaselen = 0; + + if (p->showbase != DOPRNT_SHOWBASE_NO) + { + switch (p->base) { + case 16: showbase = "0x"; showbaselen = 2; break; + case -16: showbase = "0X"; showbaselen = 2; break; + case 8: showbase = "0"; showbaselen = 1; break; + } + } + + den_showbaselen = showbaselen; + if (slash == NULL + || (p->showbase == DOPRNT_SHOWBASE_NONZERO && slash[1] == '0')) + den_showbaselen = 0; + + if (p->showbase == DOPRNT_SHOWBASE_NONZERO && s[0] == '0') + showbaselen = 0; + + /* the influence of p->prec on mpq is currently undefined */ + zeros = MAX (0, p->prec - slen); + + /* space left over after actual output length */ + justlen = p->width + - (strlen(s) + signlen + showbaselen + den_showbaselen + zeros); + + justify = p->justify; + if (justlen <= 0) /* no justifying if exceed width */ + justify = DOPRNT_JUSTIFY_NONE; + + if (justify == DOPRNT_JUSTIFY_RIGHT) /* pad right */ + DOPRNT_REPS (p->fill, justlen); + + DOPRNT_REPS_MAYBE (sign, signlen); /* sign */ + + DOPRNT_MEMORY_MAYBE (showbase, showbaselen); /* base */ + + DOPRNT_REPS_MAYBE ('0', zeros); /* zeros */ + + if (justify == DOPRNT_JUSTIFY_INTERNAL) /* pad internal */ + DOPRNT_REPS (p->fill, justlen); + + /* if there's a showbase on the denominator, then print the numerator + separately so it can be inserted */ + if (den_showbaselen != 0) + { + ASSERT (slash != NULL); + slashlen = slash+1 - s; + DOPRNT_MEMORY (s, slashlen); /* numerator and slash */ + slen -= slashlen; + s += slashlen; + DOPRNT_MEMORY (showbase, den_showbaselen); + } + + DOPRNT_MEMORY (s, slen); /* number, or denominator */ + + if (justify == DOPRNT_JUSTIFY_LEFT) /* pad left */ + DOPRNT_REPS (p->fill, justlen); + + done: + return retval; + + error: + retval = -1; + goto done; +} diff --git a/Build/source/libs/gmp/gmp-src/printf/fprintf.c b/Build/source/libs/gmp/gmp-src/printf/fprintf.c new file mode 100644 index 00000000000..0008b3b6dcc --- /dev/null +++ b/Build/source/libs/gmp/gmp-src/printf/fprintf.c @@ -0,0 +1,48 @@ +/* gmp_fprintf -- formatted output. + +Copyright 2001 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library 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 copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include <stdarg.h> +#include <stdio.h> + +#include "gmp-impl.h" + + +int +gmp_fprintf (FILE *fp, const char *fmt, ...) +{ + va_list ap; + int ret; + + va_start (ap, fmt); + + ret = __gmp_doprnt (&__gmp_fprintf_funs, fp, fmt, ap); + va_end (ap); + return ret; +} diff --git a/Build/source/libs/gmp/gmp-src/printf/obprintf.c b/Build/source/libs/gmp/gmp-src/printf/obprintf.c new file mode 100644 index 00000000000..c12d6de6c94 --- /dev/null +++ b/Build/source/libs/gmp/gmp-src/printf/obprintf.c @@ -0,0 +1,60 @@ +/* gmp_obstack_printf -- formatted output to an obstack. + +Copyright 2001, 2002, 2018 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library 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 copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "config.h" + +#if HAVE_OBSTACK_VPRINTF + +#include <stdarg.h> +#include <obstack.h> +#include <string.h> + +#include "gmp-impl.h" + + +int +gmp_obstack_printf (struct obstack *ob, const char *fmt, ...) +{ + va_list ap; + int ret; + + va_start (ap, fmt); + + ASSERT (! MEM_OVERLAP_P (obstack_base(ob), obstack_object_size(ob), + fmt, strlen(fmt)+1)); + + ret = __gmp_doprnt (&__gmp_obstack_printf_funs, ob, fmt, ap); + va_end (ap); + return ret; +} + +#else +typedef int __gmp_dummy_typedef; +#endif /* HAVE_OBSTACK_VPRINTF */ diff --git a/Build/source/libs/gmp/gmp-src/printf/obprntffuns.c b/Build/source/libs/gmp/gmp-src/printf/obprntffuns.c new file mode 100644 index 00000000000..a23e4e85f3c --- /dev/null +++ b/Build/source/libs/gmp/gmp-src/printf/obprntffuns.c @@ -0,0 +1,73 @@ +/* __gmp_obstack_printf_funs -- support for gmp_obstack_printf and + gmp_obstack_vprintf. + + THE FUNCTIONS IN THIS FILE ARE FOR INTERNAL USE ONLY. THEY'RE ALMOST + CERTAIN TO BE SUBJECT TO INCOMPATIBLE CHANGES OR DISAPPEAR COMPLETELY IN + FUTURE GNU MP RELEASES. + +Copyright 2001, 2018 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library 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 copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "config.h" + +#if HAVE_OBSTACK_VPRINTF + +#define _GNU_SOURCE /* ask glibc <stdio.h> for obstack_vprintf */ + +#include <stdarg.h> +#include <stdio.h> /* for obstack_vprintf */ +#include <string.h> +#include <obstack.h> + +#include "gmp-impl.h" + + +static int +gmp_obstack_memory (struct obstack *ob, const char *ptr, size_t len) +{ + obstack_grow (ob, ptr, len); + return len; +} + +static int +gmp_obstack_reps (struct obstack *ob, int c, int reps) +{ + obstack_blank (ob, reps); + memset ((char *) obstack_next_free(ob) - reps, c, reps); + return reps; +} + +const struct doprnt_funs_t __gmp_obstack_printf_funs = { + (doprnt_format_t) obstack_vprintf, + (doprnt_memory_t) gmp_obstack_memory, + (doprnt_reps_t) gmp_obstack_reps +}; + +#else +typedef int __gmp_dummy_typedef; +#endif /* HAVE_OBSTACK_VPRINTF */ diff --git a/Build/source/libs/gmp/gmp-src/printf/obvprintf.c b/Build/source/libs/gmp/gmp-src/printf/obvprintf.c new file mode 100644 index 00000000000..7563c111e7c --- /dev/null +++ b/Build/source/libs/gmp/gmp-src/printf/obvprintf.c @@ -0,0 +1,53 @@ +/* gmp_obstack_vprintf -- formatted output to an obstack. + +Copyright 2001, 2002, 2018 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library 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 copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "config.h" + +#if HAVE_OBSTACK_VPRINTF + +#include <stdarg.h> +#include <obstack.h> +#include <string.h> + +#include "gmp-impl.h" + + +int +gmp_obstack_vprintf (struct obstack *ob, const char *fmt, va_list ap) +{ + ASSERT (! MEM_OVERLAP_P (obstack_base(ob), obstack_object_size(ob), + fmt, strlen(fmt)+1)); + + return __gmp_doprnt (&__gmp_obstack_printf_funs, ob, fmt, ap); +} + +#else +typedef int __gmp_dummy_typedef; +#endif /* HAVE_OBSTACK_VPRINTF */ diff --git a/Build/source/libs/gmp/gmp-src/printf/printf.c b/Build/source/libs/gmp/gmp-src/printf/printf.c new file mode 100644 index 00000000000..4becb0b21c6 --- /dev/null +++ b/Build/source/libs/gmp/gmp-src/printf/printf.c @@ -0,0 +1,48 @@ +/* gmp_printf -- formatted output. + +Copyright 2001 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library 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 copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include <stdarg.h> +#include <stdio.h> + +#include "gmp-impl.h" + + +int +gmp_printf (const char *fmt, ...) +{ + va_list ap; + int ret; + + va_start (ap, fmt); + + ret = __gmp_doprnt (&__gmp_fprintf_funs, stdout, fmt, ap); + va_end (ap); + return ret; +} diff --git a/Build/source/libs/gmp/gmp-src/printf/printffuns.c b/Build/source/libs/gmp/gmp-src/printf/printffuns.c new file mode 100644 index 00000000000..957381d4c25 --- /dev/null +++ b/Build/source/libs/gmp/gmp-src/printf/printffuns.c @@ -0,0 +1,79 @@ +/* __gmp_fprintf_funs -- support for formatted output to FILEs. + + THE FUNCTIONS IN THIS FILE ARE FOR INTERNAL USE ONLY. THEY'RE ALMOST + CERTAIN TO BE SUBJECT TO INCOMPATIBLE CHANGES OR DISAPPEAR COMPLETELY IN + FUTURE GNU MP RELEASES. + +Copyright 2001 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library 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 copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include <stdarg.h> +#include <stdio.h> +#include <string.h> + +#include "gmp-impl.h" + +/* SunOS 4 stdio.h doesn't provide a prototype for this */ +#if ! HAVE_DECL_VFPRINTF +int vfprintf (FILE *, const char *, va_list); +#endif + + +static int +gmp_fprintf_memory (FILE *fp, const char *str, size_t len) +{ + return fwrite (str, 1, len, fp); +} + +/* glibc putc is a function, at least when it's in multi-threaded mode or + some such, so fwrite chunks instead of making many calls. */ +static int +gmp_fprintf_reps (FILE *fp, int c, int reps) +{ + char buf[256]; + int i, piece, ret; + ASSERT (reps >= 0); + + memset (buf, c, MIN (reps, sizeof (buf))); + for (i = reps; i > 0; i -= sizeof (buf)) + { + piece = MIN (i, sizeof (buf)); + ret = fwrite (buf, 1, piece, fp); + if (ret == -1) + return ret; + ASSERT (ret == piece); + } + + return reps; +} + +const struct doprnt_funs_t __gmp_fprintf_funs = { + (doprnt_format_t) vfprintf, + (doprnt_memory_t) gmp_fprintf_memory, + (doprnt_reps_t) gmp_fprintf_reps, +}; diff --git a/Build/source/libs/gmp/gmp-src/printf/repl-vsnprintf.c b/Build/source/libs/gmp/gmp-src/printf/repl-vsnprintf.c new file mode 100644 index 00000000000..d2286712218 --- /dev/null +++ b/Build/source/libs/gmp/gmp-src/printf/repl-vsnprintf.c @@ -0,0 +1,394 @@ +/* __gmp_replacement_vsnprintf -- for systems which don't have vsnprintf, or + only have a broken one. + + THE FUNCTIONS IN THIS FILE ARE FOR INTERNAL USE ONLY. THEY'RE ALMOST + CERTAIN TO BE SUBJECT TO INCOMPATIBLE CHANGES OR DISAPPEAR COMPLETELY IN + FUTURE GNU MP RELEASES. + +Copyright 2001, 2002, 2018 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library 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 copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "config.h" + +#define _GNU_SOURCE /* for strnlen prototype */ + +#include <stdarg.h> +#include <ctype.h> /* for isdigit */ +#include <stddef.h> /* for ptrdiff_t */ +#include <string.h> +#include <stdio.h> /* for NULL */ +#include <stdlib.h> + +#if HAVE_FLOAT_H +#include <float.h> /* for DBL_MAX_10_EXP etc */ +#endif + +#if HAVE_INTTYPES_H +# include <inttypes.h> /* for intmax_t */ +#else +# if HAVE_STDINT_H +# include <stdint.h> +# endif +#endif + +#if HAVE_SYS_TYPES_H +#include <sys/types.h> /* for quad_t */ +#endif + +#include "gmp-impl.h" + + +#if ! HAVE_VSNPRINTF /* only need this file if we don't have vsnprintf */ + +/* Autoconf notes that AIX 4.3 has a broken strnlen, but fortunately it + doesn't affect us since __gmp_replacement_vsnprintf is not required on + that system. */ +#if ! HAVE_STRNLEN +static size_t +strnlen (const char *s, size_t n) +{ + size_t i; + for (i = 0; i < n; i++) + if (s[i] == '\0') + break; + return i; +} +#endif + + +/* The approach here is to parse the fmt string, and decide how much space + it requires, then use vsprintf into a big enough buffer. The space + calculated isn't an exact amount, but it's certainly no less than + required. + + This code was inspired by GNU libiberty/vasprintf.c but we support more + datatypes, when available. + + mingw32 - doesn't have vsnprintf, it seems. Because gcc is used a full + set of types are available, but "long double" is just a plain IEEE + 64-bit "double" and LDBL_MAX_EXP_10 is correspondingly defined, so we + avoid the big 15-bit exponent estimate. */ + +int +__gmp_replacement_vsnprintf (char *buf, size_t buf_size, + const char *orig_fmt, va_list orig_ap) +{ + va_list ap; + const char *fmt; + size_t total_width, integer_sizeof, floating_sizeof, len; + char fchar, type; + int width, prec, seen_prec, double_digits, long_double_digits; + int *value; + + /* preserve orig_ap for use after size estimation */ + va_copy (ap, orig_ap); + + fmt = orig_fmt; + total_width = strlen (fmt) + 1; /* 1 extra for the '\0' */ + + integer_sizeof = sizeof (long); +#if HAVE_LONG_LONG + integer_sizeof = MAX (integer_sizeof, sizeof (long long)); +#endif +#if HAVE_QUAD_T + integer_sizeof = MAX (integer_sizeof, sizeof (quad_t)); +#endif + + floating_sizeof = sizeof (double); +#if HAVE_LONG_DOUBLE + floating_sizeof = MAX (floating_sizeof, sizeof (long double)); +#endif + + /* IEEE double or VAX G floats have an 11 bit exponent, so the default is + a maximum 308 decimal digits. VAX D floats have only an 8 bit + exponent, but we don't bother trying to detect that directly. */ + double_digits = 308; +#ifdef DBL_MAX_10_EXP + /* but in any case prefer a value the compiler says */ + double_digits = DBL_MAX_10_EXP; +#endif + + /* IEEE 128-bit quad, Intel 80-bit temporary, or VAX H floats all have 15 + bit exponents, so the default is a maximum 4932 decimal digits. */ + long_double_digits = 4932; + /* but if double == long double, then go with that size */ +#if HAVE_LONG_DOUBLE + if (sizeof (double) == sizeof (long double)) + long_double_digits = double_digits; +#endif +#ifdef LDBL_MAX_10_EXP + /* but in any case prefer a value the compiler says */ + long_double_digits = LDBL_MAX_10_EXP; +#endif + + for (;;) + { + fmt = strchr (fmt, '%'); + if (fmt == NULL) + break; + fmt++; + + type = '\0'; + width = 0; + prec = 6; + seen_prec = 0; + value = &width; + + for (;;) + { + fchar = *fmt++; + switch (fchar) { + + case 'c': + /* char, already accounted for by strlen(fmt) */ + goto next; + + case 'd': + case 'i': + case 'o': + case 'x': + case 'X': + case 'u': + /* at most 3 digits per byte in hex, dec or octal, plus a sign */ + total_width += 3 * integer_sizeof + 1; + + switch (type) { + case 'j': + /* Let's assume uintmax_t is the same size as intmax_t. */ +#if HAVE_INTMAX_T + (void) va_arg (ap, intmax_t); +#else + ASSERT_FAIL (intmax_t not available); +#endif + break; + case 'l': + (void) va_arg (ap, long); + break; + case 'L': +#if HAVE_LONG_LONG + (void) va_arg (ap, long long); +#else + ASSERT_FAIL (long long not available); +#endif + break; + case 'q': + /* quad_t is probably the same as long long, but let's treat + it separately just to be sure. Also let's assume u_quad_t + will be the same size as quad_t. */ +#if HAVE_QUAD_T + (void) va_arg (ap, quad_t); +#else + ASSERT_FAIL (quad_t not available); +#endif + break; + case 't': +#if HAVE_PTRDIFF_T + (void) va_arg (ap, ptrdiff_t); +#else + ASSERT_FAIL (ptrdiff_t not available); +#endif + break; + case 'z': + (void) va_arg (ap, size_t); + break; + default: + /* default is an "int", and this includes h=short and hh=char + since they're promoted to int in a function call */ + (void) va_arg (ap, int); + break; + } + goto next; + + case 'E': + case 'e': + case 'G': + case 'g': + /* Requested decimals, sign, point and e, plus an overestimate + of exponent digits (the assumption is all the float is + exponent!). */ + total_width += prec + 3 + floating_sizeof * 3; + if (type == 'L') + { +#if HAVE_LONG_DOUBLE + (void) va_arg (ap, long double); +#else + ASSERT_FAIL (long double not available); +#endif + } + else + (void) va_arg (ap, double); + goto next; + + case 'f': + /* Requested decimals, sign and point, and a margin for error, + then add the maximum digits that can be in the integer part, + based on the maximum exponent value. */ + total_width += prec + 2 + 10; + if (type == 'L') + { +#if HAVE_LONG_DOUBLE + (void) va_arg (ap, long double); + total_width += long_double_digits; +#else + ASSERT_FAIL (long double not available); +#endif + } + else + { + (void) va_arg (ap, double); + total_width += double_digits; + } + goto next; + + case 'h': /* short or char */ + case 'j': /* intmax_t */ + case 'L': /* long long or long double */ + case 'q': /* quad_t */ + case 't': /* ptrdiff_t */ + case 'z': /* size_t */ + set_type: + type = fchar; + break; + + case 'l': + /* long or long long */ + if (type != 'l') + goto set_type; + type = 'L'; /* "ll" means "L" */ + break; + + case 'n': + /* bytes written, no output as such */ + (void) va_arg (ap, void *); + goto next; + + case 's': + /* If no precision was given, then determine the string length + and put it there, to be added to the total under "next". If + a precision was given then that's already the maximum from + this field, but see whether the string is shorter than that, + in case the limit was very big. */ + { + const char *s = va_arg (ap, const char *); + prec = (seen_prec ? strnlen (s, prec) : strlen (s)); + } + goto next; + + case 'p': + /* pointer, let's assume at worst it's octal with some padding */ + (void) va_arg (ap, const void *); + total_width += 3 * sizeof (void *) + 16; + goto next; + + case '%': + /* literal %, already accounted for by strlen(fmt) */ + goto next; + + case '#': + /* showbase, at most 2 for "0x" */ + total_width += 2; + break; + + case '+': + case ' ': + /* sign, already accounted for under numerics */ + break; + + case '-': + /* left justify, no effect on total width */ + break; + + case '.': + seen_prec = 1; + value = ≺ + break; + + case '*': + { + /* negative width means left justify which can be ignored, + negative prec would be invalid, just use absolute value */ + int n = va_arg (ap, int); + *value = ABS (n); + } + break; + + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + /* process all digits to form a value */ + { + int n = 0; + do { + n = n * 10 + (fchar-'0'); + fchar = *fmt++; + } while (isascii (fchar) && isdigit (fchar)); + fmt--; /* unget the non-digit */ + *value = n; + } + break; + + default: + /* incomplete or invalid % sequence */ + ASSERT (0); + goto next; + } + } + + next: + total_width += width; + total_width += prec; + } + + if (total_width <= buf_size) + { + vsprintf (buf, orig_fmt, orig_ap); + len = strlen (buf); + } + else + { + char *s; + + s = __GMP_ALLOCATE_FUNC_TYPE (total_width, char); + vsprintf (s, orig_fmt, orig_ap); + len = strlen (s); + if (buf_size != 0) + { + size_t copylen = MIN (len, buf_size-1); + memcpy (buf, s, copylen); + buf[copylen] = '\0'; + } + __GMP_FREE_FUNC_TYPE (s, total_width, char); + } + + /* If total_width was somehow wrong then chances are we've already + clobbered memory, but maybe this check will still work. */ + ASSERT_ALWAYS (len < total_width); + + return len; +} + +#endif /* ! HAVE_VSNPRINTF */ diff --git a/Build/source/libs/gmp/gmp-src/printf/snprintf.c b/Build/source/libs/gmp/gmp-src/printf/snprintf.c new file mode 100644 index 00000000000..8da33f81c85 --- /dev/null +++ b/Build/source/libs/gmp/gmp-src/printf/snprintf.c @@ -0,0 +1,53 @@ +/* gmp_snprintf -- formatted output to an fixed size buffer. + +Copyright 2001 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library 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 copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include <stdarg.h> +#include <string.h> /* for strlen */ + +#include "gmp-impl.h" + + +int +gmp_snprintf (char *buf, size_t size, const char *fmt, ...) +{ + struct gmp_snprintf_t d; + va_list ap; + int ret; + + va_start (ap, fmt); + d.buf = buf; + d.size = size; + + ASSERT (! MEM_OVERLAP_P (buf, size, fmt, strlen(fmt)+1)); + + ret = __gmp_doprnt (&__gmp_snprintf_funs, &d, fmt, ap); + va_end (ap); + return ret; +} diff --git a/Build/source/libs/gmp/gmp-src/printf/snprntffuns.c b/Build/source/libs/gmp/gmp-src/printf/snprntffuns.c new file mode 100644 index 00000000000..885c7ab57e9 --- /dev/null +++ b/Build/source/libs/gmp/gmp-src/printf/snprntffuns.c @@ -0,0 +1,157 @@ +/* __gmp_snprintf_funs -- support for gmp_snprintf and gmp_vsnprintf. + + THE FUNCTIONS IN THIS FILE ARE FOR INTERNAL USE ONLY. THEY'RE ALMOST + CERTAIN TO BE SUBJECT TO INCOMPATIBLE CHANGES OR DISAPPEAR COMPLETELY IN + FUTURE GNU MP RELEASES. + +Copyright 2001, 2002, 2018 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library 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 copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include <stdarg.h> +#include <stdio.h> +#include <string.h> + +#include "gmp-impl.h" + + +#if ! HAVE_VSNPRINTF +#define vsnprintf __gmp_replacement_vsnprintf +#endif + + +/* glibc 2.0.x vsnprintf returns either -1 or size-1 for an overflow, with + no indication how big the output would have been. It's necessary to + re-run to determine that size. + + "size-1" would mean success from a C99 vsnprintf, and the re-run is + unnecessary in this case, but we don't bother to try to detect what sort + of vsnprintf we've got. size-1 should occur rarely in normal + circumstances. + + vsnprintf might trash it's given ap (it does for instance in glibc 2.1.3 + on powerpc), so copy it in case we need to use it to probe for the size + output that would have been produced. Note there's no need to preserve + it for our callers, just for ourselves. */ + +static int +gmp_snprintf_format (struct gmp_snprintf_t *d, const char *fmt, + va_list orig_ap) +{ + int ret; + size_t step, alloc, avail; + va_list ap; + char *p; + + ASSERT (d->size >= 0); + + avail = d->size; + if (avail > 1) + { + va_copy (ap, orig_ap); + ret = vsnprintf (d->buf, avail, fmt, ap); + if (ret == -1) + return ret; + + step = MIN (ret, avail-1); + d->size -= step; + d->buf += step; + + if (ret != avail-1) + return ret; + + /* probably glibc 2.0.x truncated output, probe for actual size */ + alloc = MAX (128, ret); + } + else + { + /* no space to write anything, just probe for size */ + alloc = 128; + } + + do + { + alloc *= 2; + p = __GMP_ALLOCATE_FUNC_TYPE (alloc, char); + va_copy (ap, orig_ap); + ret = vsnprintf (p, alloc, fmt, ap); + __GMP_FREE_FUNC_TYPE (p, alloc, char); + } + while (ret == alloc-1); + + return ret; +} + +static int +gmp_snprintf_memory (struct gmp_snprintf_t *d, const char *str, size_t len) +{ + size_t n; + + ASSERT (d->size >= 0); + + if (d->size > 1) + { + n = MIN (d->size-1, len); + memcpy (d->buf, str, n); + d->buf += n; + d->size -= n; + } + return len; +} + +static int +gmp_snprintf_reps (struct gmp_snprintf_t *d, int c, int reps) +{ + size_t n; + + ASSERT (reps >= 0); + ASSERT (d->size >= 0); + + if (d->size > 1) + { + n = MIN (d->size-1, reps); + memset (d->buf, c, n); + d->buf += n; + d->size -= n; + } + return reps; +} + +static int +gmp_snprintf_final (struct gmp_snprintf_t *d) +{ + if (d->size >= 1) + d->buf[0] = '\0'; + return 0; +} + +const struct doprnt_funs_t __gmp_snprintf_funs = { + (doprnt_format_t) gmp_snprintf_format, + (doprnt_memory_t) gmp_snprintf_memory, + (doprnt_reps_t) gmp_snprintf_reps, + (doprnt_final_t) gmp_snprintf_final +}; diff --git a/Build/source/libs/gmp/gmp-src/printf/sprintf.c b/Build/source/libs/gmp/gmp-src/printf/sprintf.c new file mode 100644 index 00000000000..0952a5334ce --- /dev/null +++ b/Build/source/libs/gmp/gmp-src/printf/sprintf.c @@ -0,0 +1,54 @@ +/* gmp_sprintf -- formatted output to an unrestricted string. + +Copyright 2001 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library 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 copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include <stdarg.h> +#include <string.h> /* for strlen */ + +#include "gmp-impl.h" + + +int +gmp_sprintf (char *buf, const char *fmt, ...) +{ +#if WANT_ASSERT + int fmtlen = strlen(fmt); +#endif + va_list ap; + int ret; + + va_start (ap, fmt); + + ret = __gmp_doprnt (&__gmp_sprintf_funs, &buf, fmt, ap); + va_end (ap); + + ASSERT (! MEM_OVERLAP_P (buf, strlen(buf)+1, fmt, fmtlen+1)); + + return ret; +} diff --git a/Build/source/libs/gmp/gmp-src/printf/sprintffuns.c b/Build/source/libs/gmp/gmp-src/printf/sprintffuns.c new file mode 100644 index 00000000000..6781f258286 --- /dev/null +++ b/Build/source/libs/gmp/gmp-src/printf/sprintffuns.c @@ -0,0 +1,94 @@ +/* __gmp_sprintf_funs -- support for gmp_sprintf and gmp_vsprintf. + + THE FUNCTIONS IN THIS FILE ARE FOR INTERNAL USE ONLY. THEY'RE ALMOST + CERTAIN TO BE SUBJECT TO INCOMPATIBLE CHANGES OR DISAPPEAR COMPLETELY IN + FUTURE GNU MP RELEASES. + +Copyright 2001 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library 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 copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "gmp-impl.h" + + +/* The data parameter "bufp" points to a "char *buf" which is the next + character to be written, having started as the destination from the + application. This is then increased each time output is produced. */ + + +/* If vsprintf returns -1 then pass it upwards. It doesn't matter that + "*bufp" is ruined in this case, since gmp_doprint will bail out + immediately anyway. */ +static int +gmp_sprintf_format (char **bufp, const char *fmt, va_list ap) +{ + char *buf = *bufp; + int ret; + vsprintf (buf, fmt, ap); + ret = strlen (buf); + *bufp = buf + ret; + return ret; +} + +static int +gmp_sprintf_memory (char **bufp, const char *str, size_t len) +{ + char *buf = *bufp; + *bufp = buf + len; + memcpy (buf, str, len); + return len; +} + +static int +gmp_sprintf_reps (char **bufp, int c, int reps) +{ + char *buf = *bufp; + ASSERT (reps >= 0); + *bufp = buf + reps; + memset (buf, c, reps); + return reps; +} + +static int +gmp_sprintf_final (char **bufp) +{ + char *buf = *bufp; + *buf = '\0'; + return 0; +} + +const struct doprnt_funs_t __gmp_sprintf_funs = { + (doprnt_format_t) gmp_sprintf_format, + (doprnt_memory_t) gmp_sprintf_memory, + (doprnt_reps_t) gmp_sprintf_reps, + (doprnt_final_t) gmp_sprintf_final +}; diff --git a/Build/source/libs/gmp/gmp-src/printf/vasprintf.c b/Build/source/libs/gmp/gmp-src/printf/vasprintf.c new file mode 100644 index 00000000000..8a29a123400 --- /dev/null +++ b/Build/source/libs/gmp/gmp-src/printf/vasprintf.c @@ -0,0 +1,116 @@ +/* gmp_vasprintf -- formatted output to an allocated space. + +Copyright 2001 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library 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 copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "gmp-impl.h" + +#if ! HAVE_VSNPRINTF +#define vsnprintf __gmp_replacement_vsnprintf +#endif + + +/* vasprintf isn't used since we prefer all GMP allocs to go through + __gmp_allocate_func, and in particular we don't want the -1 return from + vasprintf for out-of-memory, instead __gmp_allocate_func should handle + that. Using vsnprintf unfortunately means we might have to re-run it if + our current space is insufficient. + + The initial guess for the needed space is an arbitrary 256 bytes. If + that (and any extra GMP_ASPRINTF_T_NEED might give) isn't enough then an + ISO C99 standard vsnprintf will tell us what we really need. + + GLIBC 2.0.x vsnprintf returns either -1 or space-1 to indicate overflow, + without giving any indication how much is really needed. In this case + keep trying with double the space each time. + + A return of space-1 is success on a C99 vsnprintf, but we're not + bothering to identify which style vsnprintf we've got, so just take the + pessimistic option and assume it's glibc 2.0.x. + + Notice the use of ret+2 for the new space in the C99 case. This ensures + the next vsnprintf return value will be space-2, which is unambiguously + successful. But actually GMP_ASPRINTF_T_NEED() will realloc to even + bigger than that ret+2. + + vsnprintf might trash it's given ap, so copy it in case we need to use it + more than once. See comments with gmp_snprintf_format. */ + +static int +gmp_asprintf_format (struct gmp_asprintf_t *d, const char *fmt, + va_list orig_ap) +{ + int ret; + va_list ap; + size_t space = 256; + + for (;;) + { + GMP_ASPRINTF_T_NEED (d, space); + space = d->alloc - d->size; + va_copy (ap, orig_ap); + ret = vsnprintf (d->buf + d->size, space, fmt, ap); + if (ret == -1) + { + ASSERT (strlen (d->buf + d->size) == space-1); + ret = space-1; + } + + /* done if output fits in our space */ + if (ret < space-1) + break; + + if (ret == space-1) + space *= 2; /* possible glibc 2.0.x, so double */ + else + space = ret+2; /* C99, so now know space required */ + } + + d->size += ret; + return ret; +} + +const struct doprnt_funs_t __gmp_asprintf_funs = { + (doprnt_format_t) gmp_asprintf_format, + (doprnt_memory_t) __gmp_asprintf_memory, + (doprnt_reps_t) __gmp_asprintf_reps, + (doprnt_final_t) __gmp_asprintf_final +}; + +int +gmp_vasprintf (char **result, const char *fmt, va_list ap) +{ + struct gmp_asprintf_t d; + GMP_ASPRINTF_T_INIT (d, result); + return __gmp_doprnt (&__gmp_asprintf_funs, &d, fmt, ap); +} diff --git a/Build/source/libs/gmp/gmp-src/printf/vfprintf.c b/Build/source/libs/gmp/gmp-src/printf/vfprintf.c new file mode 100644 index 00000000000..b2d190667fa --- /dev/null +++ b/Build/source/libs/gmp/gmp-src/printf/vfprintf.c @@ -0,0 +1,41 @@ +/* gmp_vfprintf -- formatted output. + +Copyright 2001 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library 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 copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include <stdarg.h> +#include <stdio.h> + +#include "gmp-impl.h" + + +int +gmp_vfprintf (FILE *fp, const char *fmt, va_list ap) +{ + return __gmp_doprnt (&__gmp_fprintf_funs, fp, fmt, ap); +} diff --git a/Build/source/libs/gmp/gmp-src/printf/vprintf.c b/Build/source/libs/gmp/gmp-src/printf/vprintf.c new file mode 100644 index 00000000000..60a22339654 --- /dev/null +++ b/Build/source/libs/gmp/gmp-src/printf/vprintf.c @@ -0,0 +1,41 @@ +/* gmp_vprintf -- formatted output. + +Copyright 2001 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library 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 copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include <stdarg.h> +#include <stdio.h> + +#include "gmp-impl.h" + + +int +gmp_vprintf (const char *fmt, va_list ap) +{ + return __gmp_doprnt (&__gmp_fprintf_funs, stdout, fmt, ap); +} diff --git a/Build/source/libs/gmp/gmp-src/printf/vsnprintf.c b/Build/source/libs/gmp/gmp-src/printf/vsnprintf.c new file mode 100644 index 00000000000..2432f5d921f --- /dev/null +++ b/Build/source/libs/gmp/gmp-src/printf/vsnprintf.c @@ -0,0 +1,47 @@ +/* gmp_vsnprintf -- formatted output to an fixed size buffer. + +Copyright 2001 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library 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 copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include <stdarg.h> +#include <string.h> /* for strlen */ + +#include "gmp-impl.h" + + +int +gmp_vsnprintf (char *buf, size_t size, const char *fmt, va_list ap) +{ + struct gmp_snprintf_t d; + + ASSERT (! MEM_OVERLAP_P (buf, size, fmt, strlen(fmt)+1)); + + d.buf = buf; + d.size = size; + return __gmp_doprnt (&__gmp_snprintf_funs, &d, fmt, ap); +} diff --git a/Build/source/libs/gmp/gmp-src/printf/vsprintf.c b/Build/source/libs/gmp/gmp-src/printf/vsprintf.c new file mode 100644 index 00000000000..26de193f122 --- /dev/null +++ b/Build/source/libs/gmp/gmp-src/printf/vsprintf.c @@ -0,0 +1,50 @@ +/* gmp_vsprintf -- formatted output to an unrestricted string. + +Copyright 2001 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library 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 copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include <stdarg.h> +#include <string.h> /* for strlen */ + +#include "gmp-impl.h" + + +int +gmp_vsprintf (char *buf, const char *fmt, va_list ap) +{ +#if WANT_ASSERT + int fmtlen = strlen(fmt); +#endif + int ret; + + ret = __gmp_doprnt (&__gmp_sprintf_funs, &buf, fmt, ap); + + ASSERT (! MEM_OVERLAP_P (buf, strlen(buf)+1, fmt, fmtlen+1)); + + return ret; +} |