From 34087a9f9031761c2f02b12306d1822ebb1ab8b4 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Wed, 17 Apr 2019 23:13:07 +0200 Subject: [PATCH] LibC: Bring the C library close enough to newlib to trick GCC. Now we can build GCC with --with-newlib, which hopefully cuts down on weird toolchain build issues. --- LibC/ctype.cpp | 27 +++++++++- LibC/ctype.h | 129 ++++++++++++++---------------------------------- LibC/iconv.h | 13 +++++ LibC/stdlib.cpp | 8 +++ LibC/stdlib.h | 1 + 5 files changed, 83 insertions(+), 95 deletions(-) create mode 100644 LibC/iconv.h diff --git a/LibC/ctype.cpp b/LibC/ctype.cpp index af37f95036..9d4c426ba7 100644 --- a/LibC/ctype.cpp +++ b/LibC/ctype.cpp @@ -1,16 +1,39 @@ #include #include -int __tolower(int c) +extern "C" { + +const char _ctype_[256] = { + _C, _C, _C, _C, _C, _C, _C, _C, + _C, _C|_S, _C|_S, _C|_S, _C|_S, _C|_S, _C, _C, + _C, _C, _C, _C, _C, _C, _C, _C, + _C, _C, _C, _C, _C, _C, _C, _C, + (char)(_S|_B), _P, _P, _P, _P, _P, _P, _P, + _P, _P, _P, _P, _P, _P, _P, _P, + _N, _N, _N, _N, _N, _N, _N, _N, + _N, _N, _P, _P, _P, _P, _P, _P, + _P, _U|_X, _U|_X, _U|_X, _U|_X, _U|_X, _U|_X, _U, + _U, _U, _U, _U, _U, _U, _U, _U, + _U, _U, _U, _U, _U, _U, _U, _U, + _U, _U, _U, _P, _P, _P, _P, _P, + _P, _L|_X, _L|_X, _L|_X, _L|_X, _L|_X, _L|_X, _L, + _L, _L, _L, _L, _L, _L, _L, _L, + _L, _L, _L, _L, _L, _L, _L, _L, + _L, _L, _L, _P, _P, _P, _P, _C +}; + +int tolower(int c) { if (c >= 'A' && c <= 'Z') return c | 0x20; return c; } -int __toupper(int c) +int toupper(int c) { if (c >= 'a' && c <= 'z') return c & ~0x20; return c; } + +} diff --git a/LibC/ctype.h b/LibC/ctype.h index 03ee173e05..17ab57c471 100644 --- a/LibC/ctype.h +++ b/LibC/ctype.h @@ -5,102 +5,45 @@ __BEGIN_DECLS -ALWAYS_INLINE int __isascii(int ch) -{ - return (ch & ~0x7f) == 0; -} +/* Do what newlib does to appease GCC's --with-newlib option. */ +#define _U 01 +#define _L 02 +#define _N 04 +#define _S 010 +#define _P 020 +#define _C 040 +#define _X 0100 +#define _B 0200 -ALWAYS_INLINE int __isspace(int ch) -{ - return ch == ' ' || ch == '\f' || ch == '\n' || ch == '\r' || ch == '\t' || ch == '\v'; -} +extern const char _ctype_[256]; -ALWAYS_INLINE int __islower(int c) -{ - return c >= 'a' && c <= 'z'; -} +int tolower(int); +int toupper(int); +int isalnum(int); +int isalpha(int); +int iscntrl(int); +int isdigit(int); +int isxdigit(int); +int isspace(int); +int ispunct(int); +int isprint(int); +int isgraph(int); +int islower(int); +int isupper(int); -ALWAYS_INLINE int __isupper(int c) -{ - return c >= 'A' && c <= 'Z'; -} +#define isalnum(c) (_ctype_[(int)(c)] & (_U | _L | _N)) +#define isalpha(c) (_ctype_[(int)(c)] & (_U | _L)) +#define iscntrl(c) (_ctype_[(int)(c)] & (_C)) +#define isdigit(c) (_ctype_[(int)(c)] & (_N)) +#define isxdigit(c) (_ctype_[(int)(c)] & (_N | _X)) +#define isspace(c) (_ctype_[(int)(c)] & (_S)) +#define ispunct(c) (_ctype_[(int)(c)] & (_P)) +#define isprint(c) (_ctype_[(int)(c)] & (_P|_U|_L|_N|_B)) +#define isgraph(c) (_ctype_[(int)(c)] & (_P|_U|_L|_N)) +#define islower(c) ((_ctype_[(int)(c)] & (_U | _L)) == _L) +#define isupper(c) ((_ctype_[(int)(c)] & (_U | _L)) == _U) -int __tolower(int); -int __toupper(int); - -ALWAYS_INLINE int __isdigit(int c) -{ - return c >= '0' && c <= '9'; -} - -ALWAYS_INLINE int __ispunct(int c) -{ - const char* punctuation_characters = "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~"; - return !!strchr(punctuation_characters, c); -} - -ALWAYS_INLINE int __isprint(int c) -{ - return c >= 0x20 && c != 0x7f; -} - -ALWAYS_INLINE int __isalpha(int c) -{ - return __isupper(c) || __islower(c); -} - -ALWAYS_INLINE int __isalnum(int c) -{ - return __isalpha(c) || __isdigit(c); -} - -ALWAYS_INLINE int __iscntrl(int c) -{ - return (c >= 0 && c <= 0x1f) || c == 0x7f; -} - -ALWAYS_INLINE int __isxdigit(int c) -{ - return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'); -} - -ALWAYS_INLINE int __isgraph(int c) -{ - return __isalnum(c) || __ispunct(c); -} - -#ifdef __cplusplus -#define __CTYPE_FUNC(name) static inline int name(int c) { return __ ## name(c); } - -__CTYPE_FUNC(isascii) -__CTYPE_FUNC(isspace) -__CTYPE_FUNC(islower) -__CTYPE_FUNC(isupper) -__CTYPE_FUNC(tolower) -__CTYPE_FUNC(toupper) -__CTYPE_FUNC(isdigit) -__CTYPE_FUNC(ispunct) -__CTYPE_FUNC(isprint) -__CTYPE_FUNC(isalpha) -__CTYPE_FUNC(isalnum) -__CTYPE_FUNC(iscntrl) -__CTYPE_FUNC(isxdigit) -__CTYPE_FUNC(isgraph) -#else -#define isascii(c) __isascii(c) -#define isspace(c) __isspace(c) -#define islower(c) __islower(c) -#define isupper(c) __isupper(c) -#define tolower(c) __tolower(c) -#define toupper(c) __toupper(c) -#define isdigit(c) __isdigit(c) -#define ispunct(c) __ispunct(c) -#define isprint(c) __isprint(c) -#define isalpha(c) __isalpha(c) -#define isalnum(c) __isalnum(c) -#define iscntrl(c) __iscntrl(c) -#define isxdigit(c) __isxdigit(c) -#define isgraph(c) __isgraph(c) -#endif +#define isascii(c) ((unsigned)c <= 127) +#define toascii(c) ((c) & 127) __END_DECLS diff --git a/LibC/iconv.h b/LibC/iconv.h new file mode 100644 index 0000000000..4f5b9ae2bc --- /dev/null +++ b/LibC/iconv.h @@ -0,0 +1,13 @@ +#pragma once + +#include + +__BEGIN_DECLS + +typedef void * iconv_t; + +extern iconv_t iconv_open(const char* tocode, const char* fromcode); +extern size_t iconv(iconv_t, char** inbuf, size_t* inbytesleft, char** outbuf, size_t* outbytesleft); +extern int iconv_close(iconv_t); + +__END_DECLS diff --git a/LibC/stdlib.cpp b/LibC/stdlib.cpp index cc152b9b12..07096155a3 100644 --- a/LibC/stdlib.cpp +++ b/LibC/stdlib.cpp @@ -274,6 +274,14 @@ double strtod(const char* str, char** endptr) assert(false); } +float strtof(const char* str, char** endptr) +{ + (void)str; + (void)endptr; + dbgprintf("LibC: strtof: '%s'\n", str); + assert(false); +} + double atof(const char* str) { dbgprintf("LibC: atof: '%s'\n", str); diff --git a/LibC/stdlib.h b/LibC/stdlib.h index cd5ff2c297..0b4f0dea9a 100644 --- a/LibC/stdlib.h +++ b/LibC/stdlib.h @@ -20,6 +20,7 @@ int atoi(const char*); long atol(const char*); long long atoll(const char*); double strtod(const char*, char** endptr); +float strtof(const char*, char** endptr); long strtol(const char*, char** endptr, int base); unsigned long strtoul(const char*, char** endptr, int base); void qsort(void* base, size_t nmemb, size_t size, int (*compar)(const void*, const void*));