1 /* "CodeWorker": a scripting language for parsing and generating text. 2 3 Copyright (C) 1996-1997, 1999-2002 C�dric Lemaire 4 5 This library is free software; you can redistribute it and/or 6 modify it under the terms of the GNU Lesser General Public 7 License as published by the Free Software Foundation; either 8 version 2.1 of the License, or (at your option) any later version. 9 10 This library is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 Lesser General Public License for more details. 14 15 You should have received a copy of the GNU Lesser General Public 16 License along with this library; if not, write to the Free Software 17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 19 To contact the author: codeworker@free.fr 20 */ 21 22 #ifdef WIN32 23 #pragma warning (disable : 4786) 24 #endif 25 26 #include "UtlException.h" 27 #include "ExprScriptExpression.h" 28 #include "ExprScriptVariable.h" 29 #include "CGRuntime.h" 30 #include "DtaPatternScript.h" 31 #include "DtaScriptVariable.h" 32 #include "ScpStream.h" 33 #include "CppCompilerEnvironment.h" 34 #include "DtaProject.h" 35 #include "GrfGenerate.h" 36 37 namespace CodeWorker { GrfGenerate()38 GrfGenerate::GrfGenerate() : _pClass(NULL), _pCachedScript(NULL), _pPatternFileName(NULL), _pFileName(NULL) { 39 _sCurrentDirectoryAtCompileTime = CGRuntime::getCurrentDirectory(); 40 } 41 ~GrfGenerate()42 GrfGenerate::~GrfGenerate() { 43 delete _pPatternFileName; 44 delete _pClass; 45 delete _pFileName; 46 if (_pCachedScript != NULL) delete _pCachedScript; 47 } 48 setPatternFileName(ExprScriptScriptFile * pPatternFileName)49 void GrfGenerate::setPatternFileName(ExprScriptScriptFile* pPatternFileName) { 50 if (pPatternFileName->isFileName()) _pPatternFileName = pPatternFileName->getFileName(); 51 _pCachedScript = dynamic_cast<DtaPatternScript*>(pPatternFileName->getBody()); 52 pPatternFileName->release(); 53 } 54 executeInternal(DtaScriptVariable & visibility)55 SEQUENCE_INTERRUPTION_LIST GrfGenerate::executeInternal(DtaScriptVariable& visibility) { 56 DtaScriptVariable* pClass = visibility.getExistingVariable(*_pClass); 57 if (pClass == NULL) { 58 throw UtlException("runtime error: variable '" + _pClass->toString() + "' doesn't exist while calling procedure '" + std::string(getFunctionName()) + "()'"); 59 } 60 std::string sOutputFile = _pFileName->getValue(visibility); 61 62 EXECUTE_FUNCTION* executeFunction = NULL; 63 if (_pPatternFileName != NULL) { 64 std::string sPatternFileName = _pPatternFileName->getValue(visibility); 65 if ((_pCachedScript == NULL) || (_sCachedPatternFile != sPatternFileName) || ScpStream::existVirtualFile(sPatternFileName)) { 66 executeFunction = DtaScript::getRegisteredScript(sPatternFileName.c_str()); 67 if (executeFunction == NULL) { 68 if (_pCachedScript != NULL) delete _pCachedScript; 69 _pCachedScript = new DtaPatternScript(getParent()); 70 _sCachedPatternFile = sPatternFileName; 71 _pCachedScript->parseFile(sPatternFileName.c_str(), _sCurrentDirectoryAtCompileTime); 72 } 73 } 74 } 75 76 SEQUENCE_INTERRUPTION_LIST result = executeScript(sOutputFile.c_str(), pClass, executeFunction); 77 switch(result) { 78 case CONTINUE_INTERRUPTION: 79 case BREAK_INTERRUPTION: 80 case RETURN_INTERRUPTION: 81 result = NO_INTERRUPTION; 82 break; 83 } 84 return result; 85 } 86 executeScript(const char * sOutputFile,DtaScriptVariable * pThisContext,EXECUTE_FUNCTION * executeFunction)87 SEQUENCE_INTERRUPTION_LIST GrfGenerate::executeScript(const char* sOutputFile, DtaScriptVariable* pThisContext, EXECUTE_FUNCTION* executeFunction) { 88 if (executeFunction != NULL) { 89 CGRuntime::generate(executeFunction, CppParsingTree_var(pThisContext), sOutputFile); 90 return NO_INTERRUPTION; 91 } 92 // _pCachedScript->setFilename(_sCachedPatternFile.c_str()); 93 return _pCachedScript->generate(sOutputFile, *pThisContext); 94 } 95 compileCpp(CppCompilerEnvironment & theCompilerEnvironment) const96 void GrfGenerate::compileCpp(CppCompilerEnvironment& theCompilerEnvironment) const { 97 ExprScriptConstant* pConstantFileName = dynamic_cast<ExprScriptConstant*>(_pPatternFileName); 98 std::string sScriptFilename; 99 if (pConstantFileName == NULL) { 100 sScriptFilename = theCompilerEnvironment.newInlineScriptFilename(); 101 } else { 102 sScriptFilename = pConstantFileName->getConstant(); 103 } 104 std::string sRadical = DtaScript::convertFilenameAsIdentifier(CppCompilerEnvironment::getRadical(CppCompilerEnvironment::filename2Module(sScriptFilename))); 105 CW_BODY_INDENT << "CGRuntime::" << getFunctionName() << "(&Execute" << sRadical << "::instance(), "; 106 _pClass->compileCpp(theCompilerEnvironment); 107 CW_BODY_STREAM << ", "; 108 _pFileName->compileCppString(theCompilerEnvironment); 109 CW_BODY_STREAM << ");"; 110 CW_BODY_ENDL; 111 if (_pCachedScript == NULL) { 112 _pCachedScript = new DtaPatternScript(getParent()); 113 _sCachedPatternFile = sScriptFilename; 114 _pCachedScript->parseFile(_sCachedPatternFile.c_str(), _sCurrentDirectoryAtCompileTime); 115 } 116 _pCachedScript->compileCpp(theCompilerEnvironment, sScriptFilename); 117 } 118 } 119