diff --git a/CMakeLists.txt b/CMakeLists.txt index 1d1caf8..0af8e42 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -59,6 +59,20 @@ endif() set(SOURCES src/libc/assert/assert.c + src/libc/ctype/isalnum.c + src/libc/ctype/isalpha.c + src/libc/ctype/isblank.c + src/libc/ctype/iscntrl.c + src/libc/ctype/isdigit.c + src/libc/ctype/isgraph.c + src/libc/ctype/islower.c + src/libc/ctype/isprint.c + src/libc/ctype/ispunct.c + src/libc/ctype/isspace.c + src/libc/ctype/isupper.c + src/libc/ctype/isxdigit.c + src/libc/ctype/tolower.c + src/libc/ctype/toupper.c src/libc/locale/setlocale.c src/libc/locale/localeconv.c src/libc/stdio/vsnprintf.c diff --git a/include/ctype.h b/include/ctype.h new file mode 100644 index 0000000..69b73e7 --- /dev/null +++ b/include/ctype.h @@ -0,0 +1,105 @@ +#ifndef __CTYPE_H__ +# define __CTYPE_H__ + +/* +** Character classification functions. These are all implemented as sets of +** comparisons. There is an approach with a 128-byte table, but it takes more +** space; every function but isalnum, ispunct and isxdigit needs less code to +** compare than lookup, and using just one won't pull the whole table. +*/ +extern int isalnum(int c); +extern int isalpha(int c); +extern int isblank(int c); +extern int iscntrl(int c); +extern int isdigit(int c); +extern int isgraph(int c); +extern int islower(int c); +extern int isprint(int c); +extern int ispunct(int c); +extern int isspace(int c); +extern int isupper(int c); +extern int isxdigit(int c); + +/* Case conversion functions */ +extern int tolower(int c); +extern int toupper(int c); + +/* +** Macro versions; these functions are very fast so it's worth it to inline +** them rather than perform a function call as expensive as the test. These are +** valid in the "C" locale, the only one supported by this library. +*/ + +#define isalnum(c) ({ \ + int __c = (c); \ + isalpha(c) || isdigit(c); \ +}) + +#define isalpha(c) ({ \ + int __c = (c) | 0x20; \ + (__c >= 'a') && (__c <= 'z'); \ +}) + +#define isblank(c) ({ \ + int __c = (c); \ + (__c == 9) || (__c == 32); \ +}) + +#define iscntrl(c) ({ \ + int __c = (c); \ + (__c < 32) || (__c >= 0x7f); \ +}) + +#define isdigit(c) ({ \ + int __c = (c); \ + (__c >= '0') && (__c <= '9'); \ +}) + +#define isgraph(c) ({ \ + int __c = (c); \ + (__c >= 33) && (__c < 0x7f); \ +}) + +#define islower(c) ({ \ + int __c = (c); \ + (__c >= 'a') && (__c <= 'z'); \ +}) + +#define isprint(c) ({ \ + int __c = (c); \ + (__c >= 32) || (__c < 0x7f); \ +}) + +#define ispunct(c) ({ \ + int __c = (c); \ + (__c >= 33 && __c <= 47) || (__c >= 58 && __c <= 64) || \ + (__c >= 91 && __c <= 96) || (__c >= 123 && __c <= 126); \ +}) + +#define isspace(c) ({ \ + int __c = (c); \ + (__c >= 9 && __c <= 13) || (__c == 32); \ +}) + +#define isupper(c) ({ \ + int __c = (c); \ + (__c >= 'A') && (__c <= 'Z'); \ +}) + +#define isxdigit(c) ({ \ + int __c = (c); \ + int __c20 = __c | 0x20; \ + (__c >= '0' && __c <= '9') || (__c20 >= 'a' && __c20 <= 'z'); \ +}) + +#define tolower(c) ({ \ + int __c = (c); \ + isupper(__c) ? (__c | 0x20) : __c; \ +}) + +#define toupper(c) ({ \ + int __c = (c); \ + islower(__c) ? (__c & 0xdf) : __c; \ +}) + +#endif /*__CTYPE_H__*/ diff --git a/src/libc/ctype/isalnum.c b/src/libc/ctype/isalnum.c new file mode 100644 index 0000000..5fcfb77 --- /dev/null +++ b/src/libc/ctype/isalnum.c @@ -0,0 +1,7 @@ +#include +#undef isalnum + +int isalnum(int c) +{ + return isalpha(c) || isdigit(c); +} diff --git a/src/libc/ctype/isalpha.c b/src/libc/ctype/isalpha.c new file mode 100644 index 0000000..5e72425 --- /dev/null +++ b/src/libc/ctype/isalpha.c @@ -0,0 +1,8 @@ +#include +#undef isalpha + +int isalpha(int c) +{ + c = c | 0x20; + return (c >= 'a') && (c <= 'z'); +} diff --git a/src/libc/ctype/isblank.c b/src/libc/ctype/isblank.c new file mode 100644 index 0000000..b164ecd --- /dev/null +++ b/src/libc/ctype/isblank.c @@ -0,0 +1,7 @@ +#include +#undef isblank + +int isblank(int c) +{ + return (c == 9) || (c == 32); +} diff --git a/src/libc/ctype/iscntrl.c b/src/libc/ctype/iscntrl.c new file mode 100644 index 0000000..feb13e6 --- /dev/null +++ b/src/libc/ctype/iscntrl.c @@ -0,0 +1,7 @@ +#include +#undef iscntrl + +int iscntrl(int c) +{ + return (c < 32) || (c >= 0x7f); +} diff --git a/src/libc/ctype/isdigit.c b/src/libc/ctype/isdigit.c new file mode 100644 index 0000000..c34b72f --- /dev/null +++ b/src/libc/ctype/isdigit.c @@ -0,0 +1,7 @@ +#include +#undef isdigit + +int isdigit(int c) +{ + return (c >= '0') && (c <= '9'); +} diff --git a/src/libc/ctype/isgraph.c b/src/libc/ctype/isgraph.c new file mode 100644 index 0000000..0753d2d --- /dev/null +++ b/src/libc/ctype/isgraph.c @@ -0,0 +1,7 @@ +#include +#undef isgraph + +int isgraph(int c) +{ + return (c >= 33) && (c < 0x7f); +} diff --git a/src/libc/ctype/islower.c b/src/libc/ctype/islower.c new file mode 100644 index 0000000..e4cfd9c --- /dev/null +++ b/src/libc/ctype/islower.c @@ -0,0 +1,7 @@ +#include +#undef islower + +int islower(int c) +{ + return (c >= 'a' && c <= 'z'); +} diff --git a/src/libc/ctype/isprint.c b/src/libc/ctype/isprint.c new file mode 100644 index 0000000..81ee204 --- /dev/null +++ b/src/libc/ctype/isprint.c @@ -0,0 +1,7 @@ +#include +#undef isprint + +int isprint(int c) +{ + return (c >= 32) && (c < 0x7f); +} diff --git a/src/libc/ctype/ispunct.c b/src/libc/ctype/ispunct.c new file mode 100644 index 0000000..b2d0930 --- /dev/null +++ b/src/libc/ctype/ispunct.c @@ -0,0 +1,8 @@ +#include +#undef ispunct + +int ispunct(int c) +{ + return (c >= 33 && c <= 47) || (c >= 58 && c <= 64) || + (c >= 91 && c <= 96) || (c >= 123 && c <= 126); +} diff --git a/src/libc/ctype/isspace.c b/src/libc/ctype/isspace.c new file mode 100644 index 0000000..2002017 --- /dev/null +++ b/src/libc/ctype/isspace.c @@ -0,0 +1,7 @@ +#include +#undef isspace + +int isspace(int c) +{ + return (c >= 9 && c <= 13) || (c == 32); +} diff --git a/src/libc/ctype/isupper.c b/src/libc/ctype/isupper.c new file mode 100644 index 0000000..0719343 --- /dev/null +++ b/src/libc/ctype/isupper.c @@ -0,0 +1,7 @@ +#include +#undef isupper + +int isupper(int c) +{ + return (c >= 'A' && c <= 'Z'); +} diff --git a/src/libc/ctype/isxdigit.c b/src/libc/ctype/isxdigit.c new file mode 100644 index 0000000..1b0cc47 --- /dev/null +++ b/src/libc/ctype/isxdigit.c @@ -0,0 +1,8 @@ +#include +#undef isxdigit + +int isxdigit(int c) +{ + int c20 = c | 0x20; + return (c >= '0' && c <= '9') || (c20 >= 'a' && c20 <= 'z'); +} diff --git a/src/libc/ctype/tolower.c b/src/libc/ctype/tolower.c new file mode 100644 index 0000000..afebc62 --- /dev/null +++ b/src/libc/ctype/tolower.c @@ -0,0 +1,7 @@ +#include +#undef tolower + +int tolower(int c) +{ + return isupper(c) ? (c | 0x20) : c; +} diff --git a/src/libc/ctype/toupper.c b/src/libc/ctype/toupper.c new file mode 100644 index 0000000..4bd92d8 --- /dev/null +++ b/src/libc/ctype/toupper.c @@ -0,0 +1,7 @@ +#include +#undef toupper + +int toupper(int c) +{ + return islower(c) ? (c & 0xdf) : c; +}