diff --git a/lib/libc/core/CMakeLists.txt b/lib/libc/core/CMakeLists.txt index e618c23..2fc7684 100644 --- a/lib/libc/core/CMakeLists.txt +++ b/lib/libc/core/CMakeLists.txt @@ -1,4 +1,4 @@ -set(source_dirs stdio string errno) +set(source_dirs assert stdio stdlib string errno ctype wctype) foreach (dir ${source_dirs}) file(GLOB dir_sources ${CMAKE_CURRENT_SOURCE_DIR}/${dir}/*.c) diff --git a/lib/libc/core/assert/assert.c b/lib/libc/core/assert/assert.c new file mode 100644 index 0000000..e71a78e --- /dev/null +++ b/lib/libc/core/assert/assert.c @@ -0,0 +1,10 @@ +#include + +extern void __libc_assert_failed( + const char *file, + int line, + const char *func, + const char *cond) +{ + abort(); +} diff --git a/lib/libc/core/ctype/isalnum.c b/lib/libc/core/ctype/isalnum.c new file mode 100644 index 0000000..2b3e396 --- /dev/null +++ b/lib/libc/core/ctype/isalnum.c @@ -0,0 +1,16 @@ +int isalnum(int c) +{ + if (c >= 'a' && c <= 'z') { + return 1; + } + + if (c >= 'A' && c <= 'A') { + return 1; + } + + if (c >= '0' && c <= '9') { + return 1; + } + + return 0; +} diff --git a/lib/libc/core/ctype/isalpha.c b/lib/libc/core/ctype/isalpha.c new file mode 100644 index 0000000..6dc30be --- /dev/null +++ b/lib/libc/core/ctype/isalpha.c @@ -0,0 +1,12 @@ +int isalpha(int c) +{ + if (c >= 'a' && c <= 'z') { + return 1; + } + + if (c >= 'A' && c <= 'A') { + return 1; + } + + return 0; +} diff --git a/lib/libc/core/ctype/isdigit.c b/lib/libc/core/ctype/isdigit.c new file mode 100644 index 0000000..2cc16d7 --- /dev/null +++ b/lib/libc/core/ctype/isdigit.c @@ -0,0 +1,10 @@ +#include + +int isdigit(int c) +{ + if (c >= '0' && c <= '9') { + return 1; + } + + return 0; +} diff --git a/lib/libc/core/ctype/ispunct.c b/lib/libc/core/ctype/ispunct.c new file mode 100644 index 0000000..9a83e58 --- /dev/null +++ b/lib/libc/core/ctype/ispunct.c @@ -0,0 +1,22 @@ +#include + +int ispunct(int c) +{ + if (c >= 0x21 && c <= 0x2E) { + return 1; + } + + if (c >= 0x3A && c <= 0x40) { + return 1; + } + + if (c >= 0x5B && c <= 0x60) { + return 1; + } + + if (c >= 0x7B && c <= 0x7E) { + return 1; + } + + return 0; +} diff --git a/lib/libc/core/ctype/isspace.c b/lib/libc/core/ctype/isspace.c new file mode 100644 index 0000000..b73fae5 --- /dev/null +++ b/lib/libc/core/ctype/isspace.c @@ -0,0 +1,13 @@ +#include + +int isspace(int c) +{ + switch (c) { + case ' ': + case '\n': + case '\t': + return 1; + default: + return 0; + } +} diff --git a/lib/libc/core/ctype/isupper.c b/lib/libc/core/ctype/isupper.c new file mode 100644 index 0000000..f85ea9b --- /dev/null +++ b/lib/libc/core/ctype/isupper.c @@ -0,0 +1,8 @@ +int isupper(int c) +{ + if (c >= 'A' && c <= 'Z') { + return 1; + } + + return 0; +} diff --git a/lib/libc/core/ctype/isxdigit.c b/lib/libc/core/ctype/isxdigit.c new file mode 100644 index 0000000..b7b7ae6 --- /dev/null +++ b/lib/libc/core/ctype/isxdigit.c @@ -0,0 +1,18 @@ +#include + +int isxdigit(int c) +{ + if (c >= 'a' && c <= 'f') { + return 1; + } + + if (c >= 'A' && c <= 'F') { + return 1; + } + + if (c >= '0' && c <= '9') { + return 1; + } + + return 0; +} diff --git a/lib/libc/core/ctype/tolower.c b/lib/libc/core/ctype/tolower.c new file mode 100644 index 0000000..d93fcab --- /dev/null +++ b/lib/libc/core/ctype/tolower.c @@ -0,0 +1,8 @@ +int tolower(int c) +{ + if (c >= 'A' && c <= 'Z') { + return (c - 'A') + 'a'; + } + + return c; +} diff --git a/lib/libc/core/ctype/toupper.c b/lib/libc/core/ctype/toupper.c new file mode 100644 index 0000000..26a870e --- /dev/null +++ b/lib/libc/core/ctype/toupper.c @@ -0,0 +1,8 @@ +int toupper(int c) +{ + if (c >= 'a' && c <= 'z') { + return (c - 'a') + 'A'; + } + + return c; +} diff --git a/lib/libc/core/stdlib/abort.c b/lib/libc/core/stdlib/abort.c new file mode 100644 index 0000000..42dbb1f --- /dev/null +++ b/lib/libc/core/stdlib/abort.c @@ -0,0 +1,6 @@ +#include + +void abort(void) +{ + task_exit(-1); +} diff --git a/lib/libc/core/stdlib/atexit.c b/lib/libc/core/stdlib/atexit.c new file mode 100644 index 0000000..6dbe40b --- /dev/null +++ b/lib/libc/core/stdlib/atexit.c @@ -0,0 +1,6 @@ + +int atexit(void (*func)(void)) +{ + /* TODO */ + return 0; +} diff --git a/lib/libc/core/stdlib/exit.c b/lib/libc/core/stdlib/exit.c new file mode 100644 index 0000000..6ea6ca7 --- /dev/null +++ b/lib/libc/core/stdlib/exit.c @@ -0,0 +1,6 @@ +#include + +void exit(int code) +{ + task_exit(code); +} diff --git a/lib/libc/core/stdlib/strtol.c b/lib/libc/core/stdlib/strtol.c new file mode 100644 index 0000000..5b30439 --- /dev/null +++ b/lib/libc/core/stdlib/strtol.c @@ -0,0 +1,99 @@ +/* + * Copyright (c) 1990 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. [rescinded 22 July 1999] + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include + +long strtol(const char *restrict ptr, char **restrict endptr, register int base) +{ + const char *s = ptr; + long acc; + int c; + long cutoff; + int neg = 0, any, cutlim; + + do { + c = *s++; + } while (isspace(c)); + + if (c == '-') { + neg = 1; + c = *s++; + } else if (c == '+') { + c = *s++; + } + + if ((base == 0 || base == 16) && c == '0' && (*s == 'x' || *s == 'X')) { + c = s[1]; + s += 2; + base = 16; + } + + if (base == 0) { + base = c == '0' ? 8 : 10; + } + + cutoff = (long)LONG_MAX / (long)base; + cutlim = (long)LONG_MAX % (long)base; + for (acc = 0, any = 0;; c = *s++) { + if (isdigit(c)) { + c -= '0'; + } else if (isalpha(c)) { + c -= isupper(c) ? 'A' - 10 : 'a' - 10; + } else { + break; + } + + if (c >= base) { + break; + } + + if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) { + any = -1; + } else { + any = 1; + acc *= base; + acc += c; + } + } + if (any < 0) { + acc = LONG_MAX; + __set_errno(ERANGE); + } else if (neg) { + acc = -acc; + } + + if (endptr != 0) { + *endptr = (char *)(any ? s - 1 : ptr); + } + + return (acc); +} diff --git a/lib/libc/core/stdlib/strtoll.c b/lib/libc/core/stdlib/strtoll.c new file mode 100644 index 0000000..0e3e008 --- /dev/null +++ b/lib/libc/core/stdlib/strtoll.c @@ -0,0 +1,102 @@ +/* + * Copyright (c) 1990 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. [rescinded 22 July 1999] + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include + +long long strtoll( + const char *restrict ptr, + char **restrict endptr, + register int base) +{ + const char *s = ptr; + long long acc; + int c; + long long cutoff; + int neg = 0, any, cutlim; + + do { + c = *s++; + } while (isspace(c)); + + if (c == '-') { + neg = 1; + c = *s++; + } else if (c == '+') { + c = *s++; + } + + if ((base == 0 || base == 16) && c == '0' && (*s == 'x' || *s == 'X')) { + c = s[1]; + s += 2; + base = 16; + } + + if (base == 0) { + base = c == '0' ? 8 : 10; + } + + cutoff = (long long)LLONG_MAX / (long long)base; + cutlim = (long long)LLONG_MAX % (long long)base; + for (acc = 0, any = 0;; c = *s++) { + if (isdigit(c)) { + c -= '0'; + } else if (isalpha(c)) { + c -= isupper(c) ? 'A' - 10 : 'a' - 10; + } else { + break; + } + + if (c >= base) { + break; + } + + if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) { + any = -1; + } else { + any = 1; + acc *= base; + acc += c; + } + } + if (any < 0) { + acc = LONG_MAX; + __set_errno(ERANGE); + } else if (neg) { + acc = -acc; + } + + if (endptr != 0) { + *endptr = (char *)(any ? s - 1 : ptr); + } + + return (acc); +} diff --git a/lib/libc/core/stdlib/strtoul.c b/lib/libc/core/stdlib/strtoul.c new file mode 100644 index 0000000..0cb8a46 --- /dev/null +++ b/lib/libc/core/stdlib/strtoul.c @@ -0,0 +1,102 @@ +/* + * Copyright (c) 1990 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. [rescinded 22 July 1999] + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include + +unsigned long strtoul( + const char *restrict ptr, + char **restrict endptr, + register int base) +{ + const char *s = ptr; + unsigned long acc; + int c; + unsigned long cutoff; + int neg = 0, any, cutlim; + + do { + c = *s++; + } while (isspace(c)); + + if (c == '-') { + neg = 1; + c = *s++; + } else if (c == '+') { + c = *s++; + } + + if ((base == 0 || base == 16) && c == '0' && (*s == 'x' || *s == 'X')) { + c = s[1]; + s += 2; + base = 16; + } + + if (base == 0) { + base = c == '0' ? 8 : 10; + } + + cutoff = (unsigned long)ULONG_MAX / (unsigned long)base; + cutlim = (unsigned long)ULONG_MAX % (unsigned long)base; + for (acc = 0, any = 0;; c = *s++) { + if (isdigit(c)) { + c -= '0'; + } else if (isalpha(c)) { + c -= isupper(c) ? 'A' - 10 : 'a' - 10; + } else { + break; + } + + if (c >= base) { + break; + } + + if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) { + any = -1; + } else { + any = 1; + acc *= base; + acc += c; + } + } + if (any < 0) { + acc = ULONG_MAX; + __set_errno(ERANGE); + } else if (neg) { + acc = -acc; + } + + if (endptr != 0) { + *endptr = (char *)(any ? s - 1 : ptr); + } + + return (acc); +} diff --git a/lib/libc/core/stdlib/strtoull.c b/lib/libc/core/stdlib/strtoull.c new file mode 100644 index 0000000..cb86dfc --- /dev/null +++ b/lib/libc/core/stdlib/strtoull.c @@ -0,0 +1,102 @@ +/* + * Copyright (c) 1990 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. [rescinded 22 July 1999] + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include + +unsigned long long strtoull( + const char *restrict ptr, + char **restrict endptr, + register int base) +{ + const char *s = ptr; + unsigned long long acc; + int c; + unsigned long long cutoff; + int neg = 0, any, cutlim; + + do { + c = *s++; + } while (isspace(c)); + + if (c == '-') { + neg = 1; + c = *s++; + } else if (c == '+') { + c = *s++; + } + + if ((base == 0 || base == 16) && c == '0' && (*s == 'x' || *s == 'X')) { + c = s[1]; + s += 2; + base = 16; + } + + if (base == 0) { + base = c == '0' ? 8 : 10; + } + + cutoff = (unsigned long long)ULLONG_MAX / (unsigned long long)base; + cutlim = (unsigned long long)ULLONG_MAX % (unsigned long long)base; + for (acc = 0, any = 0;; c = *s++) { + if (isdigit(c)) { + c -= '0'; + } else if (isalpha(c)) { + c -= isupper(c) ? 'A' - 10 : 'a' - 10; + } else { + break; + } + + if (c >= base) { + break; + } + + if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) { + any = -1; + } else { + any = 1; + acc *= base; + acc += c; + } + } + if (any < 0) { + acc = ULLONG_MAX; + __set_errno(ERANGE); + } else if (neg) { + acc = -acc; + } + + if (endptr != 0) { + *endptr = (char *)(any ? s - 1 : ptr); + } + + return (acc); +} diff --git a/lib/libc/core/wctype/iswnumber.c b/lib/libc/core/wctype/iswnumber.c new file mode 100644 index 0000000..dd1bf7c --- /dev/null +++ b/lib/libc/core/wctype/iswnumber.c @@ -0,0 +1,8 @@ +#include +#include + +int iswnumber(wchar_t c) +{ + /* TODO locale support */ + return isdigit((int)c); +} diff --git a/lib/libc/core/wctype/iswpunct.c b/lib/libc/core/wctype/iswpunct.c new file mode 100644 index 0000000..cd259da --- /dev/null +++ b/lib/libc/core/wctype/iswpunct.c @@ -0,0 +1,8 @@ +#include +#include + +int iswpunct(wchar_t c) +{ + /* TODO locale support */ + return ispunct((int)c); +} diff --git a/lib/libc/core/wctype/iswspace.c b/lib/libc/core/wctype/iswspace.c new file mode 100644 index 0000000..41168cd --- /dev/null +++ b/lib/libc/core/wctype/iswspace.c @@ -0,0 +1,8 @@ +#include +#include + +int iswspace(wchar_t c) +{ + /* TODO locale support */ + return isspace((int)c); +} diff --git a/lib/libc/core/wctype/iswxdigit.c b/lib/libc/core/wctype/iswxdigit.c new file mode 100644 index 0000000..602b316 --- /dev/null +++ b/lib/libc/core/wctype/iswxdigit.c @@ -0,0 +1,8 @@ +#include +#include + +int iswxdigit(wchar_t c) +{ + /* TODO locale support */ + return isxdigit((int)c); +}