From 6ff0d9f87b0852fc9dd7a1b8bb3d771b93ba2bdb Mon Sep 17 00:00:00 2001 From: solar Date: Sat, 3 Dec 2005 16:50:08 +0000 Subject: [PATCH] Helper functions for strto...() functions. --- functions/_PDCLIB/strtox_main.c | 79 +++++++++++++++++++++++++++++++ functions/_PDCLIB/strtox_prelim.c | 77 ++++++++++++++++++++++++++++++ 2 files changed, 156 insertions(+) create mode 100644 functions/_PDCLIB/strtox_main.c create mode 100644 functions/_PDCLIB/strtox_prelim.c diff --git a/functions/_PDCLIB/strtox_main.c b/functions/_PDCLIB/strtox_main.c new file mode 100644 index 0000000..6ab56cd --- /dev/null +++ b/functions/_PDCLIB/strtox_main.c @@ -0,0 +1,79 @@ +/* $Id$ */ + +/* Release $Name$ */ + +/* _PDCLIB_strtox_main( const char * *, int, _PDCLIB_uintmax_t, _PDCLIB_uintmax_t, int ) + + This file is part of the Public Domain C Library (PDCLib). + Permission is granted to use, modify, and / or redistribute at will. +*/ + +#include <_PDCLIB_int.h> +#include +#include +#include + +_PDCLIB_uintmax_t _PDCLIB_strtox_main( const char ** p, int base, _PDCLIB_uintmax_t error, _PDCLIB_uintmax_t limval, int limdigit ) +{ + _PDCLIB_uintmax_t rc = 0; + int digit = -1; + const char * x; + while ( ( x = memchr( _PDCLIB_digits, toupper(**p), base ) ) != NULL ) + { + digit = x - _PDCLIB_digits; + if ( ( rc < limval ) || ( ( rc == limval ) && ( digit <= limdigit ) ) ) + { + rc = rc * base + ( x - _PDCLIB_digits ); + ++(*p); + } + else + { + errno = ERANGE; + /* TODO: Only if endptr != NULL */ + while ( memchr( _PDCLIB_digits, **p, base ) != NULL ) ++(*p); + return error; + } + } + if ( digit == -1 ) + { + *p = NULL; + return 0; + } + return rc; +} + +#ifdef TEST +#include <_PDCLIB_test.h> +#include + +int main() +{ + const char * p; + char test[] = "123_"; + char fail[] = "xxx"; + BEGIN_TESTS; + /* basic functionality */ + p = test; + errno = 0; + TESTCASE( _PDCLIB_strtox_main( &p, 10, 999, 12, 3 ) == 123 ); + TESTCASE( errno == 0 ); + TESTCASE( p == &test[3] ); + /* proper functioning to smaller base */ + p = test; + TESTCASE( _PDCLIB_strtox_main( &p, 8, 999, 12, 3 ) == 0123 ); + TESTCASE( errno == 0 ); + TESTCASE( p == &test[3] ); + /* overflowing subject sequence must still return proper endptr */ + p = test; + TESTCASE( _PDCLIB_strtox_main( &p, 4, 999, 1, 2 ) == 999 ); + TESTCASE( errno == ERANGE ); + TESTCASE( p == &test[3] ); + /* testing conversion failure */ + errno = 0; + p = fail; + TESTCASE( _PDCLIB_strtox_main( &p, 10, 999, 99, 8 ) == 0 ); + TESTCASE( p == NULL ); + return TEST_RESULTS; +} + +#endif diff --git a/functions/_PDCLIB/strtox_prelim.c b/functions/_PDCLIB/strtox_prelim.c new file mode 100644 index 0000000..8b0f442 --- /dev/null +++ b/functions/_PDCLIB/strtox_prelim.c @@ -0,0 +1,77 @@ +/* $Id$ */ + +/* Release $Name$ */ + +/* _PDCLIB_strtox_prelim( const char *, char *, int * ) + + This file is part of the Public Domain C Library (PDCLib). + Permission is granted to use, modify, and / or redistribute at will. +*/ + +#include + +const char * _PDCLIB_strtox_prelim( const char * p, char * sign, int * base ) +{ + /* skipping leading whitespace */ + while ( isspace( *p ) ) ++p; + /* determining / skipping sign */ + if ( *p != '+' && *p != '-' ) *sign = '+'; + else *sign = *(p++); + /* determining base */ + if ( *p == '0' ) + { + ++p; + if ( ( *base == 0 || *base == 16 ) && ( *p == 'x' || *p == 'X' ) ) + { + *base = 16; + ++p; + } + else if ( *base == 0 ) + { + *base = 8; + } + else + { + --p; + } + } + else if ( ! *base ) + { + *base = 10; + } + return p; +} + +#ifdef TEST +#include <_PDCLIB_test.h> + +int main() +{ + int base = 0; + char sign = '\0'; + char test1[] = " 123"; + char test2[] = "\t+0123"; + char test3[] = "\v-0x123"; + BEGIN_TESTS; + TESTCASE( _PDCLIB_strtox_prelim( test1, &sign, &base ) == &test1[2] ); + TESTCASE( sign == '+' ); + TESTCASE( base == 10 ); + base = 0; + sign = '\0'; + TESTCASE( _PDCLIB_strtox_prelim( test2, &sign, &base ) == &test2[3] ); + TESTCASE( sign == '+' ); + TESTCASE( base == 8 ); + base = 0; + sign = '\0'; + TESTCASE( _PDCLIB_strtox_prelim( test3, &sign, &base ) == &test3[4] ); + TESTCASE( sign == '-' ); + TESTCASE( base == 16 ); + base = 10; + sign = '\0'; + TESTCASE( _PDCLIB_strtox_prelim( test3, &sign, &base ) == &test3[2] ); + TESTCASE( sign == '-' ); + TESTCASE( base == 10 ); + return TEST_RESULTS; +} + +#endif -- 2.40.0