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 10static char *concat(); 11static char *concat3(); 12static char *concat4(); 13static int onlyonedir; 14static int atleastone; 15static char *fixeddirs, *origdirs; 16 17/* Convert all /'s to \'s */ 18 19char * 20slash2slash (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 33int 34mkdirpath (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 60char * 61newname (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 80int 81doheader (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 128int 129dodir (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 173int 174main () 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 229static char * 230concat (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 246static char * 247concat3 (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 255static char * 256concat4 (s1, s2, s3, s4) 257 char *s1, *s2, *s3, *s4; 258{ 259 return concat (concat (s1, s2), concat (s3, s4)); 260} 261