/* "CodeWorker": a scripting language for parsing and generating text. Copyright (C) 1996-1997, 1999-2002 Cédric Lemaire This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA To contact the author: codeworker@free.fr */ #ifdef WIN32 #pragma warning (disable : 4786) #endif #include "UtlException.h" #include "ScpStream.h" #include "CGRuntime.h" #include "Workspace.h" #include "DtaScriptVariable.h" #include "DtaProject.h" #include "DtaConsoleScript.h" #include namespace CodeWorker { DtaConsoleScript::~DtaConsoleScript() {} bool DtaConsoleScript::betweenCommands(ScpStream& script, GrfBlock&) { script.skipEmpty(); if (script.isEqualTo('@') && (_sCursor.size() > 1)) waitForCommand(script); return false; } void DtaConsoleScript::beforeParsingABlock(ScpStream&, GrfBlock&) { _sCursor += ">"; } void DtaConsoleScript::afterParsingABlock(ScpStream&, GrfBlock&) { _sCursor = _sCursor.substr(1); } void DtaConsoleScript::handleNotAWordCommand(ScpStream& script, GrfBlock& block) { if (script.isEqualTo('?')) Workspace::displayHelp(); else DtaScript::handleNotAWordCommand(script, block); } void DtaConsoleScript::handleUnknownCommand(const std::string& sCommand, ScpStream& script, GrfBlock& block) { if ((sCommand == "exit") || (sCommand == "quit")) throw "exit"; else if (sCommand == "help") { Workspace::displayHelp(); if (script.skipEmpty() && !script.isEqualTo('@')) { if (!script.isEqualTo(';')) { throw UtlException(script, "';' expected"); } } } else DtaScript::handleUnknownCommand(sCommand, script, block); } void DtaConsoleScript::waitForCommand(ScpStream& stream) { std::string sText; CGRuntime::traceText(_sCursor + " "); int iPos = stream.getInputLocation(); bool bContinue = true; do { sText = CGRuntime::inputLine(true, ""); stream << sText << CGRuntime::endl(); for (int iIndex = sText.size() - 1; iIndex >= 0; iIndex--) { if ((sText[iIndex] < '\0') || (sText[iIndex] > ' ')) { bContinue = (sText[iIndex] != ';') && (sText[iIndex] != '{') && (sText[iIndex] != '}'); break; } } if (bContinue) { stream.skipEmpty(); bContinue = !(stream.isEqualToIdentifier("help") || stream.isEqualToIdentifier("quit") || stream.isEqualToIdentifier("exit")); stream.setInputLocation(iPos); } } while (bContinue); stream << "@"; } void DtaConsoleScript::traceEngine() const { CGRuntime::traceLine("Console script:"); traceInternalEngine(); } SEQUENCE_INTERRUPTION_LIST DtaConsoleScript::execute(DtaScriptVariable& thisContext) { CGRuntime::traceLine("Console mode. Type 'help' for more information."); bool bContinue = true; GrfBlock* pTemporaryBlock = new GrfBlock(&getBlock()); DtaProject::getInstance().prepareExecution(); while (bContinue) { _sCursor = ">"; try { ScpStream stream; waitForCommand(stream); parseScript(stream, *pTemporaryBlock); pTemporaryBlock->execute(CGRuntime::getThisInternalNode()); pTemporaryBlock->moveFunctions(getBlock()); pTemporaryBlock->moveClasses(getBlock()); } catch(UtlException& exception) { CGRuntime::traceLine(exception.getMessage()); CGRuntime::traceText(exception.getTraceStack()); } catch(const char* sExit) { if (strcmp(sExit, "exit") == 0) bContinue = false; else CGRuntime::traceLine(sExit); } pTemporaryBlock->clear(); } return EXIT_INTERRUPTION; } }