home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / gcc-2.7.2.1-src.tgz / tar.out / fsf / gcc / doschk.c < prev    next >
C/C++ Source or Header  |  1996-09-28  |  7KB  |  361 lines

  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.  
  361.