diff --git a/src/config_file.c b/src/config_file.c index d6a62b85c..52a5376bd 100644 --- a/src/config_file.c +++ b/src/config_file.c @@ -156,7 +156,7 @@ int git_config_file_normalize_section(char *start, char *end) if (end && scan >= end) break; if (isalnum(*scan)) - *scan = (char)tolower(*scan); + *scan = (char)git__tolower(*scan); else if (*scan != '-' || scan == start) return GIT_EINVALIDSPEC; } @@ -1083,7 +1083,7 @@ static int parse_section_header(struct reader *reader, char **section_out) goto fail_parse; } - name[name_length++] = (char) tolower(c); + name[name_length++] = (char)git__tolower(c); } while ((c = line[pos++]) != ']'); diff --git a/src/fnmatch.c b/src/fnmatch.c index d7899e3e6..a2945b8db 100644 --- a/src/fnmatch.c +++ b/src/fnmatch.c @@ -164,8 +164,8 @@ p_fnmatchx(const char *pattern, const char *string, int flags, size_t recurs) default: normal: if (c != *string && !((flags & FNM_CASEFOLD) && - (tolower((unsigned char)c) == - tolower((unsigned char)*string)))) + (git__tolower((unsigned char)c) == + git__tolower((unsigned char)*string)))) return (FNM_NOMATCH); ++string; break; @@ -190,7 +190,7 @@ rangematch(const char *pattern, char test, int flags, char **newp) ++pattern; if (flags & FNM_CASEFOLD) - test = (char)tolower((unsigned char)test); + test = (char)git__tolower((unsigned char)test); /* * A right bracket shall lose its special meaning and represent @@ -207,7 +207,7 @@ rangematch(const char *pattern, char test, int flags, char **newp) if (c == '/' && (flags & FNM_PATHNAME)) return (RANGE_NOMATCH); if ((flags & FNM_CASEFOLD)) - c = (char)tolower((unsigned char)c); + c = (char)git__tolower((unsigned char)c); if (*pattern == '-' && (c2 = *(pattern+1)) != EOS && c2 != ']') { pattern += 2; @@ -216,7 +216,7 @@ rangematch(const char *pattern, char test, int flags, char **newp) if (c2 == EOS) return (RANGE_ERROR); if (flags & FNM_CASEFOLD) - c2 = (char)tolower((unsigned char)c2); + c2 = (char)git__tolower((unsigned char)c2); if (c <= test && test <= c2) ok = 1; } else if (c == test) diff --git a/src/iterator.c b/src/iterator.c index 93303a87d..7807a1636 100644 --- a/src/iterator.c +++ b/src/iterator.c @@ -1405,10 +1405,10 @@ GIT_INLINE(bool) workdir_path_is_dotgit(const git_buf *path) if (path->ptr[len - 1] == '/') len--; - if (tolower(path->ptr[len - 1]) != 't' || - tolower(path->ptr[len - 2]) != 'i' || - tolower(path->ptr[len - 3]) != 'g' || - tolower(path->ptr[len - 4]) != '.') + if (git__tolower(path->ptr[len - 1]) != 't' || + git__tolower(path->ptr[len - 2]) != 'i' || + git__tolower(path->ptr[len - 3]) != 'g' || + git__tolower(path->ptr[len - 4]) != '.') return false; return (len == 4 || path->ptr[len - 5] == '/'); diff --git a/src/netops.c b/src/netops.c index 6047cf1ac..5e8075597 100644 --- a/src/netops.c +++ b/src/netops.c @@ -84,7 +84,7 @@ void gitno_consume_n(gitno_buffer *buf, size_t cons) int gitno__match_host(const char *pattern, const char *host) { for (;;) { - char c = tolower(*pattern++); + char c = git__tolower(*pattern++); if (c == '\0') return *host ? -1 : 0; @@ -102,7 +102,7 @@ int gitno__match_host(const char *pattern, const char *host) */ while(*host) { - char h = tolower(*host); + char h = git__tolower(*host); if (c == h) return gitno__match_host(pattern, host++); if (h == '.') @@ -112,7 +112,7 @@ int gitno__match_host(const char *pattern, const char *host) return -1; } - if (c != tolower(*host++)) + if (c != git__tolower(*host++)) return -1; } diff --git a/src/path.c b/src/path.c index 8f861e68e..02917607a 100644 --- a/src/path.c +++ b/src/path.c @@ -1473,7 +1473,7 @@ static int32_t next_hfs_char(const char **in, size_t *len) * the ASCII range, which is perfectly fine, because the * git folder name can only be composed of ascii characters */ - return tolower(codepoint); + return git__tolower(codepoint); } return 0; /* NULL byte -- end of string */ } diff --git a/src/util.c b/src/util.c index 6bb7d03ee..c62826420 100644 --- a/src/util.c +++ b/src/util.c @@ -171,9 +171,9 @@ int git__strcmp(const char *a, const char *b) int git__strcasecmp(const char *a, const char *b) { - while (*a && *b && tolower(*a) == tolower(*b)) + while (*a && *b && git__tolower(*a) == git__tolower(*b)) ++a, ++b; - return (tolower(*a) - tolower(*b)); + return ((unsigned char)git__tolower(*a) - (unsigned char)git__tolower(*b)); } int git__strcasesort_cmp(const char *a, const char *b) @@ -182,7 +182,7 @@ int git__strcasesort_cmp(const char *a, const char *b) while (*a && *b) { if (*a != *b) { - if (tolower(*a) != tolower(*b)) + if (git__tolower(*a) != git__tolower(*b)) break; /* use case in sort order even if not in equivalence */ if (!cmp) @@ -193,7 +193,7 @@ int git__strcasesort_cmp(const char *a, const char *b) } if (*a || *b) - return tolower(*a) - tolower(*b); + return (unsigned char)git__tolower(*a) - (unsigned char)git__tolower(*b); return cmp; } @@ -212,8 +212,8 @@ int git__strncasecmp(const char *a, const char *b, size_t sz) int al, bl; do { - al = (unsigned char)tolower(*a); - bl = (unsigned char)tolower(*b); + al = (unsigned char)git__tolower(*a); + bl = (unsigned char)git__tolower(*b); ++a, ++b; } while (--sz && al && al == bl); @@ -225,7 +225,7 @@ void git__strntolower(char *str, size_t len) size_t i; for (i = 0; i < len; ++i) { - str[i] = (char) tolower(str[i]); + str[i] = (char)git__tolower(str[i]); } } @@ -255,8 +255,8 @@ int git__prefixncmp_icase(const char *str, size_t str_n, const char *prefix) int s, p; while(str_n--) { - s = (unsigned char)tolower(*str++); - p = (unsigned char)tolower(*prefix++); + s = (unsigned char)git__tolower(*str++); + p = (unsigned char)git__tolower(*prefix++); if (s != p) return s - p; diff --git a/src/util.h b/src/util.h index be6534580..b2abbe6a6 100644 --- a/src/util.h +++ b/src/util.h @@ -275,6 +275,15 @@ extern char *git__strsep(char **end, const char *sep); extern void git__strntolower(char *str, size_t len); extern void git__strtolower(char *str); +#ifdef GIT_WIN32 +GIT_INLINE(int) git__tolower(int c) +{ + return (c >= 'A' && c <= 'Z') ? (c + 32) : c; +} +#else +# define git__tolower(a) tolower(a) +#endif + GIT_INLINE(const char *) git__next_line(const char *s) { while (*s && *s != '\n') s++; diff --git a/tests/core/string.c b/tests/core/string.c index ec9575685..90e8fa027 100644 --- a/tests/core/string.c +++ b/tests/core/string.c @@ -39,3 +39,45 @@ void test_core_string__2(void) cl_assert(git__strcasesort_cmp("BAR", "foo") < 0); cl_assert(git__strcasesort_cmp("fooBar", "foobar") < 0); } + +void test_core_string__strcmp(void) +{ + cl_assert(git__strcmp("", "") == 0); + cl_assert(git__strcmp("foo", "foo") == 0); + cl_assert(git__strcmp("Foo", "foo") < 0); + cl_assert(git__strcmp("foo", "FOO") > 0); + cl_assert(git__strcmp("foo", "fOO") > 0); + + cl_assert(strcmp("rt\303\202of", "rt dev\302\266h") > 0); + cl_assert(strcmp("e\342\202\254ghi=", "et") > 0); + cl_assert(strcmp("rt dev\302\266h", "rt\303\202of") < 0); + cl_assert(strcmp("et", "e\342\202\254ghi=") < 0); + cl_assert(strcmp("\303\215", "\303\255") < 0); + + cl_assert(git__strcmp("rt\303\202of", "rt dev\302\266h") > 0); + cl_assert(git__strcmp("e\342\202\254ghi=", "et") > 0); + cl_assert(git__strcmp("rt dev\302\266h", "rt\303\202of") < 0); + cl_assert(git__strcmp("et", "e\342\202\254ghi=") < 0); + cl_assert(git__strcmp("\303\215", "\303\255") < 0); +} + +void test_core_string__strcasecmp(void) +{ + cl_assert(git__strcasecmp("", "") == 0); + cl_assert(git__strcasecmp("foo", "foo") == 0); + cl_assert(git__strcasecmp("foo", "Foo") == 0); + cl_assert(git__strcasecmp("foo", "FOO") == 0); + cl_assert(git__strcasecmp("foo", "fOO") == 0); + + cl_assert(strcasecmp("rt\303\202of", "rt dev\302\266h") > 0); + cl_assert(strcasecmp("e\342\202\254ghi=", "et") > 0); + cl_assert(strcasecmp("rt dev\302\266h", "rt\303\202of") < 0); + cl_assert(strcasecmp("et", "e\342\202\254ghi=") < 0); + cl_assert(strcasecmp("\303\215", "\303\255") < 0); + + cl_assert(git__strcasecmp("rt\303\202of", "rt dev\302\266h") > 0); + cl_assert(git__strcasecmp("e\342\202\254ghi=", "et") > 0); + cl_assert(git__strcasecmp("rt dev\302\266h", "rt\303\202of") < 0); + cl_assert(git__strcasecmp("et", "e\342\202\254ghi=") < 0); + cl_assert(git__strcasecmp("\303\215", "\303\255") < 0); +}