⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rcio.c

📁 开放源码的编译器open watcom 1.6.0版的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
    InitOutPutInfo( &errinfo );
    errinfo.severity = SEV_BANNER;
    #ifdef __OSI__
        if( _Copyright != NULL ) {                      /* 04-may-94 */
            RcFprintf( stdout, &errinfo, "%s\n", _Copyright );
        }
    #endif
    _splitpath( progpath, NULL, NULL, progfname, NULL );
    strlwr( progfname );

    GetRcMsg( USAGE_MSG_BASE, buf, sizeof( buf ) );
    RcFprintf( stdout, &errinfo, buf, progfname );
    RcFprintf( stdout, &errinfo, "\n" );
    index = USAGE_MSG_BASE + 1;
    for( ;; index++ ) {
        GetRcMsg( index, buf, sizeof( buf ) );
        if( buf[0] == '.' && buf[1] == '\0' ) break;
        RcFprintf( stdout, &errinfo, "%s\n", buf );
    }
}

/****** Text file input routines ******/
/* These routines maintain a stack of input files. Pushing a file onto the */
/* stack opens the file and sets up the buffer. Poping a file closes the file */
/* All other routines (except TextInputInit and TextInputShutdown) operate */
/* on the current file which is the one at the top of the stack */

#define MAX_INCLUDE_DEPTH   16

typedef struct PhysFileInfo {
    char    Filename[ _MAX_PATH ];
    int     IsOpen;
    int     Handle;
    long    Offset;     /* offset in file to read from next time if this */
                        /* is not the current file */
} PhysFileInfo;

typedef struct FileStackEntry {
    LogicalFileInfo     Logical;
    PhysFileInfo        Physical;
} FileStackEntry;

typedef struct FileStack {
    char *              Buffer;
    uint                BufferSize;
    char *              NextChar;
    char *              EofChar;        /* DON'T dereference, see below */
    /* + 1 for the before first entry */
    FileStackEntry      Stack[ MAX_INCLUDE_DEPTH + 1 ];
    FileStackEntry *    Current;
} FileStack;
/* EofChar points to the memory location after the last character currently */
/* in the buffer. If the physical EOF has been reached it will point to */
/* within Buffer, otherwise it will point AFTER Buffer. If NextChar == */
/* EofChar then either EOF has been reached or it's time to read in more */
/* of the file */

#define IsEmptyFileStack( stack ) ((stack).Current == (stack).Stack)

FileStack InStack;

extern void RcIoTextInputInit( void )
/***********************************/
{
    InStack.Buffer = RcMemMalloc( IO_BUFFER_SIZE );
    InStack.BufferSize = IO_BUFFER_SIZE;
    InStack.Current = InStack.Stack;
} /* RcIoTextInputInit */

extern int RcIoTextInputShutdown( void )
/**************************************/
{
    if( InStack.Buffer != NULL ) {
        RcMemFree( InStack.Buffer );
        InStack.Buffer = NULL;
        InStack.BufferSize = 0;
        if( IsEmptyFileStack( InStack ) ) {
            return( FALSE );
        } else {
            while( !IsEmptyFileStack( InStack ) ) {
                RcIoPopInputFile();
            }
            // return( TRUE );
        }
    }
    return( TRUE );
} /* RcIoTextInputShutdown */

static int OpenPhysicalFile( PhysFileInfo * phys )
/************************************************/
{
    int     seekrc;

    if( !phys->IsOpen ) {
        phys->Handle = RcIoOpenInput( phys->Filename, O_RDONLY | O_TEXT );
        if( phys->Handle == -1 ) {
            RcError( ERR_CANT_OPEN_FILE, phys->Filename, strerror( errno ) );
            return( TRUE );
        }
        phys->IsOpen = TRUE;
        seekrc = RcSeek( phys->Handle, phys->Offset, SEEK_SET );
        if( seekrc == -1 ) {
            RcError( ERR_READING_FILE, phys->Filename, strerror( errno ) );
            return( TRUE );
        }
    }

    return( FALSE );
} /* OpenPhysicalFile */

