/* * * ProLinga-Run * * Copyright (C) 2002-2008 Xobas Software. * All rights reserved. * * This file is part of ProLinga-Run. * * ProLinga-Run 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-Run 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-Run. If not, see . * * More information is available at the following addresses: * * Website : http://www.prolinga.org * * Email : prolinga-list@prolinga.org * * */ #include "RunCommon.h" #include #include #include #include "Runner.hpp" #include "ExecCmd.hpp" #include "Logic.hpp" #include "LogicCommands.hpp" extern ForBreakStackPtr breakStackPtr; int RunExec(xmlDocPtr* doc, bool idleEvent) { xmlXPathContextPtr ctxt; xmlXPathObjectPtr res; int stmCounter = 1, stmNextTrue = 1, stmNextFalse = 1; int stmCmd = 0; int i, argHits; char stm[512]; char* argList[255]; short stmNext; /* Init Xpath */ xmlXPathInit(); /* Create XPath environment */ ctxt = xmlXPathNewContext(*doc); /* Go through statements */ for(;;) { /* Get Command */ sprintf(stm,"%s%s[@%s='%d']/@%s", STM_PATH, STATEMENT, SEQ_NO, stmCounter, COMMAND); res = xmlXPathEval((const xmlChar *)stm, ctxt); stmCmd = (int)xmlXPathCastToNumber(res); if (stmCmd <= 0) break; //printf("Command : %d\n", stmCmd); /* Get next TRUE statement id */ sprintf(stm,"%s%s[@%s='%d']/@%s", STM_PATH, STATEMENT, SEQ_NO, stmCounter, NEXT_TRUE); res = xmlXPathEval((const xmlChar *)stm, ctxt); stmNextTrue = (int)xmlXPathCastToNumber(res); /* Get next FALSE statement id */ sprintf(stm,"%s%s[@%s='%d']/@%s", STM_PATH, STATEMENT, SEQ_NO, stmCounter, NEXT_FALSE); res = xmlXPathEval((const xmlChar *)stm, ctxt); stmNextFalse = (int)xmlXPathCastToNumber(res); /* Get argument hits */ sprintf(stm,"count(%s%s[@%s='%d']/%s)", STM_PATH, STATEMENT, SEQ_NO, stmCounter, ARGUMENT); res = xmlXPathEval((const xmlChar *)stm, ctxt); argHits = (int)xmlXPathCastToNumber(res); /* Clear argument array */ for (i = 1; i <= 254; i++) argList[i] = '\0'; /* Fill argument array */ for (i = 1; i <= argHits; i++) { sprintf(stm,"%s%s[@%s='%d']/%s[%d]", STM_PATH, STATEMENT, SEQ_NO, stmCounter, ARGUMENT, i); res = xmlXPathEval((const xmlChar *)stm, ctxt); argList[i] = (char *)xmlXPathCastToString(res); // printf("!!: %s\n", argList[i]); } /* For/Forever/Foreach, keep track of 1st after loop */ if ((stmCmd == LCMD_FOR) || (stmCmd == LCMD_FOREACH) || (stmCmd == LCMD_FOREVER)) breakStackPtr->push(&breakStackPtr, stmNextFalse); /* Execute command */ stmNext = ExecCommand(stmCmd, argList, argHits, idleEvent); /* For loop not to be run at all */ if ((stmCmd == LCMD_FOR) && (stmNext == 1)) breakStackPtr->pop(&breakStackPtr); if ((stmCmd == LCMD_FOREACH) && (stmNext == 1)) breakStackPtr->pop(&breakStackPtr); /* Get next statement ID */ if (stmNext == 0) stmCounter = stmNextTrue; else if (stmNext == 1) stmCounter = stmNextFalse; else if (stmNext == 2) stmCounter = 0; else if (stmNext == 3) { stmCounter = breakStackPtr->getSequenceNo(breakStackPtr); breakStackPtr->pop(&breakStackPtr); } /* Break, clear stack only, no step overrule */ if (stmCmd == LCMD_BREAK) breakStackPtr->pop(&breakStackPtr); } /* Clean up */ xmlXPathFreeObject(res); xmlXPathFreeContext(ctxt); /* Return */ return 0; }