OLD VERSION /* struct // private context for @parseDemicalNumber_2 function { bool dotAllowed; // dot-character indicator: shows if the character is // ... allowed in current state; bool signAllowed; // sign-character indicator: shows if the character is // ... allowed in current state; bool digitAllowed; // digit-character indicator: shows if the character is // ... allowed in current state; bool mantissaExpected; // mantissa indicator: shows if the mantissa // ... part of the number is expected in current state; bool exponentExpected; // exponent indicator: shows if the exponent // ... part of the number is expected in current state; bool exponentDetected; // exponent sign indicator: shows if the exponent sign // ... has been faced or not; bool whiteAllowed; // white-character indicator: shows if the character is // ... allowed in current state; bool manitssaOk; // mantissa indicator: shows if mantissa received or not. bool exponentOk; // exponent indicator: shows if exponent received or not. } parseDemicalNumber_2;*/ // ================================================================================================================= /* // @parseDemicalNumber_2 // "Parser-function", parses a SCPI Demical Numeric Program Data () // References: // "7.7.2 ", [1] // "7.7.2.2 Encoding Syntax", [1] // Parameters: // @xObj - parser context, must be prepared by @prepareParserContext // ... before each call. If it is needed to continue the processing, the // ... @bKeepContext parameter duing the call @prepareParserContext must // ... be set to 'true', and otherwise, to restart parsing the parameter // ... must be set to 'false'. // Returns: // eParserStatus_failed - error, can not parse data as a string; // eParserStatus_success - success, the string has been successfully parsed; // eParserStatus_need_data - warning, the string can not be parsed due to // there no enough data to process. eParserStatus_t parseDemicalNumber_2( xParseEntry_t * xObj ) { sParseEntry_t * pObj = (sParseEntry_t*)xObj; eParserStatus_t status = eParserStatus_invalid; if( NULL != pObj && NULL != pObj->str && 0 != ((ptrdiff_t)pObj->tail - (ptrdiff_t)pObj->head) && pObj->str != pObj->tail ) { status = eParserStatus_failed; // forward status set: the default 'eParserStatus_invalid' shall // ... not be returned due to the context will be changed. // if the context has been cleaned up if( ! pObj->bContextKept ) { // "7.7.2.2 Encoding Syntax", [1]: pObj->parseDemicalNumber_2.signAllowed = true; // Mantissa can begin with a sign; pObj->parseDemicalNumber_2.dotAllowed = true; // Mantissa can begin with a dot; pObj->parseDemicalNumber_2.mantissaExpected = true; // Mantissa is expected in the beginning; pObj->parseDemicalNumber_2.exponentExpected = false; // Exponent is not expected in the beginning; pObj->parseDemicalNumber_2.exponentDetected = false; // Exponent sign is not detected by default; pObj->parseDemicalNumber_2.whiteAllowed = false; // White-character is not allowed by default; pObj->parseDemicalNumber_2.manitssaOk = false; // reset mantissa indicator pObj->parseDemicalNumber_2.exponentOk = false; // reset exponent indicator pObj->parseDemicalNumber_2.digitAllowed = true; // allow digits: the number can start from digit } // walk til the end of the buffer while( pObj->str != pObj->tail ) { char character = *(pObj->str++); // Check if the mantissa is expected to be received: if( pObj->parseDemicalNumber_2.mantissaExpected ) { // Check if the sign-character has not been faced yet: if( pObj->parseDemicalNumber_2.signAllowed ) { // Check if the character is a sign-character: if( '-' == character || '+' == character ) { // Yes, since this moment no sign character is allowed. pObj->parseDemicalNumber_2.signAllowed = false; // skip character continue; } // Current character is not a sign-character, and // ... since this moment the sign character is not // ... allowed anymore. pObj->parseDemicalNumber_2.signAllowed = false; } // Check if the dot-character has not been faced yet: if( pObj->parseDemicalNumber_2.dotAllowed ) { // Check if the character is a dot-character: if( '.' == character ) { // Yes, since this moment no dot character is allowed. pObj->parseDemicalNumber_2.dotAllowed = false; // since this moment the exponent part is allowed pObj->parseDemicalNumber_2.exponentExpected = true; // skip character continue; } // Current character is not a dot-character, but // ... the digit character is allowed to be followed // ... by the dot character. (void)pObj->parseDemicalNumber_2.dotAllowed; } // Check if the current character is a digit-character: // Check if digit character is allowed if( (pObj->parseDemicalNumber_2.digitAllowed) && scpi_isdigit( character ) ) { // yes, the character is allowed digit character // since this moment the exponent part is allowed pObj->parseDemicalNumber_2.exponentExpected = true; // since the exponent part is allowed, a white character is allowed: pObj->parseDemicalNumber_2.whiteAllowed = true; // set mantissa indicator: it is enough to parse at least a mantissa pObj->parseDemicalNumber_2.manitssaOk = true; // skip character continue; } } // Check if the exponent is expected to be received: if( pObj->parseDemicalNumber_2.exponentExpected ) { // check if white character is allowed: if( pObj->parseDemicalNumber_2.whiteAllowed ) { // check for white character: if( scpi_iswhite( character ) ) { // since white character detected only exponent // ... character is allowed. pObj->parseDemicalNumber_2.digitAllowed = false; // disallow digits // skip character continue; } } // if the exponent sign has not been faced yet: if( ! pObj->parseDemicalNumber_2.exponentDetected ) { if( 'e' == character || 'E' == character ) { // set exponent-sign indicator: pObj->parseDemicalNumber_2.exponentDetected = true; // allow the sign character for exponent: pObj->parseDemicalNumber_2.signAllowed = true; // allow white character: pObj->parseDemicalNumber_2.whiteAllowed = true; // disable the mantissa processing pObj->parseDemicalNumber_2.mantissaExpected = false; // skip character continue; } } // if the exponent sign has been detected: if( pObj->parseDemicalNumber_2.exponentDetected ) { // check if the sign is allowed: if( pObj->parseDemicalNumber_2.signAllowed ) { // Check if the character is a sign-character: if( '-' == character || '+' == character ) { // Yes, since this moment no sign character is allowed. pObj->parseDemicalNumber_2.signAllowed = false; // disallow white character after the exponent sign pObj->parseDemicalNumber_2.whiteAllowed = false; // skip character continue; } } // Check if the current character is a digit-character: if( scpi_isdigit( character ) ) { // since this moment no sign character is allowed. pObj->parseDemicalNumber_2.signAllowed = false; // since this moment no white character is allowed. pObj->parseDemicalNumber_2.whiteAllowed = false; // since at least one digit received the exponent is correct: pObj->parseDemicalNumber_2.exponentOk = true; // skip character continue; } // check if the exponent part is already valid if( pObj->parseDemicalNumber_2.exponentOk ) { // if the white character is faced if( scpi_iswhite( character ) ) { // set length: // LENGTH = @str - 1, minus one due to // ... @str has been already incremented pObj->tail = pObj->str - 1; status = eParserStatus_success; // successfully found break; } pObj->str--; // decrement interator due to current character is invalid } } } break; } if( status != eParserStatus_success ) { // Check if the whole buffer processed? if( pObj->str >= pObj->tail ) { // yes the whole buffer processed // Not enough data to continue. // Check for end-of-message indicator: if( ! pObj->bEndMessage ) { // end-of-message is not set // set warning status: there no enough data status = eParserStatus_need_data; } else { // end-of-message is set. // Check if the white character is allowed: if( pObj->parseDemicalNumber_2.whiteAllowed ) { // yes, white character is expected: it seems as // ... end condition since the white character allowed // ... only in the place where the entity can be finished. // So, it is end of the entity: // set the length: // LENGTH = @str - @head pObj->tail = pObj->str; // set the tail pointer to indicate the length status = eParserStatus_success; // successfully found } else { // yes, white character is not expected. // It seems as incompleted entity. status = eParserStatus_failed; // incomplete } } } else { // not the whole buffer processed // check if enough data has been processed - check for mantissa: if( pObj->parseDemicalNumber_2.manitssaOk ) { // Check if the exponent sign has been detected and no exponent completely recevied? if( pObj->parseDemicalNumber_2.exponentDetected && !pObj->parseDemicalNumber_2.exponentOk ) { // set failed status: trailing exponent sign detected. status = eParserStatus_failed; } else { // set the length: // LENGTH = @str - @head pObj->tail = pObj->str; // set the tail pointer to indicate the length status = eParserStatus_success; // successfully found } } else { // set failed status: no mantissa found status = eParserStatus_failed; } } } } return status; } */