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