From a1d997f342e9fd774b7b9fed2a2853e9c860e11b Mon Sep 17 00:00:00 2001 From: Adrian Siekierka Date: Sat, 1 Jul 2023 11:29:18 +0200 Subject: [PATCH] libc improvements: ctype, errno, div/ldiv/lldiv, strerror; math.h, time.h, wchar.h stubs --- mos-platform/common/c/CMakeLists.txt | 5 +++ mos-platform/common/c/ctype.c | 64 +++++++++++++++++++++++----- mos-platform/common/c/div.cc | 14 ++++++ mos-platform/common/c/errno.c | 1 + mos-platform/common/c/strerror.c | 17 ++++++++ mos-platform/common/include/ctype.h | 24 +++++++---- mos-platform/common/include/errno.h | 22 ++++++++++ mos-platform/common/include/math.h | 24 +++++++++++ mos-platform/common/include/stdlib.h | 18 ++++++++ mos-platform/common/include/string.h | 3 +- mos-platform/common/include/time.h | 18 ++++++++ mos-platform/common/include/wchar.h | 21 +++++++++ 12 files changed, 211 insertions(+), 20 deletions(-) create mode 100644 mos-platform/common/c/div.cc create mode 100644 mos-platform/common/c/errno.c create mode 100644 mos-platform/common/c/strerror.c create mode 100644 mos-platform/common/include/errno.h create mode 100644 mos-platform/common/include/math.h create mode 100644 mos-platform/common/include/time.h create mode 100644 mos-platform/common/include/wchar.h diff --git a/mos-platform/common/c/CMakeLists.txt b/mos-platform/common/c/CMakeLists.txt index 21cef3a5b..645b04445 100644 --- a/mos-platform/common/c/CMakeLists.txt +++ b/mos-platform/common/c/CMakeLists.txt @@ -3,6 +3,9 @@ add_platform_library(common-c # ctype.h ctype.c + # errno.h + errno.c + # setjmp.h setjmp.S @@ -12,11 +15,13 @@ add_platform_library(common-c # stdlib.h abs.cc + div.cc stdlib.cc new.cc # string.h mem.c + strerror.c string.c # exception diff --git a/mos-platform/common/c/ctype.c b/mos-platform/common/c/ctype.c index 9b25439f8..d1e92262e 100644 --- a/mos-platform/common/c/ctype.c +++ b/mos-platform/common/c/ctype.c @@ -1,8 +1,23 @@ #include -int isprint(int c) { +int isalnum(int c) { + return isalpha(c) || isdigit(c); +} + +int isalpha(int c) { + char ch = (char)c; + return ((ch >= 'A') && (ch <= 'Z')) + || ((ch >= 'a') && (ch <= 'z')); +} + +int isblank(int c) { char ch = (char)c; - return ch >= 0x1f && ch < 0x7f /*DEL*/; + return ch == ' ' || ch == '\t'; +} + +int iscntrl(int c) { + char ch = (char)c; + return ch < ' '; } int isdigit(int c) { @@ -10,21 +25,23 @@ int isdigit(int c) { return ch >= '0' && ch <= '9'; } -int isalpha(int c) { +int isgraph(int c) { char ch = (char)c; - return ((ch >= 'A') && (ch <= 'Z')) - || ((ch >= 'a') && (ch <= 'z')); + return isprint(c) && (c != ' '); } -int toupper(int c) { +int islower(int c) { char ch = (char)c; - if ((ch >= 'a') && (ch <= 'z')) - ch &= ~0x20; - return ch; + return ch >= 'a' && ch <= 'z'; } -int isalnum(int c) { - return isalpha(c) || isdigit(c); +int isprint(int c) { + char ch = (char)c; + return ch > 0x1f && ch < 0x7f /*DEL*/; +} + +int ispunct(int c) { + return isprint(c) && !isspace(c) && !isalnum(c); } int isspace(int c) { @@ -33,3 +50,28 @@ int isspace(int c) { (ch == '\f') || (ch == '\r') || (ch == '\v'); } +int isupper(int c) { + char ch = (char)c; + return ch >= 'A' && ch <= 'Z'; +} + +int isxdigit(int c) { + char ch = (char)c; + return ((ch >= '0') && (ch <= '9')) + || ((ch >= 'a') && (ch <= 'f')) + || ((ch >= 'A') && (ch <= 'F')); +} + +int tolower(int c) { + char ch = (char)c; + if ((ch >= 'A') && (ch <= 'Z')) + ch |= 0x20; + return ch; +} + +int toupper(int c) { + char ch = (char)c; + if ((ch >= 'a') && (ch <= 'z')) + ch &= ~0x20; + return ch; +} diff --git a/mos-platform/common/c/div.cc b/mos-platform/common/c/div.cc new file mode 100644 index 000000000..d55e1fd11 --- /dev/null +++ b/mos-platform/common/c/div.cc @@ -0,0 +1,14 @@ +#include + +template static inline R _div(T numer, T denom) { + R result; + result.quot = numer / denom; + result.rem = numer % denom; + return result; +} + +extern "C" { +div_t div(int numer, int denom) { return _div(numer, denom); } +ldiv_t ldiv(long numer, long denom) { return _div(numer, denom); } +lldiv_t lldiv(long long numer, long long denom) { return _div(numer, denom); } +} diff --git a/mos-platform/common/c/errno.c b/mos-platform/common/c/errno.c new file mode 100644 index 000000000..acfee44d8 --- /dev/null +++ b/mos-platform/common/c/errno.c @@ -0,0 +1 @@ +int _errno = 0; diff --git a/mos-platform/common/c/strerror.c b/mos-platform/common/c/strerror.c new file mode 100644 index 000000000..5367adaaf --- /dev/null +++ b/mos-platform/common/c/strerror.c @@ -0,0 +1,17 @@ +#include + +static const char *errors[] = { + "ERANGE", + "EDOM", + "EILSEQ", + "EINVAL", + "ENOMEM" +}; + +__attribute__((weak)) const char *strerror(int n) { + if (n > 0) { + return errors[((unsigned char) n) - 1]; + } else { + return ""; + } +} diff --git a/mos-platform/common/include/ctype.h b/mos-platform/common/include/ctype.h index 859d19730..eacaffbe5 100644 --- a/mos-platform/common/include/ctype.h +++ b/mos-platform/common/include/ctype.h @@ -1,16 +1,24 @@ -#ifndef _CYTPE_H_ -#define _CYTPE_H_ +#ifndef _CTYPE_H_ +#define _CTYPE_H_ #ifdef __cplusplus extern "C" { #endif -extern int isprint(int c); -extern int isdigit(int c); -extern int isalpha(int c); -extern int toupper(int c); -extern int isspace(int c); -extern int isalnum(int c); +int isalnum(int c); +int isalpha(int c); +int isblank(int c); +int iscntrl(int c); +int isdigit(int c); +int isgraph(int c); +int islower(int c); +int isprint(int c); +int ispunct(int c); +int isspace(int c); +int isupper(int c); +int isxdigit(int c); +int tolower(int c); +int toupper(int c); #ifdef __cplusplus } diff --git a/mos-platform/common/include/errno.h b/mos-platform/common/include/errno.h new file mode 100644 index 000000000..beec0a0ff --- /dev/null +++ b/mos-platform/common/include/errno.h @@ -0,0 +1,22 @@ +#ifndef _ERRNO_H_ +#define _ERRNO_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +extern int _errno; +#define errno (_errno) + +#define ERANGE 1 +#define EDOM 2 +#define EILSEQ 3 +#define EINVAL 4 +#define ENOMEM 5 +#define ELAST 5 + +#ifdef __cplusplus +} +#endif + +#endif // not _ERRNO_H_ diff --git a/mos-platform/common/include/math.h b/mos-platform/common/include/math.h new file mode 100644 index 000000000..20d1f28e0 --- /dev/null +++ b/mos-platform/common/include/math.h @@ -0,0 +1,24 @@ +// Stub implementation of math.h. + +#ifndef _MATH_H_ +#define _MATH_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define FP_NORMAL 0 +#define FP_SUBNORMAL 1 +#define FP_ZERO 2 +#define FP_INFINITE 3 +#define FP_NAN 4 + +#define INFINITY (1.0f / 0.0f) + +#ifdef __cplusplus +} +#endif + +#endif // not _MATH_H_ diff --git a/mos-platform/common/include/stdlib.h b/mos-platform/common/include/stdlib.h index 784b216a3..51cbbdb08 100644 --- a/mos-platform/common/include/stdlib.h +++ b/mos-platform/common/include/stdlib.h @@ -25,6 +25,24 @@ int abs(int i); long labs(long i); long long llabs(long long i); +typedef struct { + int quot; + int rem; +} div_t; +div_t div(int numer, int denom); + +typedef struct { + long quot; + long rem; +} ldiv_t; +ldiv_t ldiv(long numer, long denom); + +typedef struct { + long long quot; + long long rem; +} lldiv_t; +lldiv_t lldiv(long long numer, long long denom); + /** Simple malloc/free implementation. diff --git a/mos-platform/common/include/string.h b/mos-platform/common/include/string.h index 4efc5e13d..de1b75262 100644 --- a/mos-platform/common/include/string.h +++ b/mos-platform/common/include/string.h @@ -20,6 +20,8 @@ int strcmp(const char *s1, const char *s2); char *strcpy(char * __restrict__ s1, const char * __restrict__ s2); +const char *strerror(int n); + size_t strlen(const char *s); int strncmp(const char *s1, const char *s2, size_t n); char *strncpy(char * __restrict__ s1, const char * __restrict__ s2, size_t n); @@ -30,7 +32,6 @@ size_t strspn(const char* string, const char* in); char* strpbrk(const char* string, const char* brk); char* strtok(char* string, const char* separators); - // Version of memset with better arguments for MOS. All non-pointer arguments // can fit in registers, and there is no superfluous return value. Compiler // intrinsic memset calls use this version, and user code is free to as well. diff --git a/mos-platform/common/include/time.h b/mos-platform/common/include/time.h new file mode 100644 index 000000000..f7d5bc7bf --- /dev/null +++ b/mos-platform/common/include/time.h @@ -0,0 +1,18 @@ +// Stub implementation of time.h. + +#ifndef _TIME_H_ +#define _TIME_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef long time_t; + +#ifdef __cplusplus +} +#endif + +#endif // not _TIME_H_ diff --git a/mos-platform/common/include/wchar.h b/mos-platform/common/include/wchar.h new file mode 100644 index 000000000..a3bd5dd81 --- /dev/null +++ b/mos-platform/common/include/wchar.h @@ -0,0 +1,21 @@ +// Stub implementation of wchar.h. + +#ifndef _WCHAR_H_ +#define _WCHAR_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef unsigned long mbstate_t; +typedef unsigned long wint_t; + +#define WEOF 0xFFFFFFFFul + +#ifdef __cplusplus +} +#endif + +#endif // not _WCHAR_H_