Commit | Line | Data |
---|---|---|
9c577e89 DD |
1 | /* File name comparison routine. |
2 | ||
3 | Copyright (C) 2007 Free Software Foundation, Inc. | |
4 | ||
5 | This program is free software; you can redistribute it and/or modify | |
6 | it under the terms of the GNU General Public License as published by | |
7 | the Free Software Foundation; either version 2, or (at your option) | |
8 | any later version. | |
9 | ||
10 | This program is distributed in the hope that it will be useful, | |
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 | GNU General Public License for more details. | |
14 | ||
15 | You should have received a copy of the GNU General Public License | |
16 | along with this program; if not, write to the Free Software Foundation, | |
17 | Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ | |
18 | ||
2657faa6 AS |
19 | #ifdef HAVE_CONFIG_H |
20 | #include "config.h" | |
21 | #endif | |
22 | ||
9c577e89 DD |
23 | #ifdef HAVE_STRING_H |
24 | #include <string.h> | |
25 | #endif | |
26 | ||
9c577e89 | 27 | #include "filenames.h" |
73bdefcf | 28 | #include "safe-ctype.h" |
9c577e89 DD |
29 | |
30 | /* | |
31 | ||
32 | @deftypefn Extension int filename_cmp (const char *@var{s1}, const char *@var{s2}) | |
33 | ||
34d8f01b JB |
34 | Return zero if the two file names @var{s1} and @var{s2} are equivalent. |
35 | If not equivalent, the returned value is similar to what @code{strcmp} | |
36 | would return. In other words, it returns a negative value if @var{s1} | |
37 | is less than @var{s2}, or a positive value if @var{s2} is greater than | |
38 | @var{s2}. | |
9c577e89 | 39 | |
34d8f01b | 40 | This function does not normalize file names. As a result, this function |
9c577e89 DD |
41 | will treat filenames that are spelled differently as different even in |
42 | the case when the two filenames point to the same underlying file. | |
43 | However, it does handle the fact that on DOS-like file systems, forward | |
44 | and backward slashes are equal. | |
45 | ||
46 | @end deftypefn | |
47 | ||
48 | */ | |
49 | ||
50 | int | |
51 | filename_cmp (const char *s1, const char *s2) | |
52 | { | |
7d6b320b JB |
53 | #if !defined(HAVE_DOS_BASED_FILE_SYSTEM) \ |
54 | && !defined(HAVE_CASE_INSENSITIVE_FILE_SYSTEM) | |
9c577e89 DD |
55 | return strcmp(s1, s2); |
56 | #else | |
57 | for (;;) | |
58 | { | |
7d6b320b JB |
59 | int c1 = *s1; |
60 | int c2 = *s2; | |
9c577e89 | 61 | |
7d6b320b JB |
62 | #if defined (HAVE_CASE_INSENSITIVE_FILE_SYSTEM) |
63 | c1 = TOLOWER (c1); | |
64 | c2 = TOLOWER (c2); | |
65 | #endif | |
66 | ||
67 | #if defined (HAVE_DOS_BASED_FILE_SYSTEM) | |
9c577e89 DD |
68 | /* On DOS-based file systems, the '/' and the '\' are equivalent. */ |
69 | if (c1 == '/') | |
70 | c1 = '\\'; | |
71 | if (c2 == '/') | |
72 | c2 = '\\'; | |
7d6b320b | 73 | #endif |
9c577e89 DD |
74 | |
75 | if (c1 != c2) | |
76 | return (c1 - c2); | |
77 | ||
78 | if (c1 == '\0') | |
79 | return 0; | |
80 | ||
81 | s1++; | |
82 | s2++; | |
83 | } | |
84 | #endif | |
85 | } | |
86 | ||
007d6189 KT |
87 | /* |
88 | ||
89 | @deftypefn Extension int filename_ncmp (const char *@var{s1}, const char *@var{s2}, size_t @var{n}) | |
90 | ||
91 | Return zero if the two file names @var{s1} and @var{s2} are equivalent | |
92 | in range @var{n}. | |
93 | If not equivalent, the returned value is similar to what @code{strncmp} | |
94 | would return. In other words, it returns a negative value if @var{s1} | |
95 | is less than @var{s2}, or a positive value if @var{s2} is greater than | |
96 | @var{s2}. | |
97 | ||
98 | This function does not normalize file names. As a result, this function | |
99 | will treat filenames that are spelled differently as different even in | |
100 | the case when the two filenames point to the same underlying file. | |
101 | However, it does handle the fact that on DOS-like file systems, forward | |
102 | and backward slashes are equal. | |
103 | ||
104 | @end deftypefn | |
105 | ||
106 | */ | |
107 | ||
108 | int | |
109 | filename_ncmp (const char *s1, const char *s2, size_t n) | |
110 | { | |
7d6b320b JB |
111 | #if !defined(HAVE_DOS_BASED_FILE_SYSTEM) \ |
112 | && !defined(HAVE_CASE_INSENSITIVE_FILE_SYSTEM) | |
007d6189 KT |
113 | return strncmp(s1, s2, n); |
114 | #else | |
115 | if (!n) | |
116 | return 0; | |
117 | for (; n > 0; --n) | |
118 | { | |
7d6b320b JB |
119 | int c1 = *s1; |
120 | int c2 = *s2; | |
007d6189 | 121 | |
7d6b320b JB |
122 | #if defined (HAVE_CASE_INSENSITIVE_FILE_SYSTEM) |
123 | c1 = TOLOWER (c1); | |
124 | c2 = TOLOWER (c2); | |
125 | #endif | |
126 | ||
127 | #if defined (HAVE_DOS_BASED_FILE_SYSTEM) | |
007d6189 KT |
128 | /* On DOS-based file systems, the '/' and the '\' are equivalent. */ |
129 | if (c1 == '/') | |
130 | c1 = '\\'; | |
131 | if (c2 == '/') | |
132 | c2 = '\\'; | |
7d6b320b | 133 | #endif |
007d6189 KT |
134 | |
135 | if (c1 == '\0' || c1 != c2) | |
136 | return (c1 - c2); | |
137 | ||
138 | s1++; | |
139 | s2++; | |
140 | } | |
141 | return 0; | |
142 | #endif | |
143 | } | |
0429544a DE |
144 | |
145 | /* | |
146 | ||
147 | @deftypefn Extension hashval_t filename_hash (const void *@var{s}) | |
148 | ||
149 | Return the hash value for file name @var{s} that will be compared | |
150 | using filename_cmp. | |
151 | This function is for use with hashtab.c hash tables. | |
152 | ||
153 | @end deftypefn | |
154 | ||
155 | */ | |
156 | ||
157 | hashval_t | |
158 | filename_hash (const void *s) | |
159 | { | |
160 | /* The cast is for -Wc++-compat. */ | |
161 | const unsigned char *str = (const unsigned char *) s; | |
162 | hashval_t r = 0; | |
163 | unsigned char c; | |
164 | ||
165 | while ((c = *str++) != 0) | |
166 | { | |
167 | if (c == '\\') | |
168 | c = '/'; | |
169 | c = TOLOWER (c); | |
170 | r = r * 67 + c - 113; | |
171 | } | |
172 | ||
173 | return r; | |
174 | } | |
175 | ||
176 | /* | |
177 | ||
178 | @deftypefn Extension int filename_eq (const void *@var{s1}, const void *@var{s2}) | |
179 | ||
180 | Return non-zero if file names @var{s1} and @var{s2} are equivalent. | |
181 | This function is for use with hashtab.c hash tables. | |
182 | ||
183 | @end deftypefn | |
184 | ||
185 | */ | |
186 | ||
187 | int | |
188 | filename_eq (const void *s1, const void *s2) | |
189 | { | |
190 | /* The casts are for -Wc++-compat. */ | |
191 | return filename_cmp ((const char *) s1, (const char *) s2) == 0; | |
192 | } |