mirror of https://github.com/YosysHQ/abc.git
449 lines
13 KiB
C
449 lines
13 KiB
C
/**CFile****************************************************************
|
|
|
|
FileName [verStream.c]
|
|
|
|
SystemName [ABC: Logic synthesis and verification system.]
|
|
|
|
PackageName [Verilog parser.]
|
|
|
|
Synopsis [Input file stream, which knows nothing about Verilog.]
|
|
|
|
Author [Alan Mishchenko]
|
|
|
|
Affiliation [UC Berkeley]
|
|
|
|
Date [Ver. 1.0. Started - August 19, 2006.]
|
|
|
|
Revision [$Id: verStream.c,v 1.00 2006/08/19 00:00:00 alanmi Exp $]
|
|
|
|
***********************************************************************/
|
|
|
|
#include "ver.h"
|
|
|
|
ABC_NAMESPACE_IMPL_START
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
/// DECLARATIONS ///
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
#define VER_BUFFER_SIZE 1048576 // 1M - size of the data chunk stored in memory
|
|
#define VER_OFFSET_SIZE 65536 // 64K - load new data when less than this is left
|
|
#define VER_WORD_SIZE 65536 // 64K - the largest token that can be returned
|
|
|
|
#define VER_MINIMUM(a,b) (((a) < (b))? (a) : (b))
|
|
|
|
struct Ver_Stream_t_
|
|
{
|
|
// the input file
|
|
char * pFileName; // the input file name
|
|
FILE * pFile; // the input file pointer
|
|
int nFileSize; // the total number of bytes in the file
|
|
int nFileRead; // the number of bytes currently read from file
|
|
int nLineCounter; // the counter of lines processed
|
|
// temporary storage for data
|
|
char * pBuffer; // the buffer
|
|
int nBufferSize; // the size of the buffer
|
|
char * pBufferCur; // the current reading position
|
|
char * pBufferEnd; // the first position not used by currently loaded data
|
|
char * pBufferStop; // the position where loading new data will be done
|
|
// tokens given to the user
|
|
char pChars[VER_WORD_SIZE+5]; // temporary storage for a word (plus end-of-string and two parantheses)
|
|
int nChars; // the total number of characters in the word
|
|
// status of the parser
|
|
int fStop; // this flag goes high when the end of file is reached
|
|
};
|
|
|
|
static void Ver_StreamReload( Ver_Stream_t * p );
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
/// FUNCTION DEFINITIONS ///
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Starts the file reader for the given file.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
Ver_Stream_t * Ver_StreamAlloc( char * pFileName )
|
|
{
|
|
Ver_Stream_t * p;
|
|
FILE * pFile;
|
|
int nCharsToRead;
|
|
// check if the file can be opened
|
|
pFile = fopen( pFileName, "rb" );
|
|
if ( pFile == NULL )
|
|
{
|
|
printf( "Ver_StreamAlloc(): Cannot open input file \"%s\".\n", pFileName );
|
|
return NULL;
|
|
}
|
|
// start the file reader
|
|
p = ABC_ALLOC( Ver_Stream_t, 1 );
|
|
memset( p, 0, sizeof(Ver_Stream_t) );
|
|
p->pFileName = pFileName;
|
|
p->pFile = pFile;
|
|
// get the file size, in bytes
|
|
fseek( pFile, 0, SEEK_END );
|
|
p->nFileSize = ftell( pFile );
|
|
rewind( pFile );
|
|
// allocate the buffer
|
|
p->pBuffer = ABC_ALLOC( char, VER_BUFFER_SIZE+1 );
|
|
p->nBufferSize = VER_BUFFER_SIZE;
|
|
p->pBufferCur = p->pBuffer;
|
|
// determine how many chars to read
|
|
nCharsToRead = VER_MINIMUM(p->nFileSize, VER_BUFFER_SIZE);
|
|
// load the first part into the buffer
|
|
fread( p->pBuffer, nCharsToRead, 1, p->pFile );
|
|
p->nFileRead = nCharsToRead;
|
|
// set the ponters to the end and the stopping point
|
|
p->pBufferEnd = p->pBuffer + nCharsToRead;
|
|
p->pBufferStop = (p->nFileRead == p->nFileSize)? p->pBufferEnd : p->pBuffer + VER_BUFFER_SIZE - VER_OFFSET_SIZE;
|
|
// start the arrays
|
|
p->nLineCounter = 1; // 1-based line counting
|
|
return p;
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Loads new data into the file reader.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
void Ver_StreamReload( Ver_Stream_t * p )
|
|
{
|
|
int nCharsUsed, nCharsToRead;
|
|
assert( !p->fStop );
|
|
assert( p->pBufferCur > p->pBufferStop );
|
|
assert( p->pBufferCur < p->pBufferEnd );
|
|
// figure out how many chars are still not processed
|
|
nCharsUsed = p->pBufferEnd - p->pBufferCur;
|
|
// move the remaining data to the beginning of the buffer
|
|
memmove( p->pBuffer, p->pBufferCur, nCharsUsed );
|
|
p->pBufferCur = p->pBuffer;
|
|
// determine how many chars we will read
|
|
nCharsToRead = VER_MINIMUM( p->nBufferSize - nCharsUsed, p->nFileSize - p->nFileRead );
|
|
// read the chars
|
|
fread( p->pBuffer + nCharsUsed, nCharsToRead, 1, p->pFile );
|
|
p->nFileRead += nCharsToRead;
|
|
// set the ponters to the end and the stopping point
|
|
p->pBufferEnd = p->pBuffer + nCharsUsed + nCharsToRead;
|
|
p->pBufferStop = (p->nFileRead == p->nFileSize)? p->pBufferEnd : p->pBuffer + VER_BUFFER_SIZE - VER_OFFSET_SIZE;
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Stops the file reader.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
void Ver_StreamFree( Ver_Stream_t * p )
|
|
{
|
|
if ( p->pFile )
|
|
fclose( p->pFile );
|
|
ABC_FREE( p->pBuffer );
|
|
ABC_FREE( p );
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Returns the file size.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
char * Ver_StreamGetFileName( Ver_Stream_t * p )
|
|
{
|
|
return p->pFileName;
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Returns the file size.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
int Ver_StreamGetFileSize( Ver_Stream_t * p )
|
|
{
|
|
return p->nFileSize;
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Returns the current reading position.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
int Ver_StreamGetCurPosition( Ver_Stream_t * p )
|
|
{
|
|
return p->nFileRead - (p->pBufferEnd - p->pBufferCur);
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Returns the line number for the given token.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
int Ver_StreamGetLineNumber( Ver_Stream_t * p )
|
|
{
|
|
return p->nLineCounter;
|
|
}
|
|
|
|
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Returns current symbol.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
int Ver_StreamIsOkey( Ver_Stream_t * p )
|
|
{
|
|
return !p->fStop;
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Returns current symbol.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
char Ver_StreamScanChar( Ver_Stream_t * p )
|
|
{
|
|
assert( !p->fStop );
|
|
return *p->pBufferCur;
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Returns current symbol and moves to the next.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
char Ver_StreamPopChar( Ver_Stream_t * p )
|
|
{
|
|
assert( !p->fStop );
|
|
// check if the new data should to be loaded
|
|
if ( p->pBufferCur > p->pBufferStop )
|
|
Ver_StreamReload( p );
|
|
// check if there are symbols left
|
|
if ( p->pBufferCur == p->pBufferEnd ) // end of file
|
|
{
|
|
p->fStop = 1;
|
|
return -1;
|
|
}
|
|
// count the lines
|
|
if ( *p->pBufferCur == '\n' )
|
|
p->nLineCounter++;
|
|
return *p->pBufferCur++;
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Skips the current symbol and all symbols from the list.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
void Ver_StreamSkipChars( Ver_Stream_t * p, char * pCharsToSkip )
|
|
{
|
|
char * pChar, * pTemp;
|
|
assert( !p->fStop );
|
|
assert( pCharsToSkip != NULL );
|
|
// check if the new data should to be loaded
|
|
if ( p->pBufferCur > p->pBufferStop )
|
|
Ver_StreamReload( p );
|
|
// skip the symbols
|
|
for ( pChar = p->pBufferCur; pChar < p->pBufferEnd; pChar++ )
|
|
{
|
|
// skip symbols as long as they are in the list
|
|
for ( pTemp = pCharsToSkip; *pTemp; pTemp++ )
|
|
if ( *pChar == *pTemp )
|
|
break;
|
|
if ( *pTemp == 0 ) // pChar is not found in the list
|
|
{
|
|
p->pBufferCur = pChar;
|
|
return;
|
|
}
|
|
// count the lines
|
|
if ( *pChar == '\n' )
|
|
p->nLineCounter++;
|
|
}
|
|
// the file is finished or the last part continued
|
|
// through VER_OFFSET_SIZE chars till the end of the buffer
|
|
if ( p->pBufferStop == p->pBufferEnd ) // end of file
|
|
{
|
|
p->fStop = 1;
|
|
return;
|
|
}
|
|
printf( "Ver_StreamSkipSymbol() failed to parse the file \"%s\".\n", p->pFileName );
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Skips all symbols until encountering one from the list.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
void Ver_StreamSkipToChars( Ver_Stream_t * p, char * pCharsToStop )
|
|
{
|
|
char * pChar, * pTemp;
|
|
assert( !p->fStop );
|
|
assert( pCharsToStop != NULL );
|
|
// check if the new data should to be loaded
|
|
if ( p->pBufferCur > p->pBufferStop )
|
|
Ver_StreamReload( p );
|
|
// skip the symbols
|
|
for ( pChar = p->pBufferCur; pChar < p->pBufferEnd; pChar++ )
|
|
{
|
|
// skip symbols as long as they are NOT in the list
|
|
for ( pTemp = pCharsToStop; *pTemp; pTemp++ )
|
|
if ( *pChar == *pTemp )
|
|
break;
|
|
if ( *pTemp == 0 ) // pChar is not found in the list
|
|
{
|
|
// count the lines
|
|
if ( *pChar == '\n' )
|
|
p->nLineCounter++;
|
|
continue;
|
|
}
|
|
// the symbol is found - move position and return
|
|
p->pBufferCur = pChar;
|
|
return;
|
|
}
|
|
// the file is finished or the last part continued
|
|
// through VER_OFFSET_SIZE chars till the end of the buffer
|
|
if ( p->pBufferStop == p->pBufferEnd ) // end of file
|
|
{
|
|
p->fStop = 1;
|
|
return;
|
|
}
|
|
printf( "Ver_StreamSkipToSymbol() failed to parse the file \"%s\".\n", p->pFileName );
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Returns current word delimited by the set of symbols.]
|
|
|
|
Description [Modifies the stream by inserting 0 at the first encounter
|
|
of one of the symbols in the list.]
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
char * Ver_StreamGetWord( Ver_Stream_t * p, char * pCharsToStop )
|
|
{
|
|
char * pChar, * pTemp;
|
|
if ( p->fStop )
|
|
return NULL;
|
|
assert( pCharsToStop != NULL );
|
|
// check if the new data should to be loaded
|
|
if ( p->pBufferCur > p->pBufferStop )
|
|
Ver_StreamReload( p );
|
|
// skip the symbols
|
|
p->nChars = 0;
|
|
for ( pChar = p->pBufferCur; pChar < p->pBufferEnd; pChar++ )
|
|
{
|
|
// skip symbols as long as they are NOT in the list
|
|
for ( pTemp = pCharsToStop; *pTemp; pTemp++ )
|
|
if ( *pChar == *pTemp )
|
|
break;
|
|
if ( *pTemp == 0 ) // pChar is not found in the list
|
|
{
|
|
p->pChars[p->nChars++] = *pChar;
|
|
if ( p->nChars == VER_WORD_SIZE )
|
|
{
|
|
printf( "Ver_StreamGetWord(): The buffer size is exceeded.\n" );
|
|
return NULL;
|
|
}
|
|
// count the lines
|
|
if ( *pChar == '\n' )
|
|
p->nLineCounter++;
|
|
continue;
|
|
}
|
|
// the symbol is found - move the position, set the word end, return the word
|
|
p->pBufferCur = pChar;
|
|
p->pChars[p->nChars] = 0;
|
|
return p->pChars;
|
|
}
|
|
// the file is finished or the last part continued
|
|
// through VER_OFFSET_SIZE chars till the end of the buffer
|
|
if ( p->pBufferStop == p->pBufferEnd ) // end of file
|
|
{
|
|
p->fStop = 1;
|
|
p->pChars[p->nChars] = 0;
|
|
return p->pChars;
|
|
}
|
|
printf( "Ver_StreamGetWord() failed to parse the file \"%s\".\n", p->pFileName );
|
|
return NULL;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
/// END OF FILE ///
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
ABC_NAMESPACE_IMPL_END
|
|
|