summaryrefslogtreecommitdiffstats
path: root/src/base/ver/verStream.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/base/ver/verStream.c')
-rw-r--r--src/base/ver/verStream.c435
1 files changed, 435 insertions, 0 deletions
diff --git a/src/base/ver/verStream.c b/src/base/ver/verStream.c
new file mode 100644
index 00000000..7956b13c
--- /dev/null
+++ b/src/base/ver/verStream.c
@@ -0,0 +1,435 @@
+/**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"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+#define VER_BUFFER_SIZE 1048576 // 1M - size of the data chunk stored in memory
+#define VER_OFFSET_SIZE 4096 // 4K - load new data when less than this is left
+#define VER_WORD_SIZE 4096 // 4K - 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 = 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 = 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 );
+ FREE( p->pBuffer );
+ 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;
+ }
+ 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++ )
+ {
+ // count the lines
+ if ( *pChar == '\n' )
+ p->nLineCounter++;
+ // 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;
+ }
+ }
+ // 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++ )
+ {
+ // count the lines
+ if ( *pChar == '\n' )
+ p->nLineCounter++;
+ // 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
+ 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++ )
+ {
+ // count the lines
+ if ( *pChar == '\n' )
+ p->nLineCounter++;
+ // 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 )
+ return NULL;
+ 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 ///
+////////////////////////////////////////////////////////////////////////
+
+