diff --git a/CMakeLists.txt b/CMakeLists.txt index dd2baa6..84fdb18 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -58,7 +58,9 @@ endif() # Building set(SOURCES + # assert src/libc/assert/assert.c + # ctype src/libc/ctype/isalnum.c src/libc/ctype/isalpha.c src/libc/ctype/isblank.c @@ -73,9 +75,12 @@ set(SOURCES src/libc/ctype/isxdigit.c src/libc/ctype/tolower.c src/libc/ctype/toupper.c + # errno src/libc/errno/errno.c + # locale src/libc/locale/setlocale.c src/libc/locale/localeconv.c + # stdio src/libc/stdio/vsnprintf.c src/libc/stdio/sprintf.c src/libc/stdio/dprintf.c @@ -89,8 +94,16 @@ set(SOURCES src/libc/stdio/internal/printf.h src/libc/stdio/vdprintf.c src/libc/stdio/printf.c + # stdlib + src/libc/stdlib/abs.c src/libc/stdlib/calloc.c + src/libc/stdlib/div.c + src/libc/stdlib/labs.c + src/libc/stdlib/ldiv.c + src/libc/stdlib/llabs.c + src/libc/stdlib/lldiv.c src/libc/stdlib/reallocarray.c + # string src/libc/string/strchr.c src/libc/string/strcpy.c src/libc/string/memcpy.c diff --git a/STATUS b/STATUS index f6daea7..10e883b 100644 --- a/STATUS +++ b/STATUS @@ -95,7 +95,15 @@ DONE: Function/symbol/macro is defined, builds, links, and is tested TODO (will give the full list later on) 7.20 - TODO (will give the full list later on) + 7.20.1 Numeric conversion functions: TODO + 7.20.2 Pseudo-random sequence generation functions: TODO + 7.20.3 Memory management functions: TODO (check existing code first) + 7.20.4 Communication with the environment: TODO + 7.20.5 Searching and sorting utilities: TODO + 7.20.6.1 abs, labs, llabs: TEST + 7.20.6.2 div, ldiv, lldiv: TEST + 7.20.7 Multibyte/wide character conversion functions: TODO + 7.20.8 Multibyte/wide string conversion functions: TODO 7.21 TODO (will give the full list later on) diff --git a/include/stdlib.h b/include/stdlib.h index b087499..8dd0dd5 100644 --- a/include/stdlib.h +++ b/include/stdlib.h @@ -4,9 +4,8 @@ #include #include -//--- -// Dynamic memory management -//--- +/* Dynamic memory management. */ + /* Allocate SIZE bytes of memory. */ extern void *malloc(size_t size); @@ -28,4 +27,40 @@ extern void *reallocarray(void *ptr, size_t nmemb, size_t size); /* Free a block allocated by `malloc', `realloc' or `calloc'. */ extern void free(void *ptr); +/* Integer arithmetic functions. */ + +extern int abs(int __j); +#define abs(j) ({ \ + int __j = (j); \ + (__j >= 0) ? __j : -(__j); \ +}) + +extern long int labs(long int __j); +#define labs(j) ({ \ + long int __j = (j); \ + (__j >= 0) ? __j : -(__j); \ +}) + +extern long long int llabs(long long int __j); +#define llabs(j) ({ \ + long long int __j = (j); \ + (__j >= 0) ? __j : -(__j); \ +}) + +typedef struct { + int quot, rem; +} div_t; + +typedef struct { + long int quot, rem; +} ldiv_t; + +typedef struct { + long long int quot, rem; +} lldiv_t; + +div_t div(int __num, int __denom); +ldiv_t ldiv(long int __num, long int __denom); +lldiv_t lldiv(long long int __num, long long int __denom); + #endif /*__STDLIB_H__*/ diff --git a/src/libc/stdlib/abs.c b/src/libc/stdlib/abs.c new file mode 100644 index 0000000..bc6b856 --- /dev/null +++ b/src/libc/stdlib/abs.c @@ -0,0 +1,7 @@ +#include +#undef abs + +int abs(int j) +{ + return (j >= 0) ? j : -j; +} diff --git a/src/libc/stdlib/div.c b/src/libc/stdlib/div.c new file mode 100644 index 0000000..48be8a4 --- /dev/null +++ b/src/libc/stdlib/div.c @@ -0,0 +1,12 @@ +#include + +div_t div(int num, int denom) +{ + /* + ** On SuperH, division and modulus are both very slow, so it's more + ** efficient to perform only one division. + */ + int q = num / denom; + int r = num - q * denom; + return (div_t){ q, r }; +} diff --git a/src/libc/stdlib/labs.c b/src/libc/stdlib/labs.c new file mode 100644 index 0000000..d060f3a --- /dev/null +++ b/src/libc/stdlib/labs.c @@ -0,0 +1,7 @@ +#include +#undef labs + +long int labs(long int j) +{ + return (j >= 0) ? j : -j; +} diff --git a/src/libc/stdlib/ldiv.c b/src/libc/stdlib/ldiv.c new file mode 100644 index 0000000..0570517 --- /dev/null +++ b/src/libc/stdlib/ldiv.c @@ -0,0 +1,8 @@ +#include + +ldiv_t ldiv(long int num, long int denom) +{ + long int q = num / denom; + long int r = num - q * denom; + return (ldiv_t){ q, r }; +} diff --git a/src/libc/stdlib/llabs.c b/src/libc/stdlib/llabs.c new file mode 100644 index 0000000..f4d01a8 --- /dev/null +++ b/src/libc/stdlib/llabs.c @@ -0,0 +1,7 @@ +#include +#undef llabs + +long long int llabs(long long int j) +{ + return (j >= 0) ? j : -j; +} diff --git a/src/libc/stdlib/lldiv.c b/src/libc/stdlib/lldiv.c new file mode 100644 index 0000000..27adfde --- /dev/null +++ b/src/libc/stdlib/lldiv.c @@ -0,0 +1,8 @@ +#include + +lldiv_t lldiv(long long int num, long long int denom) +{ + long long int q = num / denom; + long long int r = num - q * denom; + return (lldiv_t){ q, r }; +}