static int OpenNewPhysicalFile( PhysFileInfo * phys, char * filename )
/********************************************************************/
{
    strncpy( phys->Filename, filename, _MAX_PATH );
    phys->IsOpen = FALSE;
    phys->Offset = 0;

    return( OpenPhysicalFile( phys ) );
} /* OpenNewPhysicalFile */

static void SetPhysFileOffset( FileStack * stack )
/************************************************/
{
    PhysFileInfo *  phys;
    uint_16         charsinbuff;

    phys = &(stack->Current->Physical);

    charsinbuff = stack->BufferSize - (stack->NextChar - stack->Buffer);
    phys->Offset = RcTell( phys->Handle ) - charsinbuff;
} /* SetPhysFileOffset */

static int ReadBuffer( FileStack * stack )
/****************************************/
{
    PhysFileInfo   *phys;
    int             numread;
    int             error;
    int             inchar;

    phys = &(stack->Current->Physical);
    if( !phys->IsOpen ) {
        error = OpenPhysicalFile( phys );
        if( error ) return( TRUE );
    }
    if( CmdLineParms.NoPreprocess ) {
        numread = RcRead( phys->Handle, stack->Buffer, stack->BufferSize );
    } else {
        for( numread = 0; numread < stack->BufferSize; numread++ ) {
            inchar = PP_Char();
            if( inchar == EOF ) {
                break;
            }
            *( stack->Buffer + numread ) = (char)inchar;
        }
    }
    stack->NextChar = stack->Buffer;
    stack->EofChar = stack->Buffer + numread;   /* may be past end of buffer */

    return( FALSE );
} /* ReadBuffer */

extern int RcIoPushInputFile( char * filename )
/*********************************************/
{
    int                 error;

    if( InStack.Current == InStack.Stack + MAX_INCLUDE_DEPTH - 1 ) {
        RcError( ERR_RCINCLUDE_TOO_DEEP, MAX_INCLUDE_DEPTH );
        return( TRUE );
    }

    SetPhysFileOffset( &(InStack) );

    InStack.Current++;

    /* set up the logical file info */
    RcIoSetLogicalFileInfo( 1, filename );

    /* set up the physical file info */
    error = OpenNewPhysicalFile( &(InStack.Current->Physical), filename );
    if( error ) {
        InStack.Current--;
    } else {
        error = ReadBuffer( &(InStack) );
    }

    return( error );
} /* RcIoPushInputFile */

static void ClosePhysicalFile( PhysFileInfo * phys )
/**************************************************/
{
    if( phys->IsOpen ) {
        RcClose( phys->Handle );
        phys->IsOpen = FALSE;
    }
} /* ClosePhysicalFile */

extern int RcIoPopInputFile( void )
/*********************************/
{
    PhysFileInfo *  phys;

    phys = &(InStack.Current->Physical);
    ClosePhysicalFile( phys );
    InStack.Current--;
    if( IsEmptyFileStack( InStack ) ) {
        return( TRUE );
    } else {
        ReadBuffer( &(InStack) );
        return( FALSE );
    }
} /* RcIoPopInputFile */

static int GetLogChar( FileStack * stack )
/****************************************/
{
    int     newchar;

    newchar = *(stack->NextChar);
    if( newchar == '\n' ) {
        stack->Current->Logical.LineNum++;
    }

    stack->NextChar++;
    return( newchar );
} /* GetLogChar */

extern int RcIoGetChar( void )
/****************************/
{
    int     isempty;
    int     error;

    if( IsEmptyFileStack( InStack ) ) {
        return( RC_EOF );
    }

    if( InStack.NextChar >= InStack.EofChar ) {
        /* if this is a real EOF */
        if( InStack.NextChar < InStack.Buffer + InStack.BufferSize ) {
            /* unstack one file */
            isempty = RcIoPopInputFile();
            if( isempty ) {
                return( RC_EOF );
            } else {
                /* if we are still at the EOF char, there has been an error */
                if( InStack.NextChar >= InStack.EofChar ) {
                    /* this error is reported in ReadBuffer so just terminate */
                    RcFatalError( ERR_NO_MSG );
                } else {
                    /* return \n which will end the current token properly */
                    /* if it it is not a string and end it with a runaway */
                    /* string error for strings */
                    return( '\n' );
                }
            }
        } else {
            /* otherwise we have reached the end of the buffer */
            error = ReadBuffer( &(InStack) );
            if( error ) {
                /* this error is reported in ReadBuffer so just terminate */
                RcFatalError( ERR_NO_MSG );
            }
        }
    }
    return( GetLogChar( &InStack ) );
} /* RcIoGetChar */

