iosupp.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 977 行 · 第 1/2 页
C
977 行
}
return pp;
}
static boolean openSrcPath( // ATTEMPT TO OPEN FILE (PATH TO BE PREPENDED)
char *path, // - path
char **exts, // - file extensions
struct path_descr *fd, // - file descriptor
enum file_type typ ) // - type of file being opened
{
boolean retn; // - return: TRUE ==> opened
struct path_descr pd; // - path descriptor
char dir[ _MAX_PATH*2 ]; // - new path
char *pp; // - pointer into path
char *ext; // - extension opened
splitFileName( path, &pd );
if( fd->drv[0] == '\0' ) {
pp = stpcpy( dir, path );
} else if( pd.drv[0] == '\0' ) {
pp = stpcpy( dir, fd->drv );
pp = stpcpy( pp, path );
} else {
pp = NULL;
}
if( pp == NULL ) {
retn = NULL;
} else {
pp = concSep( pp, dir );
makeDirName( pp, fd );
splitFileName( dir, &pd );
ext = openSrcExts( exts, &pd, typ );
if( ext == NULL ) {
retn = FALSE;
} else {
if( ( typ == FT_SRC ) && ( ext != fd->ext ) ) {
_makepath( dir, fd->drv, fd->dir, fd->fnm, ext );
WholeFName = FNameAdd( dir );
}
retn = TRUE;
}
}
return retn;
}
static boolean doIoSuppOpenSrc( // OPEN A SOURCE FILE (PRIMARY,HEADER)
struct path_descr *fd, // - descriptor for file name
enum file_type typ ) // - type of search path to use
{
char **paths; // - optional paths to prepend
char **exts; // - optional extensions to append
boolean retn; // - return: TRUE ==> opened
char *path; // - next path
char bufpth[ _MAX_PATH ]; // - buffer for next path
SRCFILE curr; // - current included file
SRCFILE stdin_srcfile; // - srcfile for stdin
struct path_descr idescr; // - descriptor for included file
LINE_NO dummy; // - dummy line number holder
char prevpth[ _MAX_PATH ]; // - buffer for previous path
switch( typ ) {
case FT_SRC:
if( fd->fnm[0] == '\0' && fd->ext[0] == '.' && fd->ext[1] == '\0' ) {
if( ErrCount != 0 ) {
// command line errors may result in "." as the input name
// so the user thinks that the compiler is hung!
return( FALSE );
}
WholeFName = FNameAdd( "stdin" );
stdin_srcfile = SrcFileOpen( stdin, WholeFName );
SrcFileNotAFile( stdin_srcfile );
goto file_was_found;
}
paths = pathSrc;
exts = extsSrc;
break;
case FT_HEADER:
case FT_LIBRARY:
if( !CompFlags.ignore_current_dir ) {
paths = pathHdr;
} else {
paths = NULL;
}
exts = extsHdr;
break;
case FT_CMD:
paths = pathCmd;
exts = extsCmd;
break;
}
switch( typ ) {
case FT_LIBRARY:
if( fd->drv[0] != '\0' || IS_DIR_SEP( fd->dir[0] ) ) {
retn = openSrcPath( "", exts, fd, typ );
if( retn ) goto file_was_found;
}
break;
case FT_HEADER:
// even if ignoreing current dir, have to look for absolute paths
if( !CompFlags.ignore_current_dir || fd->drv[0] != '\0' ) {
// look in current directory
retn = openSrcPath( "", exts, fd, typ );
if( retn ) goto file_was_found;
}
/* check directories of currently included files */
if( !IS_PATH_SEP( fd->dir[0] ) ) {
prevpth[0] = '\xff'; /* to make it not compare with anything else */
prevpth[1] = '\0';
curr = SrcFileCurrent();
for( ;; ) {
if( curr == NULL ) break;
splitFileName( SrcFileName( curr ), &idescr );
_makepath( bufpth, idescr.drv, idescr.dir, NULL, NULL );
/*optimization: don't try and open if in previously checked dir*/
if( strcmp( bufpth, prevpth ) != 0 ) {
retn = openSrcPath( bufpth, exts, fd, FT_HEADER );
if( retn ) goto file_was_found;
}
curr = SrcFileIncluded( curr, &dummy );
strcpy( prevpth, bufpth );
}
}
break;
case FT_SRC:
case FT_CMD:
retn = openSrcPath( "", exts, fd, typ );
if( retn ) goto file_was_found;
break;
}
switch( typ ) {
case FT_HEADER:
case FT_LIBRARY:
HFileListStart();
for( ; ; ) {
HFileListNext( bufpth );
if( *bufpth == '\0' ) break;
retn = openSrcPath( bufpth, exts, fd, typ );
if( retn ) goto file_was_found;
}
break;
}
switch( typ ) {
case FT_HEADER:
case FT_CMD:
case FT_SRC:
if( IS_PATH_SEP( fd->dir[0] ) ) {
// absolute path
break;
}
if( paths != NULL ) {
for( ; ; ) {
path = *paths++;
if( path == NULL ) break;
retn = openSrcPath( path, exts, fd, typ );
if( retn ) goto file_was_found;
}
}
break;
}
return FALSE;
file_was_found:
switch( typ ) {
case FT_CMD:
SrcFileCommand();
break;
case FT_LIBRARY:
SrcFileLibrary();
break;
}
return TRUE;
}
boolean IoSuppOpenSrc( // OPEN A SOURCE FILE (PRIMARY,HEADER)
char *file_name, // - supplied file name
enum file_type typ ) // - type of search path to use
{
struct path_descr fd; // - descriptor for file name
#ifdef OPT_BR
if( NULL != file_name
&& file_name[0] != '\0' ) {
TOKEN_LOCN locn;
switch( typ ) {
case FT_SRC :
case FT_HEADER :
case FT_LIBRARY :
SrcFileGetTokenLocn( &locn );
BrinfIncludeSource( file_name, &locn );
break;
}
}
#endif
splitFileName( file_name, &fd );
if( doIoSuppOpenSrc( &fd, typ ) ) return TRUE;
#if !defined(__DOS__)
if( !CompFlags.check_truncated_fnames ) return FALSE;
if( strlen( fd.fnm ) <= 8 ) return FALSE;
fd.fnm[8] = '\0';
if( doIoSuppOpenSrc( &fd, typ ) ) return TRUE;
#endif
return FALSE;
}
static void tempFname( char *fname )
{
char *env;
int i;
#if defined(__UNIX__)
env = CppGetEnv( "TMPDIR" );
if( env == NULL ) env = CppGetEnv( "TMP" );
#else
env = CppGetEnv( "TMP" );
#endif
if( env == NULL ) env = "";
#define TMP_EXT ".tmp"
#define MAX_TMP_PATH (_MAX_PATH - sizeof( workFile ) - sizeof( TMP_EXT ) - 2)
strncpy( fname, env, MAX_TMP_PATH );
fname[ MAX_TMP_PATH ] = '\0';
i = strlen( fname );
if( i > 0 && !IS_PATH_SEP( fname[i-1] ) ) {
fname[i++] = PATH_SEP;
}
strcpy( &fname[i], workFile );
strcpy( &fname[i+sizeof(workFile)-1], TMP_EXT );
}
#if defined(__DOS__)
#include "tinyio.h"
extern void __SetIOMode( int, unsigned );
#endif
static void ioSuppError( // SIGNAL I/O ERROR AND ABORT
int error_code ) // - error code
{
CErr2( error_code, errno );
CSuicide();
}
static void ioSuppReadError( // SIGNAL ERROR ON READ
void )
{
ioSuppError( ERR_WORK_FILE_READ_ERROR );
}
static void ioSuppWriteError( // SIGNAL ERROR ON WRITE
void )
{
ioSuppError( ERR_WORK_FILE_WRITE_ERROR );
}
static void ioSuppTempOpen( // OPEN TEMPORARY FILE
void )
{
int mode;
auto char fname[ _MAX_PATH ];
mode = O_RDWR | O_CREAT | O_EXCL;
#if defined(__UNIX__)
// Unix files are always binary
mode |= O_TEMP;
#else
mode |= O_BINARY;
#endif
for(;;) {
tempFname( fname );
#if defined(__DOS__)
{ tiny_ret_t rc;
rc = TinyCreateNew( fname, 0 );
if( TINY_ERROR( rc ) ) {
temphandle = -1;
} else {
temphandle = TINY_INFO( rc );
__SetIOMode( temphandle, _READ | _WRITE | _BINARY );
}
}
#else
temphandle = open( fname, mode, S_IRUSR | S_IWUSR );
#endif
if( temphandle != -1 ) break;
if( workFile[5] == 'Z' ) {
temphandle = -1;
break;
}
switch( workFile[5] ) {
case '9':
workFile[5] = 'A';
break;
case 'I':
workFile[5] = 'J'; /* file-system may be EBCDIC */
break;
case 'R':
workFile[5] = 'S'; /* file-system may be EBCDIC */
break;
default:
++workFile[5];
break;
}
}
#if defined(__UNIX__)
/* Under POSIX it's legal to remove a file that's open. The file
space will be reclaimed when the handle is closed. This makes
sure that the work file always gets removed. */
remove( fname );
tempname = NULL;
#else
tempname = FNameAdd( fname );
#endif
if( temphandle == -1 ) {
ioSuppError( ERR_UNABLE_TO_OPEN_WORK_FILE );
}
}
char *IoSuppFullPath( // GET FULL PATH OF FILE NAME (ALWAYS USE RET VALUE)
char *name, // - input file name
char *buff, // - output buffer
unsigned size ) // - output buffer size
{
DbgAssert( size >= _MAX_PATH );
#ifndef NDEBUG
// caller should use return value only!
// - this code will make sure caller doesn't use buff
*buff = '.';
++buff;
--size;
#endif
return _getFilenameFullPath( buff, name, size );
}
DISK_ADDR IoSuppTempNextBlock( // GET NEXT BLOCK NUMBER
unsigned num_blocks ) // - number of blocks allocated
{
DISK_ADDR retn;
retn = tempBlock + 1;
tempBlock += num_blocks;
return retn;
}
void IoSuppTempWrite( // WRITE TO TEMPORARY FILE
DISK_ADDR block_num, // - block within temp file
size_t block_size, // - size of blocks
void *data ) // - buffer to write
{
if( temphandle == -1 ) ioSuppTempOpen();
block_num--;
if( -1 == lseek( temphandle, block_size * block_num, SEEK_SET ) ) {
ioSuppWriteError();
}
if( block_size != write( temphandle, data, block_size ) ) {
ioSuppWriteError();
}
}
void IoSuppTempRead( // READ FROM TEMPORARY FILE
DISK_ADDR block_num, // - block within temp file
size_t block_size, // - size of blocks
void *data ) // - buffer to read
{
if( temphandle == -1 ) ioSuppTempOpen();
block_num--;
if( -1 == lseek( temphandle, block_size * block_num, SEEK_SET ) ) {
ioSuppReadError();
}
if( block_size != read( temphandle, data, block_size ) ) {
ioSuppReadError();
}
}
char *IoSuppIncPathElement( // GET ONE PATH ELEMENT FROM INCLUDE LIST
const char *path, // - include list
char *prefix ) // - buffer to store element
{
unsigned length;
length = 0;
for( ; ; ) {
if( *path == '\0' ) break;
if( (*path == INC_PATH_SEP) || (*path == ';') ) {
++path;
if( length != 0 ) {
break;
}
} else {
++length;
*prefix++ = *path++;
}
}
if( ( length > 1 ) && IS_DIR_SEP( *(prefix-1) ) ) --prefix;
*prefix = '\0';
return( (char *)path );
}
char *IoSuppAddIncPathSep( // ADD AN INCLUDE PATH SEPARATOR
char *path ) // - place to add separator
{
*path = INC_PATH_SEP;
return( path + 1 );
}
static boolean pathExists( // TEST IF A PATH EXISTS
char *path ) // - path to be tested
{
DIR *dir; // - control for directory
boolean retn; // - return: TRUE ==> directory exists
retn = FALSE;
dir = opendir( path );
if( dir != NULL ) {
closedir( dir );
retn = TRUE;
}
return retn;
}
static void setPaths( // SET PATHS (IF THEY EXIST)
char **vect ) // - the vector of potential paths
{
char **dest; // - place to store
char **test; // - path to test
char *path; // - current path
dest = vect;
test = vect;
for( ;; ) {
path = *test;
if( path == NULL ) break;
if( pathExists( path ) ) {
*dest++ = path;
}
++test;
}
*dest = NULL;
}
static void ioSuppInit( // INITIALIZE IO SUPPORT
INITFINI* defn ) // - definition
{
defn = defn;
outFileChecked = 0;
tempBlock = 0;
tempname = NULL;
temphandle = -1;
workFile[5] = '0';
carve_buf = CarveCreate( sizeof( BUF_ALLOC ), 8 );
setPaths( pathSrc );
setPaths( pathHdr );
setPaths( pathCmd );
}
static void ioSuppFini( // FINALIZE IO SUPPORT
INITFINI* defn ) // - definition
{
defn = defn;
if( temphandle != -1 ) {
close( temphandle );
if( tempname != NULL ) {
remove( tempname );
}
}
while( NULL != buffers ) {
freeBuffer( buffers );
}
CarveDestroy( carve_buf );
}
INITDEFN( io_support, ioSuppInit, ioSuppFini )
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?