From: Richard Kenner Date: Tue, 12 Sep 1995 22:25:25 +0000 (-0400) Subject: Initial revision X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=2a9f2bb90143fab29da3d99b424cef091279eb04;p=gcc.git Initial revision From-SVN: r10337 --- diff --git a/gcc/config/winnt/dirent.c b/gcc/config/winnt/dirent.c new file mode 100644 index 00000000000..59f7dc1c6ef --- /dev/null +++ b/gcc/config/winnt/dirent.c @@ -0,0 +1,360 @@ +/* + * @(#)msd_dir.c 1.4 87/11/06 Public Domain. + * + * A public domain implementation of BSD directory routines for + * MS-DOS. Written by Michael Rendell ({uunet,utai}michael@garfield), + * August 1897 + * + * Modified by Ian Stewartson, Data Logic (istewart@datlog.co.uk). + * + * Updates: 1. To support OS/2 1.x + * 2. To support HPFS long filenames + * 3. To support OS/2 2.x + * 4. To support TurboC + * 5. To support Windows NT + */ + +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + + +#define WIN32_LEAN_AND_MEAN +#include + +#define FILE_NAME_E cFileName +#define OS_CloseFH(a) FindClose (a) +#define FIND_BUFFER WIN32_FIND_DATA +#define DISABLE_HARD_ERRORS SetErrorMode (0) +#define ENABLE_HARD_ERRORS SetErrorMode (SEM_FAILCRITICALERRORS | \ + SEM_NOOPENFILEERRORBOX); + +# define ERROR_EMPTY_DIR ERROR_FILE_NOT_FOUND + +# define ATTRIBUTES (_A_SUBDIR | _A_HIDDEN | _A_SYSTEM | \ + _A_NORMAL | _A_RDONLY | _A_ARCH) + +/* + * missing ?? + */ + +#ifndef ENOTDIR +# define ENOTDIR 120 /* Not a directory */ +#endif + +#ifndef S_IFMT +# define S_IFMT 0xf000 /* type of file */ +#endif + +#ifndef S_ISDIR +# define S_ISDIR(m) ((((m) & S_IFMT) == S_IFDIR)) +#endif + +/* + * Internals + */ + +typedef struct _dircontents DIRCONT; +static void free_dircontents (DIRCONT *); + +/* + * Open the directory stream + */ + +DIR * +opendir (name) + const char *name; +{ + struct stat statb; + DIR *dirp; + char *last; + DIRCONT *dp; + char *nbuf; + int len = strlen (name); + unsigned long rc; + FIND_BUFFER dtabuf; + HANDLE d_handle; + bool HPFS = FALSE; + + if (!len) + { + errno = ENOTDIR; + return (DIR *)NULL; + } + + if ((nbuf = malloc (len + 5)) == (char *)NULL) + return (DIR *) NULL; + + strcpy (nbuf, name); + last = &nbuf[len - 1]; + +/* Ok, DOS is very picky about its directory names. The following are + * valid. + * + * c:/ + * c:. + * c:name/name1 + * + * c:name/ is not valid + */ + + if (((*last == '\\') || (*last == '/')) && (len > 1) && + (!((len == 3) && (name[1] == ':')))) + *(last--) = 0; + +/* Check its a directory */ + + DISABLE_HARD_ERRORS; + rc = stat (nbuf, &statb); + ENABLE_HARD_ERRORS; + + if (rc) + { + free (nbuf); + return (DIR *) NULL; + } + + if (!S_ISDIR (statb.st_mode)) + { + free (nbuf); + errno = ENOTDIR; + return (DIR *)NULL; + } + + if ((dirp = (DIR *) malloc (sizeof (DIR))) == (DIR *) NULL) + { + free (nbuf); + return (DIR *) NULL; + } + +/* Set up to find everything */ + + if ((*last != '\\') && (*last != '/')) + strcat (last, "/"); + + strcat (last, "*.*"); + +/* Find the file system type */ + + HPFS = IsHPFSFileSystem (nbuf); + + dirp->dd_loc = 0; + dirp->dd_cp = (DIRCONT *) NULL; + dirp->dd_contents = (DIRCONT *) NULL; + + DISABLE_HARD_ERRORS; + + d_handle = FindFirstFile (nbuf, &dtabuf); + rc = (d_handle == INVALID_HANDLE_VALUE) ? GetLastError () : 0; + + ENABLE_HARD_ERRORS; + +/* Check for errors */ + + if (rc) + { + free (nbuf); + +/* Empty directory */ + +#if defined (ERROR_EMPTY_DIR) + if (rc == ERROR_EMPTY_DIR) + return dirp; +#endif + + free (dirp); + return (DIR *) NULL; + } + +/* Process the directory */ + + do + { + if (((dp = (DIRCONT *) malloc (sizeof (DIRCONT))) == (DIRCONT *)NULL) || + ((dp->_d_entry = strdup (dtabuf.FILE_NAME_E)) == (char *) NULL)) + { + if (dp->_d_entry != (char *)NULL) + free ((char *)dp); + + free (nbuf); + free_dircontents (dirp->dd_contents); + + OS_CloseFH (d_handle); + return (DIR *) NULL; + } + + if (!HPFS) + strlwr (dp->_d_entry); + + if (dirp->dd_contents != (DIRCONT *) NULL) + dirp->dd_cp = dirp->dd_cp->_d_next = dp; + + else + dirp->dd_contents = dirp->dd_cp = dp; + + dp->_d_next = (DIRCONT *) NULL; + + } while (FindNextFile (d_handle, &dtabuf)); + + dirp->dd_cp = dirp->dd_contents; + free (nbuf); + + OS_CloseFH (d_handle); + return dirp; +} + + +/* + * Close the directory stream + */ + +int +closedir (dirp) + DIR *dirp; +{ + if (dirp != (DIR *)NULL) + { + free_dircontents (dirp->dd_contents); + free ((char *)dirp); + } + + return 0; +} + +/* + * Read the next record from the stream + */ + +struct dirent * +readdir (dirp) + DIR *dirp; +{ + static struct dirent dp; + + if ((dirp == (DIR *)NULL) || (dirp->dd_cp == (DIRCONT *) NULL)) + return (struct dirent *) NULL; + + dp.d_reclen = strlen (strcpy (dp.d_name, dirp->dd_cp->_d_entry)); + dp.d_off = dirp->dd_loc * 32; + dp.d_ino = (ino_t)++dirp->dd_loc; + dirp->dd_cp = dirp->dd_cp->_d_next; + + return &dp; +} + +/* + * Restart the directory stream + */ + +void +rewinddir (dirp) + DIR *dirp; +{ + seekdir (dirp, (off_t)0); +} + +/* + * Move to a know position in the stream + */ + +void +seekdir (dirp, off) + DIR *dirp; + off_t off; +{ + long i = off; + DIRCONT *dp; + + if ((dirp == (DIR *)NULL) || (off < 0L)) + return; + + for (dp = dirp->dd_contents; (--i >= 0) && (dp != (DIRCONT *)NULL); + dp = dp->_d_next) + ; + + dirp->dd_loc = off - (i + 1); + dirp->dd_cp = dp; +} + +/* + * Get the current position + */ + +off_t +telldir(dirp) + DIR *dirp; +{ + return (dirp == (DIR *)NULL) ? (off_t) -1 : dirp->dd_loc; +} + +/* + * Release the internal structure + */ + +static void +free_dircontents (dp) + DIRCONT *dp; +{ + DIRCONT *odp; + + while ((odp = dp) != (DIRCONT *)NULL) + { + if (dp->_d_entry != (char *)NULL) + free (dp->_d_entry); + + dp = dp->_d_next; + free ((char *)odp); + } +} + + +/* + * Windows NT version + */ + +bool +IsHPFSFileSystem (directory) + char *directory; +{ + char bName[4]; + DWORD flags; + DWORD maxname; + BOOL rc; + unsigned int nDrive; + char szCurDir [MAX_PATH]; + + if (isalpha (directory[0]) && (directory[1] == ':')) + nDrive = toupper (directory[0]) - '@'; + + else + { + GetCurrentDirectory (MAX_PATH, szCurDir); + nDrive = szCurDir[0] - 'A' + 1; + } + +/* Set up the drive name */ + + strcpy (bName, "x:\\"); + bName[0] = (char) (nDrive + '@'); + +/* Read the volume info, if we fail - assume non-HPFS */ + + DISABLE_HARD_ERRORS; + + rc = GetVolumeInformation (bName, (LPTSTR)NULL, 0, (LPDWORD)NULL, + &maxname, &flags, (LPTSTR)NULL, 0); + ENABLE_HARD_ERRORS; + + return ((rc) && (flags & (FS_CASE_SENSITIVE | FS_CASE_IS_PRESERVED))) + ? TRUE : FALSE; +} + diff --git a/gcc/config/winnt/dirent.h b/gcc/config/winnt/dirent.h new file mode 100644 index 00000000000..822bd2cab06 --- /dev/null +++ b/gcc/config/winnt/dirent.h @@ -0,0 +1,96 @@ +/* + * dirent.h + */ + +#ifndef _DIRENT_H +# define _DIRENT_H + +# include +# include + +#define MAXNAMLEN 255 /* maximum filename length */ + +#ifndef NAME_MAX +#define NAME_MAX (MAXNAMLEN - 1) +#endif + +struct dirent /* data from getdents()/readdir() */ +{ + ino_t d_ino; /* inode number of entry */ + off_t d_off; /* offset of disk directory entry */ + wchar_t d_reclen; /* length of this record */ + char d_name[MAXNAMLEN + 1]; +}; + + +/* The following nonportable ugliness could have been avoided by defining + * DIRENTSIZ and DIRENTBASESIZ to also have (struct dirent *) arguments. + * There shouldn't be any problem if you avoid using the DIRENTSIZ() macro. + */ + +#define DIRENTBASESIZ (((struct dirent *)0)->d_name \ + - (char *)&((struct dirent *)0)->d_ino) + +#define DIRENTSIZ(namlen) ((DIRENTBASESIZ + sizeof(long) + (namlen)) \ + / sizeof(long) * sizeof(long)) + + + +# ifndef _BOOL_T_DEFINED +typedef unsigned char bool; +# define _BOOL_T_DEFINED +# endif + +# define DIRBUF 8192 /* buffer size for fs-indep. dirs */ + /* must in general be larger than the */ + /* filesystem buffer size */ + +struct _dircontents { + char *_d_entry; + struct _dircontents *_d_next; +}; + +typedef struct _dirdesc { + int dd_id; /* uniquely identify each open directory */ + long dd_loc; /* where we are in directory entry is this */ + struct _dircontents *dd_contents; /* pointer to contents of dir */ + struct _dircontents *dd_cp; /* pointer to current position */ +} DIR; + + +#if defined (__STDC__) +# define _PROTO(p) p +#else +# define _PROTO(p) () +# undef const +# undef volatile +#endif + +/* Functions */ + +extern DIR * opendir _PROTO ((const char *)); +extern struct dirent * readdir _PROTO ((DIR *)); +extern void rewinddir _PROTO ((DIR *)); + +extern int closedir _PROTO ((DIR *)); +extern void seekdir _PROTO ((DIR *, off_t)); +extern off_t telldir _PROTO ((DIR *)); + +extern int chdir _PROTO ((const char *)); +extern char * getcwd _PROTO ((char *, size_t)); + +extern int mkdir _PROTO ((const char *)); + +extern int rmdir _PROTO ((const char *)); +extern int scandir _PROTO ((char *, + struct dirent ***, + int (*)(const void *, const void *), + int (*)(const void *, const void *))); + +extern int _chdrive _PROTO ((int)); +extern int _getdrive _PROTO ((void)); +extern char * _getdcwd _PROTO ((int, char *, int)); + +extern bool IsHPFSFileSystem _PROTO ((char *)); + +#endif diff --git a/gcc/config/winnt/fixinc-nt.c b/gcc/config/winnt/fixinc-nt.c new file mode 100644 index 00000000000..f49d6dda1bd --- /dev/null +++ b/gcc/config/winnt/fixinc-nt.c @@ -0,0 +1,260 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +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; id_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/, where 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)); +} diff --git a/gcc/config/winnt/headers.mak b/gcc/config/winnt/headers.mak new file mode 100644 index 00000000000..69ef8598aca --- /dev/null +++ b/gcc/config/winnt/headers.mak @@ -0,0 +1,51 @@ +# Build the include directory. The stamp files are stmp-* rather than +# stamp-* so that mostlyclean does not force the include directory to +# be rebuilt. + + +# Copy in the headers provided with gcc. +USER_H = $(srcdir)\ginclude\stdarg.h $(srcdir)\ginclude\stddef.h \ + $(srcdir)\ginclude\varargs.h $(srcdir)\ginclude\va-alpha.h \ + $(srcdir)\ginclude\va-h8300.h $(srcdir)\ginclude\va-i860.h \ + $(srcdir)\ginclude\va-i960.h $(srcdir)\ginclude\va-mips.h \ + $(srcdir)\ginclude\va-m88k.h $(srcdir)\ginclude\va-pa.h \ + $(srcdir)\ginclude\va-pyr.h $(srcdir)\ginclude\va-sparc.h \ + $(srcdir)\ginclude\va-clipper.h $(srcdir)\ginclude\va-spur.h \ + $(srcdir)\ginclude\iso646.h \ + $(srcdir)\ginclude\proto.h + +# Build the include directory except for float.h (which depends upon +# enquire). + +stmp-int-hdrs: $(USER_H) + type $(srcdir)\limitx.h >xlimits.h + type $(srcdir)\glimits.h >>xlimits.h + type $(srcdir)\limity.h >>xlimits.h + + -mkdir include + for %%f in ($(USER_H)) do copy %%f include + del include\limits.h + copy xlimits.h include\limits.h + del include\syslimits.h + copy $(srcdir)\gsyslimits.h include\syslimits.h + copy include\limits.h include\syslimits.h + del include\README + copy $(srcdir)\README-fixinc include\README + touch stmp-int-hdrs + +stmp-headers: stmp-int-hdrs fixinc-nt.exe + fixinc-nt + touch stmp-headers + +# Build float.h. +stmp-float_h: libgcc.lib enquire.exe + -.\enquire -f > tmp-float.h + del include\float.h + copy tmp-float.h include\float.h + touch stmp-float_h + +fixinc-nt.obj: $(srcdir)/config/winnt/fixinc-nt.c + cl -c -I. -I$(srcdir) -I$(srcdir)/include $(srcdir)/config/winnt/fixinc-nt.c + +fixinc-nt.exe: fixinc-nt.obj dirent.obj + cl fixinc-nt.obj dirent.obj libc.lib kernel32.lib diff --git a/gcc/config/winnt/libgcc.mak b/gcc/config/winnt/libgcc.mak new file mode 100644 index 00000000000..adfb57e63cc --- /dev/null +++ b/gcc/config/winnt/libgcc.mak @@ -0,0 +1,19 @@ +# Build libgcc.a + +libgcc.lib : libgcc1.c libgcc2.c mklibgcc.exe + mklibgcc -c + mklibgcc "cl -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES)" libgcc1.c $(LIB1FUNCS) + mklibgcc "xgcc -B./ -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES)" libgcc2.c $(LIB2FUNCS) + mklibnow.bat + -del libgcc.lib + lib -verbose -out:libgcc.lib lgcctmp/*.obj + +mklibgcc.obj : $(srcdir)/config/winnt/mklibgcc.c + cl -I. -I$(srcdir) -I$(srcdir)/config/winnt -c $(srcdir)/config/winnt/mklibgcc.c + +dirent.obj : $(srcdir)/config/winnt/dirent.c stmp-int-hdrs + cl -I. -I$(srcdir) -I$(srcdir)/include -I$(srcdir)/config/winnt -c $(srcdir)/config/winnt/dirent.c + +mklibgcc.exe : mklibgcc.obj dirent.obj + cl mklibgcc.obj dirent.obj libc.lib kernel32.lib + diff --git a/gcc/config/winnt/mklibgcc.c b/gcc/config/winnt/mklibgcc.c new file mode 100644 index 00000000000..081e4ec22c4 --- /dev/null +++ b/gcc/config/winnt/mklibgcc.c @@ -0,0 +1,97 @@ +#include +#include +#include + +char *skips[] = { + 0 +}; + +int +do_clean() +{ + DIR *dir; + struct dirent *de; + remove("mklibnow.bat"); + + dir = opendir("lgcctmp"); + if (!dir) + return 0; + while ((de=readdir(dir))) + { + char buf[30]; + if (de->d_name[0] == '.') + continue; + sprintf(buf, "lgcctmp/%s", de->d_name); + unlink(buf); + } + closedir(dir); + return 0; +} + +int +main(int argc, char **argv) +{ + char *cc = argv[1]; + char *csrc=argv[2]; + int i; + FILE *batfile; + FILE *cfile; + + if (argc > 1 && strcmp(argv[1], "-c")==0) + return do_clean(); + + _mkdir("lgcctmp", 0755); + + batfile = fopen("mklibnow.bat", "a"); + if (!batfile) + { + perror("mklibnow.bat"); + return 1; + } +/* fprintf(batfile, "@echo off\n"); */ + + for (i=3; i