New testcase.
[official-gcc.git] / gcc / doschk.c
blobad553df7e8c3d62b6ed075f63b67ab777537b263
1 /*
2 ** DosFCheck - check file names for DOS consistency
3 **
4 ** Distribute freely, it only encourages DOS compatibility!
5 ** - DJ Delorie
6 */
8 /* This file is not part of GCC. */
10 #include <stdio.h>
11 #ifdef __MSDOS__
12 #include <alloc.h>
13 #else
14 #include <malloc.h>
15 #endif
16 #include <ctype.h>
17 #include <string.h>
19 typedef struct ENT
21 struct ENT *next;
22 char *dos_name;
23 char *full_name;
24 char *path;
25 int tagged;
26 } ENT;
28 ENT *eroot = 0;
30 int first_inv = 1;
31 int first_msg = 1;
33 /****************************************************************\
34 * Utility routines *
35 \****************************************************************/
37 void
38 invalid_msg ()
40 if (first_inv)
42 if (first_msg)
43 first_msg = 0;
44 else
45 putchar ('\n');
46 printf ("The following files are not valid DOS file names:\n");
47 first_inv = 0;
51 ENT *
52 alloc_ent ()
54 ENT *rv = (ENT *)malloc (sizeof (ENT));
55 if (rv == 0)
57 fprintf (stderr, "Unable to allocate memory for an ENT\n");
58 exit (1);
60 memset (rv, 0, sizeof (ENT));
61 return rv;
64 void
65 fill_ent (ent, path)
66 ENT *ent;
67 char *path;
69 char *first = path;
70 char *null = path+strlen (path);
71 char *last_slash = strrchr (path, '/');
72 char *cp, *dp;
73 int dots_seen, chars_seen;
75 if (last_slash+1 == null)
77 * --null = '\0';
78 last_slash = strrchr (path, '/');
81 if (!last_slash)
83 last_slash = first-1;
86 if (null-last_slash < 13)
87 ent->dos_name = (char *)malloc (null-last_slash);
88 else
89 ent->dos_name = (char *)malloc (13);
90 ent->full_name = (char *)malloc (null-last_slash);
91 ent->path = (char *)malloc (last_slash-first+1);
93 strcpy (ent->full_name, last_slash+1);
94 if (last_slash > first)
96 strncpy (ent->path, first, last_slash-first);
97 ent->path[last_slash-first] = '\0';
99 else
100 *ent->path = '\0';
102 cp = last_slash+1;
103 dp = ent->dos_name;
104 dots_seen = 0;
105 chars_seen = 0;
106 while (1)
108 if (! *cp)
109 break;
110 switch (*cp)
112 case '.':
113 if (cp == last_slash+1 && strcmp (last_slash+1, "."))
115 invalid_msg ();
116 printf ("%s - file name cannot start with dot\n", path);
117 *dp = 0;
118 break;
120 if (dots_seen == 1)
122 invalid_msg ();
123 printf ("%s - too many dots\n", path);
124 *dp = '\0';
125 break;
127 *dp++ = '.';
128 chars_seen = 0;
129 dots_seen++;
130 break;
131 case '"':
132 case '*':
133 case '+':
134 case ',':
135 case ';':
136 case '<':
137 case '=':
138 case '>':
139 case '?':
140 case '[':
141 case '\\':
142 case ']':
143 case '|':
144 invalid_msg ();
145 printf ("%s - invalid character `%c'\n", path, *cp);
146 *dp++ = '?';
147 chars_seen++;
148 break;
149 default:
150 if (dots_seen)
152 if (chars_seen >= 3)
153 break;
155 else
156 if (chars_seen >= 8)
157 break;
158 if ((*cp <= ' ') || (*cp >= 0x7f))
160 invalid_msg ();
161 printf ("%s - invalid character `%c'\n", path, *cp);
162 *dp++ = '?';
163 chars_seen++;
164 break;
166 if (islower (*cp))
167 *dp++ = toupper (*cp);
168 else
169 *dp++ = *cp;
170 chars_seen++;
171 break;
173 cp++;
175 *dp++ = '\0';
179 compare_ent_dosname (e1, e2)
180 ENT **e1;
181 ENT **e2;
183 int r = strcmp ((*e1)->dos_name, (*e2)->dos_name);
184 if (r == 0)
185 r = strcmp ((*e1)->path, (*e2)->path);
186 if (r == 0)
187 r = strcmp ((*e1)->full_name, (*e2)->full_name);
188 return r;
192 compare_ent_fullname (e1, e2)
193 ENT **e1;
194 ENT **e2;
196 int r = strncmp ((*e1)->full_name, (*e2)->full_name, 14);
197 if (r == 0)
198 r = strcmp ((*e1)->path, (*e2)->path);
199 if (r == 0)
200 r = strcmp ((*e1)->full_name, (*e2)->full_name);
201 return r;
204 char *
205 mpath (ent)
206 ENT *ent;
208 static char buf[500];
209 if (ent->path && ent->path[0])
210 sprintf (buf, "%s/%s", ent->path, ent->full_name);
211 else
212 return ent->full_name;
213 return buf;
216 /****************************************************************\
217 * List handling routines *
218 \****************************************************************/
220 void
221 add_ent (ent)
222 ENT *ent;
224 ent->next = eroot;
225 eroot = ent;
228 void
229 handle_input (line)
230 char *line;
232 ENT *ent = alloc_ent ();
233 fill_ent (ent, line);
234 add_ent (ent);
237 void
238 display_problems ()
240 ENT **elist, *ent;
241 int ecount, i, first, first_err;
243 for (ecount=0, ent=eroot; ent; ent=ent->next, ecount++);
244 elist = (ENT **)malloc (sizeof (ENT *) * ecount);
245 for (ecount=0, ent=eroot; ent; ent=ent->next, ecount++)
246 elist[ecount] = ent;
248 qsort (elist, ecount, sizeof (ENT *), compare_ent_dosname);
250 first = 1;
251 first_err = 1;
252 for (i=0; i<ecount-1; i++)
254 if ((strcmp (elist[i]->dos_name, elist[i+1]->dos_name) == 0)
255 && (strcmp (elist[i]->path, elist[i+1]->path) == 0))
257 if (first_err)
259 if (first_msg)
260 first_msg = 0;
261 else
262 putchar ('\n');
263 printf ("The following resolve to the same DOS file names:\n");
264 first_err = 0;
266 if (first)
268 printf ("%14s : %s\n", elist[i]->dos_name, mpath (elist[i]));
269 first = 0;
271 printf ("\t\t %s\n", mpath (elist[i+1]));
273 else
274 first = 1;
277 qsort (elist, ecount, sizeof (ENT *), compare_ent_fullname);
279 first = 1;
280 first_err = 1;
281 for (i=0; i<ecount-1; i++)
283 if ((strncmp (elist[i]->full_name, elist[i+1]->full_name, 14) == 0)
284 && (strcmp (elist[i]->path, elist[i+1]->path) == 0))
286 if (first_err)
288 if (first_msg)
289 first_msg = 0;
290 else
291 putchar ('\n');
292 printf ("The following resolve to the same SysV file names:\n");
293 first_err = 0;
295 if (first)
297 printf ("%.14s : %s\n", elist[i]->full_name, mpath (elist[i]));
298 first = 0;
299 elist[i]->tagged = 1;
301 printf ("\t\t %s\n", mpath (elist[i+1]));
302 elist[i+1]->tagged = 1;
304 else
305 first = 1;
308 first_err = 1;
309 for (i=0; i<ecount; i++)
311 if ((strlen (elist[i]->full_name) > 14) && !elist[i]->tagged)
313 if (first_err)
315 if (first_msg)
316 first_msg = 0;
317 else
318 putchar ('\n');
319 printf ("The following file names are too long for SysV:\n");
320 first_err = 0;
322 printf ("%.14s : %s\n", elist[i]->full_name, mpath (elist[i]));
327 /****************************************************************\
328 * Main entry point *
329 \****************************************************************/
331 main (argc, argv)
332 int argc;
333 char **argv;
335 FILE *input = stdin;
336 if (argc > 1)
338 input = fopen (argv[1], "r");
339 if (!input)
341 perror (argv[1]);
342 exit (1);
345 while (1)
347 char line[500];
348 char *lp;
349 fgets (line, 500, input);
350 if (feof (input))
351 break;
352 lp = line+strlen (line);
353 while ((lp != line) && (*lp <= ' '))
354 lp--;
355 lp[1] = 0;
356 handle_input (line);
358 display_problems ();