|
|
1.1 root 1: /*
2: ** DosFCheck - check file names for DOS consistency
3: **
4: ** Distribute freely, it only encourages DOS compatibility!
5: ** - DJ Delorie
6: */
7:
8: /* This file is not part of GCC. */
9:
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>
18:
19: typedef struct ENT
20: {
21: struct ENT *next;
22: char *dos_name;
23: char *full_name;
24: char *path;
25: int tagged;
26: } ENT;
27:
28: ENT *eroot = 0;
29:
30: int first_inv = 1;
31: int first_msg = 1;
32:
33: /****************************************************************\
34: * Utility routines *
35: \****************************************************************/
36:
37: void
38: invalid_msg ()
39: {
40: if (first_inv)
41: {
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;
48: }
49: }
50:
51: ENT *
52: alloc_ent ()
53: {
54: ENT *rv = (ENT *)malloc (sizeof (ENT));
55: if (rv == 0)
56: {
57: fprintf (stderr, "Unable to allocate memory for an ENT\n");
58: exit (1);
59: }
60: memset (rv, 0, sizeof (ENT));
61: return rv;
62: }
63:
64: void
65: fill_ent (ent, path)
66: ENT *ent;
67: char *path;
68: {
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;
74:
75: if (last_slash+1 == null)
76: {
77: * --null = '\0';
78: last_slash = strrchr (path, '/');
79: }
80:
81: if (!last_slash)
82: {
83: last_slash = first-1;
84: }
85:
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);
92:
93: strcpy (ent->full_name, last_slash+1);
94: if (last_slash > first)
95: {
96: strncpy (ent->path, first, last_slash-first);
97: ent->path[last_slash-first] = '\0';
98: }
99: else
100: *ent->path = '\0';
101:
102: cp = last_slash+1;
103: dp = ent->dos_name;
104: dots_seen = 0;
105: chars_seen = 0;
106: while (1)
107: {
108: if (! *cp)
109: break;
110: switch (*cp)
111: {
112: case '.':
113: if (cp == last_slash+1 && strcmp (last_slash+1, "."))
114: {
115: invalid_msg ();
116: printf ("%s - file name cannot start with dot\n", path);
117: *dp = 0;
118: break;
119: }
120: if (dots_seen == 1)
121: {
122: invalid_msg ();
123: printf ("%s - too many dots\n", path);
124: *dp = '\0';
125: break;
126: }
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)
151: {
152: if (chars_seen >= 3)
153: break;
154: }
155: else
156: if (chars_seen >= 8)
157: break;
158: if ((*cp <= ' ') || (*cp >= 0x7f))
159: {
160: invalid_msg ();
161: printf ("%s - invalid character `%c'\n", path, *cp);
162: *dp++ = '?';
163: chars_seen++;
164: break;
165: }
166: if (islower (*cp))
167: *dp++ = toupper (*cp);
168: else
169: *dp++ = *cp;
170: chars_seen++;
171: break;
172: }
173: cp++;
174: }
175: *dp++ = '\0';
176: }
177:
178: int
179: compare_ent_dosname (e1, e2)
180: ENT **e1;
181: ENT **e2;
182: {
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;
189: }
190:
191: int
192: compare_ent_fullname (e1, e2)
193: ENT **e1;
194: ENT **e2;
195: {
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;
202: }
203:
204: char *
205: mpath (ent)
206: ENT *ent;
207: {
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;
214: }
215:
216: /****************************************************************\
217: * List handling routines *
218: \****************************************************************/
219:
220: void
221: add_ent (ent)
222: ENT *ent;
223: {
224: ent->next = eroot;
225: eroot = ent;
226: }
227:
228: void
229: handle_input (line)
230: char *line;
231: {
232: ENT *ent = alloc_ent ();
233: fill_ent (ent, line);
234: add_ent (ent);
235: }
236:
237: void
238: display_problems ()
239: {
240: ENT **elist, *ent;
241: int ecount, i, first, first_err;
242:
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;
247:
248: qsort (elist, ecount, sizeof (ENT *), compare_ent_dosname);
249:
250: first = 1;
251: first_err = 1;
252: for (i=0; i<ecount-1; i++)
253: {
254: if ((strcmp (elist[i]->dos_name, elist[i+1]->dos_name) == 0) &&
255: (strcmp (elist[i]->path, elist[i+1]->path) == 0))
256: {
257: if (first_err)
258: {
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;
265: }
266: if (first)
267: {
268: printf ("%14s : %s\n", elist[i]->dos_name, mpath (elist[i]));
269: first = 0;
270: }
271: printf ("\t\t %s\n", mpath (elist[i+1]));
272: }
273: else
274: first = 1;
275: }
276:
277: qsort (elist, ecount, sizeof (ENT *), compare_ent_fullname);
278:
279: first = 1;
280: first_err = 1;
281: for (i=0; i<ecount-1; i++)
282: {
283: if ((strncmp (elist[i]->full_name, elist[i+1]->full_name, 14) == 0) &&
284: (strcmp (elist[i]->path, elist[i+1]->path) == 0))
285: {
286: if (first_err)
287: {
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;
294: }
295: if (first)
296: {
297: printf ("%.14s : %s\n", elist[i]->full_name, mpath (elist[i]));
298: first = 0;
299: elist[i]->tagged = 1;
300: }
301: printf ("\t\t %s\n", mpath (elist[i+1]));
302: elist[i+1]->tagged = 1;
303: }
304: else
305: first = 1;
306: }
307:
308: first_err = 1;
309: for (i=0; i<ecount; i++)
310: {
311: if ((strlen (elist[i]->full_name) > 14) && !elist[i]->tagged)
312: {
313: if (first_err)
314: {
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;
321: }
322: printf ("%.14s : %s\n", elist[i]->full_name, mpath (elist[i]));
323: }
324: }
325: }
326:
327: /****************************************************************\
328: * Main entry point *
329: \****************************************************************/
330:
331: main (argc, argv)
332: int argc;
333: char **argv;
334: {
335: FILE *input = stdin;
336: if (argc > 1)
337: {
338: input = fopen (argv[1], "r");
339: if (!input)
340: {
341: perror (argv[1]);
342: exit (1);
343: }
344: }
345: while (1)
346: {
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);
357: }
358: display_problems ();
359: }
360:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.