do not use ctype functions - chess-puzzles - chess puzzle book generator
 (HTM) git clone git://git.codemadness.org/chess-puzzles
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit d30b443f23a15ffab12f6a00931d979b9cfab061
 (DIR) parent 07c37ef3931e33b55aebe2561ed92d37735cabe8
 (HTM) 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(-)
       ---
 (DIR) 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;