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