Implementation of strto(u)ll, documentation and tests for strto(u)l(l)
This commit is contained in:
parent
fcaaad3317
commit
6adadade32
9 changed files with 429 additions and 17 deletions
|
@ -38,6 +38,19 @@
|
||||||
#define LONG_MAX 2147483647L /* maximum value of a long */
|
#define LONG_MAX 2147483647L /* maximum value of a long */
|
||||||
#define ULONG_MAX 0xFFFFFFFFL /* maximum value of an unsigned long */
|
#define ULONG_MAX 0xFFFFFFFFL /* maximum value of an unsigned long */
|
||||||
|
|
||||||
|
/*Definitions about long longs (64 bits, may not be supported). */
|
||||||
|
#ifdef __LONG_LONG_SUPPORTED
|
||||||
|
#define LLONG_MIN (-0x7FFFFFFFFFFFFFFFLL-1) /* minimum value of a
|
||||||
|
* long long
|
||||||
|
*/
|
||||||
|
#define LLONG_MAX 0x7FFFFFFFFFFFFFFFLL /* maximum value of a
|
||||||
|
* long long
|
||||||
|
*/
|
||||||
|
#define ULLONG_MAX 0xFFFFFFFFFFFFFFFFULL /* maximum value of an
|
||||||
|
* unsigned long long
|
||||||
|
*/
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <minix/dir.h>
|
#include <minix/dir.h>
|
||||||
|
|
||||||
/* Minimum sizes required by the POSIX P1003.1 standard (Table 2-3). */
|
/* Minimum sizes required by the POSIX P1003.1 standard (Table 2-3). */
|
||||||
|
|
|
@ -77,6 +77,14 @@ _PROTOTYPE( int putenv, (char *string) );
|
||||||
_PROTOTYPE( int setenv, (const char *envname, const char *envval,
|
_PROTOTYPE( int setenv, (const char *envname, const char *envval,
|
||||||
int overwrite) );
|
int overwrite) );
|
||||||
_PROTOTYPE( int unsetenv, (const char *name) );
|
_PROTOTYPE( int unsetenv, (const char *name) );
|
||||||
|
|
||||||
|
#ifdef __LONG_LONG_SUPPORTED
|
||||||
|
_PROTOTYPE( long long strtoll, (const char *_nptr, char **_endptr,
|
||||||
|
int _base) );
|
||||||
|
_PROTOTYPE( unsigned long long strtoull, (const char *_nptr,
|
||||||
|
char **_endptr, int _base) );
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef _MINIX
|
#ifdef _MINIX
|
||||||
|
|
|
@ -86,6 +86,7 @@ libc_FILES=" \
|
||||||
strlcat.c \
|
strlcat.c \
|
||||||
strlcpy.c \
|
strlcpy.c \
|
||||||
strtok_r.c \
|
strtok_r.c \
|
||||||
|
strtoll.c \
|
||||||
swab.c \
|
swab.c \
|
||||||
sys_eniop.c \
|
sys_eniop.c \
|
||||||
syscall.c \
|
syscall.c \
|
||||||
|
|
99
lib/other/strtoll.c
Normal file
99
lib/other/strtoll.c
Normal file
|
@ -0,0 +1,99 @@
|
||||||
|
/* Erik van der Kouwe, 8 December 2009, based on lib/ansi/strtol.c */
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#ifdef __LONG_LONG_SUPPORTED
|
||||||
|
|
||||||
|
static unsigned long long string2long(const char *nptr, char **endptr,
|
||||||
|
int base, int is_signed);
|
||||||
|
|
||||||
|
long long strtoll(const char *nptr, char **endptr, int base)
|
||||||
|
{
|
||||||
|
return (long long) string2long(nptr, endptr, base, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long long strtoull(const char *nptr, char **endptr, int base)
|
||||||
|
{
|
||||||
|
return (unsigned long long) string2long(nptr, endptr, base, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define between(a, c, z) \
|
||||||
|
((unsigned long) ((c) - (a)) <= (unsigned long) ((z) - (a)))
|
||||||
|
|
||||||
|
static unsigned long long string2long(const char *nptr, char **const endptr,
|
||||||
|
int base, int is_signed)
|
||||||
|
{
|
||||||
|
unsigned int v;
|
||||||
|
unsigned long long val = 0;
|
||||||
|
int c;
|
||||||
|
int ovfl = 0, sign = 1;
|
||||||
|
const char *startnptr = nptr, *nrstart;
|
||||||
|
|
||||||
|
if (endptr) *endptr = (char *)nptr;
|
||||||
|
while (isspace(*nptr)) nptr++;
|
||||||
|
c = *nptr;
|
||||||
|
|
||||||
|
if (c == '-' || c == '+') {
|
||||||
|
if (c == '-') sign = -1;
|
||||||
|
nptr++;
|
||||||
|
}
|
||||||
|
nrstart = nptr; /* start of the number */
|
||||||
|
|
||||||
|
/* When base is 0, the syntax determines the actual base */
|
||||||
|
if (base == 0)
|
||||||
|
if (*nptr == '0')
|
||||||
|
if (*++nptr == 'x' || *nptr == 'X') {
|
||||||
|
base = 16;
|
||||||
|
nptr++;
|
||||||
|
}
|
||||||
|
else base = 8;
|
||||||
|
else base = 10;
|
||||||
|
else if (base==16 && *nptr=='0' && (*++nptr =='x' || *nptr =='X'))
|
||||||
|
nptr++;
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
c = *nptr;
|
||||||
|
if (between('0', c, '9')) {
|
||||||
|
v = c - '0';
|
||||||
|
} else
|
||||||
|
if (between('a', c, 'z')) {
|
||||||
|
v = c - 'a' + 0xa;
|
||||||
|
} else
|
||||||
|
if (between('A', c, 'Z')) {
|
||||||
|
v = c - 'A' + 0xA;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (v >= base) break;
|
||||||
|
if (val > (ULLONG_MAX - v) / base) ovfl++;
|
||||||
|
val = (val * base) + v;
|
||||||
|
nptr++;
|
||||||
|
}
|
||||||
|
if (endptr) {
|
||||||
|
if (nrstart == nptr) *endptr = (char *)startnptr;
|
||||||
|
else *endptr = (char *)nptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ovfl) {
|
||||||
|
/* Overflow is only possible when converting a signed long. */
|
||||||
|
if (is_signed
|
||||||
|
&& ((sign < 0 && val > -(unsigned long long)LLONG_MIN)
|
||||||
|
|| (sign > 0 && val > LLONG_MAX)))
|
||||||
|
ovfl++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ovfl) {
|
||||||
|
errno = ERANGE;
|
||||||
|
if (is_signed)
|
||||||
|
if (sign < 0) return LLONG_MIN;
|
||||||
|
else return LLONG_MAX;
|
||||||
|
else return ULLONG_MAX;
|
||||||
|
}
|
||||||
|
return (long) sign * val;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* defined(__LONG_LONG_SUPPORTED) */
|
33
man/man3/strtol.3
Normal file
33
man/man3/strtol.3
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
.TH STRTOL 3 "December 9, 2009"
|
||||||
|
.UC 4
|
||||||
|
.SH NAME
|
||||||
|
strtol, strtoll, strtoul, strtoull \- convert string to number
|
||||||
|
.SH SYNOPSIS
|
||||||
|
.nf
|
||||||
|
.ft B
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
long strtol(const char *\fInptr\fP, char **\fIendptr\fP, int \fIbase\fP);
|
||||||
|
unsigned long strtoul(const char *\fInptr\fP, char **\fIendptr\fP, int \fIbase\fP);
|
||||||
|
#ifdef __LONG_LONG_SUPPORTED
|
||||||
|
long long strtoll(const char *\fInptr\fP, char **\fIendptr\fP, int \fIbase\fP);
|
||||||
|
unsigned long long strtoull(const char *\fInptr\fP, char **\fIendptr\fP, int \fIbase\fP);
|
||||||
|
#endif
|
||||||
|
.fi
|
||||||
|
.SH DESCRIPTION
|
||||||
|
These functions parse as much from the string \fInptr\fP as possible and return
|
||||||
|
it as an integer. The string should consist of any number of whitespace
|
||||||
|
characters followed by a sign (either plus or minus) and at least one digit in
|
||||||
|
the specified \fIbase\fP. The digits of a hexadecimal string may be preceded by
|
||||||
|
the prefix 0x or 0X, which is ignored. If \fIbase\fP is zero, hexadecimal is
|
||||||
|
assumed if this prefix is present, octal is assumed if there is a leading zero
|
||||||
|
and decimal is assumed otherwise. If not zero, \fIbase\fI must be at least 2
|
||||||
|
and at most 36. A pointer to the first character following the numeric string is
|
||||||
|
stored in *\fIendptr\fP.
|
||||||
|
.PP
|
||||||
|
Note that the strtoll and strtoull functions, which return 64-bit values,
|
||||||
|
are supported only on GCC as ACK does not support 64-bit arithmatic.
|
||||||
|
.SH "RETURN VALUE
|
||||||
|
The parsed number is returned.
|
||||||
|
.SH "SEE ALSO"
|
||||||
|
.BR atoi (3).
|
|
@ -1,19 +1,22 @@
|
||||||
# Makefile for the tests.
|
# Makefile for the tests.
|
||||||
|
|
||||||
CC = exec cc
|
CC = exec cc
|
||||||
|
GCC = /usr/gnu/bin/gcc
|
||||||
CFLAGS= -O -D_MINIX -D_POSIX_SOURCE
|
CFLAGS= -O -D_MINIX -D_POSIX_SOURCE
|
||||||
|
CFLAGS-GCC= $(CFLAGS) -Wall
|
||||||
|
|
||||||
OBJ= test1 test2 test3 test4 test5 test6 test7 test8 test9 \
|
OBJ= test1 test2 test3 test4 test5 test6 test7 test8 test9 \
|
||||||
test10 test12 test13 test14 test15 test16 test17 test18 test19 \
|
test10 test12 test13 test14 test15 test16 test17 test18 test19 \
|
||||||
test21 test22 test23 test25 test26 test27 test28 test29 \
|
test21 test22 test23 test25 test26 test27 test28 test29 \
|
||||||
test30 test31 test32 test34 test35 test36 test37 test38 \
|
test30 test31 test32 test34 test35 test36 test37 test38 \
|
||||||
test39 t10a t11a t11b test40 t40a t40b t40c t40d t40e t40f test41 \
|
test39 t10a t11a t11b test40 t40a t40b t40c t40d t40e t40f test41 \
|
||||||
test42 test44
|
test42 test44 test45
|
||||||
|
|
||||||
BIGOBJ= test20 test24
|
BIGOBJ= test20 test24
|
||||||
ROOTOBJ= test11 test33 test43
|
ROOTOBJ= test11 test33 test43
|
||||||
|
GCCOBJ= test45-gcc
|
||||||
|
|
||||||
all: $(OBJ) $(BIGOBJ) $(ROOTOBJ)
|
all: $(OBJ) $(BIGOBJ) $(GCCOBJ) $(ROOTOBJ)
|
||||||
chmod 755 *.sh run
|
chmod 755 *.sh run
|
||||||
|
|
||||||
$(OBJ):
|
$(OBJ):
|
||||||
|
@ -22,6 +25,9 @@ $(OBJ):
|
||||||
$(BIGOBJ):
|
$(BIGOBJ):
|
||||||
$(CC) $(CFLAGS) -o $@ $@.c
|
$(CC) $(CFLAGS) -o $@ $@.c
|
||||||
|
|
||||||
|
$(GCCOBJ):
|
||||||
|
[ ! -x $(GCC) ] || $(GCC) $(CFLAGS-GCC) -o $@ $<
|
||||||
|
|
||||||
$(ROOTOBJ):
|
$(ROOTOBJ):
|
||||||
$(CC) $(CFLAGS) $@.c
|
$(CC) $(CFLAGS) $@.c
|
||||||
@install -c -o root -m 4755 a.out $@
|
@install -c -o root -m 4755 a.out $@
|
||||||
|
@ -29,7 +35,7 @@ $(ROOTOBJ):
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
cd select && make clean
|
cd select && make clean
|
||||||
-rm -rf *.o *.s *.bak test? test?? t10a t11a t11b \
|
-rm -rf *.o *.s *.bak test? test?? test??-gcc t10a t11a t11b \
|
||||||
t40a t40b t40c t40d t40e t40f t43 DIR*
|
t40a t40b t40c t40d t40e t40f t43 DIR*
|
||||||
|
|
||||||
test1: test1.c
|
test1: test1.c
|
||||||
|
@ -85,3 +91,6 @@ test41: test41.c
|
||||||
test42: test42.c
|
test42: test42.c
|
||||||
test43: test43.c
|
test43: test43.c
|
||||||
test44: test44.c
|
test44: test44.c
|
||||||
|
test45: test45.c test45.h
|
||||||
|
test45-gcc: test45.c test45.h
|
||||||
|
|
||||||
|
|
35
test/run
35
test/run
|
@ -7,6 +7,7 @@ export PATH
|
||||||
rm -rf DIR* # remove any old junk lying around
|
rm -rf DIR* # remove any old junk lying around
|
||||||
passed=`expr 0` # count number of tests run correctly
|
passed=`expr 0` # count number of tests run correctly
|
||||||
failed=`expr 0` # count number of tests that failed
|
failed=`expr 0` # count number of tests that failed
|
||||||
|
skipped=`expr 0` # count number of tests that were skipped
|
||||||
total=`expr 0` # total number of tests tried
|
total=`expr 0` # total number of tests tried
|
||||||
badones= # list of tests that failed
|
badones= # list of tests that failed
|
||||||
|
|
||||||
|
@ -18,26 +19,32 @@ echo " "
|
||||||
# Run all the tests, keeping track of who failed.
|
# Run all the tests, keeping track of who failed.
|
||||||
for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 \
|
for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 \
|
||||||
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 \
|
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 \
|
||||||
41 42 43 44 sh1.sh sh2.sh
|
41 42 43 44 45 45-gcc sh1.sh sh2.sh
|
||||||
do total=`expr $total + 1`
|
do
|
||||||
FAIL=0
|
if [ -x ./test$i ]
|
||||||
if [ $USER = root -a \( $i = 11 -o $i = 33 \) ]
|
then
|
||||||
then su - ast -c "cd `pwd`; ./test$i" || FAIL=1
|
total=`expr $total + 1`
|
||||||
else ./test$i || FAIL=1
|
FAIL=0
|
||||||
fi
|
if [ $USER = root -a \( $i = 11 -o $i = 33 \) ]
|
||||||
|
then su - ast -c "cd `pwd`; ./test$i" || FAIL=1
|
||||||
if [ $FAIL -eq 0 ]
|
else ./test$i || FAIL=1
|
||||||
then passed=`expr $passed + 1`
|
fi
|
||||||
else failed=`expr $failed + 1`
|
if [ $FAIL -eq 0 ]
|
||||||
badones=`echo $badones " " $i`
|
then passed=`expr $passed + 1`
|
||||||
|
else failed=`expr $failed + 1`
|
||||||
|
badones=`echo $badones " " $i`
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
skipped=`expr $skipped + 1`
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
# Print results of the tests.
|
# Print results of the tests.
|
||||||
echo " "
|
echo " "
|
||||||
if test $total = $passed
|
if test $total = $passed
|
||||||
then echo All $passed tests completed without error.
|
then echo All $passed tests completed without error \($skipped skipped\).
|
||||||
else echo Testing completed. Score: $passed passed, $failed failed
|
else echo Testing completed. Score: $passed passed, $failed failed, \
|
||||||
|
skipped $skipped
|
||||||
echo The following tests failed: $badones
|
echo The following tests failed: $badones
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
85
test/test45.c
Normal file
85
test/test45.c
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#define MAX_ERROR 4
|
||||||
|
static int errct;
|
||||||
|
|
||||||
|
/* test strtol */
|
||||||
|
#define TYPE long
|
||||||
|
#define TYPEU unsigned long
|
||||||
|
#define TYPE_FUNC strtol
|
||||||
|
#include "test45.h"
|
||||||
|
#undef TYPE
|
||||||
|
#undef TYPEU
|
||||||
|
#undef TYPE_FUNC
|
||||||
|
|
||||||
|
/* test strtoul */
|
||||||
|
#define TYPE unsigned long
|
||||||
|
#define TYPEU unsigned long
|
||||||
|
#define TYPE_FUNC strtoul
|
||||||
|
#include "test45.h"
|
||||||
|
#undef TYPE
|
||||||
|
#undef TYPEU
|
||||||
|
#undef TYPE_FUNC
|
||||||
|
|
||||||
|
#ifdef __LONG_LONG_SUPPORTED
|
||||||
|
|
||||||
|
/* test strtoll */
|
||||||
|
#define TYPE long long
|
||||||
|
#define TYPEU unsigned long long
|
||||||
|
#define TYPE_FUNC strtoll
|
||||||
|
#include "test45.h"
|
||||||
|
#undef TYPE
|
||||||
|
#undef TYPEU
|
||||||
|
#undef TYPE_FUNC
|
||||||
|
|
||||||
|
/* test strtoull */
|
||||||
|
#define TYPE long long
|
||||||
|
#define TYPEU unsigned long long
|
||||||
|
#define TYPE_FUNC strtoull
|
||||||
|
#include "test45.h"
|
||||||
|
#undef TYPE
|
||||||
|
#undef TYPEU
|
||||||
|
#undef TYPE_FUNC
|
||||||
|
|
||||||
|
#endif /* defined(__LONG_LONG_SUPPORTED) */
|
||||||
|
|
||||||
|
static void quit(void)
|
||||||
|
{
|
||||||
|
if (errct == 0)
|
||||||
|
{
|
||||||
|
printf("ok\n");
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("%d errors\n", errct);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
#ifdef __LONG_LONG_SUPPORTED
|
||||||
|
printf("Test 45 (GCC) ");
|
||||||
|
#else
|
||||||
|
printf("Test 45 (ACK) ");
|
||||||
|
#endif
|
||||||
|
fflush(stdout);
|
||||||
|
|
||||||
|
/* run long/unsigned long tests */
|
||||||
|
test_strtol();
|
||||||
|
test_strtoul();
|
||||||
|
|
||||||
|
/* run long long/unsigned long long tests (GCC only) */
|
||||||
|
#ifdef __LONG_LONG_SUPPORTED
|
||||||
|
test_strtoll();
|
||||||
|
test_strtoull();
|
||||||
|
#endif /* defined(__LONG_LONG_SUPPORTED) */
|
||||||
|
|
||||||
|
quit();
|
||||||
|
return -1; /* never happens */
|
||||||
|
}
|
157
test/test45.h
Normal file
157
test/test45.h
Normal file
|
@ -0,0 +1,157 @@
|
||||||
|
#define GLUE_HELPER(x, y) x ## _ ## y
|
||||||
|
#define GLUE(x, y) GLUE_HELPER(x, y)
|
||||||
|
#define TOSTRING(x) #x
|
||||||
|
|
||||||
|
static const char *GLUE(make_string, TYPE_FUNC)(TYPE value, int base)
|
||||||
|
{
|
||||||
|
static char buffer[66];
|
||||||
|
char *s; /* allows 64-bit base 2 value with minus and null */
|
||||||
|
TYPEU valuetemp;
|
||||||
|
|
||||||
|
/* build number string in proper base, work backwards, starting with null */
|
||||||
|
s = buffer + sizeof(buffer);
|
||||||
|
*--s = 0;
|
||||||
|
|
||||||
|
/* fill in the digits */
|
||||||
|
valuetemp = (value < 0) ? -value : value;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
*--s = "0123456789abcdefghijklmnopqrstuvwxyz"[valuetemp % base];
|
||||||
|
valuetemp /= base;
|
||||||
|
} while (valuetemp);
|
||||||
|
|
||||||
|
/* add sign if needed */
|
||||||
|
if (value < 0)
|
||||||
|
*--s = '-';
|
||||||
|
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void GLUE(e, TYPE_FUNC)(int n, const char *s, TYPE result, int base)
|
||||||
|
{
|
||||||
|
/* watch out: don't overwrite the static buffer in make_string */
|
||||||
|
printf("Subtest %s, error %d, errno=%d, s=\"%s\", base=%d, ", TOSTRING(TYPE_FUNC), n, errno, s, base);
|
||||||
|
printf("result=%s\n", GLUE(make_string, TYPE_FUNC)(result, base));
|
||||||
|
if (errct++ > MAX_ERROR)
|
||||||
|
{
|
||||||
|
printf("Too many errors; test aborted\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void GLUE(test_string, TYPE_FUNC)(const char *s, TYPE value, int base)
|
||||||
|
{
|
||||||
|
char *end;
|
||||||
|
TYPE result;
|
||||||
|
|
||||||
|
/* must convert the entire string, resulting in the requested value */
|
||||||
|
result = TYPE_FUNC(s, &end, base);
|
||||||
|
if (result != value) GLUE(e, TYPE_FUNC)(1, s, result, base);
|
||||||
|
if (*end) GLUE(e, TYPE_FUNC)(2, s, result, base);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void GLUE(test_value_with_base, TYPE_FUNC)(TYPE value, int base)
|
||||||
|
{
|
||||||
|
const char *s;
|
||||||
|
|
||||||
|
/* convert to string, then convert back */
|
||||||
|
s = GLUE(make_string, TYPE_FUNC)(value, base);
|
||||||
|
GLUE(test_string, TYPE_FUNC)(s, value, base);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void GLUE(test_value, TYPE_FUNC)(TYPE value)
|
||||||
|
{
|
||||||
|
int base;
|
||||||
|
|
||||||
|
/* let's get all our bases covered */
|
||||||
|
for (base = 2; base <= 36; base++)
|
||||||
|
GLUE(test_value_with_base, TYPE_FUNC)(value, base);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void GLUE(test, TYPE_FUNC)(void)
|
||||||
|
{
|
||||||
|
int base, i;
|
||||||
|
TYPE value, valuenext;
|
||||||
|
|
||||||
|
/* check 0x0000.... and 0xffff.... */
|
||||||
|
value = 0;
|
||||||
|
for (i = 0; i < 0x10000; i++)
|
||||||
|
{
|
||||||
|
/* test current value */
|
||||||
|
GLUE(test_value, TYPE_FUNC)(value);
|
||||||
|
GLUE(test_value, TYPE_FUNC)(-value);
|
||||||
|
value++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check 0x8000.... and 0x7fff.... */
|
||||||
|
value = 0;
|
||||||
|
value = ((~value) << 1) >> 1;
|
||||||
|
for (i = 0; i < 0x10000; i++)
|
||||||
|
{
|
||||||
|
/* test current value */
|
||||||
|
GLUE(test_value, TYPE_FUNC)(value);
|
||||||
|
GLUE(test_value, TYPE_FUNC)(-value);
|
||||||
|
value++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check powers of possible bases */
|
||||||
|
for (base = 2; base <= 36; base++)
|
||||||
|
{
|
||||||
|
value = 1;
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
/* test current value with offsets */
|
||||||
|
for (i = -36; i <= 36; i++)
|
||||||
|
{
|
||||||
|
GLUE(test_value, TYPE_FUNC)(value + i);
|
||||||
|
GLUE(test_value, TYPE_FUNC)(-value + i);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* stop after overflow */
|
||||||
|
valuenext = value * base;
|
||||||
|
if (valuenext <= value)
|
||||||
|
break;
|
||||||
|
|
||||||
|
value = valuenext;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* automatic base */
|
||||||
|
GLUE(test_string, TYPE_FUNC)("10", 10, 0);
|
||||||
|
GLUE(test_string, TYPE_FUNC)("010", 010, 0);
|
||||||
|
GLUE(test_string, TYPE_FUNC)("010", 010, 8);
|
||||||
|
GLUE(test_string, TYPE_FUNC)("0x10", 0x10, 0);
|
||||||
|
GLUE(test_string, TYPE_FUNC)("0X10", 0X10, 0);
|
||||||
|
GLUE(test_string, TYPE_FUNC)("0x10", 0x10, 16);
|
||||||
|
GLUE(test_string, TYPE_FUNC)("0X10", 0X10, 16);
|
||||||
|
|
||||||
|
/* ignore plus sign, leading spaces and zeroes */
|
||||||
|
GLUE(test_string, TYPE_FUNC)("10", 10, 10);
|
||||||
|
GLUE(test_string, TYPE_FUNC)("010", 10, 10);
|
||||||
|
GLUE(test_string, TYPE_FUNC)("0010", 10, 10);
|
||||||
|
GLUE(test_string, TYPE_FUNC)(" 10", 10, 10);
|
||||||
|
GLUE(test_string, TYPE_FUNC)(" 010", 10, 10);
|
||||||
|
GLUE(test_string, TYPE_FUNC)(" 0010", 10, 10);
|
||||||
|
GLUE(test_string, TYPE_FUNC)("\t10", 10, 10);
|
||||||
|
GLUE(test_string, TYPE_FUNC)("\t010", 10, 10);
|
||||||
|
GLUE(test_string, TYPE_FUNC)("\t0010", 10, 10);
|
||||||
|
GLUE(test_string, TYPE_FUNC)(" \t10", 10, 10);
|
||||||
|
GLUE(test_string, TYPE_FUNC)(" \t010", 10, 10);
|
||||||
|
GLUE(test_string, TYPE_FUNC)(" \t0010", 10, 10);
|
||||||
|
GLUE(test_string, TYPE_FUNC)("+10", 10, 10);
|
||||||
|
GLUE(test_string, TYPE_FUNC)("+010", 10, 10);
|
||||||
|
GLUE(test_string, TYPE_FUNC)("+0010", 10, 10);
|
||||||
|
GLUE(test_string, TYPE_FUNC)(" +10", 10, 10);
|
||||||
|
GLUE(test_string, TYPE_FUNC)(" +010", 10, 10);
|
||||||
|
GLUE(test_string, TYPE_FUNC)(" +0010", 10, 10);
|
||||||
|
GLUE(test_string, TYPE_FUNC)("\t+10", 10, 10);
|
||||||
|
GLUE(test_string, TYPE_FUNC)("\t+010", 10, 10);
|
||||||
|
GLUE(test_string, TYPE_FUNC)("\t+0010", 10, 10);
|
||||||
|
GLUE(test_string, TYPE_FUNC)(" \t+10", 10, 10);
|
||||||
|
GLUE(test_string, TYPE_FUNC)(" \t+010", 10, 10);
|
||||||
|
GLUE(test_string, TYPE_FUNC)(" \t+0010", 10, 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef GLUE_HELPER
|
||||||
|
#undef GLUE
|
||||||
|
#undef TOSTRING
|
Loading…
Reference in a new issue