diff --git a/cmLex.c b/cmLex.c index 7e9eb89..0ea0f35 100644 --- a/cmLex.c +++ b/cmLex.c @@ -7,6 +7,12 @@ #include "cmMallocDebug.h" #include "cmFile.h" +enum +{ + kRealFloatLexFl = 0x01, + kIntUnsignedLexFl = 0x02 +}; + typedef struct { unsigned code; @@ -29,6 +35,7 @@ cmLexErrorRecd cmLexErrorArray[] = { kMemAllocErrLexRC, "An attempted memory allocation failed"}, { kEofRC, "The end of the input text was encountered (this is a normal condition not an error)"}, { kInvalidLexTIdLexRC, "An invalid token id was encountered."}, + { kSignErrorLexRC, "A signed integer has a 'u' or 'U' suffix."}, { kInvalidLexRC, "Unknown lexer error code." } }; @@ -75,6 +82,7 @@ typedef struct cmLex_str cmChar_t* textBuf; // text buf used by cmLexSetFile() + unsigned attrFlags; // used to store the int and real suffix type flags } cmLex; @@ -148,7 +156,7 @@ unsigned _cmLexRealMatcher( cmLex* p, const cmChar_t* cp, unsigned cn, const cm unsigned i = 0; unsigned n = 0; // decimal point counter unsigned d = 0; // digit counter - bool fl = false; // true if this real includes an exponent + bool fl = false; // expo flag for(; i0 && i 0; + fl = e > 0; } - return i>1 && (n==1 || fl) ? i : 0; + // if at least one digit was found + if( d>0 ) + { + // Note that this path allows a string w/o a decimal pt to trigger a match. + + if(iattrFlags = cmSetFlag(p->attrFlags,kRealFloatLexFl); + ++i; + break; + } + + } + + // match w/o suffix return + if( d>0 && (fl || n==1 || cmIsFlag(p->attrFlags,kRealFloatLexFl)) ) + return i; + } + + return 0; // no-match return } unsigned _cmLexIntMatcher( cmLex* p, const cmChar_t* cp, unsigned cn, const cmChar_t* keyStr ) { unsigned i = 0; bool signFl = false; + for(; iattrFlags = cmSetFlag(p->attrFlags,kIntUnsignedLexFl); + ++i; + } + break; + + default: + break; + } + } + + return i; } unsigned _cmLexHexMatcher( cmLex* p, const cmChar_t* cp, unsigned cn, const cmChar_t* keyStr ) @@ -387,23 +449,6 @@ cmLexH cmLexInit( const cmChar_t* cp, unsigned cn, unsigned flags, cmRpt_t* rpt _cmLexSetTextBuffer( p, cp, cn ); - /* - p->cp = (cn==0) ? NULL : cp; - p->cn = (cp==NULL) ? 0 : cn; - - p->ci = 0; - - - p->curTokenId = kErrorLexTId; - p->curTokenCharIdx = cmInvalidIdx; - p->curTokenCharCnt = 0; - - p->curLine = 0; - p->curCol = 0; - p->nextLine = 0; - p->nextCol = 0; - */ - int init_mfn = 10; p->mfp = cmMemAllocZ( cmLexMatcher, init_mfn ); p->mfn = init_mfn; @@ -537,70 +582,6 @@ cmRC_t cmLexSetFile( cmLexH h, const cmChar_t* fn ) return rc; } -/* -cmRC_t cmLexSetFile( cmLexH h, const cmChar_t* fn ) -{ - cmRC_t rc = kOkLexRC; - FILE* fp = NULL; - cmLex* p = _cmLexHandleToPtr(h); - unsigned n = 0; - - assert( fn != NULL && p != NULL ); - - // open the file - if((fp = fopen(fn,"rb")) == NULL ) - return _cmLexError(p,kFileOpenErrLexRC,"Unable to open the file:'%s'.",fn); - - // seek to the end - if( fseek(fp,0,SEEK_END) != 0 ) - { - rc= _cmLexError(p,kFileSeekErrLexRC,"Unable to seek to the end of '%s'.",fn); - goto errLabel; - } - - // get the length of the file - if( (n=ftell(fp)) == 0 ) - { - rc = _cmLexError(p,kFileOpenErrLexRC,"The file '%s' appears to be empty.",fn); - goto errLabel; - } - - // rewind the file - if( fseek(fp,0,SEEK_SET) != 0 ) - { - rc = _cmLexError(p,kFileSeekErrLexRC,"Unable to seek to the beginning of '%s'.",fn); - goto errLabel; - } - - // allocate the text buffer - if((p->textBuf = cmMemResizeZ( char, p->textBuf, n+1)) == NULL ) - { - rc = _cmLexError(p,kMemAllocErrLexRC,"Unable to allocate the text file buffer for:'%s'.",fn); - goto errLabel; - } - - // read the file into the text buffer - if( fread(p->textBuf,n,1,fp) != 1 ) - { - rc = _cmLexError(p,kFileReadErrLexRC,"File read failed on:'%s'.",fn); - goto errLabel; - } - - if((rc = _cmLexSetTextBuffer( p, p->textBuf, n )) != kOkLexRC ) - goto errLabel; - - errLabel: - - // close the file - if( fclose(fp) != 0 ) - { - rc = _cmLexError(p,kFileCloseErrLexRC,"File close failed on:'%s'.",fn); - goto errLabel; - } - - return rc; -} -*/ cmLexMatcher* _cmLexFindUserToken( cmLex* p, unsigned id, const cmChar_t* tokenStr ) { @@ -689,9 +670,9 @@ unsigned cmLexGetNextToken( cmLexH h ) p->curTokenId = kErrorLexTId; p->curTokenCharIdx = cmInvalidIdx; p->curTokenCharCnt = 0; + p->attrFlags = 0; - - // try each mater + // try each matcher for(; mimfi; ++mi) if( p->mfp[mi].enableFl ) { @@ -701,6 +682,7 @@ unsigned cmLexGetNextToken( cmLexH h ) else charCnt = p->mfp[mi].userPtr( p->cp + p->ci, p->cn - p->ci); + // notice if the matcher set the error code if( cmErrLastRC(&p->err) != kOkLexRC ) return kErrorLexTId; @@ -823,6 +805,19 @@ float cmLexTokenFloat( cmLexH h ) double cmLexTokenDouble( cmLexH h ) { return strtod( cmLexTokenText(h),NULL ); } + +bool cmLexTokenIsUnsigned( cmLexH h ) +{ + cmLex* p = _cmLexHandleToPtr(h); + return p->curTokenId == kIntLexTId && cmIsFlag(p->attrFlags,kIntUnsignedLexFl); +} + +bool cmLexTokenIsSinglePrecision( cmLexH h ) +{ + cmLex* p = _cmLexHandleToPtr(h); + return p->curTokenId == kRealLexTId && cmIsFlag(p->attrFlags,kRealFloatLexFl); +} + unsigned cmLexCurrentLineNumber( cmLexH h ) { cmLex* p = _cmLexHandleToPtr(h); diff --git a/cmLex.h b/cmLex.h index fcd80aa..5eed6aa 100644 --- a/cmLex.h +++ b/cmLex.h @@ -50,7 +50,8 @@ enum kMemAllocErrLexRC, //< 10 An attempted memory allocation failed kEofRC, //< 11 The end of the input text was encountered (this is a normal condition not an error) kInvalidLexTIdLexRC, //< 12 An invalid lex token id was encountered. - kInvalidLexRC //< 13 Sentinal value. + kSignErrorLexRC, //< 13 An signed integer has a 'u' or 'U' suffix." + kInvalidLexRC //< 1r Sentinal value. }; @@ -119,15 +120,23 @@ unsigned cmLexTokenCharCount( cmLexH h ); // Return the value of the current token as an integer. int cmLexTokenInt( cmLexH h ); -// Return the value of the current token as an integer. +// Return the value of the current token as an unsigned integer. unsigned cmLexTokenUInt( cmLexH h ); -// Return the value of the current token as an integer. +// Return the value of the current token as a float. float cmLexTokenFloat( cmLexH h ); // Return the value of the current token as a double. double cmLexTokenDouble( cmLexH h ); +// Return true if the current token is an int and it was suffixed +// with 'u' to indicate that it is unsigned. +bool cmLexTokenIsUnsigned( cmLexH h ); + +// Return true if the current token is a real and it was suffexed +// with 'f' to indicate that it is a single precision float. +bool cmLexTokenIsSinglePrecision( cmLexH h ); + // Return the line number associated with the current token unsigned cmLexCurrentLineNumber( cmLexH h );