Add strtoll and strtoull to libiberty.

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
This commit is contained in:
Yury Gribov 2014-10-28 09:43:20 +00:00 committed by Yury Gribov
parent 5b595d80ce
commit ea41822adf
12 changed files with 752 additions and 18 deletions

View 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>

View 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, ...);

View 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

View 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 \

View File

@ -79,6 +79,22 @@
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
@ -136,6 +152,9 @@
/* 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
@ -280,9 +299,15 @@
/* 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
@ -439,6 +464,12 @@
/* 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

122
libiberty/configure vendored
View File

@ -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

View 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.])

View 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})

175
libiberty/strtoll.c Normal file
View File

@ -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 */

122
libiberty/strtoull.c Normal file
View File

@ -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 */

View 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

View File

@ -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);
}