extern const LogicalFileInfo * RcIoGetLogicalFileInfo( void )
/***********************************************************/
{
    if( IsEmptyFileStack( InStack ) ) {
        return( NULL );
    } else {
        return( &(InStack.Current->Logical) );
    }
} /* RcIoGetLogicalFileInfo */

extern void RcIoOverrideIsCOrHFlag( void )
/****************************************/
{
    LogicalFileInfo *   log;

    if( !IsEmptyFileStack( InStack ) ) {
        log = &(InStack.Current->Logical);
        log->IsCOrHFile = FALSE;
    }
} /* RcIoOverrideIsCOrHFlag */

extern void RcIoSetIsCOrHFlag( void )
/***********************************/
{
    LogicalFileInfo *   log;
    char                ext[ _MAX_EXT ];

    if( !IsEmptyFileStack( InStack ) ) {
        log = &(InStack.Current->Logical);
        _splitpath( log->Filename, NULL, NULL, NULL, ext );
        /* if this is a c or h file ext will be '.', '[ch]', '\0' */
        if( (ext[1] == 'c' || ext[1] == 'h' || ext[1] == 'C'
            || ext[1] == 'H' ) && ext[2] == '\0' ) {
            /* if the logical file is a c or h file */
            log->IsCOrHFile = TRUE;
        } else {
            log->IsCOrHFile = FALSE;
        }
    }
} /* RcIoSetIsCOrHFlag */

extern void RcIoSetLogicalFileInfo( int linenum, char * filename )
/****************************************************************/
{
    LogicalFileInfo *   log;

    if( !IsEmptyFileStack( InStack ) ) {
        log = &(InStack.Current->Logical);
        log->LineNum = linenum;
        if( filename != NULL ) {
            strncpy( log->Filename, filename, _MAX_PATH );
            RcIoSetIsCOrHFlag();
        }
    }
} /* RcIoSetLogicalFileInfo */

extern int RcIoIsCOrHFile( void )
/*******************************/
/* returns true if the current file is a .c or .h file, false otherwise */
{
    if( IsEmptyFileStack( InStack ) ) {
        return( FALSE );
    } else {
        return( InStack.Current->Logical.IsCOrHFile );
    }
} /* RcIoIsCOrHFile */

/*
 * RcIoOpenInput
 * NB when an error occurs this function MUST return without altering errno
 */
extern int RcIoOpenInput( char * filename, int flags, ... )
/********************************************************/
{
    int                 handle;
    int                 perms;
    va_list             args;
    FileStackEntry *    currfile;

    if( flags & O_CREAT ) {
        va_start( args, flags );
        perms = va_arg( args, int );
        va_end( args );
    } else {
        perms = 0;
    }

    handle = RcOpen( filename, flags, perms );

    if( handle == -1 && errno == EMFILE ) {
        /* set currfile to be the first (not before first) entry */
        currfile = InStack.Stack + 1;
        /* close open files except the current input file until able to open */
        /* don't close the current file because Offset isn't set */
        while( currfile < InStack.Current && handle == -1 && errno == EMFILE ) {
            if( currfile->Physical.IsOpen ) {
                ClosePhysicalFile( &(currfile->Physical) );
                handle = RcOpen( filename, flags, perms );
            }
            currfile++;
       }
    }

    return( handle );
} /* RcIoOpenInput */

extern void RcIoInitStatics( void )
/*********************************/
{
    memset( &InStack, 0, sizeof( FileStack ) );
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -