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