mstream.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 537 行 · 第 1/2 页

C
537
字号
    }
    return( RET_ERROR );
}
#ifdef __WATCOMC__
#pragma off(check_stack);
#endif

extern void InsOpenFile( int fh )
/********************************
 * Push an already open file into the stream (ie: stdin)
 */
{
    SENT    *tmp;

    assert( eof( fh ) == 0 );   /* not at eof, and proper fh */

    tmp = getSENT( SENT_FILE );
    tmp->free = FALSE;
    tmp->data.file.name = NULL;

    pushFH( tmp, fh );
}


extern void InsString( const char *str, BOOLEAN weFree )
/*******************************************************
 * Push a string into the stream.  Assumes that contents of string remain
 * static while it is in the stream.  (ie: it doesn't make its own copy).
 * If weFree then, it will be FreeSafe'd when it is done.
 */
{
    SENT    *tmp;

    assert( str != NULL );

    tmp = getSENT( SENT_STR );
    tmp->free = weFree;
    tmp->data.str.str = str;
    tmp->data.str.cur = str;
}


extern void UnGetCH( STRM_T c )
/******************************
 * Push back a single character
 */
{
    SENT    *tmp;

    assert( isascii( c ) || c == STRM_END || c == STRM_MAGIC ||
            c == TMP_EOL || c == TMP_LEX_START);

    tmp = getSENT( SENT_CHAR );
    tmp->data.ch = c;
}


extern STRM_T GetCHR( void )
/**************************
 * Get single next character of input
 */
{
    SENT    *head;  /* this is just here for optimizing purposes */
    STRM_T  result;

    flagEOF = 0;
    for( ;; ) {
        head = headSent;

        if( head == NULL ) {
            return( STRM_END ); /* the big mama ending! no more stream! */
        }

        switch( head->type ) {
        case SENT_FILE:
            /* GetFileLine() depends on the order of execution here */
            if( head->data.file.cur == head->data.file.max ) {
                if( !fillBuffer() ) {
                    if( head->data.file.nestLevel != GetNestLevel() ) {
                        PrtMsg( WRN | EOF_BEFORE_ENDIF, "endif" );
                    }
                    popSENT();
                    flagEOF = 1;
                    return( EOL );
                }
            }
            result = *(head->data.file.cur++);
            if( isbarf( result ) ) {
                /* ignore \r in \r\n */
                if( result == '\r' && head->data.file.cur[0] == EOL ) {
                    result = *(head->data.file.cur++);
                } else if( Glob.microsoft && result == 0x1a ) {
                    /* embedded ^Z terminates stream in MS mode */
                    result = EOL;
                    popSENT();
                    flagEOF = 1;
                } else {
                    PrtMsg( FTL | LOC | BARF_CHARACTER, result );
                }
            }
            if( result == '\f' ) {
                result = EOL;
            }
            if( result == EOL ) {
                head->data.file.line++;
            }
            return( result );
        case SENT_STR:
            result = *(head->data.str.cur++);
            if( result == NULLCHAR ) {
                popSENT();
                continue;   /* try again */
            }
            return( result );
        case SENT_CHAR:
            result = head->data.ch;
            popSENT();
            return( result );
        }
        assert( FALSE );    /* should never get here */
    }
}

#ifdef USE_SCARCE
STATIC RET_T streamScarce( void )
/*******************************/
{
    SENT    *cur;

    if( freeSent == NULL ) {
        return( RET_ERROR );
    }

    while( freeSent != NULL ) {
        cur = freeSent;
        freeSent = freeSent->next;
        FreeSafe( cur );
    }

    return( RET_SUCCESS );
}
#endif

extern void StreamFini( void )
/****************************/
{
    while( headSent != NULL ) {
        popSENT();
    }
}


extern void StreamInit( void )
/****************************/
{
    int     count;
    SENT    *sent;

    /* preallocate storage to speed things up, and reduce fragmentation */

    freeSent = NULL;
    for( count = 0; count < STREAM_ALLOC_SENT; count++ ) {
        sent = MallocSafe( sizeof( *sent ) );
        sent->next = freeSent;
        freeSent = sent;
    }

#ifdef USE_SCARCE
    IfMemScarce( streamScarce );
#endif
}


extern RET_T GetFileLine( const char **pname, UINT16 *pline )
/************************************************************
 * get filename, and line number of file closest to top of stack
 * FALSE - no files in stack; TRUE - returned data from top file
 */
{
    SENT    *cur;

    cur = headSent;
    while( cur != NULL ) {
        if( cur->type == SENT_FILE ) {
            break;
        }
        cur = cur->next;
    }

    if( cur == NULL ) {
        return( RET_ERROR );
    }

    /*
     * Because we do a line++ when we return a {nl}, we have to check if
     * the last character returned was a {nl}.  We check the last character
     * if any characters have been read - it is just at cur[-1].  The only
     * time that cur > buf == FALSE is when nothing has been read.  (Check
     * the code for reading - even after filling the buffer this doesn't
     * evaluate improperly).
     */
    *pline = cur->data.file.line;
    if( cur->data.file.cur > cur->data.file.buf &&
        cur->data.file.cur[-1] == EOL ) {
        --(*pline);
    }

    *pname = cur->data.file.name;

    return( RET_SUCCESS );
}


extern int IsStreamEOF( void )
{
    return( flagEOF );
}


#ifdef DEVELOPMENT      /* code to dump the stack of SENTs */
extern void dispSENT( void )
/**************************/
{
    char    buf[256];
    size_t  pos;
    SENT    *cur;

    if( headSent ) {
        PrtMsg( INF | PRNTSTR, "\n[stream contents:]" );
        cur = headSent;
        while( cur ) {
            pos = FmtStr( buf, "[type %d, ", cur->type );
            switch( cur->type ) {
            case SENT_FILE:
                if( cur->data.file.cur == cur->data.file.max ) {
                    pos += FmtStr( &buf[pos], "fh %d, buffer empty, line %d",
                        cur->data.file.fh, cur->data.file.line );
                } else {
                    pos += FmtStr( &buf[pos],
                        "fh %d, in buf %d, next 0x%x, line %d",
                        cur->data.file.fh, cur->data.file.max - cur->data.file.cur,
                        *(cur->data.file.cur), cur->data.file.line );
                }
                if( cur->data.file.name ) {
                    pos += FmtStr( &buf[pos], ", name %s", cur->data.file.name );
                }
                pos += FmtStr( &buf[pos], "]" );
                PrtMsg( INF | PRNTSTR, buf );
                break;
            case SENT_STR:
                pos += FmtStr( &buf[pos], "(" );
                PrtMsg( INF | NEOL | PRNTSTR, buf );
                PrtMsg( INF | NEOL | PRNTSTR, cur->data.str.cur );
                PrtMsg( INF | PRNTSTR, ")]" );
                break;
            case SENT_CHAR:
                pos += FmtStr( &buf[pos], "character 0x%x]", cur->data.ch );
                PrtMsg( INF| PRNTSTR, buf );
                break;
            }
            cur = cur->next;
        }
    } else {
        PrtMsg( INF | PRNTSTR, "[stream empty]" );
    }
}
#endif

⌨️ 快捷键说明

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