/*
*
* 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