From 3c20633acb26837382cb77c959711d0de6f9f2ec Mon Sep 17 00:00:00 2001 From: Tom-on64 Date: Sat, 19 Oct 2024 15:11:54 +0200 Subject: [PATCH] Added most of ctype.h (missing toupper & tolower) --- libc/ctype/table.c | 115 +++++++++++++++++++++++++++++++++++++++++++ libc/include/ctype.h | 49 ++++++++++++++++++ 2 files changed, 164 insertions(+) create mode 100644 libc/ctype/table.c create mode 100644 libc/include/ctype.h diff --git a/libc/ctype/table.c b/libc/ctype/table.c new file mode 100644 index 0000000..3b95dff --- /dev/null +++ b/libc/ctype/table.c @@ -0,0 +1,115 @@ +#include + +const unsigned char _CTYPE_TABLE[256] = { + // Control characters (ASCII 0-31) + _CNTRL_MASK, _CNTRL_MASK, _CNTRL_MASK, _CNTRL_MASK, _CNTRL_MASK, _CNTRL_MASK, _CNTRL_MASK, _CNTRL_MASK, // 0-7 + _CNTRL_MASK, _CNTRL_MASK, _CNTRL_MASK, _CNTRL_MASK, _CNTRL_MASK, _CNTRL_MASK, _CNTRL_MASK, _CNTRL_MASK, // 8-15 + _CNTRL_MASK, _CNTRL_MASK, _CNTRL_MASK, _CNTRL_MASK, _CNTRL_MASK, _CNTRL_MASK, _CNTRL_MASK, _CNTRL_MASK, // 16-23 + _CNTRL_MASK, _CNTRL_MASK, _CNTRL_MASK, _CNTRL_MASK, _CNTRL_MASK, _CNTRL_MASK, _CNTRL_MASK, _CNTRL_MASK, // 24-31 + // Space (ASCII 32) + _SPACE_MASK | _PRINT_MASK, + // Punctuation (ASCII 33-47) + _PUNCT_MASK | _PRINT_MASK, // '!' (ASCII 33) + _PUNCT_MASK | _PRINT_MASK, // '"' (ASCII 34) + _PUNCT_MASK | _PRINT_MASK, // '#' (ASCII 35) + _PUNCT_MASK | _PRINT_MASK, // '$' (ASCII 36) + _PUNCT_MASK | _PRINT_MASK, // '%' (ASCII 37) + _PUNCT_MASK | _PRINT_MASK, // '&' (ASCII 38) + _PUNCT_MASK | _PRINT_MASK, // '\'' (ASCII 39) + _PUNCT_MASK | _PRINT_MASK, // '(' (ASCII 40) + _PUNCT_MASK | _PRINT_MASK, // ')' (ASCII 41) + _PUNCT_MASK | _PRINT_MASK, // '*' (ASCII 42) + _PUNCT_MASK | _PRINT_MASK, // '+' (ASCII 43) + _PUNCT_MASK | _PRINT_MASK, // ',' (ASCII 44) + _PUNCT_MASK | _PRINT_MASK, // '-' (ASCII 45) + _PUNCT_MASK | _PRINT_MASK, // '.' (ASCII 46) + _PUNCT_MASK | _PRINT_MASK, // '/' (ASCII 47) + // Digits (ASCII 48-57) + _DIGIT_MASK | _PRINT_MASK, // '0' (ASCII 48) + _DIGIT_MASK | _PRINT_MASK, // '1' (ASCII 49) + _DIGIT_MASK | _PRINT_MASK, // '2' (ASCII 50) + _DIGIT_MASK | _PRINT_MASK, // '3' (ASCII 51) + _DIGIT_MASK | _PRINT_MASK, // '4' (ASCII 52) + _DIGIT_MASK | _PRINT_MASK, // '5' (ASCII 53) + _DIGIT_MASK | _PRINT_MASK, // '6' (ASCII 54) + _DIGIT_MASK | _PRINT_MASK, // '7' (ASCII 55) + _DIGIT_MASK | _PRINT_MASK, // '8' (ASCII 56) + _DIGIT_MASK | _PRINT_MASK, // '9' (ASCII 57) + // Punctuation (ASCII 58-64) + _PUNCT_MASK | _PRINT_MASK, // ':' (ASCII 58) + _PUNCT_MASK | _PRINT_MASK, // ';' (ASCII 59) + _PUNCT_MASK | _PRINT_MASK, // '<' (ASCII 60) + _PUNCT_MASK | _PRINT_MASK, // '=' (ASCII 61) + _PUNCT_MASK | _PRINT_MASK, // '>' (ASCII 62) + _PUNCT_MASK | _PRINT_MASK, // '?' (ASCII 63) + _PUNCT_MASK | _PRINT_MASK, // '@' (ASCII 64) + // Upperchase letters (ASCII 65-90) + _ALPHA_MASK | _PRINT_MASK, // 'A' (ASCII 65) + _ALPHA_MASK | _PRINT_MASK, // 'B' (ASCII 66) + _ALPHA_MASK | _PRINT_MASK, // 'C' (ASCII 67) + _ALPHA_MASK | _PRINT_MASK, // 'D' (ASCII 68) + _ALPHA_MASK | _PRINT_MASK, // 'E' (ASCII 69) + _ALPHA_MASK | _PRINT_MASK, // 'F' (ASCII 70) + _ALPHA_MASK | _PRINT_MASK, // 'G' (ASCII 71) + _ALPHA_MASK | _PRINT_MASK, // 'H' (ASCII 72) + _ALPHA_MASK | _PRINT_MASK, // 'I' (ASCII 73) + _ALPHA_MASK | _PRINT_MASK, // 'J' (ASCII 74) + _ALPHA_MASK | _PRINT_MASK, // 'K' (ASCII 75) + _ALPHA_MASK | _PRINT_MASK, // 'L' (ASCII 76) + _ALPHA_MASK | _PRINT_MASK, // 'M' (ASCII 77) + _ALPHA_MASK | _PRINT_MASK, // 'N' (ASCII 78) + _ALPHA_MASK | _PRINT_MASK, // 'O' (ASCII 79) + _ALPHA_MASK | _PRINT_MASK, // 'P' (ASCII 80) + _ALPHA_MASK | _PRINT_MASK, // 'Q' (ASCII 81) + _ALPHA_MASK | _PRINT_MASK, // 'R' (ASCII 82) + _ALPHA_MASK | _PRINT_MASK, // 'S' (ASCII 83) + _ALPHA_MASK | _PRINT_MASK, // 'T' (ASCII 84) + _ALPHA_MASK | _PRINT_MASK, // 'U' (ASCII 85) + _ALPHA_MASK | _PRINT_MASK, // 'V' (ASCII 86) + _ALPHA_MASK | _PRINT_MASK, // 'W' (ASCII 87) + _ALPHA_MASK | _PRINT_MASK, // 'X' (ASCII 88) + _ALPHA_MASK | _PRINT_MASK, // 'Y' (ASCII 89) + _ALPHA_MASK | _PRINT_MASK, // 'Z' (ASCII 90) + // Punctuation (ASCII 91-96) + _PUNCT_MASK | _PRINT_MASK, // '[' (ASCII 91) + _PUNCT_MASK | _PRINT_MASK, // '\' (ASCII 92) + _PUNCT_MASK | _PRINT_MASK, // ']' (ASCII 93) + _PUNCT_MASK | _PRINT_MASK, // '^' (ASCII 94) + _PUNCT_MASK | _PRINT_MASK, // '_' (ASCII 95) + _PUNCT_MASK | _PRINT_MASK, // '`' (ASCII 96) + // Lowercase letters (ASCII 97-122) + _ALPHA_MASK | _LOWER_MASK | _PRINT_MASK, // 'a' (ASCII 97) + _ALPHA_MASK | _LOWER_MASK | _PRINT_MASK, // 'b' (ASCII 98) + _ALPHA_MASK | _LOWER_MASK | _PRINT_MASK, // 'c' (ASCII 99) + _ALPHA_MASK | _LOWER_MASK | _PRINT_MASK, // 'd' (ASCII 100) + _ALPHA_MASK | _LOWER_MASK | _PRINT_MASK, // 'e' (ASCII 101) + _ALPHA_MASK | _LOWER_MASK | _PRINT_MASK, // 'f' (ASCII 102) + _ALPHA_MASK | _LOWER_MASK | _PRINT_MASK, // 'g' (ASCII 103) + _ALPHA_MASK | _LOWER_MASK | _PRINT_MASK, // 'h' (ASCII 104) + _ALPHA_MASK | _LOWER_MASK | _PRINT_MASK, // 'i' (ASCII 105) + _ALPHA_MASK | _LOWER_MASK | _PRINT_MASK, // 'j' (ASCII 106) + _ALPHA_MASK | _LOWER_MASK | _PRINT_MASK, // 'k' (ASCII 107) + _ALPHA_MASK | _LOWER_MASK | _PRINT_MASK, // 'l' (ASCII 108) + _ALPHA_MASK | _LOWER_MASK | _PRINT_MASK, // 'm' (ASCII 109) + _ALPHA_MASK | _LOWER_MASK | _PRINT_MASK, // 'n' (ASCII 110) + _ALPHA_MASK | _LOWER_MASK | _PRINT_MASK, // 'o' (ASCII 111) + _ALPHA_MASK | _LOWER_MASK | _PRINT_MASK, // 'p' (ASCII 112) + _ALPHA_MASK | _LOWER_MASK | _PRINT_MASK, // 'q' (ASCII 113) + _ALPHA_MASK | _LOWER_MASK | _PRINT_MASK, // 'r' (ASCII 114) + _ALPHA_MASK | _LOWER_MASK | _PRINT_MASK, // 's' (ASCII 115) + _ALPHA_MASK | _LOWER_MASK | _PRINT_MASK, // 't' (ASCII 116) + _ALPHA_MASK | _LOWER_MASK | _PRINT_MASK, // 'u' (ASCII 117) + _ALPHA_MASK | _LOWER_MASK | _PRINT_MASK, // 'v' (ASCII 118) + _ALPHA_MASK | _LOWER_MASK | _PRINT_MASK, // 'w' (ASCII 119) + _ALPHA_MASK | _LOWER_MASK | _PRINT_MASK, // 'x' (ASCII 120) + _ALPHA_MASK | _LOWER_MASK | _PRINT_MASK, // 'y' (ASCII 121) + _ALPHA_MASK | _LOWER_MASK | _PRINT_MASK, // 'z' (ASCII 122) + // Punctuation (ASCII 123-126 + _PUNCT_MASK | _PRINT_MASK, // '{' (ASCII 123) + _PUNCT_MASK | _PRINT_MASK, // '|' (ASCII 124) + _PUNCT_MASK | _PRINT_MASK, // '}' (ASCII 125) + _PUNCT_MASK | _PRINT_MASK, // '~' (ASCII 126) + // Control character (ASCII 127) + _CNTRL_MASK // DEL (ASCII 127) +}; + diff --git a/libc/include/ctype.h b/libc/include/ctype.h new file mode 100644 index 0000000..3cf0133 --- /dev/null +++ b/libc/include/ctype.h @@ -0,0 +1,49 @@ +#ifndef _CTYPE_H +#define _CTYPE_H + +/* Bitfield values + Property | Bit + ------------|----- + Digit | 0 + Letter | 1 + Lowercase | 2 + Punct | 3 + Space | 4 + Control | 5 + Printable | 6 + Hex digit | 7 + */ +#define _DIGIT_MASK (1<<0) +#define _ALPHA_MASK (1<<1) +#define _LOWER_MASK (1<<2) +#define _PUNCT_MASK (1<<3) +#define _SPACE_MASK (1<<4) +#define _CNTRL_MASK (1<<5) +#define _PRINT_MASK (1<<6) +#define _HEXDG_MASK (1<<7) + +// A table for the ASCII character set +extern const unsigned char _CTYPE_TABLE[256]; + +// Just a macro to make this easier +#define _CTYPE_CHECK(_c, _mask) (_CTYPE_TABLE[(unsigned char)(_c)] & (_mask)) + +#define isalnum(_c) (isalpha((_c)) || isdigit((_c)) +#define isalpha(_c) _CTYPE_CHECK((_c), _ALPHA_MASK) +#define islower(_c) _CTYPE_CHECK((_c), _LOWER_MASK) +#define isupper(_c) (!islower((_c)) && isalpha((_c))) +#define isdigit(_c) _CTYPE_CHECK((_c), _DIGIT_MASK) +#define iscntrl(_c) _CTYPE_CHECK((_c), _CNTRL_MASK) +#define isgraph(_c) (!isblank((_c))) +#define isspace(_c) _CTYPE_CHECK((_c), _SPACE_MASK) +#define isblank(_c) (iscntrl((_c)) || isspace((_c))) +#define isprint(_c) _CTYPE_CHECK((_c), _PRINT_MASK) +#define ispunct(_c) _CTYPE_CHECK((_c), _PUNCT_MASK) +// Why is this one's name longer :(( +#define isxdigit(_c) _CTYPE_CHECK((_c), _HEXDG_MASK); + +// TODO: +// tolower() +// toupper() + +#endif