diff options
-rw-r--r-- | Makefile | 3 | ||||
-rw-r--r-- | ctype.c | 33 | ||||
-rw-r--r-- | dir.c | 4 | ||||
-rw-r--r-- | git-compat-util.h | 6 | ||||
-rw-r--r-- | grep.c | 8 | ||||
-rwxr-xr-x | t/t0070-fundamental.sh | 15 | ||||
-rw-r--r-- | test-ctype.c | 78 |
7 files changed, 118 insertions, 29 deletions
@@ -1357,6 +1357,7 @@ endif ### Testing rules TEST_PROGRAMS += test-chmtime$X +TEST_PROGRAMS += test-ctype$X TEST_PROGRAMS += test-date$X TEST_PROGRAMS += test-delta$X TEST_PROGRAMS += test-genrandom$X @@ -1376,6 +1377,8 @@ export NO_SVN_TESTS test: all $(MAKE) -C t/ all +test-ctype$X: ctype.o + test-date$X: date.o ctype.o test-delta$X: diff-delta.o patch-delta.o @@ -5,25 +5,22 @@ */ #include "cache.h" -/* Just so that no insane platform contaminate namespace with these symbols */ -#undef SS -#undef AA -#undef DD -#undef GS - -#define SS GIT_SPACE -#define AA GIT_ALPHA -#define DD GIT_DIGIT -#define GS GIT_SPECIAL /* \0, *, ?, [, \\ */ +enum { + S = GIT_SPACE, + A = GIT_ALPHA, + D = GIT_DIGIT, + G = GIT_GLOB_SPECIAL, /* *, ?, [, \\ */ + R = GIT_REGEX_SPECIAL, /* $, (, ), +, ., ^, {, | * */ +}; unsigned char sane_ctype[256] = { - GS, 0, 0, 0, 0, 0, 0, 0, 0, SS, SS, 0, 0, SS, 0, 0, /* 0-15 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 16-15 */ - SS, 0, 0, 0, 0, 0, 0, 0, 0, 0, GS, 0, 0, 0, 0, 0, /* 32-15 */ - DD, DD, DD, DD, DD, DD, DD, DD, DD, DD, 0, 0, 0, 0, 0, GS, /* 48-15 */ - 0, AA, AA, AA, AA, AA, AA, AA, AA, AA, AA, AA, AA, AA, AA, AA, /* 64-15 */ - AA, AA, AA, AA, AA, AA, AA, AA, AA, AA, AA, GS, GS, 0, 0, 0, /* 80-15 */ - 0, AA, AA, AA, AA, AA, AA, AA, AA, AA, AA, AA, AA, AA, AA, AA, /* 96-15 */ - AA, AA, AA, AA, AA, AA, AA, AA, AA, AA, AA, 0, 0, 0, 0, 0, /* 112-15 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, S, S, 0, 0, S, 0, 0, /* 0.. 15 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 16.. 31 */ + S, 0, 0, 0, R, 0, 0, 0, R, R, G, R, 0, 0, R, 0, /* 32.. 47 */ + D, D, D, D, D, D, D, D, D, D, 0, 0, 0, 0, 0, G, /* 48.. 63 */ + 0, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, /* 64.. 79 */ + A, A, A, A, A, A, A, A, A, A, A, G, G, 0, R, 0, /* 80.. 95 */ + 0, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, /* 96..111 */ + A, A, A, A, A, A, A, A, A, A, A, R, R, 0, 0, 0, /* 112..127 */ /* Nothing in the 128.. range */ }; @@ -75,7 +75,7 @@ static int match_one(const char *match, const char *name, int namelen) for (;;) { unsigned char c1 = *match; unsigned char c2 = *name; - if (isspecial(c1)) + if (c1 == '\0' || is_glob_special(c1)) break; if (c1 != c2) return 0; @@ -678,7 +678,7 @@ static int simple_length(const char *match) for (;;) { unsigned char c = *match++; len++; - if (isspecial(c)) + if (c == '\0' || is_glob_special(c)) return len; } } diff --git a/git-compat-util.h b/git-compat-util.h index e20b1e858c..079cbe9440 100644 --- a/git-compat-util.h +++ b/git-compat-util.h @@ -327,13 +327,15 @@ extern unsigned char sane_ctype[256]; #define GIT_SPACE 0x01 #define GIT_DIGIT 0x02 #define GIT_ALPHA 0x04 -#define GIT_SPECIAL 0x08 +#define GIT_GLOB_SPECIAL 0x08 +#define GIT_REGEX_SPECIAL 0x10 #define sane_istest(x,mask) ((sane_ctype[(unsigned char)(x)] & (mask)) != 0) #define isspace(x) sane_istest(x,GIT_SPACE) #define isdigit(x) sane_istest(x,GIT_DIGIT) #define isalpha(x) sane_istest(x,GIT_ALPHA) #define isalnum(x) sane_istest(x,GIT_ALPHA | GIT_DIGIT) -#define isspecial(x) sane_istest(x,GIT_SPECIAL) +#define is_glob_special(x) sane_istest(x,GIT_GLOB_SPECIAL) +#define is_regex_special(x) sane_istest(x,GIT_GLOB_SPECIAL | GIT_REGEX_SPECIAL) #define tolower(x) sane_case((unsigned char)(x), 0x20) #define toupper(x) sane_case((unsigned char)(x), 0) @@ -28,15 +28,9 @@ void append_grep_pattern(struct grep_opt *opt, const char *pat, p->next = NULL; } -static int isregexspecial(int c) -{ - return isspecial(c) || c == '$' || c == '(' || c == ')' || c == '+' || - c == '.' || c == '^' || c == '{' || c == '|'; -} - static int is_fixed(const char *s) { - while (!isregexspecial(*s)) + while (*s && !is_regex_special(*s)) s++; return !*s; } diff --git a/t/t0070-fundamental.sh b/t/t0070-fundamental.sh new file mode 100755 index 0000000000..680d7d6861 --- /dev/null +++ b/t/t0070-fundamental.sh @@ -0,0 +1,15 @@ +#!/bin/sh + +test_description='check that the most basic functions work + + +Verify wrappers and compatibility functions. +' + +. ./test-lib.sh + +test_expect_success 'character classes (isspace, isalpha etc.)' ' + test-ctype +' + +test_done diff --git a/test-ctype.c b/test-ctype.c new file mode 100644 index 0000000000..033c74911e --- /dev/null +++ b/test-ctype.c @@ -0,0 +1,78 @@ +#include "cache.h" + + +static int test_isdigit(int c) +{ + return isdigit(c); +} + +static int test_isspace(int c) +{ + return isspace(c); +} + +static int test_isalpha(int c) +{ + return isalpha(c); +} + +static int test_isalnum(int c) +{ + return isalnum(c); +} + +static int test_is_glob_special(int c) +{ + return is_glob_special(c); +} + +static int test_is_regex_special(int c) +{ + return is_regex_special(c); +} + +#define DIGIT "0123456789" +#define LOWER "abcdefghijklmnopqrstuvwxyz" +#define UPPER "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + +static const struct ctype_class { + const char *name; + int (*test_fn)(int); + const char *members; +} classes[] = { + { "isdigit", test_isdigit, DIGIT }, + { "isspace", test_isspace, " \n\r\t" }, + { "isalpha", test_isalpha, LOWER UPPER }, + { "isalnum", test_isalnum, LOWER UPPER DIGIT }, + { "is_glob_special", test_is_glob_special, "*?[\\" }, + { "is_regex_special", test_is_regex_special, "$()*+.?[\\^{|" }, + { NULL } +}; + +static int test_class(const struct ctype_class *test) +{ + int i, rc = 0; + + for (i = 0; i < 256; i++) { + int expected = i ? !!strchr(test->members, i) : 0; + int actual = test->test_fn(i); + + if (actual != expected) { + rc = 1; + printf("%s classifies char %d (0x%02x) wrongly\n", + test->name, i, i); + } + } + return rc; +} + +int main(int argc, char **argv) +{ + const struct ctype_class *test; + int rc = 0; + + for (test = classes; test->name; test++) + rc |= test_class(test); + + return rc; +} |