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