Add strtoll and strtoull to libiberty.
authorYury Gribov <y.gribov@samsung.com>
Tue, 28 Oct 2014 09:43:20 +0000 (09:43 +0000)
committerYury Gribov <ygribov@gcc.gnu.org>
Tue, 28 Oct 2014 09:43:20 +0000 (09:43 +0000)
2014-10-28  Yury Gribov  <y.gribov@samsung.com>

include/
* libiberty.h (strtol, strtoul, strtoll, strtoull): New prototypes.

libiberty/
* strtoll.c: New file.
* strtoull.c: New file.
* configure.ac: Add long long checks.  Add harness for strtoll and
strtoull.  Check decls for strtol, strtoul, strtoll, strtoull.
* Makefile.in (CFILES, CONFIGURED_OFILES): Add strtoll and strtoull.
* config.in: Regenerate.
* configure: Regenerate.
* functions.texi: Regenerate.
* testsuite/Makefile.in (check-strtol): New rule.
(test-strtol): Likewise.
(mostlyclean): Clean up strtol test.
* testsuite/test-strtol.c: New test.

From-SVN: r216772

12 files changed:
include/ChangeLog
include/libiberty.h
libiberty/ChangeLog
libiberty/Makefile.in
libiberty/config.in
libiberty/configure
libiberty/configure.ac
libiberty/functions.texi
libiberty/strtoll.c [new file with mode: 0644]
libiberty/strtoull.c [new file with mode: 0644]
libiberty/testsuite/Makefile.in
libiberty/testsuite/test-strtol.c [new file with mode: 0644]

index 441ea3daded5e0ce2c94effc565cddf684cc5e02..d2d14721f093872cb08ac93f71fa282e8c37ad03 100644 (file)
@@ -1,3 +1,7 @@
+2014-10-28  Yury Gribov  <y.gribov@samsung.com>
+
+       * libiberty.h (strtol, strtoul, strtoll, strtoull): New prototypes.
+
 2014-10-27  Phil Muldoon  <pmuldoon@redhat.com>
            Jan Kratochvil  <jan.kratochvil@redhat.com>
            Tom Tromey  <tromey@redhat.com>
index d09c9a54811a51a3deea31c39240de2e109a724a..571e85f1e9ee99f5f879b26af55f10056ddf6cc8 100644 (file)
@@ -655,6 +655,33 @@ extern size_t strnlen (const char *, size_t);
 extern int strverscmp (const char *, const char *);
 #endif
 
+#if defined(HAVE_DECL_STRTOL) && !HAVE_DECL_STRTOL
+extern long int strtol (const char *nptr,
+                        char **endptr, int base);
+#endif
+
+#if defined(HAVE_DECL_STRTOUL) && !HAVE_DECL_STRTOUL
+extern unsigned long int strtoul (const char *nptr,
+                                  char **endptr, int base);
+#endif
+
+#if defined(HAVE_LONG_LONG) && defined(HAVE_DECL_STRTOLL) && !HAVE_DECL_STRTOLL
+__extension__
+extern long long int strtoll (const char *nptr,
+                              char **endptr, int base);
+#endif
+
+#if defined(HAVE_LONG_LONG) && defined(HAVE_DECL_STRTOULL) && !HAVE_DECL_STRTOULL
+__extension__
+extern unsigned long long int strtoull (const char *nptr,
+                                        char **endptr, int base);
+#endif
+
+#if defined(HAVE_DECL_STRVERSCMP) && !HAVE_DECL_STRVERSCMP
+/* Compare version strings.  */
+extern int strverscmp (const char *, const char *);
+#endif
+
 /* Set the title of a process */
 extern void setproctitle (const char *name, ...);
 
index 73dee14ad67753057f085332510443c1d54f0171..d30a80b22abd6917d6ade7dd397e4d210507e0f9 100644 (file)
@@ -1,3 +1,18 @@
+2014-10-28  Yury Gribov  <y.gribov@samsung.com>
+
+       * strtoll.c: New file.
+       * strtoull.c: New file.
+       * configure.ac: Add long long checks.  Add harness for strtoll and
+       strtoull.  Check decls for strtol, strtoul, strtoll, strtoull.
+       * Makefile.in (CFILES, CONFIGURED_OFILES): Add strtoll and strtoull.
+       * config.in: Regenerate.
+       * configure: Regenerate.
+       * functions.texi: Regenerate.
+       * testsuite/Makefile.in (check-strtol): New rule.
+       (test-strtol): Likewise.
+       (mostlyclean): Clean up strtol test.
+       * testsuite/test-strtol.c: New test.
+
 2014-10-15  David Malcolm  <dmalcolm@redhat.com>
 
        * choose-temp.c (choose_tmpdir): Remove now-redundant local
