>From 27e6f6aa7dc947209f29982b66a0c760e5589db3 Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Fri, 2 Oct 2026 21:47:49 -0400 Subject: [PATCH 04/10] scanf/strtod: honor locale-specific radix point since per the specification, "additional locale-specific subject sequence forms may be accepted", we define forms using the standard radix point '.' as such an additional form. in locales where the radix point is '.' there is no change in behavior. in locales where the radix point is ',' either '.' or ',' is accepted. --- src/internal/floatscan.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/internal/floatscan.c b/src/internal/floatscan.c index 2bc6830f..ebacc545 100644 --- a/src/internal/floatscan.c +++ b/src/internal/floatscan.c @@ -8,6 +8,7 @@ #include "shgetc.h" #include "floatscan.h" +#include "locale_impl.h" #if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024 @@ -33,6 +34,12 @@ #define MASK (KMAX-1) +static int c_radixpt(locale_t loc) +{ + return '.'; +} +weak_alias(c_radixpt, __radixpt); + static long long scanexp(FILE *f, int pok) { int c; @@ -78,20 +85,21 @@ static long double decfloat(FILE *f, int c, int bits, int emin, int sign, int po long double bias=0; static const int p10s[] = { 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000 }; + int rc = __radixpt(0); j=0; k=0; /* Don't let leading zeros consume buffer space */ for (; c=='0'; c = shgetc(f)) gotdig=1; - if (c=='.') { + if (c=='.' || c==rc) { gotrad = 1; for (c = shgetc(f); c=='0'; c = shgetc(f)) gotdig=1, lrp--; } x[0] = 0; - for (; c-'0'<10U || c=='.'; c = shgetc(f)) { - if (c == '.') { + for (; c-'0'<10U || c=='.' || c==rc; c = shgetc(f)) { + if (c == '.' || c==rc) { if (gotrad) break; gotrad = 1; lrp = dc; @@ -323,21 +331,22 @@ static long double hexfloat(FILE *f, int bits, int emin, int sign, int pok) long long e2 = 0; int d; int c; + int rc = __radixpt(0); c = shgetc(f); /* Skip leading zeros */ for (; c=='0'; c = shgetc(f)) gotdig = 1; - if (c=='.') { + if (c=='.' || c==rc) { gotrad = 1; c = shgetc(f); /* Count zeros after the radix point before significand */ for (rp=0; c=='0'; c = shgetc(f), rp--) gotdig = 1; } - for (; c-'0'<10U || (c|32)-'a'<6U || c=='.'; c = shgetc(f)) { - if (c=='.') { + for (; c-'0'<10U || (c|32)-'a'<6U || c=='.' || c==rc; c = shgetc(f)) { + if (c=='.' || c==rc) { if (gotrad) break; rp = dc; gotrad = 1; -- 2.21.0