1/* fncase.c -- CVS support for case insensitive file systems.
2   Jim Blandy <jimb@cyclic.com>
3
4   This file is part of GNU CVS.
5
6   GNU CVS is free software; you can redistribute it and/or modify it
7   under the terms of the GNU General Public License as published by the
8   Free Software Foundation; either version 2, or (at your option) any
9   later version.
10
11   This program is distributed in the hope that it will be useful,
12   but WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   GNU General Public License for more details.  */
15#include <sys/cdefs.h>
16__RCSID("$NetBSD: fncase.c,v 1.2 2016/05/17 14:00:09 christos Exp $");
17
18#ifdef HAVE_CONFIG_H
19#include "config.h"
20#endif
21
22#include "system.h"
23
24/* The equivalence class mapping for filenames.
25   Windows NT filenames are case-insensitive, but case-preserving.
26   Both / and \ are path element separators.
27   Thus, this table maps both upper and lower case to lower case, and
28   both / and \ to /.  */
29
30#if 0
31main ()
32{
33  int c;
34
35  for (c = 0; c < 256; c++)
36    {
37      int t;
38
39      if (c == '\\')
40        t = '/';
41      else
42        t = tolower (c);
43
44      if ((c & 0x7) == 0x0)
45         printf ("    ");
46      printf ("0x%02x,", t);
47      if ((c & 0x7) == 0x7)
48         putchar ('\n');
49      else if ((c & 0x7) == 0x3)
50         putchar (' ');
51    }
52}
53#endif
54
55/* Under Windows NT, filenames are case-insensitive but case-preserving,
56   and both \ and / are path element separators.  */
57unsigned char
58WNT_filename_classes[] =
59{
60    0x00,0x01,0x02,0x03, 0x04,0x05,0x06,0x07,
61    0x08,0x09,0x0a,0x0b, 0x0c,0x0d,0x0e,0x0f,
62    0x10,0x11,0x12,0x13, 0x14,0x15,0x16,0x17,
63    0x18,0x19,0x1a,0x1b, 0x1c,0x1d,0x1e,0x1f,
64    0x20,0x21,0x22,0x23, 0x24,0x25,0x26,0x27,
65    0x28,0x29,0x2a,0x2b, 0x2c,0x2d,0x2e,0x2f,
66    0x30,0x31,0x32,0x33, 0x34,0x35,0x36,0x37,
67    0x38,0x39,0x3a,0x3b, 0x3c,0x3d,0x3e,0x3f,
68    0x40,0x61,0x62,0x63, 0x64,0x65,0x66,0x67,
69    0x68,0x69,0x6a,0x6b, 0x6c,0x6d,0x6e,0x6f,
70    0x70,0x71,0x72,0x73, 0x74,0x75,0x76,0x77,
71    0x78,0x79,0x7a,0x5b, 0x2f,0x5d,0x5e,0x5f,
72    0x60,0x61,0x62,0x63, 0x64,0x65,0x66,0x67,
73    0x68,0x69,0x6a,0x6b, 0x6c,0x6d,0x6e,0x6f,
74    0x70,0x71,0x72,0x73, 0x74,0x75,0x76,0x77,
75    0x78,0x79,0x7a,0x7b, 0x7c,0x7d,0x7e,0x7f,
76    0x80,0x81,0x82,0x83, 0x84,0x85,0x86,0x87,
77    0x88,0x89,0x8a,0x8b, 0x8c,0x8d,0x8e,0x8f,
78    0x90,0x91,0x92,0x93, 0x94,0x95,0x96,0x97,
79    0x98,0x99,0x9a,0x9b, 0x9c,0x9d,0x9e,0x9f,
80    0xa0,0xa1,0xa2,0xa3, 0xa4,0xa5,0xa6,0xa7,
81    0xa8,0xa9,0xaa,0xab, 0xac,0xad,0xae,0xaf,
82    0xb0,0xb1,0xb2,0xb3, 0xb4,0xb5,0xb6,0xb7,
83    0xb8,0xb9,0xba,0xbb, 0xbc,0xbd,0xbe,0xbf,
84    0xc0,0xc1,0xc2,0xc3, 0xc4,0xc5,0xc6,0xc7,
85    0xc8,0xc9,0xca,0xcb, 0xcc,0xcd,0xce,0xcf,
86    0xd0,0xd1,0xd2,0xd3, 0xd4,0xd5,0xd6,0xd7,
87    0xd8,0xd9,0xda,0xdb, 0xdc,0xdd,0xde,0xdf,
88    0xe0,0xe1,0xe2,0xe3, 0xe4,0xe5,0xe6,0xe7,
89    0xe8,0xe9,0xea,0xeb, 0xec,0xed,0xee,0xef,
90    0xf0,0xf1,0xf2,0xf3, 0xf4,0xf5,0xf6,0xf7,
91    0xf8,0xf9,0xfa,0xfb, 0xfc,0xfd,0xfe,0xff,
92};
93
94/* Same as WNT_filename_classes, but do not fold `\' into `/'.  */
95unsigned char
96OSX_filename_classes[] =
97{
98    0x00,0x01,0x02,0x03, 0x04,0x05,0x06,0x07,
99    0x08,0x09,0x0a,0x0b, 0x0c,0x0d,0x0e,0x0f,
100    0x10,0x11,0x12,0x13, 0x14,0x15,0x16,0x17,
101    0x18,0x19,0x1a,0x1b, 0x1c,0x1d,0x1e,0x1f,
102    0x20,0x21,0x22,0x23, 0x24,0x25,0x26,0x27,
103    0x28,0x29,0x2a,0x2b, 0x2c,0x2d,0x2e,0x2f,
104    0x30,0x31,0x32,0x33, 0x34,0x35,0x36,0x37,
105    0x38,0x39,0x3a,0x3b, 0x3c,0x3d,0x3e,0x3f,
106    0x40,0x61,0x62,0x63, 0x64,0x65,0x66,0x67,
107    0x68,0x69,0x6a,0x6b, 0x6c,0x6d,0x6e,0x6f,
108    0x70,0x71,0x72,0x73, 0x74,0x75,0x76,0x77,
109    0x78,0x79,0x7a,0x5b, 0x5c,0x5d,0x5e,0x5f,
110    0x60,0x61,0x62,0x63, 0x64,0x65,0x66,0x67,
111    0x68,0x69,0x6a,0x6b, 0x6c,0x6d,0x6e,0x6f,
112    0x70,0x71,0x72,0x73, 0x74,0x75,0x76,0x77,
113    0x78,0x79,0x7a,0x7b, 0x7c,0x7d,0x7e,0x7f,
114    0x80,0x81,0x82,0x83, 0x84,0x85,0x86,0x87,
115    0x88,0x89,0x8a,0x8b, 0x8c,0x8d,0x8e,0x8f,
116    0x90,0x91,0x92,0x93, 0x94,0x95,0x96,0x97,
117    0x98,0x99,0x9a,0x9b, 0x9c,0x9d,0x9e,0x9f,
118    0xa0,0xa1,0xa2,0xa3, 0xa4,0xa5,0xa6,0xa7,
119    0xa8,0xa9,0xaa,0xab, 0xac,0xad,0xae,0xaf,
120    0xb0,0xb1,0xb2,0xb3, 0xb4,0xb5,0xb6,0xb7,
121    0xb8,0xb9,0xba,0xbb, 0xbc,0xbd,0xbe,0xbf,
122    0xc0,0xc1,0xc2,0xc3, 0xc4,0xc5,0xc6,0xc7,
123    0xc8,0xc9,0xca,0xcb, 0xcc,0xcd,0xce,0xcf,
124    0xd0,0xd1,0xd2,0xd3, 0xd4,0xd5,0xd6,0xd7,
125    0xd8,0xd9,0xda,0xdb, 0xdc,0xdd,0xde,0xdf,
126    0xe0,0xe1,0xe2,0xe3, 0xe4,0xe5,0xe6,0xe7,
127    0xe8,0xe9,0xea,0xeb, 0xec,0xed,0xee,0xef,
128    0xf0,0xf1,0xf2,0xf3, 0xf4,0xf5,0xf6,0xf7,
129    0xf8,0xf9,0xfa,0xfb, 0xfc,0xfd,0xfe,0xff,
130};
131
132/* Like strcmp, but with the appropriate tweaks for file names.
133   Under Windows NT, filenames are case-insensitive but case-preserving,
134   and both \ and / are path element separators.  Under Mac OS X, filenames
135   are case-insensitive but case-preserving.  */
136int
137fncmp (const char *n1, const char *n2)
138{
139    while (*n1 && *n2
140           && (FOLD_FN_CHAR(*n1)
141	       == FOLD_FN_CHAR(*n2)))
142        n1++, n2++;
143    return (FOLD_FN_CHAR(*n1) - FOLD_FN_CHAR(*n2));
144}
145
146/* Fold characters in FILENAME to their canonical forms.
147   If FOLD_FN_CHAR is not #defined, the system provides a default
148   definition for this.  */
149void
150fnfold (char *filename)
151{
152    while (*filename)
153    {
154        *filename = FOLD_FN_CHAR (*filename);
155	filename++;
156    }
157}
158