mirror of
https://git.planet-casio.com/Vhex-Kernel-Core/fxlibc.git
synced 2024-12-29 13:03:38 +01:00
stdlib: add and test strtoull (DONE)
This commit is contained in:
parent
41ab197ba2
commit
b1dc3e77de
4 changed files with 111 additions and 1 deletions
|
@ -106,6 +106,7 @@ set(SOURCES
|
||||||
src/libc/stdlib/llabs.c
|
src/libc/stdlib/llabs.c
|
||||||
src/libc/stdlib/lldiv.c
|
src/libc/stdlib/lldiv.c
|
||||||
src/libc/stdlib/reallocarray.c
|
src/libc/stdlib/reallocarray.c
|
||||||
|
src/libc/stdlib/strtoull.c
|
||||||
# string
|
# string
|
||||||
src/libc/string/strchr.c
|
src/libc/string/strchr.c
|
||||||
src/libc/string/strcpy.c
|
src/libc/string/strcpy.c
|
||||||
|
|
8
STATUS
8
STATUS
|
@ -67,6 +67,8 @@ DONE: Function/symbol/macro is defined, builds, links, and is tested
|
||||||
files in /usr/share/i18n/locales
|
files in /usr/share/i18n/locales
|
||||||
-> Implement setlocale() and localeconv() properly (not hard)
|
-> Implement setlocale() and localeconv() properly (not hard)
|
||||||
-> Probably support nl_langinfo(), which is much better than localeconv()
|
-> Probably support nl_langinfo(), which is much better than localeconv()
|
||||||
|
-> Fix the "TODO: locale: ..." messages wherever assumptions on the locale
|
||||||
|
are made in the code
|
||||||
|
|
||||||
7.12 <math.h>
|
7.12 <math.h>
|
||||||
Provided by Lephenixnoir's port of OpenLibm.
|
Provided by Lephenixnoir's port of OpenLibm.
|
||||||
|
@ -95,7 +97,11 @@ DONE: Function/symbol/macro is defined, builds, links, and is tested
|
||||||
TODO (will give the full list later on)
|
TODO (will give the full list later on)
|
||||||
|
|
||||||
7.20 <stdlib.h>
|
7.20 <stdlib.h>
|
||||||
7.20.1 Numeric conversion functions: TODO
|
7.20.1.1 atof: TODO
|
||||||
|
7.20.1.2 atoi, atol, atoll: TODO
|
||||||
|
7.20.1.3 strtod, strtof, strtold: TODO
|
||||||
|
7.20.1.4 strtol, strtoul, strtoll: TODO
|
||||||
|
strtoull: DONE
|
||||||
7.20.2 Pseudo-random sequence generation functions: TODO
|
7.20.2 Pseudo-random sequence generation functions: TODO
|
||||||
7.20.3 Memory management functions: TODO (check existing code first)
|
7.20.3 Memory management functions: TODO (check existing code first)
|
||||||
7.20.4 Communication with the environment: TODO
|
7.20.4 Communication with the environment: TODO
|
||||||
|
|
|
@ -63,4 +63,45 @@ div_t div(int __num, int __denom);
|
||||||
ldiv_t ldiv(long int __num, long int __denom);
|
ldiv_t ldiv(long int __num, long int __denom);
|
||||||
lldiv_t lldiv(long long int __num, long long int __denom);
|
lldiv_t lldiv(long long int __num, long long int __denom);
|
||||||
|
|
||||||
|
/* Numeric conversion functions. */
|
||||||
|
|
||||||
|
/* Parse a long int from a string. */
|
||||||
|
extern long int strtol(
|
||||||
|
char const * restrict __ptr,
|
||||||
|
char ** restrict __endptr,
|
||||||
|
int __base);
|
||||||
|
|
||||||
|
/* Parse a long unsigned int from a string. */
|
||||||
|
extern unsigned long int strtoul(
|
||||||
|
char const * restrict __ptr,
|
||||||
|
char ** restrict __endptr,
|
||||||
|
int __base);
|
||||||
|
|
||||||
|
/* Parse a long long int from a string. */
|
||||||
|
extern long long int strtoll(
|
||||||
|
char const * restrict __ptr,
|
||||||
|
char ** restrict __endptr,
|
||||||
|
int __base);
|
||||||
|
|
||||||
|
/* Parse a long long unsigned int from a string. */
|
||||||
|
extern unsigned long long int strtoull(
|
||||||
|
char const * restrict __ptr,
|
||||||
|
char ** restrict __endptr,
|
||||||
|
int __base);
|
||||||
|
|
||||||
|
/* Parse a double from a string. */
|
||||||
|
extern double strtod(
|
||||||
|
char const * restrict __ptr,
|
||||||
|
char ** restrict __endptr);
|
||||||
|
|
||||||
|
/* Parse a float from a string. */
|
||||||
|
extern float strtof(
|
||||||
|
char const * restrict __ptr,
|
||||||
|
char ** restrict __endptr);
|
||||||
|
|
||||||
|
/* Parse a long double from a string. */
|
||||||
|
extern long double strtold(
|
||||||
|
char const * restrict __ptr,
|
||||||
|
char ** restrict __endptr);
|
||||||
|
|
||||||
#endif /*__STDLIB_H__*/
|
#endif /*__STDLIB_H__*/
|
||||||
|
|
62
src/libc/stdlib/strtoull.c
Normal file
62
src/libc/stdlib/strtoull.c
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
unsigned long long int strtoull(char const * restrict ptr,
|
||||||
|
char ** restrict endptr, int base)
|
||||||
|
{
|
||||||
|
/* Save the value of ptr in endptr now in case the format is invalid */
|
||||||
|
if(endptr) *endptr = (char *)ptr;
|
||||||
|
|
||||||
|
/* Skip initial whitespace */
|
||||||
|
while(isspace(*ptr)) ptr++;
|
||||||
|
|
||||||
|
/* Accept a sign character */
|
||||||
|
bool negative = false;
|
||||||
|
if(*ptr == '-') negative = true;
|
||||||
|
if(*ptr == '-' || *ptr == '+') ptr++;
|
||||||
|
|
||||||
|
unsigned long long x = 0;
|
||||||
|
bool valid = false;
|
||||||
|
|
||||||
|
/* Read prefixes and determine base */
|
||||||
|
if((base == 0 || base == 16) && ptr[0]=='0' && tolower(ptr[1])=='x') {
|
||||||
|
ptr += 2;
|
||||||
|
base = 16;
|
||||||
|
}
|
||||||
|
else if(base == 0 && ptr[0] == '0') {
|
||||||
|
ptr++;
|
||||||
|
base = 8;
|
||||||
|
}
|
||||||
|
else if(base == 0) {
|
||||||
|
base = 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Read digits */
|
||||||
|
while(1) {
|
||||||
|
int v = -1;
|
||||||
|
if(isdigit(*ptr)) v = *ptr - '0';
|
||||||
|
if(islower(*ptr)) v = *ptr - 'a' + 10;
|
||||||
|
if(v == -1 || v >= base) break;
|
||||||
|
|
||||||
|
/* The value is valid as long as there is at least one digit */
|
||||||
|
valid = true;
|
||||||
|
|
||||||
|
/* (x = base*x + v) but with overflow checks */
|
||||||
|
if(__builtin_umulll_overflow(x, base, &x))
|
||||||
|
errno = ERANGE;
|
||||||
|
if(__builtin_uaddll_overflow(x, v, &x))
|
||||||
|
errno = ERANGE;
|
||||||
|
|
||||||
|
ptr++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(negative) {
|
||||||
|
if(x != 0) errno = ERANGE;
|
||||||
|
x = -x;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(endptr && valid) *endptr = (char *)ptr;
|
||||||
|
return x;
|
||||||
|
}
|
Loading…
Reference in a new issue