/** * \brief This function interprets <If> Code * * \param[in] pCode - Start of code to interpret * \return STATUS_PASS - Test conformance (PASS) * STATUS_FAIL - Test nonconformance (FAIL) */ static int16_t interpretIf(P_CODE *pCode) { int16_t status; boolean compareResult; if (STATUS_PASS == (status = exprEvaluate(pCode->common.lineNumber, &pCode->code.cIf.expr, &compareResult))) { if (compareResult) { outputXmlAttrAddCommon(LEVEL_TRACE, &pCode->common, A_NAME); outputXmlAttrAdd(A_EXPR, pCode->code.cIf.expr.pExpr); outputXmlAttrAdd(A_EVAL, VALUE_TRUE); outputXmlTagOpen(LEVEL_TRACE, P_IF, outputXmlAttrGet()); status = interpretPcode(pCode->code.cIf.pThen); outputXmlTagClose(LEVEL_TRACE, P_IF); } else { outputXmlAttrAddCommon(LEVEL_TRACE, &pCode->common, A_NAME); outputXmlAttrAdd(A_EXPR, pCode->code.cIf.expr.pExpr); outputXmlAttrAdd(A_EVAL, VALUE_FALSE); outputXmlTagOpen(LEVEL_TRACE, P_IF, outputXmlAttrGet()); status = interpretPcode(pCode->code.cIf.pElse); outputXmlTagClose(LEVEL_TRACE, P_IF); } } return(status); }
/** * \brief This function interprets <While> Code * * \param[in] pCode - Start of code to interpret * \return STATUS_PASS - Test conformance (PASS) * STATUS_FAIL - Test nonconformance (FAIL) */ static int16_t interpretWhile(P_CODE *pCode) { int16_t status; boolean compareResult; status = exprEvaluate(pCode->common.lineNumber, &pCode->code.cWhile.expr, &compareResult); while (compareResult && (STATUS_PASS == status)) { outputXmlAttrAddCommon(LEVEL_TRACE, &pCode->common, A_NAME); outputXmlAttrAdd(A_EXPR, pCode->code.cWhile.expr.pExpr); outputXmlAttrAdd(A_EVAL, VALUE_TRUE); outputXmlTagOpen(LEVEL_TRACE, P_WHILE, outputXmlAttrGet()); status = interpretPcode(pCode->code.cWhile.pWhile); outputXmlTagClose(LEVEL_TRACE, P_WHILE); if (STATUS_PASS == status) { status = exprEvaluate(pCode->common.lineNumber, &pCode->code.cWhile.expr, &compareResult); } } if (STATUS_PASS == status) { outputXmlAttrAddCommon(LEVEL_TRACE, &pCode->common, A_NAME); outputXmlAttrAdd(A_EXPR, pCode->code.cWhile.expr.pExpr); outputXmlAttrAdd(A_EVAL, VALUE_FALSE); outputXmlTagCurrent(LEVEL_TRACE, P_WHILE, outputXmlAttrGet()); } return(status); }
// // Function: argScan // // Scan a (partial) argument profile. // For a char, word or string profile just copy the char/string value // into the designated array or string argument variable. // For a numeric profile though copy the string expression and push // it through the expression evaluator to get a resulting numeric // value. When a valid numeric value is obtained copy it into the // designated integer array variable. // It returns parmater input that is modified to point to the remaining // string to be scanned. // int argScan(argItem_t argItem[], int argCount, char **input, int silent) { char *workPtr = *input; char *evalString; int i = 0; int j = 0; int retVal = CMD_RET_OK; while (i < argCount) { char c = *workPtr; if (argItem[i].argType == ARG_CHAR) { // Scan a single character argument profile char nextChar; // Verify argument count overflow if (argCharIdx == ARG_TYPE_COUNT_MAX) { printf("%s? internal: overflow char argument count\n", argItem[i].argName); return CMD_RET_ERROR; } // Verify end-of-string if (c == '\0') { if (silent == GLCD_FALSE) printf("%s? missing value\n", argItem[i].argName); return CMD_RET_ERROR; } // The next character must be white space or end of string nextChar = *(workPtr + 1); if (nextChar != ' ' && nextChar != '\t' && nextChar != '\0') { if (silent == GLCD_FALSE) printf("%s? invalid value: too long\n", argItem[i].argName); return CMD_RET_ERROR; } // Validate the character (if a validation rule has been setup) retVal = argValidateChar(argItem[i], c, silent); if (retVal != CMD_RET_OK) return retVal; // Value approved so copy the char argument argChar[argCharIdx] = c; argCharIdx++; // Skip to next argument element in string workPtr++; while (*workPtr == ' ' || *workPtr == '\t') { workPtr++; } // Next argument profile i++; } else if (argItem[i].argType == ARG_UINT || argItem[i].argType == ARG_INT) { // Scan an (unsigned) integer argument profile. // An integer profile is an expression that can be a constant, // a variable or a combination of both in a mathematical // expression. We'll use flex/bison to evaluate the expression. // Verify argument count overflow if (argCharIdx == ARG_TYPE_COUNT_MAX) { printf("%s? internal: overflow int argument count\n", argItem[i].argName); return CMD_RET_ERROR; } // Verify end-of-string if (c == '\0') { if (silent == GLCD_FALSE) printf("%s? missing value\n", argItem[i].argName); return CMD_RET_ERROR; } // Copy the integer expression upto next delimeter j = 0; while (workPtr[j] != ' ' && workPtr[j] != '\t' && workPtr[j] != '\0') { j++; } evalString = malloc(j + 2); j = 0; while (*workPtr != ' ' && *workPtr != '\t' && *workPtr != '\0') { evalString[j] = *workPtr; workPtr++; j++; } evalString[j] = '\n'; evalString[j + 1] = '\0'; // Evaluate the integer expression retVal = exprEvaluate(evalString); free(evalString); if (varError == 1) { printf("%s? parse error\n", argItem[i].argName); return CMD_RET_ERROR; } else if (retVal == 1) { printf("%s? syntax error\n", argItem[i].argName); return CMD_RET_ERROR; } // Validate unsigned integer if (argItem[i].argType == ARG_UINT && exprValue < 0) { if (silent == GLCD_FALSE) printf("%s? invalid value: %d\n", argItem[i].argName, exprValue); return CMD_RET_ERROR; } // Validate the number (if a validation rule has been setup) retVal = argValidateNum(argItem[i], exprValue, silent); if (retVal != CMD_RET_OK) return retVal; // Value approved so copy the resulting value of the expression argInt[argIntIdx] = exprValue; argIntIdx++; // Skip to next argument element in string while (*workPtr == ' ' || *workPtr == '\t') { workPtr++; } // Next argument profile i++; } else if (argItem[i].argType == ARG_WORD) { // Scan a character word argument profile // Verify argument count overflow if (argCharIdx == ARG_TYPE_COUNT_MAX) { printf("%s? internal: overflow word argument count\n", argItem[i].argName); return CMD_RET_ERROR; } // Verify end-of-string if (c == '\0') { if (silent == GLCD_FALSE) printf("%s? missing value\n", argItem[i].argName); return CMD_RET_ERROR; } // Value exists so copy the word upto next delimeter j = 0; while (workPtr[j] != ' ' && workPtr[j] != '\t' && workPtr[j] != '\0') { j++; } argWord[argWordIdx] = malloc(j + 1); j = 0; while (*workPtr != ' ' && *workPtr != '\t' && *workPtr != '\0') { argWord[argWordIdx][j] = *workPtr; workPtr++; j++; } argWord[argWordIdx][j] = '\0'; argWordIdx++; // Validate the word (if a validation rule has been setup) retVal = argValidateWord(argItem[i], argWord[argWordIdx - 1], silent); if (retVal != CMD_RET_OK) return retVal; // Skip to next argument element in string while (*workPtr == ' ' || *workPtr == '\t') { workPtr++; } // Next argument profile i++; } else if (argItem[i].argType == ARG_STRING) { // Scan a character string argument profile // Verify end-of-string if (c == '\0') { if (silent == GLCD_FALSE) printf("%s? missing value\n", argItem[i].argName); return CMD_RET_ERROR; } // As the remainder of the input string is to be considered // the string argument we skip to the end of the input string j = 0; while (workPtr[j] != '\0') { j++; } argString = malloc(j + 1); j = 0; while (*workPtr != '\0') { argString[j] = *workPtr; workPtr++; j++; } // Set end of string argString[j] = '\0'; // Next argument profile i++; } else if (argItem[i].argType == ARG_END) { // Scan an end-of-line argument profile // Verify end-of-line if (c != '\0') { if (silent == GLCD_FALSE) printf("command %s? too many arguments\n", argWord[0]); return CMD_RET_ERROR; } // Next argument profile i++; } else { printf("internal: invalid element: %d %d\n", i, argItem[i].argType); return CMD_RET_ERROR; } } // Successful scan *input = workPtr; return CMD_RET_OK; }