René Scharfe <l.s.r@xxxxxx> writes: > Test the character classifier added by c2e9364a06 (cleanup: add > isascii(), 2009-03-07). It returns 1 for NUL as well, which requires > special treatment, as our string-based tester can't find it with > strcmp(3). Allow NUL to be given as the first character in a class > specification string. This has the downside of no longer supporting > the empty string, but that's OK since we are not interested in testing > character classes with no members. I wonder how effective a test we can have by checking a table we use in production (i.e. ctype.c::sane_ctype[]) against another table we use only for testing (i.e. string literals in test-ctype.c), but that is not something new in this series. I do not offhand know if the string literal prefixed with NUL is safe against clever compilers; my gut feeling says it should (i.e. allowing such an "optimization" does not seem to have much merit), but my gut has been wrong many times in this area, so... > > Signed-off-by: René Scharfe <l.s.r@xxxxxx> > --- > t/helper/test-ctype.c | 19 +++++++++++++++++-- > 1 file changed, 17 insertions(+), 2 deletions(-) > > diff --git a/t/helper/test-ctype.c b/t/helper/test-ctype.c > index 92c4c2313e..caf586649f 100644 > --- a/t/helper/test-ctype.c > +++ b/t/helper/test-ctype.c > @@ -11,9 +11,14 @@ static void report_error(const char *class, int ch) > > static int is_in(const char *s, int ch) > { > - /* We can't find NUL using strchr. It's classless anyway. */ > + /* > + * We can't find NUL using strchr. Accept it as the first > + * character in the spec -- there are no empty classes. > + */ > if (ch == '\0') > - return 0; > + return ch == *s; > + if (*s == '\0') > + s++; > return !!strchr(s, ch); > } > > @@ -28,6 +33,15 @@ static int is_in(const char *s, int ch) > #define DIGIT "0123456789" > #define LOWER "abcdefghijklmnopqrstuvwxyz" > #define UPPER "ABCDEFGHIJKLMNOPQRSTUVWXYZ" > +#define ASCII \ > + "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" \ > + "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f" \ > + "\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f" \ > + "\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f" \ > + "\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f" \ > + "\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f" \ > + "\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f" \ > + "\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f" > > int cmd__ctype(int argc, const char **argv) > { > @@ -38,6 +52,7 @@ int cmd__ctype(int argc, const char **argv) > TEST_CLASS(is_glob_special, "*?[\\"); > TEST_CLASS(is_regex_special, "$()*+.?[\\^{|"); > TEST_CLASS(is_pathspec_magic, "!\"#%&',-/:;<=>@_`~"); > + TEST_CLASS(isascii, ASCII); > > return rc; > } > -- > 2.39.1