Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

libc improvements: ctype, errno, div/ldiv/lldiv, strerror; math.h, ti… #128

Merged
merged 1 commit into from
Jul 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 5 additions & 0 deletions mos-platform/common/c/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ add_platform_library(common-c
# ctype.h
ctype.c

# errno.h
errno.c

# setjmp.h
setjmp.S

Expand All @@ -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
Expand Down
64 changes: 53 additions & 11 deletions mos-platform/common/c/ctype.c
Original file line number Diff line number Diff line change
@@ -1,30 +1,47 @@
#include <ctype.h>

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) {
char ch = (char)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) {
Expand All @@ -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;
}
14 changes: 14 additions & 0 deletions mos-platform/common/c/div.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#include <stdlib.h>

template <typename T, typename R> 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<int, div_t>(numer, denom); }
ldiv_t ldiv(long numer, long denom) { return _div<long, ldiv_t>(numer, denom); }
lldiv_t lldiv(long long numer, long long denom) { return _div<long long, lldiv_t>(numer, denom); }
}
1 change: 1 addition & 0 deletions mos-platform/common/c/errno.c
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
int _errno = 0;
17 changes: 17 additions & 0 deletions mos-platform/common/c/strerror.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#include <string.h>

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 "";
}
}
24 changes: 16 additions & 8 deletions mos-platform/common/include/ctype.h
Original file line number Diff line number Diff line change
@@ -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
}
Expand Down
22 changes: 22 additions & 0 deletions mos-platform/common/include/errno.h
Original file line number Diff line number Diff line change
@@ -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_
24 changes: 24 additions & 0 deletions mos-platform/common/include/math.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Stub implementation of math.h.

#ifndef _MATH_H_
#define _MATH_H_

#include <stddef.h>

#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_
18 changes: 18 additions & 0 deletions mos-platform/common/include/stdlib.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down
3 changes: 2 additions & 1 deletion mos-platform/common/include/string.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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.
Expand Down
18 changes: 18 additions & 0 deletions mos-platform/common/include/time.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Stub implementation of time.h.

#ifndef _TIME_H_
#define _TIME_H_

#include <stddef.h>

#ifdef __cplusplus
extern "C" {
#endif

typedef long time_t;

#ifdef __cplusplus
}
#endif

#endif // not _TIME_H_
21 changes: 21 additions & 0 deletions mos-platform/common/include/wchar.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Stub implementation of wchar.h.

#ifndef _WCHAR_H_
#define _WCHAR_H_

#include <stddef.h>

#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_