From dd9193dac1c21c44d6c20e80fbd1dcba99feb8fe Mon Sep 17 00:00:00 2001 From: Cody Boone Ferguson <53008573+xexyl@users.noreply.github.com> Date: Fri, 28 Aug 2026 08:20:58 -0700 Subject: [PATCH] Fix ctype.h funcs/macros in 2024/ferguson/dms.c The to*() and is*() of ctype.h require that the passed in arg (an int) must be representable as either an unsigned char or EOF (which is guaranteed to be < 0 but not necessarily - though often - -1). I didn't bother with this when I submitted it but I do now. As the comments in the code say I believe I have the algorithm right but I could have missed something. It's not actually needed for 2024/ferguson but can be a useful tool in some cases. --- 2025/ferguson/dms.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/2025/ferguson/dms.c b/2025/ferguson/dms.c index e266775d90..ebf40655f2 100644 --- a/2025/ferguson/dms.c +++ b/2025/ferguson/dms.c @@ -62,11 +62,14 @@ int main(int argc, char **argv) if (argc == 9) { /* - * No. I don't make it an error if it's not ASCII. I could but since - * it's binary (either the value or not) I don't bother. + * the standard says that for the is*() and to*() functions of ctype.h + * they must be represented as an unsigned char or EOF (though the + * function takes an int). EOF is guaranteed to be a negative number but + * it is not guaranteed to be -1. We cast the args to unsigned char and + * compare that to the character we need. */ - a = toupper(argv[4][0]=='S'); - b = toupper(argv[8][0]=='W'); + a = toupper((unsigned char)argv[4][0])=='S'; + b = toupper((unsigned char)argv[8][0])=='W'; lat = dec(strtod(argv[1], 0), strtod(argv[2], 0), strtod(argv[3], 0), a); lon = dec(strtod(argv[5], 0), strtod(argv[6], 0), strtod(argv[7], 0), b); @@ -78,11 +81,7 @@ int main(int argc, char **argv) } else { - /* - * No. I don't make it an error if it's not ASCII. I could but since - * it's binary (either the value or not) I don't bother. - */ - c = toupper(argv[4][0]); + c = toupper((unsigned char)argv[4][0]); alt = dec(strtod(argv[1], 0), strtod(argv[2], 0), strtod(argv[3], 0), c=='S'||c=='W'); if(c == 'S' || c == 'N')