Implementation of strto(u)ll, documentation and tests for strto(u)l(l)

This commit is contained in:
Erik van der Kouwe
2009-12-09 19:01:38 +00:00
parent fcaaad3317
commit 6adadade32
9 changed files with 429 additions and 17 deletions

View File

@@ -1,19 +1,22 @@
# Makefile for the tests.
CC = exec cc
GCC = /usr/gnu/bin/gcc
CFLAGS= -O -D_MINIX -D_POSIX_SOURCE
CFLAGS-GCC= $(CFLAGS) -Wall
OBJ= test1 test2 test3 test4 test5 test6 test7 test8 test9 \
test10 test12 test13 test14 test15 test16 test17 test18 test19 \
test21 test22 test23 test25 test26 test27 test28 test29 \
test30 test31 test32 test34 test35 test36 test37 test38 \
test39 t10a t11a t11b test40 t40a t40b t40c t40d t40e t40f test41 \
test42 test44
test42 test44 test45
BIGOBJ= test20 test24
ROOTOBJ= test11 test33 test43
GCCOBJ= test45-gcc
all: $(OBJ) $(BIGOBJ) $(ROOTOBJ)
all: $(OBJ) $(BIGOBJ) $(GCCOBJ) $(ROOTOBJ)
chmod 755 *.sh run
$(OBJ):
@@ -22,6 +25,9 @@ $(OBJ):
$(BIGOBJ):
$(CC) $(CFLAGS) -o $@ $@.c
$(GCCOBJ):
[ ! -x $(GCC) ] || $(GCC) $(CFLAGS-GCC) -o $@ $<
$(ROOTOBJ):
$(CC) $(CFLAGS) $@.c
@install -c -o root -m 4755 a.out $@
@@ -29,7 +35,7 @@ $(ROOTOBJ):
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*
test1: test1.c
@@ -85,3 +91,6 @@ test41: test41.c
test42: test42.c
test43: test43.c
test44: test44.c
test45: test45.c test45.h
test45-gcc: test45.c test45.h

View File

@@ -7,6 +7,7 @@ export PATH
rm -rf DIR* # remove any old junk lying around
passed=`expr 0` # count number of tests run correctly
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
badones= # list of tests that failed
@@ -18,26 +19,32 @@ echo " "
# 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 \
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
do total=`expr $total + 1`
FAIL=0
if [ $USER = root -a \( $i = 11 -o $i = 33 \) ]
then su - ast -c "cd `pwd`; ./test$i" || FAIL=1
else ./test$i || FAIL=1
fi
if [ $FAIL -eq 0 ]
then passed=`expr $passed + 1`
else failed=`expr $failed + 1`
badones=`echo $badones " " $i`
41 42 43 44 45 45-gcc sh1.sh sh2.sh
do
if [ -x ./test$i ]
then
total=`expr $total + 1`
FAIL=0
if [ $USER = root -a \( $i = 11 -o $i = 33 \) ]
then su - ast -c "cd `pwd`; ./test$i" || FAIL=1
else ./test$i || FAIL=1
fi
if [ $FAIL -eq 0 ]
then passed=`expr $passed + 1`
else failed=`expr $failed + 1`
badones=`echo $badones " " $i`
fi
else
skipped=`expr $skipped + 1`
fi
done
# Print results of the tests.
echo " "
if test $total = $passed
then echo All $passed tests completed without error.
else echo Testing completed. Score: $passed passed, $failed failed
then echo All $passed tests completed without error \($skipped skipped\).
else echo Testing completed. Score: $passed passed, $failed failed, \
skipped $skipped
echo The following tests failed: $badones
fi

85
test/test45.c Normal file
View 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
View 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