commit d30b443f23a15ffab12f6a00931d979b9cfab061
parent 07c37ef3931e33b55aebe2561ed92d37735cabe8
Author: Hiltjo Posthuma <hiltjo@codemadness.org>
Date: Sun, 9 Mar 2025 10:46:12 +0100
do not use ctype functions
These can be locale-specific on some platforms.
Diffstat:
M | fen.c | | | 23 | ++++++++++++++--------- |
1 file changed, 14 insertions(+), 9 deletions(-)
diff --git a/fen.c b/fen.c
@@ -1,4 +1,3 @@
-#include <ctype.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
@@ -11,6 +10,12 @@
#define LEN(s) (sizeof(s)/sizeof(*s))
+/* ctype-like macros, but always compatible with ASCII / UTF-8 */
+#define ISDIGIT(c) (((unsigned)c) - '0' < 10)
+#define ISXDIGIT(c) ((((unsigned)c) - '0' < 10) || ((unsigned)c | 32) - 'a' < 6)
+#define TOLOWER(c) ((((unsigned)c) - 'A' < 26) ? ((c) | 32) : (c))
+#define TOUPPER(c) ((((unsigned)c) - 'a' < 26) ? ((c) & 0x5f) : (c))
+
/* macro for truecolor RGB output to tty */
#define SETFGCOLOR(r,g,b) printf("\x1b[38;2;%d;%d;%dm", r, g, b)
#define SETBGCOLOR(r,g,b) printf("\x1b[48;2;%d;%d;%dm", r, g, b)
@@ -238,7 +243,7 @@ speak(const char *fmt, ...)
int
pgnpiece(int piece)
{
- piece = toupper(piece);
+ piece = TOUPPER(piece);
/* no mapping */
if (!pgn_piecemapping[0])
@@ -554,7 +559,7 @@ output_tty(struct board *b)
fputs("\x1b[30m", stdout); /* black */
/* workaround: use black unicode chess symbol, because
the color is filled and better visible */
- showpiece_tty(tolower(piece));
+ showpiece_tty(TOLOWER(piece));
} else {
fputs(" ", stdout);
}
@@ -1027,7 +1032,7 @@ board_setup_fen(struct board *b, const char *fen)
if (l >= 0 && l < 32767) {
b->halfmove = l;
- for (; *s && isdigit((unsigned char)*s); s++)
+ for (; *s && ISDIGIT((unsigned char)*s); s++)
;
}
break;
@@ -1038,7 +1043,7 @@ board_setup_fen(struct board *b, const char *fen)
l = strtol(s, NULL, 10);
if (l >= 0 && l < 32767) {
b->movenumber = (int)l;
- for (; *s && isdigit((unsigned char)*s); s++)
+ for (; *s && ISDIGIT((unsigned char)*s); s++)
;
}
break;
@@ -1162,9 +1167,9 @@ board_playmoves(struct board *b, const char *moves)
/* is a valid piece? should be queen, rook, bishop, knight (not validated exactly) */
if (isvalidpiece(*s)) {
if (side == 'w')
- promote = toupper(*s);
+ promote = TOUPPER(*s);
else
- promote = tolower(*s);
+ promote = TOLOWER(*s);
s++;
}
@@ -1450,8 +1455,8 @@ decodeparam(char *buf, size_t bufsiz, const char *s)
case '%':
if (i + 3 >= bufsiz)
return -1;
- if (!isxdigit((unsigned char)*(s+1)) ||
- !isxdigit((unsigned char)*(s+2)))
+ if (!ISXDIGIT((unsigned char)*(s+1)) ||
+ !ISXDIGIT((unsigned char)*(s+2)))
return -1;
buf[i++] = hexdigit(*(s+1)) * 16 + hexdigit(*(s+2));
s += 2;