xref: /openbsd-src/gnu/usr.bin/gcc/gcc/doschk.c (revision c87b03e512fc05ed6e0222f6fb0ae86264b1d05b)
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
invalid_msg()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 *
alloc_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
fill_ent(ent,path)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
compare_ent_dosname(e1,e2)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
compare_ent_fullname(e1,e2)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 *
mpath(ent)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
add_ent(ent)221 add_ent (ent)
222 ENT *ent;
223 {
224   ent->next = eroot;
225   eroot = ent;
226 }
227 
228 void
handle_input(line)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
display_problems()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 
main(argc,argv)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 
361