Sat, 18 Jan 2025 13:30:51 +0100
remove uses of ctype.h - temporarily fixes #577
we are in desperate need of a good solution that also supports Unicode, though
src/json.c | file | annotate | diff | comparison | revisions | |
src/string.c | file | annotate | diff | comparison | revisions |
--- a/src/json.c Fri Jan 17 17:55:21 2025 +0100 +++ b/src/json.c Sat Jan 18 13:30:51 2025 +0100 @@ -29,7 +29,6 @@ #include "cx/json.h" #include <string.h> -#include <ctype.h> #include <assert.h> #include <stdio.h> #include <inttypes.h> @@ -133,6 +132,16 @@ } } +static bool json_isdigit(char c) { + // TODO: remove once UCX has public API for this + return c >= '0' && c <= '9'; +} + +static bool json_isspace(char c) { + // TODO: remove once UCX has public API for this + return c == ' ' || c == '\t' || c == '\r' || c == '\n' || c == '\v' || c == '\f'; +} + static int num_isexp(const char *content, size_t length, size_t pos) { if (pos >= length) { return 0; @@ -141,7 +150,7 @@ int ok = 0; for (size_t i = pos; i < length; i++) { char c = content[i]; - if (isdigit(c)) { + if (json_isdigit(c)) { ok = 1; } else if (i == pos) { if (!(c == '+' || c == '-')) { @@ -158,7 +167,7 @@ static CxJsonTokenType token_numbertype(const char *content, size_t length) { if (length == 0) return CX_JSON_TOKEN_ERROR; - if (content[0] != '-' && !isdigit(content[0])) { + if (content[0] != '-' && !json_isdigit(content[0])) { return CX_JSON_TOKEN_ERROR; } @@ -171,7 +180,7 @@ type = CX_JSON_TOKEN_NUMBER; } else if (content[i] == 'e' || content[i] == 'E') { return num_isexp(content, length, i + 1) ? CX_JSON_TOKEN_NUMBER : CX_JSON_TOKEN_ERROR; - } else if (!isdigit(content[i])) { + } else if (!json_isdigit(content[i])) { return CX_JSON_TOKEN_ERROR; // char is not a digit, decimal separator or exponent sep } } @@ -235,7 +244,7 @@ return CX_JSON_TOKEN_STRING; } default: { - if (isspace(c)) { + if (json_isspace(c)) { return CX_JSON_TOKEN_SPACE; } }
--- a/src/string.c Fri Jan 17 17:55:21 2025 +0100 +++ b/src/string.c Sat Jan 18 13:30:51 2025 +0100 @@ -30,7 +30,6 @@ #include <string.h> #include <stdarg.h> -#include <ctype.h> #include <assert.h> #include <errno.h> #include <limits.h> @@ -529,14 +528,19 @@ return result; } +static bool str_isspace(char c) { + // TODO: remove once UCX has public API for this + return c == ' ' || c == '\t' || c == '\r' || c == '\n' || c == '\v' || c == '\f'; +} + cxstring cx_strtrim(cxstring string) { cxstring result = string; // TODO: optimize by comparing multiple bytes at once - while (result.length > 0 && isspace(*result.ptr)) { + while (result.length > 0 && str_isspace(*result.ptr)) { result.ptr++; result.length--; } - while (result.length > 0 && isspace(result.ptr[result.length - 1])) { + while (result.length > 0 && str_isspace(result.ptr[result.length - 1])) { result.length--; } return result; @@ -592,13 +596,17 @@ void cx_strlower(cxmutstr string) { for (size_t i = 0; i < string.length; i++) { - string.ptr[i] = (char) tolower(string.ptr[i]); + if ((unsigned int) (string.ptr[i] - 'A') < 26u) { + string.ptr[i] += 'a' - 'A'; + } } } void cx_strupper(cxmutstr string) { for (size_t i = 0; i < string.length; i++) { - string.ptr[i] = (char) toupper(string.ptr[i]); + if ((unsigned int) (string.ptr[i] - 'a') < 26u) { + string.ptr[i] += 'A' - 'a'; + } } } @@ -1055,6 +1063,11 @@ return 0; } +static bool str_isdigit(char c) { + // TODO: remove once UCX has public API for this + return c >= '0' && c <= '9'; +} + int cx_strtod_lc(cxstring str, double *output, char decsep, const char *groupsep) { // TODO: overflow check // TODO: increase precision @@ -1088,7 +1101,7 @@ // parse all digits until we find the decsep size_t pos = 0; do { - if (isdigit(str.ptr[pos])) { + if (str_isdigit(str.ptr[pos])) { result = result * 10 + (str.ptr[pos] - '0'); } else if (strchr(groupsep, str.ptr[pos]) == NULL) { break; @@ -1117,7 +1130,7 @@ // parse everything until exponent or end double factor = 1.; do { - if (isdigit(str.ptr[pos])) { + if (str_isdigit(str.ptr[pos])) { factor *= 0.1; result = result + factor * (str.ptr[pos] - '0'); } else if (strchr(groupsep, str.ptr[pos]) == NULL) { @@ -1158,7 +1171,7 @@ // parse the exponent unsigned int exp = 0; do { - if (isdigit(str.ptr[pos])) { + if (str_isdigit(str.ptr[pos])) { exp = 10 * exp + (str.ptr[pos] - '0'); } else if (strchr(groupsep, str.ptr[pos]) == NULL) { errno = EINVAL;