X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=libiberty%2Ffilename_cmp.c;h=9e16d242086d499a795f1d8f954fc4964c391b8e;hb=d180bcbd34b9ed5f0062636786ff31c803c2f735;hp=59bb726b90eaa07dbd2690954d6bdbd51e869f7a;hpb=34d8f01b8064f205026ae3fe3649b9218eed8694;p=deliverable%2Fbinutils-gdb.git diff --git a/libiberty/filename_cmp.c b/libiberty/filename_cmp.c index 59bb726b90..9e16d24208 100644 --- a/libiberty/filename_cmp.c +++ b/libiberty/filename_cmp.c @@ -24,8 +24,8 @@ #include #endif -#include #include "filenames.h" +#include "safe-ctype.h" /* @@ -50,19 +50,27 @@ and backward slashes are equal. int filename_cmp (const char *s1, const char *s2) { -#ifndef HAVE_DOS_BASED_FILE_SYSTEM +#if !defined(HAVE_DOS_BASED_FILE_SYSTEM) \ + && !defined(HAVE_CASE_INSENSITIVE_FILE_SYSTEM) return strcmp(s1, s2); #else for (;;) { - int c1 = tolower (*s1); - int c2 = tolower (*s2); + int c1 = *s1; + int c2 = *s2; +#if defined (HAVE_CASE_INSENSITIVE_FILE_SYSTEM) + c1 = TOLOWER (c1); + c2 = TOLOWER (c2); +#endif + +#if defined (HAVE_DOS_BASED_FILE_SYSTEM) /* On DOS-based file systems, the '/' and the '\' are equivalent. */ if (c1 == '/') c1 = '\\'; if (c2 == '/') c2 = '\\'; +#endif if (c1 != c2) return (c1 - c2); @@ -76,3 +84,109 @@ filename_cmp (const char *s1, const char *s2) #endif } +/* + +@deftypefn Extension int filename_ncmp (const char *@var{s1}, const char *@var{s2}, size_t @var{n}) + +Return zero if the two file names @var{s1} and @var{s2} are equivalent +in range @var{n}. +If not equivalent, the returned value is similar to what @code{strncmp} +would return. In other words, it returns a negative value if @var{s1} +is less than @var{s2}, or a positive value if @var{s2} is greater than +@var{s2}. + +This function does not normalize file names. As a result, this function +will treat filenames that are spelled differently as different even in +the case when the two filenames point to the same underlying file. +However, it does handle the fact that on DOS-like file systems, forward +and backward slashes are equal. + +@end deftypefn + +*/ + +int +filename_ncmp (const char *s1, const char *s2, size_t n) +{ +#if !defined(HAVE_DOS_BASED_FILE_SYSTEM) \ + && !defined(HAVE_CASE_INSENSITIVE_FILE_SYSTEM) + return strncmp(s1, s2, n); +#else + if (!n) + return 0; + for (; n > 0; --n) + { + int c1 = *s1; + int c2 = *s2; + +#if defined (HAVE_CASE_INSENSITIVE_FILE_SYSTEM) + c1 = TOLOWER (c1); + c2 = TOLOWER (c2); +#endif + +#if defined (HAVE_DOS_BASED_FILE_SYSTEM) + /* On DOS-based file systems, the '/' and the '\' are equivalent. */ + if (c1 == '/') + c1 = '\\'; + if (c2 == '/') + c2 = '\\'; +#endif + + if (c1 == '\0' || c1 != c2) + return (c1 - c2); + + s1++; + s2++; + } + return 0; +#endif +} + +/* + +@deftypefn Extension hashval_t filename_hash (const void *@var{s}) + +Return the hash value for file name @var{s} that will be compared +using filename_cmp. +This function is for use with hashtab.c hash tables. + +@end deftypefn + +*/ + +hashval_t +filename_hash (const void *s) +{ + /* The cast is for -Wc++-compat. */ + const unsigned char *str = (const unsigned char *) s; + hashval_t r = 0; + unsigned char c; + + while ((c = *str++) != 0) + { + if (c == '\\') + c = '/'; + c = TOLOWER (c); + r = r * 67 + c - 113; + } + + return r; +} + +/* + +@deftypefn Extension int filename_eq (const void *@var{s1}, const void *@var{s2}) + +Return non-zero if file names @var{s1} and @var{s2} are equivalent. +This function is for use with hashtab.c hash tables. + +@end deftypefn + +*/ + +int +filename_eq (const void *s1, const void *s2) +{ + /* The casts are for -Wc++-compat. */ + return filename_cmp ((const char *) s1, (const char *) s2) == 0; +}