This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] strtoll and strtoull in libiberty (fix: libstdc++/5611)


The attached patch (against the mainline) is a revised version of the one 
posted in
  http://gcc.gnu.org/ml/libstdc++/2002-02/msg00169.html

It fixes libstdc++/5611 and should also fix the unresolved symbol problems on 
HP-UX reported here:
  http://gcc.gnu.org/ml/gcc-patches/2002-02/msg01491.html
  
Tested on i386-unknown-freebsd3.4 (which needs strtoll/strtoull from 
libiberty) and i686-pc-linux-gnu/glibc 2.2.4 (which doesn't need 
strtoll/strotoull from libiberty); bootstrap ok, no new regressions.

Changelog entries:
in libiberty:
  strtoll.c: New file
  strtoull.c: Likewise
  Makefile.in: Add strtoll and strtoull
  configure.in: Likewise

in libstdc++-v3:
  acconfig.h: Add _GLIBCPP_USE_LIBIBERTY_STRTOLL
  acinclude.m4: Determine if libiberty is needed based on strtoll/strotoull
  configure.in: Add GLIBCPP_NEED_LIBIBERTY
  config/locale/generic/c_locale.cc: Add prototypes for strtoll/strotoull 
when not supplied by native C library
  src/Makefile.am: Link with libiberty when required
  
	Doug Gregor
	gregod@cs.rpi.edu
