/gnu/usr.bin/gcc/gcc/doschk.c

https://github.com/avsm/src · C · 360 lines · 336 code · 14 blank · 10 comment · 18 complexity · 5a6da22e5a1e7ee56f79b0bdcadfe237 MD5 · raw file

  1. /*
  2. ** DosFCheck - check file names for DOS consistency
  3. **
  4. ** Distribute freely, it only encourages DOS compatibility!
  5. ** - DJ Delorie
  6. */
  7. /* This file is not part of GCC. */
  8. #include <stdio.h>
  9. #ifdef __MSDOS__
  10. #include <alloc.h>
  11. #else
  12. #include <malloc.h>
  13. #endif
  14. #include <ctype.h>
  15. #include <string.h>
  16. typedef struct ENT
  17. {
  18. struct ENT *next;
  19. char *dos_name;
  20. char *full_name;
  21. char *path;
  22. int tagged;
  23. } ENT;
  24. ENT *eroot = 0;
  25. int first_inv = 1;
  26. int first_msg = 1;
  27. /****************************************************************\
  28. * Utility routines *
  29. \****************************************************************/
  30. void
  31. invalid_msg ()
  32. {
  33. if (first_inv)
  34. {
  35. if (first_msg)
  36. first_msg = 0;
  37. else
  38. putchar ('\n');
  39. printf ("The following files are not valid DOS file names:\n");
  40. first_inv = 0;
  41. }
  42. }
  43. ENT *
  44. alloc_ent ()
  45. {
  46. ENT *rv = (ENT *)malloc (sizeof (ENT));
  47. if (rv == 0)
  48. {
  49. fprintf (stderr, "Unable to allocate memory for an ENT\n");
  50. exit (1);
  51. }
  52. memset (rv, 0, sizeof (ENT));
  53. return rv;
  54. }
  55. void
  56. fill_ent (ent, path)
  57. ENT *ent;
  58. char *path;
  59. {
  60. char *first = path;
  61. char *null = path+strlen (path);
  62. char *last_slash = strrchr (path, '/');
  63. char *cp, *dp;
  64. int dots_seen, chars_seen;
  65. if (last_slash+1 == null)
  66. {
  67. * --null = '\0';
  68. last_slash = strrchr (path, '/');
  69. }
  70. if (!last_slash)
  71. {
  72. last_slash = first-1;
  73. }
  74. if (null-last_slash < 13)
  75. ent->dos_name = (char *)malloc (null-last_slash);
  76. else
  77. ent->dos_name = (char *)malloc (13);
  78. ent->full_name = (char *)malloc (null-last_slash);
  79. ent->path = (char *)malloc (last_slash-first+1);
  80. strcpy (ent->full_name, last_slash+1);
  81. if (last_slash > first)
  82. {
  83. strncpy (ent->path, first, last_slash-first);
  84. ent->path[last_slash-first] = '\0';
  85. }
  86. else
  87. *ent->path = '\0';
  88. cp = last_slash+1;
  89. dp = ent->dos_name;
  90. dots_seen = 0;
  91. chars_seen = 0;
  92. while (1)
  93. {
  94. if (! *cp)
  95. break;
  96. switch (*cp)
  97. {
  98. case '.':
  99. if (cp == last_slash+1 && strcmp (last_slash+1, "."))
  100. {
  101. invalid_msg ();
  102. printf ("%s - file name cannot start with dot\n", path);
  103. *dp = 0;
  104. break;
  105. }
  106. if (dots_seen == 1)
  107. {
  108. invalid_msg ();
  109. printf ("%s - too many dots\n", path);
  110. *dp = '\0';
  111. break;
  112. }
  113. *dp++ = '.';
  114. chars_seen = 0;
  115. dots_seen++;
  116. break;
  117. case '"':
  118. case '*':
  119. case '+':
  120. case ',':
  121. case ';':
  122. case '<':
  123. case '=':
  124. case '>':
  125. case '?':
  126. case '[':
  127. case '\\':
  128. case ']':
  129. case '|':
  130. invalid_msg ();
  131. printf ("%s - invalid character `%c'\n", path, *cp);
  132. *dp++ = '?';
  133. chars_seen++;
  134. break;
  135. default:
  136. if (dots_seen)
  137. {
  138. if (chars_seen >= 3)
  139. break;
  140. }
  141. else
  142. if (chars_seen >= 8)
  143. break;
  144. if ((*cp <= ' ') || (*cp >= 0x7f))
  145. {
  146. invalid_msg ();
  147. printf ("%s - invalid character `%c'\n", path, *cp);
  148. *dp++ = '?';
  149. chars_seen++;
  150. break;
  151. }
  152. if (islower (*cp))
  153. *dp++ = toupper (*cp);
  154. else
  155. *dp++ = *cp;
  156. chars_seen++;
  157. break;
  158. }
  159. cp++;
  160. }
  161. *dp++ = '\0';
  162. }
  163. int
  164. compare_ent_dosname (e1, e2)
  165. ENT **e1;
  166. ENT **e2;
  167. {
  168. int r = strcmp ((*e1)->dos_name, (*e2)->dos_name);
  169. if (r == 0)
  170. r = strcmp ((*e1)->path, (*e2)->path);
  171. if (r == 0)
  172. r = strcmp ((*e1)->full_name, (*e2)->full_name);
  173. return r;
  174. }
  175. int
  176. compare_ent_fullname (e1, e2)
  177. ENT **e1;
  178. ENT **e2;
  179. {
  180. int r = strncmp ((*e1)->full_name, (*e2)->full_name, 14);
  181. if (r == 0)
  182. r = strcmp ((*e1)->path, (*e2)->path);
  183. if (r == 0)
  184. r = strcmp ((*e1)->full_name, (*e2)->full_name);
  185. return r;
  186. }
  187. char *
  188. mpath (ent)
  189. ENT *ent;
  190. {
  191. static char buf[500];
  192. if (ent->path && ent->path[0])
  193. sprintf (buf, "%s/%s", ent->path, ent->full_name);
  194. else
  195. return ent->full_name;
  196. return buf;
  197. }
  198. /****************************************************************\
  199. * List handling routines *
  200. \****************************************************************/
  201. void
  202. add_ent (ent)
  203. ENT *ent;
  204. {
  205. ent->next = eroot;
  206. eroot = ent;
  207. }
  208. void
  209. handle_input (line)
  210. char *line;
  211. {
  212. ENT *ent = alloc_ent ();
  213. fill_ent (ent, line);
  214. add_ent (ent);
  215. }
  216. void
  217. display_problems ()
  218. {
  219. ENT **elist, *ent;
  220. int ecount, i, first, first_err;
  221. for (ecount=0, ent=eroot; ent; ent=ent->next, ecount++);
  222. elist = (ENT **)malloc (sizeof (ENT *) * ecount);
  223. for (ecount=0, ent=eroot; ent; ent=ent->next, ecount++)
  224. elist[ecount] = ent;
  225. qsort (elist, ecount, sizeof (ENT *), compare_ent_dosname);
  226. first = 1;
  227. first_err = 1;
  228. for (i=0; i<ecount-1; i++)
  229. {
  230. if ((strcmp (elist[i]->dos_name, elist[i+1]->dos_name) == 0)
  231. && (strcmp (elist[i]->path, elist[i+1]->path) == 0))
  232. {
  233. if (first_err)
  234. {
  235. if (first_msg)
  236. first_msg = 0;
  237. else
  238. putchar ('\n');
  239. printf ("The following resolve to the same DOS file names:\n");
  240. first_err = 0;
  241. }
  242. if (first)
  243. {
  244. printf ("%14s : %s\n", elist[i]->dos_name, mpath (elist[i]));
  245. first = 0;
  246. }
  247. printf ("\t\t %s\n", mpath (elist[i+1]));
  248. }
  249. else
  250. first = 1;
  251. }
  252. qsort (elist, ecount, sizeof (ENT *), compare_ent_fullname);
  253. first = 1;
  254. first_err = 1;
  255. for (i=0; i<ecount-1; i++)
  256. {
  257. if ((strncmp (elist[i]->full_name, elist[i+1]->full_name, 14) == 0)
  258. && (strcmp (elist[i]->path, elist[i+1]->path) == 0))
  259. {
  260. if (first_err)
  261. {
  262. if (first_msg)
  263. first_msg = 0;
  264. else
  265. putchar ('\n');
  266. printf ("The following resolve to the same SysV file names:\n");
  267. first_err = 0;
  268. }
  269. if (first)
  270. {
  271. printf ("%.14s : %s\n", elist[i]->full_name, mpath (elist[i]));
  272. first = 0;
  273. elist[i]->tagged = 1;
  274. }
  275. printf ("\t\t %s\n", mpath (elist[i+1]));
  276. elist[i+1]->tagged = 1;
  277. }
  278. else
  279. first = 1;
  280. }
  281. first_err = 1;
  282. for (i=0; i<ecount; i++)
  283. {
  284. if ((strlen (elist[i]->full_name) > 14) && !elist[i]->tagged)
  285. {
  286. if (first_err)
  287. {
  288. if (first_msg)
  289. first_msg = 0;
  290. else
  291. putchar ('\n');
  292. printf ("The following file names are too long for SysV:\n");
  293. first_err = 0;
  294. }
  295. printf ("%.14s : %s\n", elist[i]->full_name, mpath (elist[i]));
  296. }
  297. }
  298. }
  299. /****************************************************************\
  300. * Main entry point *
  301. \****************************************************************/
  302. main (argc, argv)
  303. int argc;
  304. char **argv;
  305. {
  306. FILE *input = stdin;
  307. if (argc > 1)
  308. {
  309. input = fopen (argv[1], "r");
  310. if (!input)
  311. {
  312. perror (argv[1]);
  313. exit (1);
  314. }
  315. }
  316. while (1)
  317. {
  318. char line[500];
  319. char *lp;
  320. fgets (line, 500, input);
  321. if (feof (input))
  322. break;
  323. lp = line+strlen (line);
  324. while ((lp != line) && (*lp <= ' '))
  325. lp--;
  326. lp[1] = 0;
  327. handle_input (line);
  328. }
  329. display_problems ();
  330. }