OSDN Git Service

entered into RCS
[pf3gnuchains/gcc-fork.git] / gcc / doschk.c
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