*** /dev/null	Sun Nov 11 09:22:38 2001
--- libiberty/strtoll.c	Thu Mar 14 11:26:11 2002
***************
*** 0 ****
--- 1,155 ----
+ /*-
+  * Copyright (c) 1990 The Regents of the University of California.
+  * All rights reserved.
+  *
+  * Redistribution and use in source and binary forms, with or without
+  * modification, are permitted provided that the following conditions
+  * are met:
+  * 1. Redistributions of source code must retain the above copyright
+  *    notice, this list of conditions and the following disclaimer.
+  * 2. Redistributions in binary form must reproduce the above copyright
+  *    notice, this list of conditions and the following disclaimer in the
+  *    documentation and/or other materials provided with the distribution.
+  * 3. [rescinded 22 July 1999]
+  * 4. Neither the name of the University nor the names of its contributors
+  *    may be used to endorse or promote products derived from this software
+  *    without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+  * SUCH DAMAGE.
+  */
+ 
+ #ifdef HAVE_CONFIG_H
+ #include "config.h"
+ #endif
+ #ifdef HAVE_LIMITS_H
+ #include <limits.h>
+ #endif
+ #ifdef HAVE_SYS_PARAM_H
+ #include <sys/param.h>
+ #endif
+ #include <errno.h>
+ #ifdef NEED_DECLARATION_ERRNO
+ extern int errno;
+ #endif
+ #include "safe-ctype.h"
+ 
+ /* FIXME: It'd be nice to configure around these, but the include files are too
+    painful.  These macros should at least be more portable than hardwired hex
+    constants. */
+ 
+ #ifndef ULONG_LONG_MAX
+ #define	ULONG_LONG_MAX	((unsigned long long)(~0LL))
+ #endif
+ 
+ #ifndef LONG_LONG_MAX
+ #define	LONG_LONG_MAX	((long long)(ULONG_LONG_MAX >> 1))
+ #endif
+ 
+ #ifndef LONG_LONG_MIN
+ #define	LONG_LONG_MIN	((long long)(~LONG_LONG_MAX))
+ #endif
+ 
+ /*
+  * Convert a string to a long long integer.
+  *
+  * Ignores `locale' stuff.  Assumes that the upper and lower case
+  * alphabets and digits are each contiguous.
+  */
+ long long
+ strtoll (nptr, endptr, base)
+      const char *nptr;
+      char **endptr;
+      register int base;
+ {
+   register const char *s = nptr;
+   register unsigned long long acc;
+   register int c;
+   register unsigned long long cutoff;
+   register int neg = 0, any, cutlim;
+ 
+   /*
+    * Skip white space and pick up leading +/- sign if any.
+    * If base is 0, allow 0x for hex and 0 for octal, else
+    * assume decimal; if base is already 16, allow 0x.
+    */
+   do
+     {
+       c = *s++;
+     }
+   while (ISSPACE (c));
+   if (c == '-')
+     {
+       neg = 1;
+       c = *s++;
+     }
+   else if (c == '+')
+     c = *s++;
+   if ((base == 0 || base == 16) && c == '0' && (*s == 'x' || *s == 'X'))
+     {
+       c = s[1];
+       s += 2;
+       base = 16;
+     }
+   if (base == 0)
+     base = c == '0' ? 8 : 10;
+ 
+   /*
+    * Compute the cutoff value between legal numbers and illegal
+    * numbers.  That is the largest legal value, divided by the
+    * base.  An input number that is greater than this value, if
+    * followed by a legal input character, is too big.  One that
+    * is equal to this value may be valid or not; the limit
+    * between valid and invalid numbers is then based on the last
+    * digit.  For instance, if the range for long longs is
+    * [-2147483648..2147483647] and the input base is 10,
+    * cutoff will be set to 214748364 and cutlim to either
+    * 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated
+    * a value > 214748364, or equal but the next digit is > 7 (or 8),
+    * the number is too big, and we will return a range error.
+    *
+    * Set any if any `digits' consumed; make it negative to indicate
+    * overflow.
+    */
+   cutoff = neg ? -(unsigned long long) LONG_LONG_MIN : LONG_LONG_MAX;
+   cutlim = cutoff % (unsigned long long) base;
+   cutoff /= (unsigned long long) base;
+   for (acc = 0, any = 0;; c = *s++)
+     {
+       if (ISDIGIT (c))
+ 	c -= '0';
+       else if (ISALPHA (c))
+ 	c -= ISUPPER (c) ? 'A' - 10 : 'a' - 10;
+       else
+ 	break;
+       if (c >= base)
+ 	break;
+       if (any < 0 || acc > cutoff || acc == cutoff && c > cutlim)
+ 	any = -1;
+       else
+ 	{
+ 	  any = 1;
+ 	  acc *= base;
+ 	  acc += c;
+ 	}
+     }
+   if (any < 0)
+     {
+       acc = neg ? LONG_LONG_MIN : LONG_LONG_MAX;
+       errno = ERANGE;
+     }
+   else if (neg)
+     acc = -acc;
+   if (endptr != 0)
+     *endptr = (char *) (any ? s - 1 : nptr);
+   return (acc);
+ }
*** /dev/null	Sun Nov 11 09:22:38 2001
--- libiberty/strtoull.c	Thu Mar 14 11:26:11 2002
***************
*** 0 ****
--- 1,126 ----
+ /*
+  * Copyright (c) 1990 Regents of the University of California.
+  * All rights reserved.
+  *
+  * Redistribution and use in source and binary forms, with or without
+  * modification, are permitted provided that the following conditions
+  * are met:
+  * 1. Redistributions of source code must retain the above copyright
+  *    notice, this list of conditions and the following disclaimer.
+  * 2. Redistributions in binary form must reproduce the above copyright
+  *    notice, this list of conditions and the following disclaimer in the
+  *    documentation and/or other materials provided with the distribution.
+  * 3. [rescinded 22 July 1999]
+  * 4. Neither the name of the University nor the names of its contributors
+  *    may be used to endorse or promote products derived from this software
+  *    without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+  * SUCH DAMAGE.
+  */
+ 
+ #ifdef HAVE_CONFIG_H
+ #include "config.h"
+ #endif
+ #ifdef HAVE_LIMITS_H
+ #include <limits.h>
+ #endif
+ #ifdef HAVE_SYS_PARAM_H
+ #include <sys/param.h>
+ #endif
+ #include <errno.h>
+ #ifdef NEED_DECLARATION_ERRNO
+ extern int errno;
+ #endif
+ #if 0
+ #include <stdlib.h>
+ #endif
+ #include "ansidecl.h"
+ #include "safe-ctype.h"
+ 
+ #ifndef ULONG_LONG_MAX
+ #define	ULONG_LONG_MAX	((unsigned long long)(~0LL))
+ #endif
+ 
+ /*
+  * Convert a string to an unsigned long integer.
+  *
+  * Ignores `locale' stuff.  Assumes that the upper and lower case
+  * alphabets and digits are each contiguous.
+  */
+ unsigned long long
+ strtoull (nptr, endptr, base)
+      const char *nptr;
+      char **endptr;
+      register int base;
+ {
+   register const char *s = nptr;
+   register unsigned long long acc;
+   register int c;
+   register unsigned long long cutoff;
+   register int neg = 0, any, cutlim;
+ 
+   /*
+    * See strtoll for comments as to the logic used.
+    */
+   do
+     {
+       c = *s++;
+     }
+   while (ISSPACE (c));
+   if (c == '-')
+     {
+       neg = 1;
+       c = *s++;
+     }
+   else if (c == '+')
+     c = *s++;
+   if ((base == 0 || base == 16) && c == '0' && (*s == 'x' || *s == 'X'))
+     {
+       c = s[1];
+       s += 2;
+       base = 16;
+     }
+   if (base == 0)
+     base = c == '0' ? 8 : 10;
+   cutoff = (unsigned long long) ULONG_LONG_MAX / (unsigned long long) base;
+   cutlim = (unsigned long long) ULONG_LONG_MAX % (unsigned long long) base;
+   for (acc = 0, any = 0;; c = *s++)
+     {
+       if (ISDIGIT (c))
+ 	c -= '0';
+       else if (ISALPHA (c))
+ 	c -= ISUPPER (c) ? 'A' - 10 : 'a' - 10;
+       else
+ 	break;
+       if (c >= base)
+ 	break;
+       if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
+ 	any = -1;
+       else
+ 	{
+ 	  any = 1;
+ 	  acc *= base;
+ 	  acc += c;
+ 	}
+     }
+   if (any < 0)
+     {
+       acc = ULONG_LONG_MAX;
+       errno = ERANGE;
+     }
+   else if (neg)
+     acc = -acc;
+   if (endptr != 0)
+     *endptr = (char *) (any ? s - 1 : nptr);
+   return (acc);
+ }
Index: libiberty/Makefile.in
===================================================================
RCS file: /cvsroot/gcc/gcc/libiberty/Makefile.in,v
retrieving revision 1.74
diff -r1.74 Makefile.in
143c143
< 	 strtod.c strtol.c strtoul.c					\
---
> 	 strtod.c strtol.c strtoll.c strtoul.c strtoull.c		\
182c182
< 	 strtoul.o							\
---
> 	 strtoul.o strtoll.o strtoull.o					\
284c284,285
< 	 strerror strncmp strrchr strstr strtol strtoul tmpnam vfprintf vprintf \
---
> 	 strerror strncmp strrchr strstr strtol strtoul strtoll strtoull \
>          stmpnam vfprintf vprintf \
466a468
> strtoll.o: config.h $(INCDIR)/safe-ctype.h
467a470
> strtoull.o: config.h $(INCDIR)/ansidecl.h $(INCDIR)/safe-ctype.h
Index: libiberty/configure.in
===================================================================
RCS file: /cvsroot/gcc/gcc/libiberty/configure.in,v
retrieving revision 1.47
diff -r1.47 configure.in
173a174,175
> funcs="$funcs strtoll"
> funcs="$funcs strtoull"
194c196,197
<   AC_CHECK_FUNCS(strtod strtol strtoul tmpnam vasprintf vfprintf vprintf)
---
>   AC_CHECK_FUNCS(strtod strtol strtoul strtoll strtoull)
>   AC_CHECK_FUNCS(tmpnam vasprintf vfprintf vprintf)
Index: libstdc++-v3/acconfig.h
===================================================================
RCS file: /cvsroot/gcc/gcc/libstdc++-v3/acconfig.h,v
retrieving revision 1.25
diff -r1.25 acconfig.h
21a22,24
> // Use strtoll and strtoull from libiberty
> #undef _GLIBCPP_USE_LIBIBERTY_STRTOLL
> 
Index: libstdc++-v3/acinclude.m4
===================================================================
RCS file: /cvsroot/gcc/gcc/libstdc++-v3/acinclude.m4,v
retrieving revision 1.198
diff -r1.198 acinclude.m4
1581,1582c1581,1584
<   AC_MSG_CHECKING([for enabled long long I/O support])
<   # iostreams require strtoll, strtoull to compile
---
>   AC_MSG_CHECKING([for native long long I/O support])
>   # iostreams require strtoll, strtoull to compile. determine if we have 
>   # native versions, or if we need to use libiberty
>   native_long_long=yes ;
1584c1586
<                  [char* tmp; strtoll("gnu", &tmp, 10);],,[enable_long_long=no])
---
>                  [char* tmp; strtoll("gnu", &tmp, 10);],,[native_long_long=no])
1586c1588,1593
<                  [char* tmp; strtoull("gnu", &tmp, 10);],,[enable_long_long=no])
---
>                  [char* tmp; strtoull("gnu", &tmp, 10);],,[native_long_long=no])
> 
>   if test x"$native_long_long" = xno; then
>     AC_DEFINE(_GLIBCPP_USE_LIBIBERTY_STRTOLL)
>     need_libiberty=yes; 
>   fi
1592c1599
<   AC_MSG_RESULT($enable_long_long)
---
>   AC_MSG_RESULT($native_long_long)
Index: libstdc++-v3/configure.in
===================================================================
RCS file: /cvsroot/gcc/gcc/libstdc++-v3/configure.in,v
retrieving revision 1.84
diff -r1.84 configure.in
15a16
> 
40a42
> need_libiberty=no
305a308,309
> 
> AM_CONDITIONAL(GLIBCPP_NEED_LIBIBERTY, test "$need_libiberty" = yes)
Index: libstdc++-v3/config/locale/generic/c_locale.cc
===================================================================
RCS file: /cvsroot/gcc/gcc/libstdc++-v3/config/locale/generic/c_locale.cc,v
retrieving revision 1.1
diff -r1.1 c_locale.cc
79a80,84
> #  ifdef _GLIBCPP_USE_LIBIBERTY_STRTOLL
>   extern "C" long long strtoll(const char*, char**, int);
>   extern "C" unsigned long long strtoull(const char*, char**, int);
> #  endif
> 
Index: libstdc++-v3/src/Makefile.am
===================================================================
RCS file: /cvsroot/gcc/gcc/libstdc++-v3/src/Makefile.am,v
retrieving revision 1.104
diff -r1.104 Makefile.am
25c25
< AUTOMAKE_OPTIONS = 1.3 gnits
---
> AUTOMAKE_OPTIONS = 1.3 gnits 
29a30,37
> if GLIBCPP_NEED_LIBIBERTY
> LIBIBERTY = -L../../libiberty -liberty
> else
> LIBIBERTY =
> endif
> 
> LIBS = $(LIBIBERTY)
> 
147a156
> 

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]