From 11da511c784eca003deb90c23570f0873954e0de Mon Sep 17 00:00:00 2001 From: Duncan Wilkie Date: Sat, 18 Nov 2023 06:11:09 -0600 Subject: Initial commit. --- gmp-6.3.0/mpz/get_str.c | 115 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 gmp-6.3.0/mpz/get_str.c (limited to 'gmp-6.3.0/mpz/get_str.c') diff --git a/gmp-6.3.0/mpz/get_str.c b/gmp-6.3.0/mpz/get_str.c new file mode 100644 index 0000000..c00a9a3 --- /dev/null +++ b/gmp-6.3.0/mpz/get_str.c @@ -0,0 +1,115 @@ +/* mpz_get_str (string, base, mp_src) -- Convert the multiple precision + number MP_SRC to a string STRING of base BASE. If STRING is NULL + allocate space for the result. In any case, return a pointer to the + result. If STRING is not NULL, the caller must ensure enough space is + available to store the result. + +Copyright 1991, 1993, 1994, 1996, 2000-2002, 2005, 2012, 2017 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 /* for strlen */ +#include "gmp-impl.h" +#include "longlong.h" + +char * +mpz_get_str (char *res_str, int base, mpz_srcptr x) +{ + mp_ptr xp; + mp_size_t x_size = SIZ (x); + char *return_str; + size_t str_size; + size_t alloc_size = 0; + const char *num_to_text; + int i; + TMP_DECL; + + num_to_text = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + if (base > 1) + { + if (base <= 36) + num_to_text = "0123456789abcdefghijklmnopqrstuvwxyz"; + else if (UNLIKELY (base > 62)) + return NULL; + } + else if (base > -2) + { + base = 10; + } + else + { + base = -base; + if (UNLIKELY (base > 36)) + return NULL; + } + + /* allocate string for the user if necessary */ + if (res_str == NULL) + { + /* digits, null terminator, possible minus sign */ + MPN_SIZEINBASE (alloc_size, PTR(x), ABS(x_size), base); + alloc_size += 1 + (x_size<0); + res_str = __GMP_ALLOCATE_FUNC_TYPE (alloc_size, char); + } + return_str = res_str; + + if (x_size < 0) + { + *res_str++ = '-'; + x_size = -x_size; + } + + /* mpn_get_str clobbers its input on non power-of-2 bases */ + TMP_MARK; + xp = PTR (x); + if (! POW2_P (base)) + { + xp = TMP_ALLOC_LIMBS (x_size | 1); /* |1 in case x_size==0 */ + MPN_COPY (xp, PTR (x), x_size); + } + + str_size = mpn_get_str ((unsigned char *) res_str, base, xp, x_size); + ASSERT (alloc_size == 0 || str_size <= alloc_size - (SIZ(x) < 0)); + + /* Convert result to printable chars. */ + for (i = 0; i < str_size; i++) + res_str[i] = num_to_text[(int) res_str[i]]; + res_str[str_size] = 0; + + TMP_FREE; + + /* if allocated then resize down to the actual space required */ + if (alloc_size != 0) + { + size_t actual_size = str_size + 1 + (res_str - return_str); + ASSERT (actual_size == strlen (return_str) + 1); + __GMP_REALLOCATE_FUNC_MAYBE_TYPE (return_str, alloc_size, actual_size, + char); + } + return return_str; +} -- cgit v1.2.3