Subversion Repositories Kolibri OS

Rev

Rev 5191 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

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