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 + -
显示快捷键?