1*e4b17023SJohn Marino /* File name comparison routine.
2*e4b17023SJohn Marino
3*e4b17023SJohn Marino Copyright (C) 2007 Free Software Foundation, Inc.
4*e4b17023SJohn Marino
5*e4b17023SJohn Marino This program is free software; you can redistribute it and/or modify
6*e4b17023SJohn Marino it under the terms of the GNU General Public License as published by
7*e4b17023SJohn Marino the Free Software Foundation; either version 2, or (at your option)
8*e4b17023SJohn Marino any later version.
9*e4b17023SJohn Marino
10*e4b17023SJohn Marino This program is distributed in the hope that it will be useful,
11*e4b17023SJohn Marino but WITHOUT ANY WARRANTY; without even the implied warranty of
12*e4b17023SJohn Marino MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13*e4b17023SJohn Marino GNU General Public License for more details.
14*e4b17023SJohn Marino
15*e4b17023SJohn Marino You should have received a copy of the GNU General Public License
16*e4b17023SJohn Marino along with this program; if not, write to the Free Software Foundation,
17*e4b17023SJohn Marino Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
18*e4b17023SJohn Marino
19*e4b17023SJohn Marino #ifdef HAVE_CONFIG_H
20*e4b17023SJohn Marino #include "config.h"
21*e4b17023SJohn Marino #endif
22*e4b17023SJohn Marino
23*e4b17023SJohn Marino #ifdef HAVE_STRING_H
24*e4b17023SJohn Marino #include <string.h>
25*e4b17023SJohn Marino #endif
26*e4b17023SJohn Marino
27*e4b17023SJohn Marino #include "filenames.h"
28*e4b17023SJohn Marino #include "safe-ctype.h"
29*e4b17023SJohn Marino
30*e4b17023SJohn Marino /*
31*e4b17023SJohn Marino
32*e4b17023SJohn Marino @deftypefn Extension int filename_cmp (const char *@var{s1}, const char *@var{s2})
33*e4b17023SJohn Marino
34*e4b17023SJohn Marino Return zero if the two file names @var{s1} and @var{s2} are equivalent.
35*e4b17023SJohn Marino If not equivalent, the returned value is similar to what @code{strcmp}
36*e4b17023SJohn Marino would return. In other words, it returns a negative value if @var{s1}
37*e4b17023SJohn Marino is less than @var{s2}, or a positive value if @var{s2} is greater than
38*e4b17023SJohn Marino @var{s2}.
39*e4b17023SJohn Marino
40*e4b17023SJohn Marino This function does not normalize file names. As a result, this function
41*e4b17023SJohn Marino will treat filenames that are spelled differently as different even in
42*e4b17023SJohn Marino the case when the two filenames point to the same underlying file.
43*e4b17023SJohn Marino However, it does handle the fact that on DOS-like file systems, forward
44*e4b17023SJohn Marino and backward slashes are equal.
45*e4b17023SJohn Marino
46*e4b17023SJohn Marino @end deftypefn
47*e4b17023SJohn Marino
48*e4b17023SJohn Marino */
49*e4b17023SJohn Marino
50*e4b17023SJohn Marino int
filename_cmp(const char * s1,const char * s2)51*e4b17023SJohn Marino filename_cmp (const char *s1, const char *s2)
52*e4b17023SJohn Marino {
53*e4b17023SJohn Marino #if !defined(HAVE_DOS_BASED_FILE_SYSTEM) \
54*e4b17023SJohn Marino && !defined(HAVE_CASE_INSENSITIVE_FILE_SYSTEM)
55*e4b17023SJohn Marino return strcmp(s1, s2);
56*e4b17023SJohn Marino #else
57*e4b17023SJohn Marino for (;;)
58*e4b17023SJohn Marino {
59*e4b17023SJohn Marino int c1 = *s1;
60*e4b17023SJohn Marino int c2 = *s2;
61*e4b17023SJohn Marino
62*e4b17023SJohn Marino #if defined (HAVE_CASE_INSENSITIVE_FILE_SYSTEM)
63*e4b17023SJohn Marino c1 = TOLOWER (c1);
64*e4b17023SJohn Marino c2 = TOLOWER (c2);
65*e4b17023SJohn Marino #endif
66*e4b17023SJohn Marino
67*e4b17023SJohn Marino #if defined (HAVE_DOS_BASED_FILE_SYSTEM)
68*e4b17023SJohn Marino /* On DOS-based file systems, the '/' and the '\' are equivalent. */
69*e4b17023SJohn Marino if (c1 == '/')
70*e4b17023SJohn Marino c1 = '\\';
71*e4b17023SJohn Marino if (c2 == '/')
72*e4b17023SJohn Marino c2 = '\\';
73*e4b17023SJohn Marino #endif
74*e4b17023SJohn Marino
75*e4b17023SJohn Marino if (c1 != c2)
76*e4b17023SJohn Marino return (c1 - c2);
77*e4b17023SJohn Marino
78*e4b17023SJohn Marino if (c1 == '\0')
79*e4b17023SJohn Marino return 0;
80*e4b17023SJohn Marino
81*e4b17023SJohn Marino s1++;
82*e4b17023SJohn Marino s2++;
83*e4b17023SJohn Marino }
84*e4b17023SJohn Marino #endif
85*e4b17023SJohn Marino }
86*e4b17023SJohn Marino
87*e4b17023SJohn Marino /*
88*e4b17023SJohn Marino
89*e4b17023SJohn Marino @deftypefn Extension int filename_ncmp (const char *@var{s1}, const char *@var{s2}, size_t @var{n})
90*e4b17023SJohn Marino
91*e4b17023SJohn Marino Return zero if the two file names @var{s1} and @var{s2} are equivalent
92*e4b17023SJohn Marino in range @var{n}.
93*e4b17023SJohn Marino If not equivalent, the returned value is similar to what @code{strncmp}
94*e4b17023SJohn Marino would return. In other words, it returns a negative value if @var{s1}
95*e4b17023SJohn Marino is less than @var{s2}, or a positive value if @var{s2} is greater than
96*e4b17023SJohn Marino @var{s2}.
97*e4b17023SJohn Marino
98*e4b17023SJohn Marino This function does not normalize file names. As a result, this function
99*e4b17023SJohn Marino will treat filenames that are spelled differently as different even in
100*e4b17023SJohn Marino the case when the two filenames point to the same underlying file.
101*e4b17023SJohn Marino However, it does handle the fact that on DOS-like file systems, forward
102*e4b17023SJohn Marino and backward slashes are equal.
103*e4b17023SJohn Marino
104*e4b17023SJohn Marino @end deftypefn
105*e4b17023SJohn Marino
106*e4b17023SJohn Marino */
107*e4b17023SJohn Marino
108*e4b17023SJohn Marino int
filename_ncmp(const char * s1,const char * s2,size_t n)109*e4b17023SJohn Marino filename_ncmp (const char *s1, const char *s2, size_t n)
110*e4b17023SJohn Marino {
111*e4b17023SJohn Marino #if !defined(HAVE_DOS_BASED_FILE_SYSTEM) \
112*e4b17023SJohn Marino && !defined(HAVE_CASE_INSENSITIVE_FILE_SYSTEM)
113*e4b17023SJohn Marino return strncmp(s1, s2, n);
114*e4b17023SJohn Marino #else
115*e4b17023SJohn Marino if (!n)
116*e4b17023SJohn Marino return 0;
117*e4b17023SJohn Marino for (; n > 0; --n)
118*e4b17023SJohn Marino {
119*e4b17023SJohn Marino int c1 = *s1;
120*e4b17023SJohn Marino int c2 = *s2;
121*e4b17023SJohn Marino
122*e4b17023SJohn Marino #if defined (HAVE_CASE_INSENSITIVE_FILE_SYSTEM)
123*e4b17023SJohn Marino c1 = TOLOWER (c1);
124*e4b17023SJohn Marino c2 = TOLOWER (c2);
125*e4b17023SJohn Marino #endif
126*e4b17023SJohn Marino
127*e4b17023SJohn Marino #if defined (HAVE_DOS_BASED_FILE_SYSTEM)
128*e4b17023SJohn Marino /* On DOS-based file systems, the '/' and the '\' are equivalent. */
129*e4b17023SJohn Marino if (c1 == '/')
130*e4b17023SJohn Marino c1 = '\\';
131*e4b17023SJohn Marino if (c2 == '/')
132*e4b17023SJohn Marino c2 = '\\';
133*e4b17023SJohn Marino #endif
134*e4b17023SJohn Marino
135*e4b17023SJohn Marino if (c1 == '\0' || c1 != c2)
136*e4b17023SJohn Marino return (c1 - c2);
137*e4b17023SJohn Marino
138*e4b17023SJohn Marino s1++;
139*e4b17023SJohn Marino s2++;
140*e4b17023SJohn Marino }
141*e4b17023SJohn Marino return 0;
142*e4b17023SJohn Marino #endif
143*e4b17023SJohn Marino }
144