index 9b877209bd18b46031ac099ab14a597e2f9d2655..1b0d8ae782bfd579c4e339c4563c16aebd67ea90 100644 (file)
@@ -152,8 +152,8 @@ CFILES = alloca.c argv.c asprintf.c atexit.c                                \
         spaces.c splay-tree.c stack-limit.c stpcpy.c stpncpy.c         \
         strcasecmp.c strchr.c strdup.c strerror.c strncasecmp.c        \
         strncmp.c strrchr.c strsignal.c strstr.c strtod.c strtol.c     \
-        strtoul.c strndup.c strnlen.c strverscmp.c                     \
-       timeval-utils.c tmpnam.c                                        \
+        strtoll.c strtoul.c strtoull.c strndup.c strnlen.c             \
+        strverscmp.c timeval-utils.c tmpnam.c                          \
        unlink-if-ordinary.c                                            \
        vasprintf.c vfork.c vfprintf.c vprintf.c vsnprintf.c vsprintf.c \
        waitpid.c                                                       \
@@ -219,8 +219,8 @@ CONFIGURED_OFILES = ./asprintf.$(objext) ./atexit.$(objext)         \
         ./strchr.$(objext) ./strdup.$(objext) ./strncasecmp.$(objext)  \
         ./strncmp.$(objext) ./strndup.$(objext) ./strnlen.$(objext)    \
         ./strrchr.$(objext) ./strstr.$(objext) ./strtod.$(objext)      \
-        ./strtol.$(objext) ./strtoul.$(objext) ./strverscmp.$(objext)  \
-       ./tmpnam.$(objext)                                              \
+        ./strtol.$(objext) ./strtoul.$(objext) strtoll.$(objext)       \
+       ./strtoull.$(objext) ./tmpnam.$(objext) ./strverscmp.$(objext)  \
        ./vasprintf.$(objext) ./vfork.$(objext) ./vfprintf.$(objext)    \
         ./vprintf.$(objext) ./vsnprintf.$(objext) ./vsprintf.$(objext) \
        ./waitpid.$(objext)
@@ -694,6 +694,17 @@ $(CONFIGURED_OFILES): stamp-picdir stamp-noasandir
        else true; fi
        $(COMPILE.c) $(srcdir)/crc32.c $(OUTPUT_OPTION)
 
+./d-demangle.$(objext): $(srcdir)/d-demangle.c config.h $(INCDIR)/ansidecl.h \
+       $(INCDIR)/demangle.h $(INCDIR)/libiberty.h \
+       $(INCDIR)/safe-ctype.h
+       if [ x"$(PICFLAG)" != x ]; then \
+         $(COMPILE.c) $(PICFLAG) $(srcdir)/d-demangle.c -o pic/$@; \
+       else true; fi
+       if [ x"$(NOASANFLAG)" != x ]; then \
+         $(COMPILE.c) $(PICFLAG) $(NOASANFLAG) $(srcdir)/d-demangle.c -o noasan/$@; \
+       else true; fi
+       $(COMPILE.c) $(srcdir)/d-demangle.c $(OUTPUT_OPTION)
+
 ./dwarfnames.$(objext): $(srcdir)/dwarfnames.c $(INCDIR)/dwarf2.def \
        $(INCDIR)/dwarf2.h
        if [ x"$(PICFLAG)" != x ]; then \
@@ -714,14 +725,6 @@ $(CONFIGURED_OFILES): stamp-picdir stamp-noasandir
        else true; fi
        $(COMPILE.c) $(srcdir)/dyn-string.c $(OUTPUT_OPTION)
 
