=================================================================== RCS file: /home/cvs/OpenXM_contrib/gmp/mpz/Attic/get_str.c,v retrieving revision 1.1.1.2 retrieving revision 1.1.1.3 diff -u -p -r1.1.1.2 -r1.1.1.3 --- OpenXM_contrib/gmp/mpz/Attic/get_str.c 2000/09/09 14:12:52 1.1.1.2 +++ OpenXM_contrib/gmp/mpz/Attic/get_str.c 2003/08/25 16:06:33 1.1.1.3 @@ -4,7 +4,8 @@ result. If STRING is not NULL, the caller must ensure enough space is available to store the result. -Copyright (C) 1991, 1993, 1994, 1996 Free Software Foundation, Inc. +Copyright 1991, 1993, 1994, 1996, 2000, 2001, 2002 Free Software Foundation, +Inc. This file is part of the GNU MP Library. @@ -23,29 +24,24 @@ along with the GNU MP Library; see the file COPYING.LI the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include /* for strlen */ #include "gmp.h" #include "gmp-impl.h" +#include "longlong.h" char * -#if __STDC__ mpz_get_str (char *res_str, int base, mpz_srcptr x) -#else -mpz_get_str (res_str, base, x) - char *res_str; - int base; - mpz_srcptr x; -#endif { mp_ptr xp; mp_size_t x_size = x->_mp_size; - unsigned char *str; + char *str; char *return_str; size_t str_size; + size_t alloc_size = 0; char *num_to_text; int i; TMP_DECL (marker); - TMP_MARK (marker); if (base >= 0) { if (base == 0) @@ -58,61 +54,58 @@ mpz_get_str (res_str, base, x) num_to_text = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; } - /* We allways allocate space for the string. If the caller passed a - NULL pointer for RES_STR, we allocate permanent space and return - a pointer to that to the caller. */ - str_size = ((size_t) (ABS (x_size) * BITS_PER_MP_LIMB - * __mp_bases[base].chars_per_bit_exactly)) + 3; - if (res_str == 0) + /* allocate string for the user if necessary */ + if (res_str == NULL) { - /* We didn't get a string from the user. Allocate one (and return - a pointer to it). */ - res_str = (char *) (*_mp_allocate_func) (str_size); - /* Make str, the variable used for raw result from mpn_get_str, - point to the same string, but just after a possible minus sign. */ - str = (unsigned char *) res_str + 1; + /* digits, null terminator, possible minus sign */ + MPN_SIZEINBASE (alloc_size, PTR(x), ABS(x_size), base); + alloc_size += 1 + (x_size<0); + res_str = (char *) (*__gmp_allocate_func) (alloc_size); } - else - { - /* Use TMP_ALLOC to get temporary space, since we need a few extra bytes - that we can't expect to caller to supply us with. */ - str = (unsigned char *) TMP_ALLOC (str_size); - } - return_str = res_str; - if (x_size == 0) - { - res_str[0] = '0'; - res_str[1] = 0; - TMP_FREE (marker); - return res_str; - } if (x_size < 0) { *res_str++ = '-'; x_size = -x_size; } - /* Move the number to convert into temporary space, since mpn_get_str - clobbers its argument + needs one extra high limb.... */ - xp = (mp_ptr) TMP_ALLOC ((x_size + 1) * BYTES_PER_MP_LIMB); - MPN_COPY (xp, x->_mp_d, x_size); + /* mpn_get_str clobbers its input on non power-of-2 bases */ + TMP_MARK (marker); + xp = x->_mp_d; + if (! POW2_P (base)) + { + xp = TMP_ALLOC_LIMBS (x_size + 1); /* +1 in case x_size==0 */ + MPN_COPY (xp, x->_mp_d, x_size); + } - str_size = mpn_get_str (str, base, xp, 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)); - /* mpn_get_str might make some leading zeros. Skip them. */ - while (*str == 0) + /* might have a leading zero, skip it */ + str = res_str; + if (*res_str == 0 && str_size != 1) { str_size--; str++; + ASSERT (*str != 0); /* at most one leading zero */ } - /* Translate result to printable chars and move result to RES_STR. */ + /* Convert result to printable chars, and move down if there was a leading + zero. */ for (i = 0; i < str_size; i++) res_str[i] = num_to_text[str[i]]; res_str[str_size] = 0; TMP_FREE (marker); + + /* 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; }