/* * * ProLinga-Validate * * Copyright (C) 2002-2008 Xobas Software. * All rights reserved. * * This file is part of ProLinga-Validate. * * ProLinga-Validate is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * ProLinga-Validate is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with ProLinga-Validate. If not, see . * * More information is available at the following addresses: * * Website : http://www.prolinga.org * * Email : prolinga-list@prolinga.org * * */ %{ #include "ValCommon.h" #include "ValConfig.hpp" #include #include #include /*#include "SyntaxError.h" */ #include "SyntaxCheck.hpp" #include "CmdValCmd.hpp" #include "ValidateDocument.hpp" #include "LogicCommands.hpp" #include "ValMain.hpp" #include "VCDocumentParse.hpp" extern "C" { int yyparse(void); int yylex(void); int yywrap(void); } extern xmlDocPtr docSyntax; extern FILE *yyin; FILE *fp; xmlDocPtr docVal; xmlNodePtr curVal, curTmp, curLast; xmlBufferPtr bufVal; int lastCommand = 0; ValIfElseStackPtr valIfElsePtr = NULL; ValEndifStackPtr valEndifPtr = NULL; ValForStackPtr valForPtr = NULL; ValEndforStackPtr valEndforPtr = NULL; ValBreakStackPtr valBreakPtr = NULL; LoopListPtr loopListPtr = NULL; int i = 1; int j = 1; int sequenceNo = 0, loopCounter = 0, lineNo = 1; char *arg[255]; int yyerror(const char *); LoopList::LoopList() { stepNo = 0; stepValue = 0; } LoopList::~LoopList() { /* nothing */ } int LoopList::getLoopStep(LoopList **loopPtr, int step) { LoopListPtr curPtr; /* Check if step exists in memlist */ curPtr = *loopPtr; while (curPtr != NULL) { if (curPtr->stepNo == step) return curPtr->stepValue; curPtr = curPtr->nextPtr; } /* Return */ return -1; } void LoopList::putLoopStep(LoopList **loopPtr, int step, int value) { LoopListPtr curPtr, prevPtr, newPtr; /* Check if step exists in memlist */ curPtr = *loopPtr; prevPtr = NULL; while (curPtr != NULL) { if (curPtr->stepNo == step) { curPtr->stepValue = value; return; } prevPtr = curPtr; curPtr = curPtr->nextPtr; } /* If not then append new record */ newPtr = new LoopList; newPtr->stepNo = step; newPtr->stepValue = value; newPtr->nextPtr = NULL; if (prevPtr == NULL) { /* First Record */ *loopPtr = newPtr; } else { prevPtr->nextPtr = newPtr; } } void LoopList::printList(LoopList *loopPtr) const { LoopListPtr curPtr; curPtr = loopPtr; while (curPtr != NULL) { printf("Step : %d - Value : %d\n", curPtr->stepNo, curPtr->stepValue); curPtr = curPtr->nextPtr; } } void LoopList::deleteList(LoopList **loopPtr) { LoopListPtr curPtr, nextPtr; curPtr = *loopPtr; *loopPtr = NULL; while (curPtr != NULL) { nextPtr = curPtr->nextPtr; delete curPtr; curPtr = nextPtr; } } ValIfElseStack::ValIfElseStack() { stepNo = 0; nextPtr = NULL; } ValIfElseStack::~ValIfElseStack() { /* Dummy ? */ } void ValIfElseStack::push(ValIfElseStack **topPtr, int step) { ValIfElseStack *newPtr; newPtr = new ValIfElseStack; newPtr->stepNo = step; newPtr->nextPtr = *topPtr; *topPtr = newPtr; } int ValIfElseStack::pop(ValIfElseStack **topPtr) { ValIfElseStack *tmpPtr; int returnValue; tmpPtr = *topPtr; returnValue = tmpPtr->stepNo; *topPtr = (*topPtr)->nextPtr; delete tmpPtr; return returnValue; } ValEndifStack::ValEndifStack() { stepNo = 0; nextPtr = NULL; } ValEndifStack::~ValEndifStack() { /* Dummy ? */ } void ValEndifStack::push(ValEndifStack **topPtr, int step) { ValEndifStack *newPtr; newPtr = new ValEndifStack; newPtr->stepNo = step; newPtr->nextPtr = *topPtr; *topPtr = newPtr; } int ValEndifStack::pop(ValEndifStack **topPtr) { ValEndifStack *tmpPtr; int returnValue; tmpPtr = *topPtr; returnValue = tmpPtr->stepNo; *topPtr = (*topPtr)->nextPtr; delete tmpPtr; return returnValue; } int ValEndifStack::getStep(ValEndifStack *topPtr) { return topPtr->stepNo; } ValForStack::ValForStack() { stepNo = 0; nextPtr = NULL; } ValForStack::~ValForStack() { /* Dummy ? */ } void ValForStack::push(ValForStack **topPtr, int step) { ValForStack *newPtr; newPtr = new ValForStack; newPtr->stepNo = step; newPtr->nextPtr = *topPtr; *topPtr = newPtr; } int ValForStack::pop(ValForStack **topPtr) { ValForStack *tmpPtr; int returnValue; tmpPtr = *topPtr; returnValue = tmpPtr->stepNo; *topPtr = (*topPtr)->nextPtr; delete tmpPtr; return returnValue; } int ValForStack::getValue(ValForStack **topPtr) { return (*topPtr)->stepNo; } ValEndforStack::ValEndforStack() { stepNo = 0; nextPtr = NULL; } ValEndforStack::~ValEndforStack() { /* Dummy ? */ } void ValEndforStack::push(ValEndforStack **topPtr, int step) { ValEndforStack *newPtr; newPtr = new ValEndforStack; newPtr->stepNo = step; newPtr->nextPtr = *topPtr; *topPtr = newPtr; } int ValEndforStack::pop(ValEndforStack **topPtr) { ValEndforStack *tmpPtr; int returnValue; tmpPtr = *topPtr; returnValue = tmpPtr->stepNo; *topPtr = (*topPtr)->nextPtr; delete tmpPtr; return returnValue; } int ValEndforStack::getValue(ValEndforStack **topPtr) { return (*topPtr)->stepNo; } ValBreakStack::ValBreakStack() { stepNo = 0; nextPtr = NULL; } ValBreakStack::~ValBreakStack() { /* Dummy ? */ } void ValBreakStack::push(ValBreakStack **topPtr, int step) { ValBreakStack *newPtr; newPtr = new ValBreakStack; newPtr->stepNo = step; newPtr->nextPtr = *topPtr; *topPtr = newPtr; } int ValBreakStack::pop(ValBreakStack **topPtr) { ValBreakStack *tmpPtr; int returnValue; tmpPtr = *topPtr; returnValue = tmpPtr->stepNo; *topPtr = (*topPtr)->nextPtr; delete tmpPtr; return returnValue; } int ValBreakStack::getValue(ValBreakStack **topPtr) { return (*topPtr)->stepNo; } void TransformStart(void) { /* Init val document */ lineNo = 1; sequenceNo = 0; docVal = xmlNewDoc((const xmlChar *)"1.0"); docVal->children = xmlNewDocNode(docVal, NULL, (const xmlChar *)"ProLinga", NULL); curVal = xmlDocGetRootElement(docVal); curVal = xmlNewTextChild (curVal, NULL, (const xmlChar *)"Runner", (const xmlChar *)""); xmlNewProp (curVal, (const xmlChar *)"Version", (const xmlChar *)"1.0"); curVal = xmlNewTextChild (curVal, NULL, (const xmlChar *)"Statements", (const xmlChar *)""); curTmp = curVal; } void AddCommand(const int lcmd) { char str2int[5], strNextTrue[5], strNextFalse[5], strPrevNextTrue[5], strPrevNextFalse[5]; int nextStep, loopValue; sequenceNo++; nextStep = sequenceNo + 1; curVal = curTmp; curVal = xmlNewTextChild (curVal, NULL, (const xmlChar *)"Statement", (const xmlChar *)""); sprintf(str2int,"%d",sequenceNo); xmlNewProp (curVal, (const xmlChar *)"SequenceNo", (const xmlChar *)str2int); sprintf(strNextTrue,"%d",nextStep); sprintf(strNextFalse,"%d",nextStep); if (lcmd == LCMD_RETURN) { sprintf(strNextTrue,"0"); sprintf(strNextFalse,"0"); } else if (lcmd == LCMD_IF) { /* Create Endif Stack entry */ loopCounter --; loopListPtr->putLoopStep(&loopListPtr, loopCounter, -1); valEndifPtr->push(&valEndifPtr, loopCounter); /* NextFalse unknown at this stage */ loopCounter--; nextStep = loopCounter; sprintf(strNextFalse,"%d",nextStep); /* Create list entry */ loopListPtr->putLoopStep(&loopListPtr, loopCounter, -1); /* Create stack entry */ valIfElsePtr->push(&valIfElsePtr, loopCounter); } else if (lcmd == LCMD_ELSEIF) { if (valIfElsePtr != 0) { loopValue = valIfElsePtr->pop(&valIfElsePtr); nextStep = sequenceNo; loopListPtr->putLoopStep(&loopListPtr, loopValue, nextStep); /* NextFalse unknown at this stage */ loopCounter--; sprintf(strNextFalse,"%d",loopCounter); loopListPtr->putLoopStep(&loopListPtr, loopCounter, -1); valIfElsePtr->push(&valIfElsePtr, loopCounter); /* Set next step last statement to ENDIF */ loopValue = valEndifPtr->getStep(valEndifPtr); } else loopValue = 0; sprintf(strPrevNextTrue,"%d",loopValue); sprintf(strPrevNextFalse,"%d",loopValue); xmlSetProp (curLast, (const xmlChar *)"NextTrue", (const xmlChar *)strPrevNextTrue); xmlSetProp (curLast, (const xmlChar *)"NextFalse", (const xmlChar *)strPrevNextFalse); } else if (lcmd == LCMD_ELSE) { if (valIfElsePtr != NULL) { loopValue = valIfElsePtr->pop(&valIfElsePtr); nextStep = sequenceNo; loopListPtr->putLoopStep(&loopListPtr, loopValue, nextStep); loopCounter--; //sprintf(strNextTrue,"%d",loopCounter); //sprintf(strNextFalse,"%d",loopCounter); /* Dummy entries, but for consitency with elseif */ loopListPtr->putLoopStep(&loopListPtr, loopCounter, -1); valIfElsePtr->push(&valIfElsePtr, loopCounter); /* Set next step last statement to ENDIF */ loopValue = valEndifPtr->getStep(valEndifPtr); } else loopValue = 0; sprintf(strPrevNextTrue,"%d",loopValue); sprintf(strPrevNextFalse,"%d",loopValue); xmlSetProp (curLast, (const xmlChar *)"NextTrue", (const xmlChar *)strPrevNextTrue); xmlSetProp (curLast, (const xmlChar *)"NextFalse", (const xmlChar *)strPrevNextFalse); } else if (lcmd == LCMD_ENDIF) { if (valIfElsePtr != NULL) { loopValue = valIfElsePtr->pop(&valIfElsePtr); loopListPtr->putLoopStep(&loopListPtr, loopValue, sequenceNo); /* Set ENDIF step */ loopValue = valEndifPtr->pop(&valEndifPtr); loopListPtr->putLoopStep(&loopListPtr, loopValue, sequenceNo); } } else if ((lcmd == LCMD_FOR) || (lcmd == LCMD_FOREACH)) { /* Create For stack entry */ loopValue = sequenceNo + 1; valForPtr->push(&valForPtr, loopValue); /* Add begin mark to break stack */ valBreakPtr->push(&valBreakPtr, 0); /* Create Endfor Stack entry */ loopCounter --; loopListPtr->putLoopStep(&loopListPtr, loopCounter, -1); valEndforPtr->push(&valEndforPtr, loopCounter); /* Next False unknown so far */ nextStep = loopCounter; sprintf(strNextFalse,"%d",nextStep); } else if (lcmd == LCMD_FOREVER) { /* Create For stack entry */ loopValue = sequenceNo + 1; valForPtr->push(&valForPtr, loopValue); /* Add begin mark to break stack */ valBreakPtr->push(&valBreakPtr, 0); /* Create Endfor Stack entry */ loopCounter --; loopListPtr->putLoopStep(&loopListPtr, loopCounter, -1); valEndforPtr->push(&valEndforPtr, loopCounter); /* Next False unknown so far */ nextStep = loopCounter; sprintf(strNextFalse,"%d",nextStep); } else if (lcmd == LCMD_BREAK) { if (valForPtr != NULL) { /* NextTrue + NextFalse unknown at this stage */ loopCounter--; nextStep = loopCounter; /* Create break stack entry */ valBreakPtr->push(&valBreakPtr, loopCounter); /* Create list entry */ loopListPtr->putLoopStep(&loopListPtr, loopCounter, -1); } else nextStep = 0; sprintf(strNextTrue,"%d",nextStep); sprintf(strNextFalse,"%d",nextStep); } else if (lcmd == LCMD_CONTINUE) { if (valForPtr != NULL) loopValue = valForPtr->getValue(&valForPtr); else loopValue = 0; sprintf(strNextTrue,"%d",loopValue); sprintf(strNextFalse,"%d",loopValue); } else if (lcmd == LCMD_ENDFOR) { if (valForPtr != NULL) { loopValue = valForPtr->pop(&valForPtr); sprintf(strNextTrue,"%d",loopValue); sprintf(strNextFalse,"%d",loopValue); nextStep = sequenceNo + 1; /* Get all break statements */ for (;;) { loopValue = valBreakPtr->pop(&valBreakPtr); if ( loopValue == 0) break; loopListPtr->putLoopStep(&loopListPtr, loopValue, nextStep); } loopValue = valEndforPtr->pop(&valEndforPtr); loopListPtr->putLoopStep(&loopListPtr, loopValue, nextStep); } else { loopValue = 0; sprintf(strNextTrue,"%d",loopValue); sprintf(strNextFalse,"%d",loopValue); } } xmlNewProp (curVal, (const xmlChar *)"NextTrue", (const xmlChar *)strNextTrue); xmlNewProp (curVal, (const xmlChar *)"NextFalse", (const xmlChar *)strNextFalse); sprintf(str2int,"%d",lcmd); xmlNewProp (curVal, (const xmlChar *)"Command", (const xmlChar *)str2int); sprintf(str2int,"%d",lineNo); xmlNewProp (curVal, (const xmlChar *)"LogicLineNo", (const xmlChar *)str2int); curLast = curVal; curVal = xmlNewTextChild (curVal, NULL, (const xmlChar *)"Arguments", (const xmlChar *)""); lastCommand = lcmd; } void AddArgument(const char *arg) { xmlNewTextChild (curVal, NULL, (const xmlChar *)"Argument", (const xmlChar *)arg); } void TransformStop(void) { xmlNodePtr cur; xmlXPathContextPtr ctxt; xmlXPathObjectPtr res; int i, stepNo, stepValue, stepNextTrue, stepNextFalse; char tmpValue[5]; if (lastCommand != LCMD_ENDFOR) { xmlSetProp (curLast, (const xmlChar *)"NextTrue", (const xmlChar *)"0"); xmlSetProp (curLast, (const xmlChar *)"NextFalse", (const xmlChar *)"0"); } /* Post Process document */ /* Init XPath */ xmlXPathInit(); /* Create XPath environment */ ctxt = xmlXPathNewContext(docVal); res = xmlXPathEval((const xmlChar *)"/ProLinga/Runner/Statements/Statement[attribute::NextTrue<\"0\" or attribute::NextFalse<\"0\"]", ctxt); /* Check If Results */ if (res->nodesetval->nodeTab == NULL) return; /* Process Results */ cur = res->nodesetval->nodeTab[0]; for (i=1; i<=res->nodesetval->nodeNr; i++) { stepNextTrue = atoi((char *)xmlGetProp(cur, (const xmlChar *)"NextTrue")); stepNextFalse = atoi((char *)xmlGetProp(cur, (const xmlChar *)"NextFalse")); if (stepNextTrue < 0) stepNo = stepNextTrue; else stepNo = stepNextFalse; stepValue = loopListPtr->getLoopStep(&loopListPtr, stepNo); if (stepValue > sequenceNo) stepValue = 0; sprintf(tmpValue,"%d",stepValue); if (stepNextTrue < 0) xmlSetProp(cur, (const xmlChar *)"NextTrue", (const xmlChar *)tmpValue); if (stepNextFalse < 0) xmlSetProp(cur, (const xmlChar *)"NextFalse", (const xmlChar *)tmpValue); /* Get next */ cur = res->nodesetval->nodeTab[i]; } //loopListPtr->printList(loopListPtr); loopListPtr->deleteList(&loopListPtr); /* bufVal = xmlBufferCreate(); curVal = xmlDocGetRootElement(docVal); xmlNodeDump(bufVal, docVal, curVal, 0, 1); printf("%s\n", (char *)xmlBufferContent(bufVal)); */ } xmlDocPtr qqqCreateErrorDoc(void) { xmlDocPtr docError; xmlNodePtr curError; /* Create empty error document */ docError = xmlNewDoc((const xmlChar *)"1.0"); docError->children = xmlNewDocNode(docError, NULL, (const xmlChar *)"ProLinga", NULL); curError = xmlDocGetRootElement(docError); curError = xmlNewTextChild (curError, NULL, (const xmlChar *)"Runner", (const xmlChar *)""); xmlNewProp (curError, (const xmlChar *)"Version", (const xmlChar *)"1.0"); curError = xmlNewTextChild (curError, NULL, (const xmlChar *)"ValidateErrors", (const xmlChar *)""); /* Return */ return docError; } void qqInsertError(const int lineno, const int argno, const int id, const char *severity, const char *description, const char *details, xmlDocPtr docError) { xmlNodePtr curError; char dummy[10]=""; /* Set Pointer */ curError = xmlDocGetRootElement(docError); curError = curError->xmlChildrenNode; curError = xmlGetLastChild(curError); /* Insert Error */ curError = xmlNewTextChild (curError, NULL, (const xmlChar *)"ValidateError", (const xmlChar *)""); sprintf(dummy, "%d", lineno); xmlNewProp (curError, (const xmlChar *)"LineNo", (const xmlChar *)dummy); sprintf(dummy, "%d", argno); xmlNewProp (curError, (const xmlChar *)"ArgumentNo", (const xmlChar *)dummy); xmlNewTextChild (curError, NULL, (const xmlChar *)"Severity", (const xmlChar *)severity); sprintf(dummy, "%d", id); xmlNewTextChild (curError, NULL, (const xmlChar *)"Id", (const xmlChar *)dummy); xmlNewTextChild (curError, NULL, (const xmlChar *)"Description", (const xmlChar *)description); xmlNewTextChild (curError, NULL, (const xmlChar *)"Details", (const xmlChar *)details); } /* void qqInsertPredefinedError(const int lineno, const int argno, const int id, const char *details, xmlDocPtr docError) { InsertError(lineno, argno, id, errorSyntaxSeverity[errorSyntaxTable40000[(id-40000)].severity], errorSyntaxTable40000[(id-40000)].description, details, docError); } */ void SyntaxCheck(const char *applicationName) { xmlDocPtr docError; xmlXPathContextPtr ctxVal, ctxSyntax; xmlXPathObjectPtr resVal, resSyntax; int i,stmCount=0, logicLineNo=0, lcmd; int argCount=0, minArguments=0, maxArguments=0; int pathNo, stepNo, syntaxStepNo, nextStepNo; char evalString[255], *stringValid, *argument, style[255], *staticValue = NULL; bool valOK = true, argOK, lastStep=false, nextStm=false; ValIfElseStackPtr cmdIfPtr = NULL; ValForStackPtr cmdForPtr = NULL; /* Create Empty Error Doc */ docError = ValCreateErrorDoc(); /* Check if Syntax File Loaded */ //docSyntax = ParseSyntaxDoc(); if (docSyntax == NULL) { /* Set Status */ valOK = false; /* Insert Error */ ValInsertPredefinedError(0, 0, 40001, "", docError); /* Copy Error info to output tree */ xmlFreeDoc(docVal); docVal = xmlCopyDoc(docError,1); /* Clean up and return */ //xmlFreeDoc(docSyntax); xmlFreeDoc(docError); return; } /* Init XPath */ xmlXPathInit(); /* Create XPath environments */ ctxVal = xmlXPathNewContext(docVal); ctxSyntax = xmlXPathNewContext(docSyntax); /* Get number of statements */ resVal = xmlXPathEval((const xmlChar *)"count(/ProLinga/Runner/Statements/Statement)", ctxVal); stmCount = (int)xmlXPathCastToNumber(resVal); /* Loop through all statements */ for (i=1; i<=stmCount;i++) { /* Loop init */ maxArguments = 0; minArguments = 0; nextStm = false; /* Get Logic Line No */ sprintf(evalString, "/ProLinga/Runner/Statements/Statement[%d]/@LogicLineNo",i); resVal = xmlXPathEval((const xmlChar *)evalString, ctxVal); logicLineNo = (int)xmlXPathCastToNumber(resVal); /* Get Logic Command */ sprintf(evalString, "/ProLinga/Runner/Statements/Statement[%d]/@Command",i); resVal = xmlXPathEval((const xmlChar *)evalString, ctxVal); lcmd = (int)xmlXPathCastToNumber(resVal); /* Test if command in syntax file */ sprintf(evalString, "/ProLinga/Language/LogicCommands/LogicCommand[@Command='%d']", lcmd); resSyntax = xmlXPathEval((const xmlChar *)evalString, ctxSyntax); /* Check for valid logic command */ if(xmlXPathNodeSetIsEmpty(resSyntax->nodesetval)) { /* Set Status */ valOK = false; /* Get first argument containing invalid lcmd */ sprintf(evalString, "/ProLinga/Runner/Statements/Statement[%d]/Arguments/Argument[1]",i); resVal = xmlXPathEval((const xmlChar *)evalString, ctxVal); stringValid = (char *)xmlXPathCastToString(resVal); /* Insert Error */ ValInsertPredefinedError(logicLineNo, 0, 40002, stringValid, docError); /* Continue */ continue; } /* Prevent structure control commands to be used outside any structure */ if (((lcmd == LCMD_BREAK) || (lcmd == LCMD_CONTINUE)) && (cmdForPtr == NULL)) { /* Set Status */ valOK = false; /* Insert Error */ ValInsertPredefinedError(logicLineNo, 0, 40006, "", docError); /* Continue */ continue; } /* Prevent structure control commands to be used outside any structure */ if (((lcmd == LCMD_ELSE) || (lcmd == LCMD_ELSEIF)) && (cmdIfPtr == NULL)) { /* Set Status */ valOK = false; /* Insert Error */ ValInsertPredefinedError(logicLineNo, 0, 40006, "", docError); /* Continue */ continue; } /* Prevent structure close commands to be used outside any structure */ if (((lcmd == LCMD_ENDIF) && (cmdIfPtr == NULL)) || ((lcmd == LCMD_ENDFOR) && (cmdForPtr == NULL))) { /* Set Status */ valOK = false; /* Insert Error */ ValInsertPredefinedError(logicLineNo, 0, 40007, "", docError); /* Continue */ continue; } /* Keep track of nested IF/FOR/FOREVER structures */ if (lcmd == LCMD_IF) cmdIfPtr->push(&cmdIfPtr, logicLineNo); else if (lcmd == LCMD_ENDIF) cmdIfPtr->pop(&cmdIfPtr); else if ((lcmd == LCMD_FOR) || (lcmd == LCMD_FOREACH) || (lcmd == LCMD_FOREVER)) cmdForPtr->push(&cmdForPtr, logicLineNo); else if (lcmd == LCMD_ENDFOR) cmdForPtr->pop(&cmdForPtr); /* Check for valid number of arguments */ sprintf(evalString, "/ProLinga/Language/LogicCommands/LogicCommand[@Command='%d']/MinArguments", lcmd); resSyntax = xmlXPathEval((const xmlChar *)evalString, ctxSyntax); if(!xmlXPathNodeSetIsEmpty(resSyntax->nodesetval)) minArguments = (int)xmlXPathCastToNumber(resSyntax); sprintf(evalString, "/ProLinga/Language/LogicCommands/LogicCommand[@Command='%d']/MaxArguments", lcmd); resSyntax = xmlXPathEval((const xmlChar *)evalString, ctxSyntax); if(!xmlXPathNodeSetIsEmpty(resSyntax->nodesetval)) maxArguments = (int)xmlXPathCastToNumber(resSyntax); /* Get number of arguments */ sprintf(evalString, "count(/ProLinga/Runner/Statements/Statement[%d]/Arguments/Argument)",i); resVal = xmlXPathEval((const xmlChar *)evalString, ctxVal); argCount = (int)xmlXPathCastToNumber(resVal); if ((argCount < minArguments) | (argCount > maxArguments)) { /* Set Status */ valOK = false; /* Insert Error */ ValInsertPredefinedError(logicLineNo, 0, 40003, "", docError); /* Continue */ continue; } /* If no arguments no point to process further */ if (argCount == 0) continue; /* Process Arguments */ nextStepNo = 0; for (stepNo=1; stepNo<=argCount;stepNo++) { /* Init */ pathNo = 1; if (nextStepNo != 0) syntaxStepNo = nextStepNo; else syntaxStepNo = stepNo; /* Get Argument */ sprintf(evalString,"/ProLinga/Runner/Statements/Statement[%d]/Arguments/Argument[%d]",i,stepNo); resVal = xmlXPathEval((const xmlChar *)evalString, ctxVal); argument = (char *)xmlXPathCastToString(resVal); /* Get Style */ for (;;) { /* Init */ staticValue = NULL; sprintf(evalString, "/ProLinga/Language/LogicCommands/LogicCommand[@Command='%d']/Arguments/Argument[@Step='%d']/ArgumentStep[@Path='%d']/@NextStep", lcmd, syntaxStepNo, pathNo); resSyntax = xmlXPathEval((const xmlChar *)evalString, ctxSyntax); if (xmlXPathNodeSetIsEmpty(resSyntax->nodesetval)) nextStepNo = 0; else nextStepNo = (int)xmlXPathCastToNumber(resSyntax); sprintf(evalString, "/ProLinga/Language/LogicCommands/LogicCommand[@Command='%d']/Arguments/Argument[@Step='%d']/ArgumentStep[@Path='%d']/@LastStep", lcmd, syntaxStepNo, pathNo); resSyntax = xmlXPathEval((const xmlChar *)evalString, ctxSyntax); lastStep = false; if ((!xmlXPathNodeSetIsEmpty(resSyntax->nodesetval)) && (strcmp((char *)xmlXPathCastToString(resSyntax), "True") == 0)) lastStep = true; sprintf(evalString, "/ProLinga/Language/LogicCommands/LogicCommand[@Command='%d']/Arguments/Argument[@Step='%d']/ArgumentStep[@Path='%d']/@Style", lcmd, syntaxStepNo, pathNo); resSyntax = xmlXPathEval((const xmlChar *)evalString, ctxSyntax); if (xmlXPathNodeSetIsEmpty(resSyntax->nodesetval)) { /* Set Status */ valOK = false; /* Insert Error */ ValInsertPredefinedError(logicLineNo, stepNo, 40004, argument, docError); /* Next Statement */ nextStm = true; break; } /* Get Style */ strcpy(style,(char *)xmlXPathCastToString(resSyntax)); if (strcmp(style, "Static") == 0) { sprintf(evalString, "/ProLinga/Language/LogicCommands/LogicCommand[@Command='%d']/Arguments/Argument[@Step='%d']/ArgumentStep[@Path='%d']/@Value", lcmd, syntaxStepNo, pathNo); resSyntax = xmlXPathEval((const xmlChar *)evalString, ctxSyntax); if (xmlXPathNodeSetIsEmpty(resSyntax->nodesetval)) staticValue = NULL; else staticValue = (char *)xmlXPathCastToString(resSyntax); } /* Check argument against style */ argOK = CheckArgumentStyle(applicationName, argument, style, staticValue); if (argOK == false) { pathNo = pathNo + 1; continue; } /* Next Statement */ break; } if (nextStm == true) break; } if (nextStm == true) continue; /* If ends with unexpected argument, error */ if ((lastStep == false) && (valOK == true)) { valOK = false; /* Insert Error */ ValInsertPredefinedError(logicLineNo, stepNo, 40005, argument, docError); } } /* Check if all structures are close */ if (cmdIfPtr != NULL) { /* Set Status */ valOK = false; /* Insert Error */ ValInsertPredefinedError(cmdIfPtr->pop(&cmdIfPtr), 0, 40008, "ENDIF", docError); } if (cmdForPtr != NULL) { /* Set Status */ valOK = false; /* Insert Error */ ValInsertPredefinedError(cmdForPtr->pop(&cmdForPtr), 0, 40008, "ENDFOR", docError); } if (valOK == false) { /* Copy Error info to output tree */ xmlFreeDoc(docVal); docVal = xmlCopyDoc(docError,1); } /* Clean up + Return*/ // xmlFreeDoc(docSyntax); xmlFreeDoc(docError); } %} %union { char *sval; int numval; } %token LCMD %token ILCMD %token CMT %token AOID %token BOS %token EOS %% file : statement file | statement ; statement : commentstatement | argumentstatement | commandstatement | emptystatement | faultstatement ; argumentstatement : lcmd argument EOS { for (j=1;j