-./d-demangle.$(objext): $(srcdir)/d-demangle.c config.h $(INCDIR)/ansidecl.h \
-       $(srcdir)/cp-demangle.h $(INCDIR)/demangle.h \
-       $(INCDIR)/dyn-string.h $(INCDIR)/getopt.h $(INCDIR)/libiberty.h
-       if [ x"$(PICFLAG)" != x ]; then \
-         $(COMPILE.c) $(PICFLAG) $(srcdir)/d-demangle.c -o pic/$@; \
-       else true; fi
-       $(COMPILE.c) $(srcdir)/d-demangle.c $(OUTPUT_OPTION)
-
 ./fdmatch.$(objext): $(srcdir)/fdmatch.c config.h $(INCDIR)/ansidecl.h \
        $(INCDIR)/libiberty.h
        if [ x"$(PICFLAG)" != x ]; then \
@@ -1471,6 +1474,15 @@ $(CONFIGURED_OFILES): stamp-picdir stamp-noasandir
        else true; fi
        $(COMPILE.c) $(srcdir)/strtol.c $(OUTPUT_OPTION)
 
+./strtoll.$(objext): $(srcdir)/strtoll.c config.h $(INCDIR)/safe-ctype.h
+       if [ x"$(PICFLAG)" != x ]; then \
+         $(COMPILE.c) $(PICFLAG) $(srcdir)/strtoll.c -o pic/$@; \
+       else true; fi
+       if [ x"$(NOASANFLAG)" != x ]; then \
+         $(COMPILE.c) $(PICFLAG) $(NOASANFLAG) $(srcdir)/strtoll.c -o noasan/$@; \
+       else true; fi
+       $(COMPILE.c) $(srcdir)/strtoll.c $(OUTPUT_OPTION)
+
 ./strtoul.$(objext): $(srcdir)/strtoul.c config.h $(INCDIR)/ansidecl.h \
        $(INCDIR)/safe-ctype.h
        if [ x"$(PICFLAG)" != x ]; then \
@@ -1481,6 +1493,16 @@ $(CONFIGURED_OFILES): stamp-picdir stamp-noasandir
        else true; fi
        $(COMPILE.c) $(srcdir)/strtoul.c $(OUTPUT_OPTION)
 
+./strtoull.$(objext): $(srcdir)/strtoull.c config.h $(INCDIR)/ansidecl.h \
+       $(INCDIR)/safe-ctype.h
+       if [ x"$(PICFLAG)" != x ]; then \
+         $(COMPILE.c) $(PICFLAG) $(srcdir)/strtoull.c -o pic/$@; \
+       else true; fi
+       if [ x"$(NOASANFLAG)" != x ]; then \
+         $(COMPILE.c) $(PICFLAG) $(NOASANFLAG) $(srcdir)/strtoull.c -o noasan/$@; \
+       else true; fi
+       $(COMPILE.c) $(srcdir)/strtoull.c $(OUTPUT_OPTION)
+
 ./strverscmp.$(objext): $(srcdir)/strverscmp.c $(INCDIR)/ansidecl.h \
        $(INCDIR)/libiberty.h $(INCDIR)/safe-ctype.h
        if [ x"$(PICFLAG)" != x ]; then \
index 1cf9c11b6ee7735bd0d7cac2fc07d9b513626d73..7c05b9d846e62f1218825128a68a638322c71f3f 100644 (file)
    don't. */
 #undef HAVE_DECL_SNPRINTF
 
+/* Define to 1 if you have the declaration of `strtol', and to 0 if you don't.
+   */
+#undef HAVE_DECL_STRTOL
+
+/* Define to 1 if you have the declaration of `strtoll', and to 0 if you
+   don't. */
+#undef HAVE_DECL_STRTOLL
+
+/* Define to 1 if you have the declaration of `strtoul', and to 0 if you
+   don't. */
+#undef HAVE_DECL_STRTOUL
+
+/* Define to 1 if you have the declaration of `strtoull', and to 0 if you
+   don't. */
+#undef HAVE_DECL_STRTOULL
+
 /* Define to 1 if you have the declaration of `strverscmp', and to 0 if you
    don't. */
 #undef HAVE_DECL_STRVERSCMP
 /* Define to 1 if you have the <limits.h> header file. */
 #undef HAVE_LIMITS_H
 
+/* Define if you have the `long long' type. */
+#undef HAVE_LONG_LONG
+
 /* Define to 1 if you have the <machine/hal_sysinfo.h> header file. */
 #undef HAVE_MACHINE_HAL_SYSINFO_H
 
 /* Define to 1 if you have the `strtol' function. */
 #undef HAVE_STRTOL
 
