blob: f49d6dda1bd6884b40df29c9ded8b7adb9c2a2fa [file] [log] [blame]
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <dirent.h>
#include <stdio.h>
#include <io.h>
#include <fcntl.h>
#include <process.h>
static char *concat();
static char *concat3();
static char *concat4();
static int onlyonedir;
static int atleastone;
static char *fixeddirs, *origdirs;
/* Convert all /'s to \'s */
char *
slash2slash (dirname)
char *dirname;
{
int i;
for (i=0; dirname[i]; i++)
if (dirname [i] == '/')
dirname [i] = '\\';
return dirname;
}
/* Examine each directory component of a path and create the directory */
int
mkdirpath (dirpath)
char *dirpath;
{
char *ndirpath = strdup (dirpath);
char *bp, *fp;
fp = bp = ndirpath;
while (bp)
{
bp = strchr (fp, '\\');
if (bp)
{
*bp = 0;
_mkdir (ndirpath);
*bp = '\\';
fp = ++bp;
}
else
_mkdir (ndirpath);
}
}
/* Construct a relative directory path from a given path by removing the
leading slash, if it exists and changing a drive letter from X: to X-. */
char *
newname (olddirname)
char *olddirname;
{
char *newname = strdup (olddirname);
if ((strlen (newname) >= 2)
&& (isalpha (newname[0]) && newname[1] == ':'))
newname [1] = '-';
else if ((strlen (newname) >= 1)
&& (newname [0] == '/' || newname [0] == '\\'))
newname = &newname[1];
return newname;
}
/* Run the sed script on one header file. If no modifications were made, then
delete the newly created file. */
int
doheader (oneheader, outheader, oldsize)
char *oneheader, *outheader;
int oldsize;
{
char *newbuff, *oldbuff;
char *newheader = concat3 ("include", "\\", newname (outheader));
struct _stat newstatbuf;
int newdesc, olddesc;
int i;
system (concat4 ("sed -f fixinc-nt.sed ", oneheader, " > ", newheader));
_stat (newheader, &newstatbuf);
if (oldsize != newstatbuf.st_size)
{
atleastone = 1;
printf ("Fixing: %s\n", oneheader);
return 0;
}
oldbuff = malloc (oldsize);
newbuff = malloc (newstatbuf.st_size);
olddesc = open (oneheader, _O_RDONLY | _O_BINARY);
newdesc = open (newheader, _O_RDONLY | _O_BINARY);
read (olddesc, oldbuff, oldsize);
read (newdesc, newbuff, newstatbuf.st_size);
close (olddesc);
close (newdesc);
for (i=0; i<oldsize; i++)
{
if (oldbuff [i] != newbuff [i])
{
free (oldbuff);
free (newbuff);
atleastone = 1;
printf ("Fixing: %s\n", oneheader);
return 0;
}
}
free (oldbuff);
free (newbuff);
unlink (newheader);
return 0;
}
/* Examine the contents of a directory and call doheader () for a regular file
and recursively call dodir () for an enclosed directory. */
int
dodir (indir, outdir)
char *indir, *outdir;
{
DIR *dir;
struct dirent *dire;
struct _stat statbuf;
char *intempbuf, *outtempbuf;
dir = opendir (indir);
if (!dir) return 0;
mkdirpath (concat3 ("include", "\\", newname (outdir)));
while ((dire = readdir (dir)))
{
if (dire->d_name[0] == '.')
continue;
intempbuf = slash2slash (concat3 (indir, "\\", dire->d_name));
outtempbuf = slash2slash (concat3 (outdir, "\\", dire->d_name));
_stat (intempbuf, &statbuf);
/* If directory ... */
if (statbuf.st_mode & _S_IFDIR)
dodir (intempbuf, outtempbuf);
/* If regular file ... */
if (statbuf.st_mode & _S_IFREG)
doheader (intempbuf, outtempbuf, statbuf.st_size);
}
closedir (dir);
return 0;
}
/* Retrieve the value of the Include environment variable, copy it into a
temporary and append a semi-colon for book-keeping purposes. Then call
dodir () for each complete directory that is named therein. If there is
only one directory, then direct the output to use include\. as the
root instead of include/<directory path>, where <directory path> is a path
constructed from the path named in the Include environment variable.
I.e. if Include=C:\MSTOOLS\Include;D:\MSVC20\Include then the modified
header files will be in include\C-\MSTOOLS\Include and
include\D-\MSVC20\Include. However if Include=C:\MSTOOLS\Include then the
modified files will be in include\. */
int
main ()
{
char *fp, *bp, *foobar;
char *incvar = getenv ("Include");
int varlen = 0;
struct _stat statbuf;
if (incvar == NULL) return 0;
varlen = strlen (incvar);
foobar = (char *) malloc (varlen + 2);
strcpy (foobar, incvar);
foobar = slash2slash (foobar);
if (foobar [varlen-1] != ';') strcat (foobar, ";");
fp = bp = foobar;
if (strchr (fp, ';') == strrchr (fp, ';'))
onlyonedir = 1;
else
onlyonedir = 0;
fixeddirs = strdup(".\\include");
origdirs = strdup("");
while (bp)
{
bp = strchr (fp, ';');
if (bp)
{
*bp = 0;
_stat (fp, &statbuf);
if (statbuf.st_mode & _S_IFDIR)
{
atleastone = 0;
if (onlyonedir)
dodir (fp, ".");
else
dodir (fp, fp);
if (atleastone && !onlyonedir)
{
origdirs = concat3 (origdirs, ";", fp);
fixeddirs = concat3 (fixeddirs, ";",
concat3 (".\\include", "\\", newname(fp)));
}
}
fp = ++bp;
}
}
printf ("set C_Include_Path=%s%s\n", fixeddirs, origdirs);
return 0;
}
/* Utility function that mallocs space and concatenates two strings. */
static char *
concat (s1, s2)
char *s1, *s2;
{
int len1 = strlen (s1);
int len2 = strlen (s2);
char *result = malloc (len1 + len2 + 1);
strcpy (result, s1);
strcpy (result + len1, s2);
*(result + len1 + len2) = 0;
return result;
}
/* Utility function that concatenates three strings. */
static char *
concat3 (s1, s2, s3)
char *s1, *s2, *s3;
{
return concat (concat (s1, s2), s3);
}
/* Utility function that concatenates four strings. */
static char *
concat4 (s1, s2, s3, s4)
char *s1, *s2, *s3, *s4;
{
return concat (concat (s1, s2), concat (s3, s4));
}