home *** CD-ROM | disk | FTP | other *** search
/ OpenStep 4.2J (Developer) / os42jdev.iso / NextDeveloper / Source / GNU / gcc / config / winnt / fixinc-nt.c < prev    next >
C/C++ Source or Header  |  1995-12-11  |  6KB  |  261 lines

  1. #include <stdlib.h>
  2. #include <string.h>
  3. #include <sys/stat.h>
  4. #include <dirent.h>
  5. #include <stdio.h>
  6. #include <io.h>
  7. #include <fcntl.h>
  8. #include <process.h>
  9.  
  10. static char *concat();
  11. static char *concat3();
  12. static char *concat4();
  13. static int onlyonedir;
  14. static int atleastone;
  15. static char *fixeddirs, *origdirs;
  16.  
  17. /* Convert all /'s to \'s */
  18.  
  19. char *
  20. slash2slash (dirname)
  21.   char *dirname;
  22. {
  23.   int i;
  24.   for (i=0; dirname[i]; i++)
  25.     if (dirname [i] == '/')
  26.       dirname [i] = '\\';
  27.  
  28.   return dirname;
  29. }
  30.  
  31. /* Examine each directory component of a path and create the directory */
  32.  
  33. int
  34. mkdirpath (dirpath)
  35.   char *dirpath;
  36. {
  37.   char *ndirpath = strdup (dirpath);
  38.   char *bp, *fp;
  39.  
  40.   fp = bp = ndirpath;
  41.  
  42.   while (bp) 
  43.     {
  44.       bp = strchr (fp, '\\');
  45.       if (bp)
  46.         {
  47.           *bp = 0;
  48.           _mkdir (ndirpath);
  49.           *bp = '\\';
  50.           fp = ++bp;
  51.         }
  52.       else
  53.         _mkdir (ndirpath);
  54.     }
  55. }
  56.  
  57. /* Construct a relative directory path from a given path by removing the
  58.    leading slash, if it exists and changing a drive letter from X: to X-. */
  59.  
  60. char *
  61. newname (olddirname)
  62.   char *olddirname;
  63. {
  64.   char *newname = strdup (olddirname);
  65.  
  66.   if ((strlen (newname) >= 2)
  67.       && (isalpha (newname[0]) && newname[1] == ':'))
  68.     newname [1] = '-';
  69.   else if ((strlen (newname) >= 1) 
  70.            && (newname [0] == '/' || newname [0] == '\\'))
  71.     newname = &newname[1];
  72.  
  73.   return newname;
  74.  
  75. }
  76.  
  77. /* Run the sed script on one header file.  If no modifications were made, then
  78.    delete the newly created file. */
  79.  
  80. int
  81. doheader (oneheader, outheader, oldsize)
  82.   char *oneheader, *outheader;
  83.   int oldsize;
  84. {
  85.   char *newbuff, *oldbuff;
  86.   char *newheader = concat3 ("include", "\\", newname (outheader));
  87.   struct _stat newstatbuf;
  88.   int newdesc, olddesc;
  89.   int i;
  90.  
  91.   system (concat4 ("sed -f fixinc-nt.sed ", oneheader, " > ", newheader));
  92.   _stat (newheader, &newstatbuf);
  93.   if (oldsize != newstatbuf.st_size) 
  94.     {
  95.       atleastone = 1;
  96.       printf ("Fixing: %s\n", oneheader);
  97.       return 0;
  98.     }
  99.   oldbuff = malloc (oldsize);
  100.   newbuff = malloc (newstatbuf.st_size);
  101.   olddesc = open (oneheader, _O_RDONLY | _O_BINARY);
  102.   newdesc = open (newheader, _O_RDONLY | _O_BINARY);
  103.   read (olddesc, oldbuff, oldsize);
  104.   read (newdesc, newbuff, newstatbuf.st_size);
  105.   close (olddesc);
  106.   close (newdesc);
  107.   for (i=0; i<oldsize; i++)
  108.     {
  109.       if (oldbuff [i] != newbuff [i])
  110.         {
  111.           free (oldbuff);
  112.           free (newbuff);
  113.           atleastone = 1;
  114.           printf ("Fixing: %s\n", oneheader);
  115.           return 0;
  116.         }
  117.     }
  118.   free (oldbuff);
  119.   free (newbuff);
  120.   unlink (newheader);
  121.   return 0;
  122.   
  123. }
  124.  
  125. /* Examine the contents of a directory and call doheader () for a regular file
  126.    and recursively call dodir () for an enclosed directory. */
  127.  
  128. int
  129. dodir (indir, outdir)
  130.   char *indir, *outdir;
  131. {
  132.   DIR *dir;
  133.   struct dirent *dire;
  134.   struct _stat statbuf;
  135.   char *intempbuf, *outtempbuf;
  136.  
  137.   dir = opendir (indir);
  138.   if (!dir) return 0;
  139.  
  140.   mkdirpath (concat3 ("include", "\\", newname (outdir)));
  141.   while ((dire = readdir (dir)))
  142.     {
  143.       if (dire->d_name[0] == '.')
  144.         continue;
  145.   
  146.       intempbuf = slash2slash (concat3 (indir, "\\", dire->d_name));
  147.       outtempbuf = slash2slash (concat3 (outdir, "\\", dire->d_name));
  148.       _stat (intempbuf, &statbuf);
  149.   
  150.       /* If directory ... */
  151.       if (statbuf.st_mode & _S_IFDIR)
  152.         dodir (intempbuf, outtempbuf);
  153.   
  154.       /* If regular file ... */
  155.       if (statbuf.st_mode & _S_IFREG)
  156.         doheader (intempbuf, outtempbuf, statbuf.st_size);
  157.     }
  158.   closedir (dir);
  159.   return 0;
  160. }
  161.  
  162. /* Retrieve the value of the Include environment variable, copy it into a
  163.    temporary and append a semi-colon for book-keeping purposes. Then call
  164.    dodir () for each complete directory that is named therein.  If there is
  165.    only one directory, then direct the output to use include\. as the
  166.    root instead of include/<directory path>, where <directory path> is a path
  167.    constructed from the path named in the Include environment variable.  
  168.    I.e. if Include=C:\MSTOOLS\Include;D:\MSVC20\Include then the modified
  169.    header files will be in include\C-\MSTOOLS\Include and 
  170.    include\D-\MSVC20\Include.  However if Include=C:\MSTOOLS\Include then the
  171.    modified files will be in include\. */
  172.  
  173. int
  174. main ()
  175. {
  176.   char *fp, *bp, *foobar;
  177.   char *incvar = getenv ("Include");
  178.   int varlen = 0;
  179.   struct _stat statbuf;
  180.  
  181.   if (incvar == NULL) return 0;
  182.  
  183.   varlen = strlen (incvar);
  184.   foobar = (char *) malloc (varlen + 2);
  185.  
  186.   strcpy (foobar, incvar);
  187.   foobar = slash2slash (foobar);
  188.   if (foobar [varlen-1] != ';') strcat (foobar, ";");
  189.   fp = bp = foobar;
  190.  
  191.   if (strchr (fp, ';') == strrchr (fp, ';'))
  192.     onlyonedir = 1;
  193.   else
  194.     onlyonedir = 0;
  195.  
  196.   fixeddirs = strdup(".\\include");
  197.   origdirs = strdup("");
  198.  
  199.   while (bp)
  200.     {
  201.       bp = strchr (fp, ';');
  202.       if (bp)
  203.         {
  204.           *bp = 0;
  205.           _stat (fp, &statbuf);
  206.           if (statbuf.st_mode & _S_IFDIR)
  207.             {
  208.               atleastone = 0;
  209.               if (onlyonedir) 
  210.                 dodir (fp, ".");
  211.               else
  212.                 dodir (fp, fp);
  213.               if (atleastone && !onlyonedir)
  214.                 {
  215.                   origdirs = concat3 (origdirs, ";", fp);
  216.                   fixeddirs = concat3 (fixeddirs, ";", 
  217.                     concat3 (".\\include", "\\", newname(fp)));
  218.                 }
  219.             }
  220.           fp = ++bp;
  221.         }
  222.     }
  223.   printf ("set C_Include_Path=%s%s\n", fixeddirs, origdirs);
  224.   return 0;
  225. }
  226.  
  227. /* Utility function that mallocs space and concatenates two strings. */
  228.  
  229. static char *
  230. concat (s1, s2)
  231.      char *s1, *s2;
  232. {
  233.   int len1 = strlen (s1);
  234.   int len2 = strlen (s2);
  235.   char *result = malloc (len1 + len2 + 1);
  236.  
  237.   strcpy (result, s1);
  238.   strcpy (result + len1, s2);
  239.   *(result + len1 + len2) = 0;
  240.  
  241.   return result;
  242. }
  243.  
  244. /* Utility function that concatenates three strings. */
  245.  
  246. static char *
  247. concat3 (s1, s2, s3)
  248.      char *s1, *s2, *s3;
  249. {
  250.   return concat (concat (s1, s2), s3);
  251. }
  252.  
  253. /* Utility function that concatenates four strings. */
  254.  
  255. static char *
  256. concat4 (s1, s2, s3, s4)
  257.      char *s1, *s2, *s3, *s4;
  258. {
  259.   return concat (concat (s1, s2), concat (s3, s4));
  260. }
  261.