+/* Define to 1 if you have the `strtoll' function. */
+#undef HAVE_STRTOLL
+
 /* Define to 1 if you have the `strtoul' function. */
 #undef HAVE_STRTOUL
 
+/* Define to 1 if you have the `strtoull' function. */
+#undef HAVE_STRTOULL
+
 /* Define to 1 if you have the `strverscmp' function. */
 #undef HAVE_STRVERSCMP
 
 /* The size of `int', as computed by sizeof. */
 #undef SIZEOF_INT
 
+/* The size of `long', as computed by sizeof. */
+#undef SIZEOF_LONG
+
+/* The size of `long long', as computed by sizeof. */
+#undef SIZEOF_LONG_LONG
+
 /* Define if you know the direction of stack growth for your system; otherwise
    it will be automatically deduced at run-time. STACK_DIRECTION > 0 => grows
    toward higher addresses STACK_DIRECTION < 0 => grows toward lower addresses
index 96feaedbeba25c25b12c8fddb74e5f0af9ff6a44..4a5e40ab8cc46defedd08e60ca9d3a1d4cfd5b8e 100755 (executable)
@@ -5124,7 +5124,7 @@ $as_echo "#define NEED_DECLARATION_ERRNO 1" >>confdefs.h
 fi
 
 
-# Determine the size of an int for struct fibnode.
+# Determine sizes of some types.
 # The cast to long int works around a bug in the HP C Compiler
 # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
 # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
@@ -5159,6 +5159,82 @@ cat >>confdefs.h <<_ACEOF
 _ACEOF
 
 
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long" >&5
+$as_echo_n "checking size of long... " >&6; }
+if test "${ac_cv_sizeof_long+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long))" "ac_cv_sizeof_long"        "$ac_includes_default"; then :
+
+else
+  if test "$ac_cv_type_long" = yes; then
+     { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+{ as_fn_set_status 77
+as_fn_error "cannot compute sizeof (long)
+See \`config.log' for more details." "$LINENO" 5; }; }
+   else
+     ac_cv_sizeof_long=0
+   fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long" >&5
+$as_echo "$ac_cv_sizeof_long" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_LONG $ac_cv_sizeof_long
+_ACEOF
+
+
+
+# Check for presense of long long
+ac_fn_c_check_type "$LINENO" "long long" "ac_cv_type_long_long" "$ac_includes_default"
+if test "x$ac_cv_type_long_long" = x""yes; then :
+
+$as_echo "#define HAVE_LONG_LONG 1" >>confdefs.h
+ # The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long long" >&5
+$as_echo_n "checking size of long long... " >&6; }
+if test "${ac_cv_sizeof_long_long+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long long))" "ac_cv_sizeof_long_long"        "$ac_includes_default"; then :
+
+else
+  if test "$ac_cv_type_long_long" = yes; then
+     { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+{ as_fn_set_status 77
+as_fn_error "cannot compute sizeof (long long)
+See \`config.log' for more details." "$LINENO" 5; }; }
+   else
+     ac_cv_sizeof_long_long=0
+   fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long_long" >&5
+$as_echo "$ac_cv_sizeof_long_long" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_LONG_LONG $ac_cv_sizeof_long_long
+_ACEOF
+
+
+fi
+
 
 # Look for a 64-bit type.
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a 64-bit type" >&5
@@ -5387,6 +5463,8 @@ funcs="$funcs strstr"
 funcs="$funcs strtod"
 funcs="$funcs strtol"
 funcs="$funcs strtoul"
+funcs="$funcs strtoll"
+funcs="$funcs strtoull"
 funcs="$funcs strverscmp"
 funcs="$funcs tmpnam"
 funcs="$funcs vasprintf"
@@ -5423,7 +5501,7 @@ if test "x" = "y"; then
     sbrk setenv setproctitle setrlimit sigsetmask snprintf spawnve spawnvpe \
      stpcpy stpncpy strcasecmp strchr strdup \
      strerror strncasecmp strndup strnlen strrchr strsignal strstr strtod \
-     strtol strtoul strverscmp sysconf sysctl sysmp \
+     strtol strtoul strtoll strtoull strverscmp sysconf sysctl sysmp \
     table times tmpnam \
     vasprintf vfprintf vprintf vsprintf \
     wait3 wait4 waitpid
@@ -5499,6 +5577,46 @@ fi
 cat >>confdefs.h <<_ACEOF
 #define HAVE_DECL_VSNPRINTF $ac_have_decl
 _ACEOF
+ac_fn_c_check_decl "$LINENO" "strtol" "ac_cv_have_decl_strtol" "$ac_includes_default"
+if test "x$ac_cv_have_decl_strtol" = x""yes; then :
+  ac_have_decl=1
+else
+  ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_STRTOL $ac_have_decl
+_ACEOF
+ac_fn_c_check_decl "$LINENO" "strtoul" "ac_cv_have_decl_strtoul" "$ac_includes_default"
+if test "x$ac_cv_have_decl_strtoul" = x""yes; then :
+  ac_have_decl=1
+else
+  ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_STRTOUL $ac_have_decl
+_ACEOF
+ac_fn_c_check_decl "$LINENO" "strtoll" "ac_cv_have_decl_strtoll" "$ac_includes_default"
+if test "x$ac_cv_have_decl_strtoll" = x""yes; then :
+  ac_have_decl=1
+else
+  ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_STRTOLL $ac_have_decl
+_ACEOF
+ac_fn_c_check_decl "$LINENO" "strtoull" "ac_cv_have_decl_strtoull" "$ac_includes_default"
+if test "x$ac_cv_have_decl_strtoull" = x""yes; then :
+  ac_have_decl=1
+else
+  ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_STRTOULL $ac_have_decl
+_ACEOF
 
 
 $as_echo "#define HAVE_SYS_ERRLIST 1" >>confdefs.h
index 3380819ab3a7c350d24727ca2727656ace138d87..90adaea1ad2f3ef38cb1c01e714265fdca0955f2 100644 (file)
@@ -272,8 +272,14 @@ AC_HEADER_TIME
 
 libiberty_AC_DECLARE_ERRNO
 
-# Determine the size of an int for struct fibnode.
+# Determine sizes of some types.
 AC_CHECK_SIZEOF([int])
+AC_CHECK_SIZEOF([long])
+
+# Check for presense of long long
+AC_CHECK_TYPE([long long],
+  [AC_DEFINE(HAVE_LONG_LONG, 1, [Define if you have the `long long' type.]) AC_CHECK_SIZEOF([long long])],
+  [])
 
 # Look for a 64-bit type.
 AC_MSG_CHECKING([for a 64-bit type])
@@ -365,6 +371,8 @@ funcs="$funcs strstr"
 funcs="$funcs strtod"
 funcs="$funcs strtol"
 funcs="$funcs strtoul"
+funcs="$funcs strtoll"
+funcs="$funcs strtoull"
 funcs="$funcs strverscmp"
 funcs="$funcs tmpnam"
 funcs="$funcs vasprintf"
@@ -401,11 +409,11 @@ if test "x" = "y"; then
     sbrk setenv setproctitle setrlimit sigsetmask snprintf spawnve spawnvpe \
      stpcpy stpncpy strcasecmp strchr strdup \
      strerror strncasecmp strndup strnlen strrchr strsignal strstr strtod \
-     strtol strtoul strverscmp sysconf sysctl sysmp \
+     strtol strtoul strtoll strtoull strverscmp sysconf sysctl sysmp \
     table times tmpnam \
     vasprintf vfprintf vprintf vsprintf \
     wait3 wait4 waitpid)
-  AC_CHECK_DECLS([basename(char *), ffs, asprintf, vasprintf, snprintf, vsnprintf])
+  AC_CHECK_DECLS([basename(char *), ffs, asprintf, vasprintf, snprintf, vsnprintf, strtol, strtoul, strtoll, strtoull])
   AC_DEFINE(HAVE_SYS_ERRLIST, 1, [Define if you have the sys_errlist variable.])
   AC_DEFINE(HAVE_SYS_NERR,    1, [Define if you have the sys_nerr variable.])
   AC_DEFINE(HAVE_SYS_SIGLIST, 1, [Define if you have the sys_siglist variable.])
index 387aee0bb9c39305573094c27628b4e7cff3c706..3627285f9059c9cf552f0a247e221079208176a5 100644 (file)
@@ -1714,6 +1714,24 @@ that the converted value is unsigned.
 
 @end deftypefn
 
+@c strtoll.c:33
+@deftypefn Supplemental {long long int} strtoll (const char *@var{string}, @
+  char **@var{endptr}, int @var{base})
+@deftypefnx Supplemental {unsigned long long int} strtoul (@
+  const char *@var{string}, char **@var{endptr}, int @var{base})
+
+The @code{strtoll} function converts the string in @var{string} to a
+long long integer value according to the given @var{base}, which must be
+between 2 and 36 inclusive, or be the special value 0.  If @var{base}
+is 0, @code{strtoll} will look for the prefixes @code{0} and @code{0x}
+to indicate bases 8 and 16, respectively, else default to base 10.
+When the base is 16 (either explicitly or implicitly), a prefix of
+@code{0x} is allowed.  The handling of @var{endptr} is as that of
+@code{strtod} above.  The @code{strtoull} function is the same, except
+that the converted value is unsigned.
+
+@end deftypefn
+
 @c strsignal.c:502
 @deftypefn Extension int strtosigno (const char *@var{name})
 
diff --git a/libiberty/strtoll.c b/libiberty/strtoll.c
new file mode 100644 (file)
index 0000000..37ff8cd
--- /dev/null
@@ -0,0 +1,175 @@
+/*-
+ * Copyright (c) 2014 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.
+ */
+
+/*
+
+@deftypefn Supplemental {long long int} strtoll (const char *@var{string}, @
+  char **@var{endptr}, int @var{base})
+@deftypefnx Supplemental {unsigned long long int} strtoul (@
+  const char *@var{string}, char **@var{endptr}, int @var{base})
+
+The @code{strtoll} function converts the string in @var{string} to a
+long long integer value according to the given @var{base}, which must be
+between 2 and 36 inclusive, or be the special value 0.  If @var{base}
+is 0, @code{strtoll} will look for the prefixes @code{0} and @code{0x}
+to indicate bases 8 and 16, respectively, else default to base 10.
+When the base is 16 (either explicitly or implicitly), a prefix of
+@code{0x} is allowed.  The handling of @var{endptr} is as that of
+@code{strtod} above.  The @code{strtoull} function is the same, except
+that the converted value is unsigned.
+
+@end deftypefn
+
+*/
+
+#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"
+
+#ifdef HAVE_LONG_LONG
+
+__extension__
+typedef unsigned long long ullong_type;
+
+__extension__
+typedef long long llong_type;
+
+/* 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 ULLONG_MAX
+#define ULLONG_MAX (~(ullong_type)0) /* 0xFFFFFFFFFFFFFFFF */
+#endif
+
+#ifndef LLONG_MAX
+#define LLONG_MAX ((llong_type)(ULLONG_MAX >> 1)) /* 0x7FFFFFFFFFFFFFFF */
+#endif
+
+#ifndef LLONG_MIN
+#define LLONG_MIN (~LLONG_MAX) /* 0x8000000000000000 */
+#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.
+ */
+llong_type
+strtoll(const char *nptr, char **endptr, register int base)
+{
+       register const char *s = nptr;
+       register ullong_type acc;
+       register int c;
+       register ullong_type 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 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 ? -(ullong_type)LLONG_MIN : LLONG_MAX;
+       cutlim = cutoff % (ullong_type)base;
+       cutoff /= (ullong_type)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 ? LLONG_MIN : LLONG_MAX;
+               errno = ERANGE;
+       } else if (neg)
+               acc = -acc;
+       if (endptr != 0)
+               *endptr = (char *) (any ? s - 1 : nptr);
+       return (acc);
+}
+
+#endif /* ifdef HAVE_LONG_LONG */
diff --git a/libiberty/strtoull.c b/libiberty/strtoull.c
new file mode 100644 (file)
index 0000000..2f580fb
--- /dev/null
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2014 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"
+
+#ifdef HAVE_LONG_LONG
+
+__extension__
+typedef unsigned long long ullong_type;
+
+#ifndef ULLONG_MAX
+#define ULLONG_MAX (~(ullong_type)0) /* 0xFFFFFFFFFFFFFFFF */
+#endif
+
+/*
+ * Convert a string to an unsigned long long integer.
+ *
+ * Ignores `locale' stuff.  Assumes that the upper and lower case
+ * alphabets and digits are each contiguous.
+ */
+ullong_type
+strtoull(const char *nptr, char **endptr, register int base)
+{
+       register const char *s = nptr;
+       register ullong_type acc;
+       register int c;
+       register ullong_type cutoff;
+       register int neg = 0, any, cutlim;
+
+       /*
+        * See strtol 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 = (ullong_type)ULLONG_MAX / (ullong_type)base;
+       cutlim = (ullong_type)ULLONG_MAX % (ullong_type)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 = ULLONG_MAX;
+               errno = ERANGE;
+       } else if (neg)
+               acc = -acc;
+       if (endptr != 0)
+               *endptr = (char *) (any ? s - 1 : nptr);
+       return (acc);
+}
+
+#endif /* ifdef HAVE_LONG_LONG */
index bb2db67fb662edb3534dd90148b242607ee5736d..4324a8f1dc4d2b43b2186a504345052d713c20d4 100644 (file)
@@ -45,7 +45,8 @@ all:
 # CHECK is set to "really_check" or the empty string by configure.
 check: @CHECK@
 
-really-check: check-cplus-dem check-d-demangle check-pexecute check-expandargv
+really-check: check-cplus-dem check-d-demangle check-pexecute check-expandargv \
+               check-strtol
 
 # Run some tests of the demangler.
 check-cplus-dem: test-demangle $(srcdir)/demangle-expected
@@ -62,6 +63,10 @@ check-pexecute: test-pexecute
 check-expandargv: test-expandargv
        ./test-expandargv
 
+# Check the strtol functionality
+check-strtol: test-strtol
+       ./test-strtol
+
 # Run the demangler fuzzer
 fuzz-demangler: demangler-fuzzer
        ./demangler-fuzzer
@@ -79,6 +84,10 @@ test-expandargv: $(srcdir)/test-expandargv.c ../libiberty.a
        $(TEST_COMPILE) -DHAVE_CONFIG_H -I.. -o test-expandargv \
                $(srcdir)/test-expandargv.c ../libiberty.a
 
+test-strtol: $(srcdir)/test-strtol.c ../libiberty.a
+       $(TEST_COMPILE) -DHAVE_CONFIG_H -I.. -o test-strtol \
+               $(srcdir)/test-strtol.c ../libiberty.a
+
 demangler-fuzzer: $(srcdir)/demangler-fuzzer.c ../libiberty.a
        $(TEST_COMPILE) -o demangler-fuzzer \
                $(srcdir)/demangler-fuzzer.c ../libiberty.a
@@ -92,6 +101,7 @@ mostlyclean:
        rm -f test-demangle
        rm -f test-pexecute
        rm -f test-expandargv
+       rm -f test-strtol
        rm -f demangler-fuzzer
        rm -f core
 clean: mostlyclean
diff --git a/libiberty/testsuite/test-strtol.c b/libiberty/testsuite/test-strtol.c
new file mode 100644 (file)
index 0000000..96d6871
--- /dev/null
@@ -0,0 +1,184 @@
+/* Test program for strtol family of funtions,
+   Copyright (C) 2014 Free Software Foundation, Inc.
+   Written by Yury Gribov <y.gribov@samsung.com>
+
+   This file is part of the libiberty library, which is part of GCC.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of 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.
+
+   In addition to the permissions in the GNU General Public License, the
+   Free Software Foundation gives you unlimited permission to link the
+   compiled version of this file into combinations with other programs,
+   and to distribute those combinations without any restriction coming
+   from the use of this file.  (The General Public License restrictions
+   do apply in other respects; for example, they cover modification of
+   the file, and distribution when not linked into a combined
+   executable.)
+
+   This program 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 a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. 
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include "libiberty.h"
+#include <stdio.h>
+#include <errno.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#ifndef EXIT_SUCCESS
+#define EXIT_SUCCESS 0
+#endif
+
+#ifndef EXIT_FAILURE
+#define EXIT_FAILURE 1
+#endif
+
+
+/* Test input data. */
+
+enum conversion_fun
+{
+  STRTOL,
+  STRTOLL,
+  STRTOUL,
+  STRTOULL,
+};
+
+#ifdef HAVE_LONG_LONG
+typedef unsigned long long integer_type;
+#else
+typedef unsigned long integer_type;
+#endif
+
+struct test_data_t
+{
+  enum conversion_fun fun;
+  const char *nptr;
+  int base;
+  integer_type res;
+  int errnum;
+};
+
+const struct test_data_t test_data[] = {
+  { STRTOL,  "0x123",       0, 0x123L,        0      },
+  { STRTOL,  "123",         0, 123L,          0      },
+  { STRTOL,  "0123",        0, 0123L,         0      },
+  { STRTOL,  "0x7FFFFFFF",  0, 0x7fffffffL,   0      },
+  { STRTOL,  "-0x80000000", 0, -0x80000000L,  0      },
+  { STRTOUL, "0x123",       0, 0x123UL,       0      },
+  { STRTOUL, "123",         0, 123UL,         0      },
+  { STRTOUL, "0123",        0, 0123UL,        0      },
+  { STRTOUL, "0xFFFFFFFF",  0, 0xffffffffUL,  0      },
+#if SIZEOF_LONG == 4
+  { STRTOL,  "0x80000000",  0, 0x7fffffffL,   ERANGE },
+  { STRTOL,  "-0x80000001", 0, -0x80000000L,  ERANGE },
+  { STRTOUL, "0x100000000", 0, 0xffffffffUL,  ERANGE },
+#endif
+#ifdef HAVE_LONG_LONG
+  { STRTOLL,  "0x123",               0, 0x123LL,               0      },
+  { STRTOLL,  "123",                 0, 123LL,                 0      },
+  { STRTOLL,  "0123",                0, 0123LL,                0      },
+  { STRTOLL,  "0x7FFFFFFFFFFFFFFF",  0, 0x7fffffffffffffffLL,  0      },
+  { STRTOLL,  "-0x8000000000000000", 0, -0x8000000000000000LL, 0      },
+  { STRTOULL, "0x123",               0, 0x123ULL,              0      },
+  { STRTOULL, "123",                 0, 123ULL,                0      },
+  { STRTOULL, "0123",                0, 0123ULL,               0      },
+  { STRTOULL, "0xFFFFFFFFFFFFFFFF",  0, 0xffffffffffffffffULL, 0      },
+#if SIZEOF_LONG_LONG == 8
+  { STRTOLL,  "0x8000000000000000",  0, 0x7fffffffffffffffLL,  ERANGE },
+  { STRTOLL,  "-0x8000000000000001", 0, -0x8000000000000000LL, ERANGE },
+  { STRTOULL, "0x10000000000000000", 0, 0xffffffffffffffffULL, ERANGE },
+#endif
+#endif
+};
+
+/* run_tests:
+    Run conversion function
+    Compare results
+    Return number of fails */
+
+int
+run_tests (const struct test_data_t *test_data, size_t ntests)
+{
+  int fails = 0, failed;
+  size_t i;
+
+  for (i = 0; i < ntests; ++i)
+    {
+      integer_type res;
+      int saved_errno;
+
+      errno = 0;
+
+      switch (test_data[i].fun)
+       {
+       case STRTOL:
+         res = strtol (test_data[i].nptr, 0, test_data[i].base);
+         break;
+       case STRTOUL:
+         res = strtoul (test_data[i].nptr, 0, test_data[i].base);
+         break;
+#ifdef HAVE_LONG_LONG
+       case STRTOLL:
+         res = strtoll (test_data[i].nptr, 0, test_data[i].base);
+         break;
+       case STRTOULL:
+         res = strtoull (test_data[i].nptr, 0, test_data[i].base);
+         break;
+#endif
+       }
+
+      saved_errno = errno;
+
+      failed = 0;
+
+      /* Compare result */
+      if (res != test_data[i].res)
+        {
+          printf ("FAIL: test-strtol-%zd. Results don't match.\n", i);
+         failed++;
+        }
+
+      /* Compare errno */
+      if (saved_errno != test_data[i].errnum)
+        {
+          printf ("FAIL: test-strtol-%zd. Errnos don't match.\n", i);
+         failed++;
+        }
+
+      if (!failed)
+        printf ("PASS: test-strtol-%zd.\n", i);
+      else
+        fails++;
+    }
+
+  return fails;
+}
+
+int 
+main(int argc, char **argv)
+{
+  int fails;
+  fails = run_tests (test_data, sizeof (test_data) / sizeof (test_data[0]));
+  exit (fails ? EXIT_FAILURE : EXIT_SUCCESS);
+}
+