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 // function 'mkdir'
27 #ifdef WIN32
28 #	include <direct.h>
29 #else
30 #	include <sys/stat.h>
31 #endif
32 
33 #include "ScpStream.h"
34 #include "UtlException.h"
35 #include "UtlTrace.h"
36 #include "UtlDirectory.h"
37 
38 #include "CGRuntime.h"
39 #include "Workspace.h"
40 #include "GrfForeach.h"
41 #include "GrfSelect.h"
42 #include "GrfIfThenElse.h"
43 #include "GrfDelay.h"
44 #include "GrfNewProject.h"
45 #include "GrfDebugExecution.h"
46 #include "GrfQuantifyExecution.h"
47 #include "GrfQuiet.h"
48 #include "GrfFileAsStandardInput.h"
49 #include "GrfStringAsStandardInput.h"
50 #include "GrfDo.h"
51 #include "GrfSwitch.h"
52 #include "GrfTryCatch.h"
53 #include "GrfWhile.h"
54 #include "GrfContinue.h"
55 #include "GrfBreak.h"
56 #include "GrfReturn.h"
57 #include "GrfExit.h"
58 #include "GrfFunction.h"
59 #include "GrfReadonlyHook.h"
60 #include "GrfWritefileHook.h"
61 #include "GrfWriteText.h"
62 #include "DtaClass.h"
63 #include "GrfNop.h"
64 #include "GrfLocalReference.h"
65 #include "GrfLocalVariable.h"
66 #include "GrfGlobalVariable.h"
67 #include "GrfSetAssignment.h"
68 #include "GrfInsertAssignment.h"
69 #include "GrfSetAll.h"
70 #include "GrfMerge.h"
71 #include "GrfPushItem.h"
72 #include "GrfReference.h"
73 #include "GrfParsedFile.h"
74 #include "GrfParsedString.h"
75 #include "GrfAlienInstruction.h"
76 #include "CGExternalHandling.h" // for CGQuietOutput
77 //##markup##"include files"
78 //##begin##"include files"
79 #include "GrfAppendFile.h"
80 #include "GrfAutoexpand.h"
81 #include "GrfClearVariable.h"
82 #include "GrfCompileToCpp.h"
83 #include "GrfCopyFile.h"
84 #include "GrfCopyGenerableFile.h"
85 #include "GrfCopySmartDirectory.h"
86 #include "GrfCutString.h"
87 #include "GrfEnvironTable.h"
88 #include "GrfError.h"
89 #include "GrfExecuteString.h"
90 #include "GrfExpand.h"
91 #include "GrfExtendExecutedScript.h"
92 #include "GrfGenerate.h"
93 #include "GrfGenerateString.h"
94 #include "GrfInsertElementAt.h"
95 #include "GrfInvertArray.h"
96 #include "GrfListAllGeneratedFiles.h"
97 #include "GrfLoadProject.h"
98 #include "GrfOpenLogFile.h"
99 #include "GrfParseAsBNF.h"
100 #include "GrfParseStringAsBNF.h"
101 #include "GrfParseFree.h"
102 #include "GrfProduceHTML.h"
103 #include "GrfPutEnv.h"
104 #include "GrfRandomSeed.h"
105 #include "GrfRemoveAllElements.h"
106 #include "GrfRemoveElement.h"
107 #include "GrfRemoveFirstElement.h"
108 #include "GrfRemoveLastElement.h"
109 #include "GrfRemoveRecursive.h"
110 #include "GrfRemoveVariable.h"
111 #include "GrfSaveBinaryToFile.h"
112 #include "GrfSaveProject.h"
113 #include "GrfSaveProjectTypes.h"
114 #include "GrfSaveToFile.h"
115 #include "GrfSetCommentBegin.h"
116 #include "GrfSetCommentEnd.h"
117 #include "GrfSetGenerationHeader.h"
118 #include "GrfSetIncludePath.h"
119 #include "GrfSetNow.h"
120 #include "GrfSetProperty.h"
121 #include "GrfSetTextMode.h"
122 #include "GrfSetVersion.h"
123 #include "GrfSetWriteMode.h"
124 #include "GrfSetWorkingPath.h"
125 #include "GrfSleep.h"
126 #include "GrfSlideNodeContent.h"
127 #include "GrfSortArray.h"
128 #include "GrfTraceEngine.h"
129 #include "GrfTraceLine.h"
130 #include "GrfTraceObject.h"
131 #include "GrfTraceStack.h"
132 #include "GrfTraceText.h"
133 #include "GrfTranslate.h"
134 #include "GrfCloseSocket.h"
135 //##end##"include files"
136 #include "ExprScriptVariable.h"
137 #include "ExprScriptMotif.h"
138 #include "ExprScriptFunction.h"
139 #include "ExprScriptBinaryExpression.h"
140 #include "DtaProject.h"
141 #include "CppCompilerEnvironment.h"
142 #include "DtaBNFScript.h" // for alien languages
143 #include "DynFunction.h"
144 #include "DynPackage.h"
145 
146 #include "DtaScript.h"
147 #include "DtaPatternScript.h"
148 
149 namespace CodeWorker {
150 	bool DtaScript::_bParseWithSymbols = true;
151 	std::vector<const char*> DtaScript::_listOfAllFilesAlreadyParsed;
152 	std::map<std::string, EXECUTE_FUNCTION*> DtaScript::_mapOfScriptFunctions;
153 	std::map<std::string, std::string> DtaScript::_mapOfSyntaxModes;
154 	std::map<std::string, int> DtaScript::_mapOfReferenceMagicNumbers;
155 
156 
executeInternal(DtaScriptVariable & visibility)157 	SEQUENCE_INTERRUPTION_LIST GrfScriptBlock::executeInternal(DtaScriptVariable& visibility) {
158 		SEQUENCE_INTERRUPTION_LIST result = NO_INTERRUPTION;
159 		GrfCommand* pCommand = NULL;
160 		try {
161 			if (hasLocalVariables()) {
162 				DtaScriptVariable localVariables(&visibility, "##stack## block");
163 				for (std::vector<GrfCommand*>::iterator i = _commands.begin(); i != _commands.end(); i++) {
164 					pCommand = *i;
165 					if ((result = pCommand->execute(localVariables)) != NO_INTERRUPTION) break;
166 				}
167 			} else {
168 				for (std::vector<GrfCommand*>::iterator i = _commands.begin(); i != _commands.end(); i++) {
169 					pCommand = *i;
170 					if ((result = pCommand->execute(visibility)) != NO_INTERRUPTION) break;
171 				}
172 			}
173 		} catch(UtlException& exception) {
174 			std::string sLineStack;
175 			if (pCommand->_sParsingFilePtr != NULL) {
176 				char tcNumber[1024];
177 				std::string sCompleteFileName;
178 				std::auto_ptr<std::ifstream> pFile(openInputFileFromIncludePath(pCommand->_sParsingFilePtr, sCompleteFileName));
179 				if (pFile.get() == NULL) {
180 					sprintf(tcNumber, "\"%s\": offset[%d], ", pCommand->_sParsingFilePtr, pCommand->_iFileLocation);
181 				} else {
182 					setLocation(*pFile, pCommand->_iFileLocation);
183 					int iLine = getLineCount(*pFile);
184 					std::string sScriptFilename = pCommand->_sParsingFilePtr;
185 					std::string::size_type iIndex = sScriptFilename.find_last_of("\\/");
186 					if (iIndex != std::string::npos) sScriptFilename = sScriptFilename.substr(iIndex + 1);
187 					sprintf(tcNumber, "%s(%d): ", sScriptFilename.c_str(), iLine);
188 					pFile->close();
189 				}
190 				sLineStack += tcNumber;
191 			}
192 			sLineStack += "main scope";
193 			sLineStack += "\n";
194 			std::string sTraceStack = exception.getTraceStack();
195 			if (sTraceStack.substr(0, sLineStack.size()) != sLineStack) {
196 				sTraceStack = sLineStack + sTraceStack;
197 			}
198 			throw UtlException(sTraceStack, exception.getMessage());
199 		}
200 		return result;
201 	}
202 
203 
204 
205 
DtaScript(GrfBlock * pParentBlock,const char * sFilename)206 	DtaScript::DtaScript(/*DtaScriptVariable* pVisibility, */GrfBlock* pParentBlock, const char* sFilename) : _graph(pParentBlock), /*_pVisibility(pVisibility), */_pPreviousScript(NULL), _bNumericalExpression(false), _bCurrentFunctionGenericTemplateKey(false) {
207 		setFilename(sFilename);
208 		_graph.setScript(this);
209 		allocateLocalParameters();
210 	}
211 
~DtaScript()212 	DtaScript::~DtaScript() {
213 		freeLocalParameters();
214 	}
215 
allocateLocalParameters()216 	void DtaScript::allocateLocalParameters() {
217 		_sPreviousVersion = DtaProject::getInstance().getVersion();
218 		_pPreviousScript = DtaProject::getInstance().getScript();
219 		_sPreviousMarkupKey = DtaProject::getInstance().getMarkupKey();
220 		_sPreviousMarkupValue = DtaProject::getInstance().getMarkupValue();
221 		DtaProject::getInstance().setScript(this);
222 	}
223 
freeLocalParameters()224 	void DtaScript::freeLocalParameters() {
225 		DtaProject::getInstance().setVersion(_sPreviousVersion);
226 		DtaProject::getInstance().setScript(_pPreviousScript);
227 		DtaProject::getInstance().setMarkupKey(_sPreviousMarkupKey);
228 		DtaProject::getInstance().setMarkupValue(_sPreviousMarkupValue);
229 	}
230 
getType() const231 	DtaScriptFactory::SCRIPT_TYPE DtaScript::getType() const { return DtaScriptFactory::COMMON_SCRIPT; }
isAParseScript() const232 	bool DtaScript::isAParseScript() const { return false; }
isAGenerateScript() const233 	bool DtaScript::isAGenerateScript() const { return false; }
234 
setFilename(const char * sFilename)235 	void DtaScript::setFilename(const char* sFilename) {
236 		if ((sFilename == NULL) || (sFilename[0] == '\0')) _tcFilePtr = NULL;
237 		else {
238 			// determine the target language
239 			if (!DtaProject::getInstance().getCodeWorkerHome().empty()) {
240 				std::string sFileForTarget = sFilename;
241 				std::string::size_type iIndex = sFileForTarget.find_last_of("/\\");
242 				if (iIndex != std::string::npos) sFileForTarget = sFileForTarget.substr(iIndex + 1);
243 				iIndex = sFileForTarget.find_last_of(".");
244 				if (iIndex != std::string::npos) {
245 					sFileForTarget = sFileForTarget.substr(0, iIndex);
246 					iIndex = sFileForTarget.find_last_of(".");
247 					if (iIndex != std::string::npos) {
248 						sFileForTarget = sFileForTarget.substr(iIndex + 1);
249 						UtlDirectory theTargetDir(DtaProject::getInstance().getCodeWorkerHome() + sFileForTarget);
250 						if (theTargetDir.scan()) {
251 							_sTargetLanguage = sFileForTarget;
252 							if (DtaProject::getInstance().hasTargetLanguage()) {
253 								if (DtaProject::getInstance().getTargetLanguage() != _sTargetLanguage) {
254 									throw UtlException("you can't specify two different target languages");
255 								}
256 							} else {
257 								DtaProject::getInstance().setTargetLanguage(_sTargetLanguage);
258 							}
259 						}
260 					}
261 				}
262 			}
263 			// register the filename pointer
264 			for (std::vector<const char*>::const_iterator i = _listOfAllFilesAlreadyParsed.begin(); i != _listOfAllFilesAlreadyParsed.end(); i++) {
265 				if (*i == sFilename) {
266 					_tcFilePtr = *i;
267 					return;
268 				}
269 			}
270 #ifdef WIN32
271 			_tcFilePtr = _strdup(sFilename);
272 #else
273 			_tcFilePtr = strdup(sFilename);
274 #endif
275 			_listOfAllFilesAlreadyParsed.push_back(_tcFilePtr);
276 		}
277 	}
278 
traceEngine() const279 	void DtaScript::traceEngine() const {
280 		if (_tcFilePtr == NULL) CGRuntime::traceLine("Common script (no filename):");
281 		else CGRuntime::traceLine("Common script \"" + std::string(_tcFilePtr) + "\":");
282 		traceInternalEngine();
283 	}
284 
traceInternalEngine() const285 	void DtaScript::traceInternalEngine() const {
286 		if (_pPreviousScript != NULL) {
287 			CGRuntime::traceLine("--------------");
288 			_pPreviousScript->traceEngine();
289 		}
290 	}
291 
openOutputFile(const char * sFileName,bool bThrowOnError)292 	std::fstream* DtaScript::openOutputFile(const char* sFileName, bool bThrowOnError) {
293 		std::fstream* pFile = openIOFile(sFileName);
294 		if (pFile == NULL) {
295 			std::string sFile = sFileName;
296 			int iEndPos = sFile.find_first_of("\\/", 1);
297 			while (iEndPos > 0) {
298 				std::string sDirectory = sFile.substr(0, iEndPos);
299 #ifdef WIN32
300 				mkdir(sDirectory.c_str());
301 #else
302 				mkdir(sDirectory.c_str(), S_IRWXU);
303 #endif
304 				iEndPos = sFile.find_first_of("\\/", iEndPos + 1);
305 			}
306 			pFile = openIOFile(sFileName);
307 		}
308 		if ((pFile == NULL) && bThrowOnError) throw UtlException(std::string("Unable to create file \"") + sFileName + "\"");
309 		return pFile;
310 	}
311 
registerScript(const char * sRegistration,EXECUTE_FUNCTION * executeFunction)312 	void DtaScript::registerScript(const char* sRegistration, EXECUTE_FUNCTION* executeFunction) {
313 		_mapOfScriptFunctions[sRegistration] = executeFunction;
314 	}
315 
getRegisteredScript(const char * sRegistration)316 	EXECUTE_FUNCTION* DtaScript::getRegisteredScript(const char* sRegistration) {
317 		if (sRegistration == NULL) return NULL;
318 		std::string sModule(sRegistration);
319 		std::string::size_type iIndex = sModule.find('.');
320 		if (iIndex != std::string::npos) sModule = sModule.substr(0, iIndex);
321 		std::map<std::string, EXECUTE_FUNCTION*>::const_iterator cursor = _mapOfScriptFunctions.find(sModule);
322 		if (cursor == _mapOfScriptFunctions.end()) return NULL;
323 		return cursor->second;
324 	}
325 
parseFile(const char * tcScriptFileName,GrfBlock * pIncluded,bool bDebugMode,const std::string & sQuantifyFile)326 	void DtaScript::parseFile(const char* tcScriptFileName, GrfBlock* pIncluded, bool bDebugMode, const std::string& sQuantifyFile) {
327 		ScpStream* pFile = NULL;
328 		ScpStream theFileContent;
329 		std::string sCompleteFileName;
330 		if (ScpStream::existVirtualFile(tcScriptFileName)) {
331 			std::string sContent;
332 			if (!ScpStream::loadVirtualFile(tcScriptFileName, sContent)) throw UtlException(std::string("unable to load the virtual script file \"") + tcScriptFileName + "\"");
333 			theFileContent << sContent;
334 		} else {
335 			pFile = ScpStream::openInputFileFromIncludePath(tcScriptFileName, sCompleteFileName);
336 			if (pFile == NULL) {
337 				throw UtlException(std::string("unable to open script file \"") + tcScriptFileName + "\"");
338 			}
339 			sCompleteFileName = CGRuntime::canonizePath(sCompleteFileName);
340 		}
341 		const char* sOldFile = getFilenamePtr();
342 		setFilename(sCompleteFileName.c_str());
343 		_mapOfAttachedAreas = std::map<int, int>();
344 		std::string sOldCurrentDirectory;
345 		try {
346 			if (pFile != NULL) {
347 				sOldCurrentDirectory = CGRuntime::getCurrentDirectory();
348 				std::string sNewCurrentDirectory = sCompleteFileName.substr(0, 1 + sCompleteFileName.find_last_of('/'));
349 				CGRuntime::changeDirectory(sNewCurrentDirectory);
350 				if (pIncluded != NULL) parseScript(*pFile, *pIncluded);
351 				else parseStream(*pFile, bDebugMode, sQuantifyFile);
352 				CGRuntime::changeDirectory(sOldCurrentDirectory);
353 			} else {
354 				if (pIncluded != NULL) parseScript(theFileContent, *pIncluded);
355 				else parseStream(theFileContent, bDebugMode, sQuantifyFile);
356 			}
357 		} catch(UtlExitException&) {
358 			if (pFile != NULL) {
359 				CGRuntime::changeDirectory(sOldCurrentDirectory);
360 				pFile->close();
361 				delete pFile;
362 			}
363 			throw;
364 		} catch(UtlException& e) {
365 			std::string sMessage;
366 			sMessage += tcScriptFileName;
367 			setFilenamePtr(sOldFile);
368 			char tcNumber[64];
369 			sprintf(tcNumber, "(%d):", ((pFile == NULL) ? theFileContent.getLineCount() : pFile->getLineCount()));
370 			sMessage += tcNumber + CGRuntime::endl();
371 			if (pFile != NULL) {
372 				CGRuntime::changeDirectory(sOldCurrentDirectory);
373 				pFile->close();
374 				delete pFile;
375 			}
376 			throw UtlException(e.getTraceStack(), sMessage + e.getMessage());
377 		}
378 		if (sOldFile != NULL) {
379 			// we were including a script file here
380 			setFilenamePtr(sOldFile);
381 		}
382 		if (pFile != NULL) {
383 			pFile->close();
384 			delete pFile;
385 		}
386 		if (!_mapOfAttachedAreas.empty()) {
387 			std::auto_ptr<ScpStream> pStream;
388 			if (ScpStream::existVirtualFile(tcScriptFileName)) {
389 				std::auto_ptr<ScpStream> pExistingFile(new ScpStream);
390 				pStream = pExistingFile;
391 				std::string sContent;
392 				if (!ScpStream::loadVirtualFile(tcScriptFileName, sContent)) throw UtlException(std::string("unable to load the virtual script file \"") + tcScriptFileName + "\"");
393 				pStream->setFilename(tcScriptFileName);
394 				(*pStream) << sContent;
395 			} else {
396 				std::auto_ptr<ScpStream> pNewFile(new ScpStream(tcScriptFileName, ScpStream::IN | ScpStream::PATH));
397 				pStream = pNewFile;
398 			}
399 			std::map<int, int>::const_iterator i;
400 			char tcNumber[32];
401 			for (i = _mapOfAttachedAreas.begin(); i != _mapOfAttachedAreas.end(); ++i) {
402 				pStream->setOutputLocation(i->first);
403 				sprintf(tcNumber, "%d", i->first);
404 				pStream->newFloatingLocation(tcNumber);
405 			}
406 			char tcMagicNumber[32];
407 			ScpStream* pOwner;
408 			for (i = _mapOfAttachedAreas.begin(); i != _mapOfAttachedAreas.end(); ++i) {
409 				sprintf(tcMagicNumber, ", %d", i->second);
410 				sprintf(tcNumber, "%d", i->first);
411 				pStream->insertText(tcMagicNumber, pStream->getFloatingLocation(tcNumber, pOwner));
412 			}
413 			GrfWritefileHook* pHook = DtaProject::getInstance().getWritefileHook();
414 			if (pHook != NULL) {
415 				std::string sSuccess;
416 				try {
417 					sSuccess = pHook->executeHook(DtaProject::getInstance(), tcScriptFileName, -1, false);
418 				} catch(UtlException& exc) {
419 					throw UtlException(std::string("FATAL ERROR! Before writing the script file \"") + tcScriptFileName + "\", a call to 'writefileHook' has raised the following error:" + CGRuntime::endl() + "\"" + exc.getMessage() + "\"");
420 				}
421 				if (sSuccess.empty()) return;
422 			}
423 			try {
424 				pStream->saveIntoFile(tcScriptFileName, false);
425 			} catch(UtlException&/* exception*/) {
426 				GrfReadonlyHook* pHook = DtaProject::getInstance().getReadonlyHook();
427 				if (pHook != NULL) {
428 					try {
429 						pHook->executeHook(DtaProject::getInstance(), tcScriptFileName);
430 					} catch(UtlException& exc) {
431 						throw UtlException(std::string("FATAL ERROR! Script file \"") + tcScriptFileName + "\" is read-only and call to the hook has launched the following error:\n\"" + exc.getMessage() + "\"");
432 					}
433 					pStream->saveIntoFile(tcScriptFileName, false);
434 				} else {
435 					throw/* UtlException(exception.getTraceStack(), exception.getMessage())*/;
436 				}
437 			}
438 		}
439 	}
440 
parseFile(const char * sScriptName,const std::string & sCurrentDirectoryAtCompileTime)441 	void DtaScript::parseFile(const char* sScriptName, const std::string& sCurrentDirectoryAtCompileTime) {
442 		std::string sOldCurrentDirectory;
443 		try {
444 			sOldCurrentDirectory = CGRuntime::getCurrentDirectory();
445 			CGRuntime::changeDirectory(sCurrentDirectoryAtCompileTime);
446 			parseFile(sScriptName);
447 			CGRuntime::changeDirectory(sOldCurrentDirectory);
448 		} catch(std::exception&) {
449 			CGRuntime::changeDirectory(sOldCurrentDirectory);
450 			throw;
451 		}
452 	}
453 
parseStream(ScpStream & myStream,bool bDebugMode,const std::string & sQuantifyFile)454 	void DtaScript::parseStream(ScpStream& myStream, bool bDebugMode, const std::string& sQuantifyFile) {
455 		GrfBlock* pRoot = &_graph;
456 		if (!sQuantifyFile.empty()) {
457 			GrfQuantifyExecution* pQuantify = new GrfQuantifyExecution(pRoot);
458 			if (sQuantifyFile != "true") pQuantify->setFilename(new ExprScriptConstant(sQuantifyFile.c_str()));
459 			pRoot->add(pQuantify);
460 			pRoot = pQuantify;
461 		}
462 		if (bDebugMode) {
463 			GrfDebugExecution* pDebug = new GrfDebugExecution(pRoot);
464 			pRoot->add(pDebug);
465 			pRoot = pDebug;
466 		}
467 		parseScript(myStream, *pRoot);
468 	}
469 
handleNotAWordCommand(ScpStream & script,GrfBlock & block)470 	void DtaScript::handleNotAWordCommand(ScpStream& script, GrfBlock& block) {
471 		int iChar = script.readChar();
472 		if (iChar == (int) '{') {
473 			script.goBack();
474 			GrfBlock* pBlock = new GrfBlock(&block);
475 			if (requiresParsingInformation()) pBlock->setParsingInformation(getFilenamePtr(), script);
476 			block.add(pBlock);
477 			parseBlock(script, *pBlock);
478 		} else if (iChar == (int) '#') {
479 			std::string sDirective;
480 			if (!script.readIdentifier(sDirective)) throw UtlException(script, "preprocessor directive expected after '#' symbol");
481 			sDirective = "#" + sDirective;
482 			parsePreprocessorDirective(sDirective, script, block);
483 		} else {
484 			std::string sMessage = "command or procedure or function expected, instead of ";
485 			if (iChar < 0) {
486 				throw UtlException(script, sMessage + "end of file");
487 			} else {
488 				throw UtlException(script, sMessage + "'" + (char) iChar + "'");
489 			}
490 		}
491 	}
492 
parsePreprocessorDirective(const std::string & sDirective,ScpStream & script,GrfBlock & block)493 	void DtaScript::parsePreprocessorDirective(const std::string& sDirective, ScpStream& script, GrfBlock& block) {
494 		if (sDirective == "#include") {
495 			script.skipEmpty();
496 			std::string sScriptFileName;
497 			if (!script.readString(sScriptFileName)) throw UtlException(script, "syntax error: constant string expected");
498 			// protect against the multi-inclusion in the same script file
499 			std::set<std::string>::const_iterator	itIncluded;
500 			itIncluded = _setOfIncludedFiles.find(sScriptFileName);
501 			if (itIncluded == _setOfIncludedFiles.end()) {
502 				_setOfIncludedFiles.insert(sScriptFileName);
503 				parseFile(sScriptFileName.c_str(), &block);
504 			}
505 		} else if (sDirective == "#use") {
506 			script.skipEmpty();
507 			std::string sPackageName;
508 			if (!script.readIdentifier(sPackageName)) throw UtlException(script, "syntax error: module name expected as a constant string");
509 			DynPackage::addPackage(sPackageName, block);
510 		} else if (sDirective == "#line") {
511 			script.skipEmpty();
512 			int iLine;
513 			if (!script.readInt(iLine)) throw UtlException(script, "syntax error: line number expected as a constant integer");
514 			int iChar = script.readChar();
515 			while ((iChar == (int) ' ') && (iChar == (int) '\t')) iChar = script.readChar();
516 			if (iChar == (int) '/') {
517 				iChar = script.readChar();
518 				if (iChar != (int) '/') throw UtlException(script, "syntax error: end of line or line comment expected");
519 				do {
520 					iChar = script.readChar();
521 				} while ((iChar >= 0) && (iChar != (int)'\r') && (iChar != (int)'\n'));
522 			}
523 			if (iChar == '\r') iChar = script.readChar();
524 			if (iChar != '\n') throw UtlException(script, "syntax error: end of line expected");
525 			script.setLineDirective(iLine);
526 		} else if (sDirective == "#attach") {
527 			script.skipLineBlanks();
528 			std::string sKey;
529 			std::string sReferenceFile;
530 			if (!script.readString(sReferenceFile)) throw UtlException(script, "syntax error on '#attach': reference script file expected");
531 			script.skipLineBlanks();
532 			if (!script.isEqualTo(':')) throw UtlException(script, "syntax error on '#attach', ':' expected");
533 			script.skipLineBlanks();
534 			if (!script.readIdentifier(sKey)) throw UtlException(script, "syntax error on '#attach': identifier expected");
535 			int iMagicNumberLocation = script.getInputLocation();
536 			script.skipLineBlanks();
537 			if (script.isEqualTo(',')) {
538 				script.skipLineBlanks();
539 				int iMagicNumber;
540 				if (!script.readInt(iMagicNumber)) throw UtlException(script, "syntax error on '#attach': magic number expected after the comma");
541 				int iReferenceMagicNumber;
542 				if (extractReferenceMagicNumber(sReferenceFile, sKey, iReferenceMagicNumber)) {
543 					if (iReferenceMagicNumber != iMagicNumber) {
544 						std::string sErrorMessage = "warning: attached area '" + sKey + "' isn't equivalent to the same area in the reference script file \"" + sReferenceFile + "\"" + CGRuntime::endl();
545 						sErrorMessage += DtaProject::getInstance().getTraceStack(script);
546 						if (DtaProject::getInstance().addWarning(sErrorMessage) == 1) CGRuntime::traceLine(sErrorMessage);
547 					}
548 				} else {
549 					std::string sErrorMessage = "warning: attached area '" + sKey + "' refers to an unexisting script file \"" + sReferenceFile + "\" or key" + CGRuntime::endl();
550 					sErrorMessage += DtaProject::getInstance().getTraceStack(script);
551 					if (DtaProject::getInstance().addWarning(sErrorMessage) == 1) CGRuntime::traceLine(sErrorMessage);
552 				}
553 			} else {
554 				if (!script.findString("\n")) throw UtlException(script, "syntax error on '#attach': end of line expected");
555 				int iReferenceMagicNumber;
556 				if (extractReferenceMagicNumber(sReferenceFile, sKey, iReferenceMagicNumber)) {
557 					_mapOfAttachedAreas[iMagicNumberLocation] = iReferenceMagicNumber;
558 				} else {
559 					std::string sErrorMessage = "warning: attached area '" + sKey + "' refers to an unexisting script file \"" + sReferenceFile + "\" or key" + CGRuntime::endl();
560 					sErrorMessage += DtaProject::getInstance().getTraceStack(script);
561 					if (DtaProject::getInstance().addWarning(sErrorMessage) == 1) CGRuntime::traceLine(sErrorMessage);
562 				}
563 			}
564 		} else if (sDirective == "#reference") {
565 			if (getFilenamePtr() == NULL) throw UtlException(script, "a '#reference' area must be put into a script file; this isn't the case here");
566 			script.skipLineBlanks();
567 			std::string sKey;
568 			if (!script.readIdentifier(sKey)) throw UtlException(script, "syntax error on '#reference': identifier expected");
569 			if (!script.findString("\n")) throw UtlException(script, "syntax error on '#reference': end of line expected");
570 			int iLocation = script.getInputLocation();
571 			computeReferenceMagicNumber(script, getFilenamePtr(), sKey);
572 			script.setInputLocation(iLocation);
573 		} else if (sDirective == "#end") {
574 			if (!script.findString("\n")) throw UtlException(script, "syntax error on '#end': end of line expected");
575 		} else if (sDirective == "#syntax") {
576 			parseSyntax(block, script);
577 		} else {
578 			throw UtlException(script, "unknown preprocessor directive '" + sDirective + "' found");
579 		}
580 	}
581 
handleUnknownCommand(const std::string & sCommand,ScpStream & script,GrfBlock & block)582 	void DtaScript::handleUnknownCommand(const std::string& sCommand, ScpStream& script, GrfBlock& block) {
583 		int iLocation = script.getInputLocation() - sCommand.size();
584 		DynPackage* pPackage = NULL;
585 		std::string sPackageMember;
586 		script.skipEmpty();
587 		int iChar = script.readChar();
588 		if (iChar == (int) ':') {
589 			if (!script.isEqualTo(':')) {
590 				script.goBack();
591 				throw UtlException(script, "unexpected identifier \"" + sCommand + "\"");
592 			} else {
593 				pPackage = DynPackage::getPackage(sCommand);
594 				if (pPackage == NULL) throw UtlException(script, "unknown module '" + sCommand +"'; type '#use' to load the dynamic library");
595 				script.skipEmpty();
596 				if (!script.readIdentifier(sPackageMember)) throw UtlException(script, "function or variable name expected after '" + sCommand + "::'");
597 				script.skipEmpty();
598 				iChar = script.readChar();
599 			}
600 		}
601 		if (iChar == (int) '(') {
602 			if (pPackage != NULL) {
603 				// the variable comes from a module
604 				DynFunction* pFunction = pPackage->getFunction(sPackageMember);
605 				if (pFunction == NULL) throw UtlException(script, "the module '" + sCommand + "' doesn't export the function '" + sCommand + "::" + sPackageMember + "'");
606 				GrfNop* pNop = new GrfNop;
607 				if (requiresParsingInformation()) pNop->setParsingInformation(getFilenamePtr(), script);
608 				block.add(pNop);
609 				pNop->setExpression(parseFunctionExpression(block, script, NULL, new ExprScriptFunction(pFunction), NULL, true));
610 			} else {
611 				// classical variable kind
612 				ExprScriptFunction* pFunction = ExprScriptFunction::create(block, script, sCommand, "", false);
613 				if (pFunction == NULL) throw UtlException(script, "unknown command or procedure or function \"" + sCommand + "\"");
614 				checkIfAllowedFunction(script, *pFunction);
615 				GrfNop* pNop = new GrfNop;
616 				if (requiresParsingInformation()) pNop->setParsingInformation(getFilenamePtr(), script);
617 				block.add(pNop);
618 				pNop->setExpression(parseFunctionExpression(block, script, NULL, pFunction, NULL, true));
619 			}
620 			script.skipEmpty();
621 			if (!script.isEqualTo(';')) throw UtlException(script, "';' expected after calling a procedure");
622 		} else if ((iChar == (int) '.') || (iChar == (int) '#') || (iChar == (int) '[') || (iChar == (int) '$' && script.peekChar() == (int) '[')) {
623 			script.goBack();
624 			std::string sVariable;
625 			if (pPackage != NULL) {
626 				if (pPackage->getVariable(sPackageMember) == NULL) throw UtlException(script, "the module '" + sCommand + "' doesn't export the variable '" + sCommand + "::" + sPackageMember + "'");
627 				sVariable = sPackageMember;
628 			} else {
629 				sVariable = sCommand;
630 			}
631 			ExprScriptExpression* pMethodFunction;
632 			GrfCommand* pMethodProc;
633 			std::auto_ptr<ExprScriptVariable> pVariable(parseVariableExpression(block, script, new ExprScriptVariable(sVariable.c_str(), pPackage), pMethodFunction, pMethodProc));
634 			script.skipEmpty();
635 			if (pMethodFunction != NULL) {
636 				pVariable.release();
637 				GrfNop* pNop = new GrfNop;
638 				if (requiresParsingInformation()) pNop->setParsingInformation(getFilenamePtr(), script);
639 				block.add(pNop);
640 				pNop->setExpression(pMethodFunction);
641 				if (!script.isEqualTo(';')) throw UtlException(script, "';' expected to close an instruction (function call)");
642 			} else if (pMethodProc != NULL) {
643 				pVariable.release();
644 				// nothing to do: the procedure has been added
645 			} else {
646 				GrfSetAssignment* pAssignment = new GrfSetAssignment;
647 				if (requiresParsingInformation()) pAssignment->setParsingInformation(getFilenamePtr(), script);
648 				block.add(pAssignment);
649 				pAssignment->setVariable(pVariable.release());
650 				bool bConcat = script.isEqualTo('+');
651 				if (!script.isEqualTo('=')) throw UtlException(script, "syntax error: assignment expected ('+=' or '=' operator)");
652 				script.skipEmpty();
653 				pAssignment->setValue(parseExpression(block, script), bConcat);
654 				script.skipEmpty();
655 				if (!script.isEqualTo(';')) throw UtlException(script, "';' expected to close an assignment instruction");
656 			}
657 		} else if ((iChar == (int) '=') || ((iChar == (int) '+') && script.isEqualTo('='))) {
658 			script.setInputLocation(iLocation);
659 			parseSetAssignment(block, script);
660 		} else if (iChar == (int) '<') {
661 			std::auto_ptr<ExprScriptExpression> pTemplate(parseKeyTemplateExpression(block, script));
662 			script.skipEmpty();
663 			if (script.isEqualTo('>')) {
664 				script.skipEmpty();
665 				if (!script.isEqualTo('(')) throw UtlException(script, "'(' expected after instantiating a template procedure");
666 				ExprScriptFunction* pFunction = ExprScriptFunction::create(block, script, sCommand, "", false);
667 				if (pFunction == NULL) throw UtlException(script, "unknown command or procedure or function \"" + sCommand + "\"");
668 				checkIfAllowedFunction(script, *pFunction);
669 				GrfNop* pNop = new GrfNop;
670 				if (requiresParsingInformation()) pNop->setParsingInformation(getFilenamePtr(), script);
671 				block.add(pNop);
672 				pNop->setExpression(parseFunctionExpression(block, script, NULL, pFunction, pTemplate.release(), true));
673 				if (!script.isEqualTo(';')) throw UtlException(script, "';' expected after calling a function or procedure");
674 			} else {
675 				script.setInputLocation(iLocation);
676 				throw UtlException(script, "unknown command or procedure or function \"" + sCommand + "\"");
677 			}
678 		} else {
679 			throw UtlException(script, "unexpected identifier \"" + sCommand + "\"");
680 		}
681 	}
682 
betweenCommands(ScpStream &,GrfBlock &)683 	bool DtaScript::betweenCommands(ScpStream& /*script*/, GrfBlock& /*block*/) { return false; }
684 
parseScript(ScpStream & script,GrfBlock & block)685 	void DtaScript::parseScript(ScpStream& script, GrfBlock& block) {
686 		_stackOfParsedBlocks.push_front(&block);
687 		if (hasTargetLanguage()) {
688 			// alien programming language
689 			parseAlienScript(script, block);
690 		} else {
691 			// ordinary scripting
692 			betweenCommands(script, block);
693 			while (script.skipEmpty()) parseInstruction(script, block);
694 		}
695 		_stackOfParsedBlocks.pop_front();
696 	}
697 
parseEmbeddedScript(ScpStream & script)698 	void DtaScript::parseEmbeddedScript(ScpStream& script) {
699 		if (!script.isEqualTo('{')) throw UtlException(script, "'{' expected to start an embedded script");
700 		_stackOfParsedBlocks.push_front(&_graph);
701 		betweenCommands(script, _graph);
702 		script.skipEmpty();
703 		while (!script.isEqualTo('}')) {
704 			parseInstruction(script, _graph);
705 			script.skipEmpty();
706 		}
707 		_stackOfParsedBlocks.pop_front();
708 	}
709 
beforeParsingABlock(ScpStream &,GrfBlock &)710 	void DtaScript::beforeParsingABlock(ScpStream& /*script*/, GrfBlock& /*block*/) {}
afterParsingABlock(ScpStream &,GrfBlock &)711 	void DtaScript::afterParsingABlock(ScpStream& /*script*/, GrfBlock& /*block*/) {}
712 
parseBlock(ScpStream & script,GrfBlock & block)713 	void DtaScript::parseBlock(ScpStream& script, GrfBlock& block) {
714 		script.skipEmpty();
715 		if (!script.isEqualTo('{')) {
716 			if (script.isEqualTo(';')) return;
717 			if (!betweenCommands(script, block)) {
718 				if (hasTargetLanguage()) {
719 					// alien programming language
720 					parseAlienInstruction(script, block);
721 				} else {
722 					// standard CodeWorker scripting
723 					std::string sCommand;
724 					script.skipEmpty();
725 					if (!script.readIdentifier(sCommand)) handleNotAWordCommand(script, block);
726 					else if (!parseKeyword(sCommand, script, block)) {
727 						handleUnknownCommand(sCommand, script, block);
728 					}
729 					script.skipEmpty();
730 				}
731 			}
732 		} else {
733 			_stackOfParsedBlocks.push_front(&block);
734 			beforeParsingABlock(script, block);
735 			if (hasTargetLanguage()) {
736 				// alien programming language
737 				script.goBack();
738 				parseAlienBlock(script, block);
739 			} else {
740 				betweenCommands(script, block);
741 				script.skipEmpty();
742 				while (!script.isEqualTo('}')) {
743 					if (!script.skipEmpty()) throw UtlException(script, "unexpected end of file: '}' expected");
744 					parseInstruction(script, block);
745 					script.skipEmpty();
746 				}
747 			}
748 			afterParsingABlock(script, block);
749 			_stackOfParsedBlocks.pop_front();
750 			betweenCommands(script, *(_stackOfParsedBlocks.front()));
751 		}
752 	}
753 
parseInstruction(ScpStream & script,GrfBlock & block)754 	void DtaScript::parseInstruction(ScpStream& script, GrfBlock& block) {
755 		std::string sCommand;
756 		script.skipEmpty();
757 		if (!script.readIdentifier(sCommand)) handleNotAWordCommand(script, block);
758 		else if (!parseKeyword(sCommand, script, block)) {
759 			handleUnknownCommand(sCommand, script, block);
760 		}
761 		script.skipEmpty();
762 		betweenCommands(script, block);
763 	}
764 
getAlienParser() const765 	DtaBNFScript& DtaScript::getAlienParser() const {
766 		DtaBNFScript* pScript = DtaProject::getInstance().getCommonAlienParser();
767 		if (pScript == NULL) throw UtlException("compiling a common script in " + _sTargetLanguage + " requires \"($CODEWORKER_HOME)/" + _sTargetLanguage + "/default-scripts/" + _sTargetLanguage + "CommonScript.cwp\"");
768 		return *pScript;
769 	}
770 
parseAlienInstructions(DtaScriptVariable & parseTree,ScpStream & script,GrfBlock & block)771 	void DtaScript::parseAlienInstructions(DtaScriptVariable& parseTree, ScpStream& script, GrfBlock& block) {
772 		const std::list<DtaScriptVariable*>* pInstructions = parseTree.getArray();
773 		if (pInstructions == NULL) return;
774 		for (std::list<DtaScriptVariable*>::const_iterator i = pInstructions->begin(); i != pInstructions->end(); ++i) {
775 			std::string sType = (*i)->getValue();
776 			if (sType == "alien") {
777 				DtaScriptVariable* pCode = (*i)->getNode("code");
778 				if (pCode == NULL) {
779 					throw UtlException(script, "instruction type 'alien' is expected to have the attribute 'code'");
780 				}
781 				DtaScriptVariable* pLine = (*i)->getNode("line");
782 				if (pLine == NULL) {
783 					throw UtlException(script, "instruction type 'alien' is expected to have the attribute 'line'");
784 				}
785 				GrfAlienInstruction* pAlien = new GrfAlienInstruction(_sTargetLanguage, pLine->getIntValue(), pCode->getValue());
786 				if (requiresParsingInformation()) pAlien->setParsingInformation(getFilenamePtr(), script);
787 				block.add(pAlien);
788 			} else if (sType == "write_alien_expr") {
789 				DtaScriptVariable* pCode = (*i)->getNode("code");
790 				if (pCode == NULL) {
791 					throw UtlException(script, "instruction type 'write_alien_expr' is expected to have the attribute 'code'");
792 				}
793 				GrfWriteText* pWriteText = new GrfWriteText;
794 				pWriteText->setText(new ExprScriptAlien(pCode->getValue(), _sTargetLanguage));
795 				if (requiresParsingInformation()) pWriteText->setParsingInformation(getFilenamePtr(), script);
796 				block.add(pWriteText);
797 			} else if (sType == "text") {
798 				DtaScriptVariable* pText = (*i)->getNode("text");
799 				if (pText == NULL) {
800 					throw UtlException(script, "instruction type 'text' is expected to have the attribute 'text'");
801 				}
802 				GrfWriteText* pWriteText = new GrfWriteText;
803 				pWriteText->setText(new ExprScriptConstant(pText->getValue()));
804 				if (requiresParsingInformation()) pWriteText->setParsingInformation(getFilenamePtr(), script);
805 				block.add(pWriteText);
806 			} else {
807 				throw UtlException(script, "unknown instruction type '" + sType + "' to add in the parse tree");
808 			}
809 		}
810 	}
811 
parseAlienExpression(DtaScriptVariable & parseTree,ScpStream & script,GrfBlock & block)812 	ExprScriptExpression* DtaScript::parseAlienExpression(DtaScriptVariable& parseTree, ScpStream& script, GrfBlock& block) {
813 		DtaScriptVariable* pExpression = parseTree.getNode("expression");
814 		if (pExpression == NULL) return NULL;
815 		ExprScriptExpression* pResult;
816 		std::string sType = pExpression->getValue();
817 		if (sType == "alien_expr") {
818 			DtaScriptVariable* pCode = pExpression->getNode("code");
819 			if (pCode == NULL) {
820 				throw UtlException(script, "Expression type 'alien_expr' is expected to have the attribute 'code'");
821 			}
822 			pResult = new ExprScriptAlien(pCode->getValue(), _sTargetLanguage);
823 		} else if (sType == "alien_variable_expr") {
824 			DtaScriptVariable* pCode = pExpression->getNode("code");
825 			if (pCode == NULL) {
826 				throw UtlException(script, "Expression type 'alien_variable_expr' is expected to have the attribute 'code'");
827 			}
828 			pResult = new ExprScriptAlienVariable(pCode->getValue(), _sTargetLanguage);
829 		} else {
830 			throw UtlException(script, "unknown Expression type '" + sType + "' to add in the parse tree");
831 		}
832 		return pResult;
833 	}
834 
parseAlienScript(ScpStream & script,GrfBlock & block)835 	void DtaScript::parseAlienScript(ScpStream& script, GrfBlock& block) {
836 		for (;;) {
837 			DtaScriptVariable parseTree(NULL, "parseTree");
838 			parseTree.insertNode("type")->setValue("script");
839 			getAlienParser().generate(script, parseTree);
840 			parseAlienInstructions(parseTree, script, block);
841 			if (!parseTree.getBooleanValue()) break;
842 			parseInstruction(script, block);
843 		}
844 	}
845 
parseAlienBlock(ScpStream & script,GrfBlock & block)846 	void DtaScript::parseAlienBlock(ScpStream& script, GrfBlock& block) {
847 		DtaScriptVariable parseTree(NULL, "parseTree");
848 		parseTree.insertNode("type")->setValue("block");
849 		getAlienParser().generate(script, parseTree);
850 		parseAlienInstructions(parseTree, script, block);
851 	}
852 
parseAlienInstruction(ScpStream & script,GrfBlock & block)853 	void DtaScript::parseAlienInstruction(ScpStream& script, GrfBlock& block) {
854 		DtaScriptVariable parseTree(NULL, "parseTree");
855 		parseTree.insertNode("type")->setValue("instruction");
856 		getAlienParser().generate(script, parseTree);
857 		parseAlienInstructions(parseTree, script, block);
858 	}
859 
parseAlienVariableExpression(GrfBlock & block,ScpStream & script)860 	ExprScriptVariable* DtaScript::parseAlienVariableExpression(GrfBlock& block, ScpStream& script) {
861 		DtaScriptVariable parseTree(NULL, "parseTree");
862 		parseTree.insertNode("type")->setValue("variable");
863 		getAlienParser().generate(script, parseTree);
864 		ExprScriptExpression* pResult = parseAlienExpression(parseTree, script, block);
865 		ExprScriptVariable* pVariable = dynamic_cast<ExprScriptVariable*>(pResult);
866 		if (pVariable == NULL) {
867 			if (pResult != NULL) {
868 				throw UtlException(script, "the target language parser should have returned a variable expression");
869 			}
870 		}
871 		return pVariable;
872 	}
873 
parseAlienExpression(GrfBlock & block,ScpStream & script)874 	ExprScriptExpression* DtaScript::parseAlienExpression(GrfBlock& block, ScpStream& script) {
875 		DtaScriptVariable parseTree(NULL, "parseTree");
876 		parseTree.insertNode("type")->setValue("expression");
877 		getAlienParser().generate(script, parseTree);
878 		return parseAlienExpression(parseTree, script, block);
879 	}
880 
parseConstantNodeExpression(GrfBlock & block,ScpStream & script)881 	ExprScriptExpression* DtaScript::parseConstantNodeExpression(GrfBlock& block, ScpStream& script) {
882 		// parse the tree and array part of the node, not the value
883 		if (!script.isEqualTo('{')) return NULL;
884 		std::auto_ptr<ExprScriptConstantTree> pConstantTree(new ExprScriptConstantTree);
885 		script.skipEmpty();
886 		if (!script.isEqualTo('}')) {
887 			int iDeprecatedSyntax = -1;
888 			do {
889 				script.skipEmpty();
890 				if (script.isEqualTo('.')) {
891 					if (iDeprecatedSyntax == 1) {
892 						throw UtlException(script, "syntax error: cannot melt both deprecated and legacy constant tree syntax");
893 					}
894 					iDeprecatedSyntax = 0;
895 					std::string sAttribute;
896 					if (!script.readIdentifier(sAttribute)) {
897 						throw UtlException(script, "syntax error: attribute name expected");
898 					}
899 					script.skipEmpty();
900 					if (!script.isEqualTo('=')) {
901 						throw UtlException(script, "syntax error: '=' expected");
902 					}
903 					script.skipEmpty();
904 					if (script.isEqualTo('&')) {
905 						script.skipEmpty();
906 						if (!script.isEqualToIdentifier("ref")) {
907 							throw UtlException(script, "syntax error: '&ref' expected to announce a reference node");
908 						}
909 						script.skipEmpty();
910 						ExprScriptVariable* pRefExpr = parseVariableExpression(block, script);
911 						pConstantTree->addAttribute("&"+sAttribute, pRefExpr);
912 					} else {
913 						pConstantTree->addAttribute(sAttribute, parseAssignmentExpression(block, script));
914 					}
915 				} else if (script.isEqualTo('[')) {
916 					if (iDeprecatedSyntax == 1) {
917 						throw UtlException(script, "syntax error: cannot melt both deprecated and legacy constant tree syntax");
918 					}
919 					iDeprecatedSyntax = 0;
920 					do {
921 						script.skipEmpty();
922 						if (iDeprecatedSyntax == 1) {
923 							throw UtlException(script, "syntax error: cannot melt both deprecated and legacy constant tree syntax");
924 						}
925 						iDeprecatedSyntax = 0;
926 						ExprScriptExpression* pItem = parseAssignmentExpression(block, script);
927 						if (pItem == NULL) {
928 							throw UtlException(script, "syntax error: key or item expression expected");
929 						}
930 						script.skipEmpty();
931 						if (script.isEqualTo(':')) {
932 							script.skipEmpty();
933 							ExprScriptExpression* pKey = pItem;
934 							if (dynamic_cast<ExprScriptConstantTree*>(pKey) != NULL) {
935 								delete pKey;
936 								throw UtlException(script, "syntax error: a dictionary key cannot be a constant tree");
937 							}
938 							pItem = parseAssignmentExpression(block, script);
939 							if (pItem == NULL) {
940 								delete pKey;
941 								throw UtlException(script, "syntax error: malformed item expression");
942 							}
943 							pConstantTree->addItem(pKey, pItem);
944 							script.skipEmpty();
945 						} else {
946 							pConstantTree->addItem(pItem);
947 						}
948 					} while (script.isEqualTo(','));
949 					if (!script.isEqualTo(']')) throw UtlException(script, "']' expected to end a constant array");
950 				} else {
951 					// deprecated way of descripting a constant tree
952 					if (iDeprecatedSyntax == 0) {
953 						throw UtlException(script, "syntax error: cannot melt both deprecated and legacy constant tree syntax");
954 					}
955 					iDeprecatedSyntax = 1;
956 					pConstantTree->addItem(parseAssignmentExpression(block, script));
957 				}
958 				script.skipEmpty();
959 			} while (script.isEqualTo(','));
960 			if (!script.isEqualTo('}')) throw UtlException(script, "'}' expected to end a constant tree");
961 		}
962 		return pConstantTree.release();
963 	}
964 
parseAssignmentExpression(GrfBlock & block,ScpStream & script)965 	ExprScriptExpression* DtaScript::parseAssignmentExpression(GrfBlock& block, ScpStream& script) {
966 		ExprScriptExpression* expr = NULL;
967 		if (script.peekChar() != '{') {
968 			expr = parseExpression(block, script);
969 		}
970 		ExprScriptConstantTree* pTree = (ExprScriptConstantTree*) parseConstantNodeExpression(block, script);
971 		if (pTree != NULL) {
972 			pTree->setValueExpression(expr);
973 			expr = pTree;
974 		}
975 		return expr;
976 	}
977 
getParsingFunctionRegister()978 	std::map<std::string, int>& DtaScript::getParsingFunctionRegister() {
979 		static std::map<std::string, int> _register;
980 		if (_register.empty()) {
981 			_register["foreach"] = 1;
982 			_register["if"] = 2;
983 			_register["do"] = 3;
984 			_register["switch"] = 4;
985 			_register["try"] = 5;
986 			_register["while"] = 6;
987 			_register["function"] = 7;
988 			_register["continue"] = 8;
989 			_register["break"] = 9;
990 			_register["finally"] = 10;
991 			_register["return"] = 11;
992 			_register["external"] = 12;
993 			_register["file_as_standard_input"] = 13;
994 			_register["string_as_standard_input"] = 14;
995 			_register["nop"] = 15;
996 			_register["declare"] = 16;
997 			_register["delay"] = 17;
998 			_register["debug"] = 18;
999 			_register["quantify"] = 19;
1000 			_register["quiet"] = 20;
1001 			_register["local"] = 21;
1002 			_register["localref"] = 22;
1003 			_register["set"] = 23;
1004 			_register["setall"] = 24;
1005 			_register["ref"] = 25;
1006 			_register["pushItem"] = 26;
1007 			_register["new_project"] = 27;
1008 			_register["generated_file"] = 28;
1009 			_register["appended_file"] = 29;
1010 			_register["generated_string"] = 30;
1011 			_register["forfile"] = 31;
1012 			_register["insert"] = 32;
1013 			_register["readonlyHook"] = 33;
1014 			_register["writefileHook"] = 34;
1015 			_register["merge"] = 35;
1016 			_register["parsed_file"] = 36;
1017 			_register["select"] = 37;
1018 			_register["global"] = 38;
1019 			_register["parsed_string"] = 39;
1020 			_register["exit"] = 40;
1021 			_register["class"] = 41;
1022 //##markup##"getParsingFunctionRegister()"
1023 //##begin##"getParsingFunctionRegister()"
1024 		if (_register.find("appendFile") != _register.end()) throw UtlException("DtaScript::getParsingFunctionRegister('appendFile') already exists");
1025 		_register["appendFile"] = 179126;
1026 		if (_register.find("autoexpand") != _register.end()) throw UtlException("DtaScript::getParsingFunctionRegister('autoexpand') already exists");
1027 		_register["autoexpand"] = 2911241;
1028 		if (_register.find("clearVariable") != _register.end()) throw UtlException("DtaScript::getParsingFunctionRegister('clearVariable') already exists");
1029 		_register["clearVariable"] = 7413225;
1030 		if (_register.find("compileToCpp") != _register.end()) throw UtlException("DtaScript::getParsingFunctionRegister('compileToCpp') already exists");
1031 		_register["compileToCpp"] = 18027701;
1032 		if (_register.find("copyFile") != _register.end()) throw UtlException("DtaScript::getParsingFunctionRegister('copyFile') already exists");
1033 		_register["copyFile"] = 2106257;
1034 		if (_register.find("copyGenerableFile") != _register.end()) throw UtlException("DtaScript::getParsingFunctionRegister('copyGenerableFile') already exists");
1035 		_register["copyGenerableFile"] = 9921918;
1036 		if (_register.find("copySmartDirectory") != _register.end()) throw UtlException("DtaScript::getParsingFunctionRegister('copySmartDirectory') already exists");
1037 		_register["copySmartDirectory"] = 18645881;
1038 		if (_register.find("cutString") != _register.end()) throw UtlException("DtaScript::getParsingFunctionRegister('cutString') already exists");
1039 		_register["cutString"] = 5833203;
1040 		if (_register.find("environTable") != _register.end()) throw UtlException("DtaScript::getParsingFunctionRegister('environTable') already exists");
1041 		_register["environTable"] = 19353497;
1042 		if (_register.find("error") != _register.end()) throw UtlException("DtaScript::getParsingFunctionRegister('error') already exists");
1043 		_register["error"] = 16784904;
1044 		if (_register.find("executeString") != _register.end()) throw UtlException("DtaScript::getParsingFunctionRegister('executeString') already exists");
1045 		_register["executeString"] = 10410726;
1046 		if (_register.find("expand") != _register.end()) throw UtlException("DtaScript::getParsingFunctionRegister('expand') already exists");
1047 		_register["expand"] = 5800090;
1048 		if (_register.find("extendExecutedScript") != _register.end()) throw UtlException("DtaScript::getParsingFunctionRegister('extendExecutedScript') already exists");
1049 		_register["extendExecutedScript"] = 11255540;
1050 		if (_register.find("generate") != _register.end()) throw UtlException("DtaScript::getParsingFunctionRegister('generate') already exists");
1051 		_register["generate"] = 3100533;
1052 		if (_register.find("generateString") != _register.end()) throw UtlException("DtaScript::getParsingFunctionRegister('generateString') already exists");
1053 		_register["generateString"] = 17410534;
1054 		if (_register.find("insertElementAt") != _register.end()) throw UtlException("DtaScript::getParsingFunctionRegister('insertElementAt') already exists");
1055 		_register["insertElementAt"] = 13901206;
1056 		if (_register.find("invertArray") != _register.end()) throw UtlException("DtaScript::getParsingFunctionRegister('invertArray') already exists");
1057 		_register["invertArray"] = 7040035;
1058 		if (_register.find("listAllGeneratedFiles") != _register.end()) throw UtlException("DtaScript::getParsingFunctionRegister('listAllGeneratedFiles') already exists");
1059 		_register["listAllGeneratedFiles"] = 3779115;
1060 		if (_register.find("loadProject") != _register.end()) throw UtlException("DtaScript::getParsingFunctionRegister('loadProject') already exists");
1061 		_register["loadProject"] = 15590483;
1062 		if (_register.find("openLogFile") != _register.end()) throw UtlException("DtaScript::getParsingFunctionRegister('openLogFile') already exists");
1063 		_register["openLogFile"] = 4625718;
1064 		if (_register.find("parseAsBNF") != _register.end()) throw UtlException("DtaScript::getParsingFunctionRegister('parseAsBNF') already exists");
1065 		_register["parseAsBNF"] = 8623893;
1066 		if (_register.find("parseStringAsBNF") != _register.end()) throw UtlException("DtaScript::getParsingFunctionRegister('parseStringAsBNF') already exists");
1067 		_register["parseStringAsBNF"] = 12713924;
1068 		if (_register.find("parseFree") != _register.end()) throw UtlException("DtaScript::getParsingFunctionRegister('parseFree') already exists");
1069 		_register["parseFree"] = 3007935;
1070 		if (_register.find("produceHTML") != _register.end()) throw UtlException("DtaScript::getParsingFunctionRegister('produceHTML') already exists");
1071 		_register["produceHTML"] = 2453643;
1072 		if (_register.find("putEnv") != _register.end()) throw UtlException("DtaScript::getParsingFunctionRegister('putEnv') already exists");
1073 		_register["putEnv"] = 18042462;
1074 		if (_register.find("randomSeed") != _register.end()) throw UtlException("DtaScript::getParsingFunctionRegister('randomSeed') already exists");
1075 		_register["randomSeed"] = 15941076;
1076 		if (_register.find("removeAllElements") != _register.end()) throw UtlException("DtaScript::getParsingFunctionRegister('removeAllElements') already exists");
1077 		_register["removeAllElements"] = 15019924;
1078 		if (_register.find("removeElement") != _register.end()) throw UtlException("DtaScript::getParsingFunctionRegister('removeElement') already exists");
1079 		_register["removeElement"] = 15071448;
1080 		if (_register.find("removeFirstElement") != _register.end()) throw UtlException("DtaScript::getParsingFunctionRegister('removeFirstElement') already exists");
1081 		_register["removeFirstElement"] = 19507408;
1082 		if (_register.find("removeLastElement") != _register.end()) throw UtlException("DtaScript::getParsingFunctionRegister('removeLastElement') already exists");
1083 		_register["removeLastElement"] = 18768482;
1084 		if (_register.find("removeRecursive") != _register.end()) throw UtlException("DtaScript::getParsingFunctionRegister('removeRecursive') already exists");
1085 		_register["removeRecursive"] = 5023246;
1086 		if (_register.find("removeVariable") != _register.end()) throw UtlException("DtaScript::getParsingFunctionRegister('removeVariable') already exists");
1087 		_register["removeVariable"] = 7468320;
1088 		if (_register.find("saveBinaryToFile") != _register.end()) throw UtlException("DtaScript::getParsingFunctionRegister('saveBinaryToFile') already exists");
1089 		_register["saveBinaryToFile"] = 3078933;
1090 		if (_register.find("saveProject") != _register.end()) throw UtlException("DtaScript::getParsingFunctionRegister('saveProject') already exists");
1091 		_register["saveProject"] = 18607068;
1092 		if (_register.find("saveProjectTypes") != _register.end()) throw UtlException("DtaScript::getParsingFunctionRegister('saveProjectTypes') already exists");
1093 		_register["saveProjectTypes"] = 730621;
1094 		if (_register.find("saveToFile") != _register.end()) throw UtlException("DtaScript::getParsingFunctionRegister('saveToFile') already exists");
1095 		_register["saveToFile"] = 14995060;
1096 		if (_register.find("setCommentBegin") != _register.end()) throw UtlException("DtaScript::getParsingFunctionRegister('setCommentBegin') already exists");
1097 		_register["setCommentBegin"] = 14972940;
1098 		if (_register.find("setCommentEnd") != _register.end()) throw UtlException("DtaScript::getParsingFunctionRegister('setCommentEnd') already exists");
1099 		_register["setCommentEnd"] = 9300734;
1100 		if (_register.find("setGenerationHeader") != _register.end()) throw UtlException("DtaScript::getParsingFunctionRegister('setGenerationHeader') already exists");
1101 		_register["setGenerationHeader"] = 3237703;
1102 		if (_register.find("setIncludePath") != _register.end()) throw UtlException("DtaScript::getParsingFunctionRegister('setIncludePath') already exists");
1103 		_register["setIncludePath"] = 5288747;
1104 		if (_register.find("setNow") != _register.end()) throw UtlException("DtaScript::getParsingFunctionRegister('setNow') already exists");
1105 		_register["setNow"] = 9162260;
1106 		if (_register.find("setProperty") != _register.end()) throw UtlException("DtaScript::getParsingFunctionRegister('setProperty') already exists");
1107 		_register["setProperty"] = 10303831;
1108 		if (_register.find("setTextMode") != _register.end()) throw UtlException("DtaScript::getParsingFunctionRegister('setTextMode') already exists");
1109 		_register["setTextMode"] = 3850482;
1110 		if (_register.find("setVersion") != _register.end()) throw UtlException("DtaScript::getParsingFunctionRegister('setVersion') already exists");
1111 		_register["setVersion"] = 12168214;
1112 		if (_register.find("setWriteMode") != _register.end()) throw UtlException("DtaScript::getParsingFunctionRegister('setWriteMode') already exists");
1113 		_register["setWriteMode"] = 5067744;
1114 		if (_register.find("setWorkingPath") != _register.end()) throw UtlException("DtaScript::getParsingFunctionRegister('setWorkingPath') already exists");
1115 		_register["setWorkingPath"] = 16222516;
1116 		if (_register.find("sleep") != _register.end()) throw UtlException("DtaScript::getParsingFunctionRegister('sleep') already exists");
1117 		_register["sleep"] = 9522647;
1118 		if (_register.find("slideNodeContent") != _register.end()) throw UtlException("DtaScript::getParsingFunctionRegister('slideNodeContent') already exists");
1119 		_register["slideNodeContent"] = 13707430;
1120 		if (_register.find("sortArray") != _register.end()) throw UtlException("DtaScript::getParsingFunctionRegister('sortArray') already exists");
1121 		_register["sortArray"] = 9410907;
1122 		if (_register.find("traceEngine") != _register.end()) throw UtlException("DtaScript::getParsingFunctionRegister('traceEngine') already exists");
1123 		_register["traceEngine"] = 13561575;
1124 		if (_register.find("traceLine") != _register.end()) throw UtlException("DtaScript::getParsingFunctionRegister('traceLine') already exists");
1125 		_register["traceLine"] = 16138969;
1126 		if (_register.find("traceObject") != _register.end()) throw UtlException("DtaScript::getParsingFunctionRegister('traceObject') already exists");
1127 		_register["traceObject"] = 8856036;
1128 		if (_register.find("traceStack") != _register.end()) throw UtlException("DtaScript::getParsingFunctionRegister('traceStack') already exists");
1129 		_register["traceStack"] = 7087939;
1130 		if (_register.find("traceText") != _register.end()) throw UtlException("DtaScript::getParsingFunctionRegister('traceText') already exists");
1131 		_register["traceText"] = 16373778;
1132 		if (_register.find("translate") != _register.end()) throw UtlException("DtaScript::getParsingFunctionRegister('translate') already exists");
1133 		_register["translate"] = 4934734;
1134 		if (_register.find("attachInputToSocket") != _register.end()) throw UtlException("DtaScript::getParsingFunctionRegister('attachInputToSocket') already exists");
1135 		_register["attachInputToSocket"] = 4116339;
1136 		if (_register.find("detachInputFromSocket") != _register.end()) throw UtlException("DtaScript::getParsingFunctionRegister('detachInputFromSocket') already exists");
1137 		_register["detachInputFromSocket"] = 16057876;
1138 		if (_register.find("goBack") != _register.end()) throw UtlException("DtaScript::getParsingFunctionRegister('goBack') already exists");
1139 		_register["goBack"] = 13375983;
1140 		if (_register.find("setInputLocation") != _register.end()) throw UtlException("DtaScript::getParsingFunctionRegister('setInputLocation') already exists");
1141 		_register["setInputLocation"] = 17901405;
1142 		if (_register.find("allFloatingLocations") != _register.end()) throw UtlException("DtaScript::getParsingFunctionRegister('allFloatingLocations') already exists");
1143 		_register["allFloatingLocations"] = 16157783;
1144 		if (_register.find("attachOutputToSocket") != _register.end()) throw UtlException("DtaScript::getParsingFunctionRegister('attachOutputToSocket') already exists");
1145 		_register["attachOutputToSocket"] = 2539668;
1146 		if (_register.find("detachOutputFromSocket") != _register.end()) throw UtlException("DtaScript::getParsingFunctionRegister('detachOutputFromSocket') already exists");
1147 		_register["detachOutputFromSocket"] = 10159185;
1148 		if (_register.find("incrementIndentLevel") != _register.end()) throw UtlException("DtaScript::getParsingFunctionRegister('incrementIndentLevel') already exists");
1149 		_register["incrementIndentLevel"] = 9232969;
1150 		if (_register.find("insertText") != _register.end()) throw UtlException("DtaScript::getParsingFunctionRegister('insertText') already exists");
1151 		_register["insertText"] = 2938502;
1152 		if (_register.find("insertTextOnce") != _register.end()) throw UtlException("DtaScript::getParsingFunctionRegister('insertTextOnce') already exists");
1153 		_register["insertTextOnce"] = 10767911;
1154 		if (_register.find("insertTextToFloatingLocation") != _register.end()) throw UtlException("DtaScript::getParsingFunctionRegister('insertTextToFloatingLocation') already exists");
1155 		_register["insertTextToFloatingLocation"] = 2074012;
1156 		if (_register.find("insertTextOnceToFloatingLocation") != _register.end()) throw UtlException("DtaScript::getParsingFunctionRegister('insertTextOnceToFloatingLocation') already exists");
1157 		_register["insertTextOnceToFloatingLocation"] = 19491581;
1158 		if (_register.find("overwritePortion") != _register.end()) throw UtlException("DtaScript::getParsingFunctionRegister('overwritePortion') already exists");
1159 		_register["overwritePortion"] = 4193756;
1160 		if (_register.find("populateProtectedArea") != _register.end()) throw UtlException("DtaScript::getParsingFunctionRegister('populateProtectedArea') already exists");
1161 		_register["populateProtectedArea"] = 19875729;
1162 		if (_register.find("resizeOutputStream") != _register.end()) throw UtlException("DtaScript::getParsingFunctionRegister('resizeOutputStream') already exists");
1163 		_register["resizeOutputStream"] = 3517365;
1164 		if (_register.find("setFloatingLocation") != _register.end()) throw UtlException("DtaScript::getParsingFunctionRegister('setFloatingLocation') already exists");
1165 		_register["setFloatingLocation"] = 11884637;
1166 		if (_register.find("setOutputLocation") != _register.end()) throw UtlException("DtaScript::getParsingFunctionRegister('setOutputLocation') already exists");
1167 		_register["setOutputLocation"] = 8004824;
1168 		if (_register.find("setProtectedArea") != _register.end()) throw UtlException("DtaScript::getParsingFunctionRegister('setProtectedArea') already exists");
1169 		_register["setProtectedArea"] = 14826777;
1170 		if (_register.find("writeBytes") != _register.end()) throw UtlException("DtaScript::getParsingFunctionRegister('writeBytes') already exists");
1171 		_register["writeBytes"] = 6512844;
1172 		if (_register.find("writeText") != _register.end()) throw UtlException("DtaScript::getParsingFunctionRegister('writeText') already exists");
1173 		_register["writeText"] = 16211116;
1174 		if (_register.find("writeTextOnce") != _register.end()) throw UtlException("DtaScript::getParsingFunctionRegister('writeTextOnce') already exists");
1175 		_register["writeTextOnce"] = 8521805;
1176 		if (_register.find("closeSocket") != _register.end()) throw UtlException("DtaScript::getParsingFunctionRegister('closeSocket') already exists");
1177 		_register["closeSocket"] = 19888011;
1178 //##end##"getParsingFunctionRegister()"
1179 		}
1180 		return _register;
1181 	}
1182 
parseKeyword(const std::string & sCommand,ScpStream & script,GrfBlock & block,ExprScriptVariable * pMethodCaller)1183 	bool DtaScript::parseKeyword(const std::string& sCommand, ScpStream& script, GrfBlock& block, ExprScriptVariable* pMethodCaller) {
1184 		std::map<std::string, int>::const_iterator cursor = getParsingFunctionRegister().find(sCommand);
1185 		bool bSuccess = (cursor != getParsingFunctionRegister().end());
1186 		if (bSuccess) {
1187 			switch(cursor->second) {
1188 				case  1: parseForeach(block, script);break;
1189 				case  2: parseIfThenElse(block, script);break;
1190 				case  3: parseDo(block, script);break;
1191 				case  4: parseSwitch(block, script);break;
1192 				case  5: parseTryCatch(block, script);break;
1193 				case  6: parseWhile(block, script);break;
1194 				case  7: parseFunction(block, script);break;
1195 				case  8: parseContinue(block, script);break;
1196 				case  9: parseBreak(block, script);break;
1197 				case 10: parseFinally(block, script);break;
1198 				case 11: parseReturn(block, script);break;
1199 				case 12: parseExternal(block, script);break;
1200 				case 13: parseFileAsStandardInput(block, script);break;
1201 				case 14: parseStringAsStandardInput(block, script);break;
1202 				case 15: parseNop(block, script);break;
1203 				case 16: parseDeclare(block, script);break;
1204 				case 17: parseDelay(block, script);break;
1205 				case 18: parseDebug(block, script);break;
1206 				case 19: parseQuantify(block, script);break;
1207 				case 20: parseQuiet(block, script);break;
1208 				case 21: parseLocalVariable(block, script);break;
1209 				case 22: parseLocalReference(block, script);break;
1210 				case 23: parseSetAssignment(block, script);break;
1211 				case 24: parseSetAll(block, script);break;
1212 				case 25: parseReference(block, script);break;
1213 				case 26: parsePushItem(block, script);break;
1214 				case 27: parseNewProject(block, script);break;
1215 				case 28: parseGeneratedFile(block, script);break;
1216 				case 29: parseAppendedFile(block, script);break;
1217 				case 30: parseGeneratedString(block, script);break;
1218 				case 31: parseForfile(block, script);break;
1219 				case 32: parseInsertAssignment(block, script);break;
1220 				case 33: parseReadonlyHook(block, script);break;
1221 				case 34: parseWritefileHook(block, script);break;
1222 				case 35: parseMerge(block, script);break;
1223 				case 36: parseParsedFile(block, script);break;
1224 				case 37: parseSelect(block, script);break;
1225 				case 38: parseGlobalVariable(block, script);break;
1226 				case 39: parseParsedString(block, script);break;
1227 				case 40: parseExit(block, script);break;
1228 				case 41: parseClass(block, script);break;
1229 //##markup##"parseKeyword()"
1230 //##begin##"parseKeyword()"
1231 			case 179126: parseAppendFile(block, script, pMethodCaller);break;
1232 			case 2911241: parseAutoexpand(block, script, pMethodCaller);break;
1233 			case 7413225: parseClearVariable(block, script, pMethodCaller);break;
1234 			case 18027701: parseCompileToCpp(block, script, pMethodCaller);break;
1235 			case 2106257: parseCopyFile(block, script, pMethodCaller);break;
1236 			case 9921918: parseCopyGenerableFile(block, script, pMethodCaller);break;
1237 			case 18645881: parseCopySmartDirectory(block, script, pMethodCaller);break;
1238 			case 5833203: parseCutString(block, script, pMethodCaller);break;
1239 			case 19353497: parseEnvironTable(block, script, pMethodCaller);break;
1240 			case 16784904: parseError(block, script, pMethodCaller);break;
1241 			case 10410726: parseExecuteString(block, script, pMethodCaller);break;
1242 			case 5800090: parseExpand(block, script, pMethodCaller);break;
1243 			case 11255540: parseExtendExecutedScript(block, script, pMethodCaller);break;
1244 			case 3100533: parseGenerate(block, script, pMethodCaller);break;
1245 			case 17410534: parseGenerateString(block, script, pMethodCaller);break;
1246 			case 13901206: parseInsertElementAt(block, script, pMethodCaller);break;
1247 			case 7040035: parseInvertArray(block, script, pMethodCaller);break;
1248 			case 3779115: parseListAllGeneratedFiles(block, script, pMethodCaller);break;
1249 			case 15590483: parseLoadProject(block, script, pMethodCaller);break;
1250 			case 4625718: parseOpenLogFile(block, script, pMethodCaller);break;
1251 			case 8623893: parseParseAsBNF(block, script, pMethodCaller);break;
1252 			case 12713924: parseParseStringAsBNF(block, script, pMethodCaller);break;
1253 			case 3007935: parseParseFree(block, script, pMethodCaller);break;
1254 			case 2453643: parseProduceHTML(block, script, pMethodCaller);break;
1255 			case 18042462: parsePutEnv(block, script, pMethodCaller);break;
1256 			case 15941076: parseRandomSeed(block, script, pMethodCaller);break;
1257 			case 15019924: parseRemoveAllElements(block, script, pMethodCaller);break;
1258 			case 15071448: parseRemoveElement(block, script, pMethodCaller);break;
1259 			case 19507408: parseRemoveFirstElement(block, script, pMethodCaller);break;
1260 			case 18768482: parseRemoveLastElement(block, script, pMethodCaller);break;
1261 			case 5023246: parseRemoveRecursive(block, script, pMethodCaller);break;
1262 			case 7468320: parseRemoveVariable(block, script, pMethodCaller);break;
1263 			case 3078933: parseSaveBinaryToFile(block, script, pMethodCaller);break;
1264 			case 18607068: parseSaveProject(block, script, pMethodCaller);break;
1265 			case 730621: parseSaveProjectTypes(block, script, pMethodCaller);break;
1266 			case 14995060: parseSaveToFile(block, script, pMethodCaller);break;
1267 			case 14972940: parseSetCommentBegin(block, script, pMethodCaller);break;
1268 			case 9300734: parseSetCommentEnd(block, script, pMethodCaller);break;
1269 			case 3237703: parseSetGenerationHeader(block, script, pMethodCaller);break;
1270 			case 5288747: parseSetIncludePath(block, script, pMethodCaller);break;
1271 			case 9162260: parseSetNow(block, script, pMethodCaller);break;
1272 			case 10303831: parseSetProperty(block, script, pMethodCaller);break;
1273 			case 3850482: parseSetTextMode(block, script, pMethodCaller);break;
1274 			case 12168214: parseSetVersion(block, script, pMethodCaller);break;
1275 			case 5067744: parseSetWriteMode(block, script, pMethodCaller);break;
1276 			case 16222516: parseSetWorkingPath(block, script, pMethodCaller);break;
1277 			case 9522647: parseSleep(block, script, pMethodCaller);break;
1278 			case 13707430: parseSlideNodeContent(block, script, pMethodCaller);break;
1279 			case 9410907: parseSortArray(block, script, pMethodCaller);break;
1280 			case 13561575: parseTraceEngine(block, script, pMethodCaller);break;
1281 			case 16138969: parseTraceLine(block, script, pMethodCaller);break;
1282 			case 8856036: parseTraceObject(block, script, pMethodCaller);break;
1283 			case 7087939: parseTraceStack(block, script, pMethodCaller);break;
1284 			case 16373778: parseTraceText(block, script, pMethodCaller);break;
1285 			case 4934734: parseTranslate(block, script, pMethodCaller);break;
1286 			case 4116339: parseAttachInputToSocket(block, script, pMethodCaller);break;
1287 			case 16057876: parseDetachInputFromSocket(block, script, pMethodCaller);break;
1288 			case 13375983: parseGoBack(block, script, pMethodCaller);break;
1289 			case 17901405: parseSetInputLocation(block, script, pMethodCaller);break;
1290 			case 16157783: parseAllFloatingLocations(block, script, pMethodCaller);break;
1291 			case 2539668: parseAttachOutputToSocket(block, script, pMethodCaller);break;
1292 			case 10159185: parseDetachOutputFromSocket(block, script, pMethodCaller);break;
1293 			case 9232969: parseIncrementIndentLevel(block, script, pMethodCaller);break;
1294 			case 2938502: parseInsertText(block, script, pMethodCaller);break;
1295 			case 10767911: parseInsertTextOnce(block, script, pMethodCaller);break;
1296 			case 2074012: parseInsertTextToFloatingLocation(block, script, pMethodCaller);break;
1297 			case 19491581: parseInsertTextOnceToFloatingLocation(block, script, pMethodCaller);break;
1298 			case 4193756: parseOverwritePortion(block, script, pMethodCaller);break;
1299 			case 19875729: parsePopulateProtectedArea(block, script, pMethodCaller);break;
1300 			case 3517365: parseResizeOutputStream(block, script, pMethodCaller);break;
1301 			case 11884637: parseSetFloatingLocation(block, script, pMethodCaller);break;
1302 			case 8004824: parseSetOutputLocation(block, script, pMethodCaller);break;
1303 			case 14826777: parseSetProtectedArea(block, script, pMethodCaller);break;
1304 			case 6512844: parseWriteBytes(block, script, pMethodCaller);break;
1305 			case 16211116: parseWriteText(block, script, pMethodCaller);break;
1306 			case 8521805: parseWriteTextOnce(block, script, pMethodCaller);break;
1307 			case 19888011: parseCloseSocket(block, script, pMethodCaller);break;
1308 //##end##"parseKeyword()"
1309 				default:
1310 					throw UtlException("DtaScript::parseKeyword() unhandled command");
1311 			}
1312 		} else if (sCommand == "include") {
1313 			std::string sErrorMessage = "warning: procedure-like syntax of the 'include' directive is obsolete since version 1.40 -> replace it by the preprocessor directive '#include'" + CGRuntime::endl();
1314 			sErrorMessage += UtlTrace::getTraceStack();
1315 			if (DtaProject::getInstance().addWarning(sErrorMessage) == 1) CGRuntime::traceLine(sErrorMessage);
1316 			script.skipEmpty();
1317 			if (!script.isEqualTo('(')) throw UtlException(script, "syntax error: '(' expected");
1318 			script.skipEmpty();
1319 			std::string sScriptFileName;
1320 			if (!script.readString(sScriptFileName)) throw UtlException(script, "syntax error: constant string expected");
1321 			script.skipEmpty();
1322 			if (!script.isEqualTo(')')) throw UtlException(script, "syntax error: ')' expected");
1323 			script.skipEmpty();
1324 			if (!script.isEqualTo(';')) throw UtlException(script, "syntax error: ';' expected");
1325 			parseFile(sScriptFileName.c_str(), &block);
1326 			bSuccess = true;
1327 //##markup##"parseKeyword()::deprecated"
1328 //##begin##"parseKeyword()::deprecated"
1329 	} else if (sCommand == "clearNode") {
1330 		std::string sErrorMessage = "warning: procedure 'clearNode' has been deprecated since version 3.8.7 -> replace it by procedure 'clearVariable'" + CGRuntime::endl();
1331 		sErrorMessage += UtlTrace::getTraceStack();
1332 		if (DtaProject::getInstance().addWarning(sErrorMessage) == 1) CGRuntime::traceLine(sErrorMessage);
1333 		parseClearVariable(block, script, pMethodCaller);
1334 		bSuccess = true;
1335 	} else if (sCommand == "loadDesign") {
1336 		std::string sErrorMessage = "warning: procedure 'loadDesign' has been deprecated since version 1.6 -> replace it by procedure 'parseFree'" + CGRuntime::endl();
1337 		sErrorMessage += UtlTrace::getTraceStack();
1338 		if (DtaProject::getInstance().addWarning(sErrorMessage) == 1) CGRuntime::traceLine(sErrorMessage);
1339 		parseParseFree(block, script, pMethodCaller);
1340 		bSuccess = true;
1341 	} else if (sCommand == "setDefineTarget") {
1342 		std::string sErrorMessage = "warning: procedure 'setDefineTarget' has been deprecated since version 1.30 -> replace it by procedure 'setProperty'" + CGRuntime::endl();
1343 		sErrorMessage += UtlTrace::getTraceStack();
1344 		if (DtaProject::getInstance().addWarning(sErrorMessage) == 1) CGRuntime::traceLine(sErrorMessage);
1345 		parseSetProperty(block, script, pMethodCaller);
1346 		bSuccess = true;
1347 	} else if (sCommand == "setLocation") {
1348 		std::string sErrorMessage = "warning: procedure 'setLocation' has been deprecated since version 3.7.1 -> replace it by procedure 'setInputLocation'" + CGRuntime::endl();
1349 		sErrorMessage += UtlTrace::getTraceStack();
1350 		if (DtaProject::getInstance().addWarning(sErrorMessage) == 1) CGRuntime::traceLine(sErrorMessage);
1351 		parseSetInputLocation(block, script, pMethodCaller);
1352 		bSuccess = true;
1353 //##end##"parseKeyword()::deprecated"
1354 		}
1355 		return bSuccess;
1356 	}
1357 
parseForeachListDeclaration(GrfBlock & block,ScpStream & script,GrfForeach * pForeach)1358 	void DtaScript::parseForeachListDeclaration(GrfBlock& block, ScpStream& script, GrfForeach* pForeach) {
1359 		script.skipEmpty();
1360 		pForeach->setIndex(parseIndexExpression(block, script));
1361 		script.skipEmpty();
1362 		if (!script.isEqualToIdentifier("in")) throw UtlException(script, "syntax error, 'in' expected");
1363 		script.skipEmpty();
1364 		for (;;) {
1365 			if (script.isEqualToIdentifier("sorted")) {
1366 				if (pForeach->getSorted()) throw UtlException(script, "'sorted' encountered twice");
1367 				script.skipEmpty();
1368 				if (script.isEqualToIdentifier("no_case")) pForeach->setSortedNoCase(true);
1369 				else pForeach->setSorted(true);
1370 			} else if (script.isEqualToIdentifier("reverse")) {
1371 				pForeach->setReverse(true);
1372 			} else if (script.isEqualToIdentifier("cascading")) {
1373 				if (pForeach->getCascading() != GrfForeach::NO_CASCADING) throw UtlException(script, "'cascading' encountered twice");
1374 				script.skipEmpty();
1375 				if (script.isEqualToIdentifier("first")) pForeach->setCascading(GrfForeach::CASCADING_FIRST);
1376 				else if (script.isEqualToIdentifier("last")) pForeach->setCascading(GrfForeach::CASCADING_LAST);
1377 				else pForeach->setCascading(GrfForeach::CASCADING_LAST);
1378 			} else if (script.isEqualToIdentifier("by_value")) {
1379 				if (!pForeach->getSorted()) throw UtlException(script, "'sorted' keywork expected before 'by_value'");
1380 				pForeach->setSortOnValue(true);
1381 			} else break;
1382 			script.skipEmpty();
1383 		}
1384 		pForeach->setList(parseVariableExpression(block, script));
1385 	}
1386 
parseForeach(GrfBlock & block,ScpStream & script)1387 	void DtaScript::parseForeach(GrfBlock& block, ScpStream& script) {
1388 		GrfForeach* pForeach = new GrfForeach(&block);
1389 		if (requiresParsingInformation()) pForeach->setParsingInformation(getFilenamePtr(), script);
1390 		block.add(pForeach);
1391 		parseForeachListDeclaration(block, script, pForeach);
1392 		parseBlock(script, *pForeach);
1393 	}
1394 
parseSelect(GrfBlock & block,ScpStream & script)1395 	void DtaScript::parseSelect(GrfBlock& block, ScpStream& script) {
1396 		GrfSelect* pSelect = new GrfSelect(&block);
1397 		if (requiresParsingInformation()) pSelect->setParsingInformation(getFilenamePtr(), script);
1398 		block.add(pSelect);
1399 		script.skipEmpty();
1400 		pSelect->setIndex(parseIndexExpression(block, script));
1401 		script.skipEmpty();
1402 		if (!script.isEqualToIdentifier("in")) throw UtlException(script, "syntax error, 'in' expected");
1403 		script.skipEmpty();
1404 		for (;;) {
1405 			if (script.isEqualToIdentifier("sorted")) {
1406 				throw UtlException("select-sorted not implemented yet!");
1407 			} else break;
1408 			script.skipEmpty();
1409 		}
1410 		pSelect->setMotif(parseMotifExpression(block, script));
1411 		parseBlock(script, *pSelect);
1412 	}
1413 
parseForfile(GrfBlock & block,ScpStream & script)1414 	void DtaScript::parseForfile(GrfBlock& block, ScpStream& script) {
1415 		script.skipEmpty();
1416 		std::auto_ptr<ExprScriptVariable> pIndex(parseIndexExpression(block, script));
1417 		script.skipEmpty();
1418 		if (!script.isEqualToIdentifier("in")) throw UtlException(script, "syntax error, 'in' expected");
1419 		script.skipEmpty();
1420 		bool bSorted = false;
1421 		bool bNoCase = false;
1422 		GrfForeach::CASCADING iCascading = GrfForeach::NO_CASCADING;
1423 		for (;;) {
1424 			if (script.isEqualToIdentifier("sorted")) {
1425 				if (bSorted) throw UtlException(script, "'sorted' encountered twice");
1426 				script.skipEmpty();
1427 				bSorted = true;
1428 				if (script.isEqualToIdentifier("no_case")) bNoCase = true;
1429 			} else if (script.isEqualToIdentifier("cascading")) {
1430 				if (iCascading != GrfForeach::NO_CASCADING) throw UtlException(script, "'cascading' encountered twice");
1431 				script.skipEmpty();
1432 				if (script.isEqualToIdentifier("first")) iCascading = GrfForeach::CASCADING_FIRST;
1433 				else if (script.isEqualToIdentifier("last")) iCascading = GrfForeach::CASCADING_LAST;
1434 				else iCascading = GrfForeach::CASCADING_LAST;
1435 			} else break;
1436 			script.skipEmpty();
1437 		}
1438 		std::auto_ptr<ExprScriptExpression> pPattern(parseExpression(block, script));
1439 		char tcCursor[32];
1440 		sprintf(tcCursor, "%d", script.getInputLocation());
1441 		std::string sCursor = tcCursor;
1442 		ScpStream theStream;
1443 		std::string sPattern = "_compilerForfile_pattern" + sCursor;
1444 		std::string sPosition = "_compilerForfile_position" + sCursor;
1445 		std::string sTmpPosition = "_compilerForfile_tmpPosition" + sCursor;
1446 		std::string sPath = "_compilerForfile_path" + sCursor;
1447 		std::string sFiles = "_compilerForfile_files" + sCursor;
1448 		theStream << "\tlocal " << sPattern << " = " << pPattern->toString() << ";\n";
1449 		theStream << "\tlocal " << sPosition << " = findLastString(" << sPattern << ", \"\\\\\");\n";
1450 		theStream << "\tlocal " << sTmpPosition << " = findLastString(" << sPattern << ", \"/\");\n";
1451 		theStream << "\tif $" << sTmpPosition << " > " << sPosition << "$ set " << sPosition << " = " << sTmpPosition << ";\n";
1452 		theStream << "\tlocal " << sPath << ";\n";
1453 		theStream << "\tif isPositive(" << sPosition << ") {\n";
1454 		theStream << "\t\tset " << sPath << " = leftString(" << sPattern << ", " << sPosition << ");\n";
1455 		theStream << "\t\tset " << sPattern << " = subString(" << sPattern << ", $" << sPosition << " + 1$);\n";
1456 		theStream << "\t}\n";
1457 		theStream << "\tlocal " << sFiles << ";\n";
1458 		if (iCascading == GrfForeach::NO_CASCADING) {
1459 			theStream << "\tscanFiles(" << sFiles << ", "  << sPath << ", " << sPattern << ", false);\n";
1460 			theStream << "\tforeach " << pIndex->toString() << " in ";
1461 			if (bSorted) {
1462 				theStream << "sorted ";
1463 				if (bNoCase) theStream << "no_case ";
1464 			}
1465 			theStream << sFiles << " ;\n";
1466 		} else {
1467 			std::string sDirectories = sFiles + ".directories";
1468 			std::string sIndex = "_compilerForfile_index" + sCursor;
1469 			theStream << "\tpushItem " << sDirectories << ";\n";
1470 			theStream << "\tscanDirectories(" << sDirectories << "#front, "  << sPath << ", " << sPattern << ");\n";
1471 			theStream << "\tforeach " << sIndex << " in cascading ";
1472 			if (bSorted) {
1473 				theStream << "sorted ";
1474 				if (bNoCase) theStream << "no_case ";
1475 			}
1476 			theStream << sDirectories << "{\n";
1477 			theStream << "\t\tforeach " << pIndex->toString() << " in ";
1478 			if (bSorted) {
1479 				theStream << "sorted ";
1480 				if (bNoCase) theStream << "no_case ";
1481 			}
1482 			theStream << sIndex << ".files {\n";
1483 			theStream << "\t\t\tlocal _compilerForfile_file = " << sIndex << " + " << pIndex->toString() << ";\n";
1484 			theStream << "\t\t\tinsert " << sIndex << ".list[_compilerForfile_file] = _compilerForfile_file;\n";
1485 			theStream << "\t\t}\n";
1486 			theStream << "\t\tforeach " << pIndex->toString() << " in ";
1487 			theStream << sIndex << ".list ;\n";
1488 			theStream << "\t}\n";
1489 		}
1490 		bool bRequiresParsingInformation = requiresParsingInformation();
1491 		try {
1492 			requiresParsingInformation(false);
1493 			parseScript(theStream, block);
1494 			requiresParsingInformation(bRequiresParsingInformation);
1495 		} catch(UtlException& exception) {
1496 			requiresParsingInformation(bRequiresParsingInformation);
1497 			std::string sMessage = "internal error while parsing the following expanded expression of 'forfile':" + CGRuntime::endl();
1498 			sMessage += theStream.readBuffer();
1499 			sMessage += exception.getMessage();
1500 			throw UtlException(exception.getTraceStack(), sMessage);
1501 		}
1502 		GrfForeach* pForeach = dynamic_cast<GrfForeach*>(block.getCommands()[block.getNbCommands() - 1]);
1503 		if (pForeach == NULL) throw UtlException(script, "internal error on parsing of 'forfile'");
1504 		if (iCascading != GrfForeach::NO_CASCADING) {
1505 			pForeach = dynamic_cast<GrfForeach*>(pForeach->getCommands()[pForeach->getNbCommands() - 1]);
1506 			if (pForeach == NULL) throw UtlException(script, "internal error on parsing of 'forfile'");
1507 		}
1508 		if (requiresParsingInformation()) pForeach->setParsingInformation(getFilenamePtr(), script);
1509 		parseBlock(script, *pForeach);
1510 	}
1511 
parseDo(GrfBlock & block,ScpStream & script)1512 	void DtaScript::parseDo(GrfBlock& block, ScpStream& script) {
1513 		GrfDo* pDo = new GrfDo(&block);
1514 		if (requiresParsingInformation()) pDo->setParsingInformation(getFilenamePtr(), script);
1515 		block.add(pDo);
1516 		parseBlock(script, *pDo);
1517 		script.skipEmpty();
1518 		std::string sWord;
1519 		if (!script.readIdentifier(sWord)) throw UtlException(script, "syntax error, 'while' expected after a 'do' statement");
1520 		pDo->setCondition(parseExpression(block, script));
1521 		script.skipEmpty();
1522 		if (!script.isEqualTo(';')) throw UtlException(script, "syntax error, ';' expected");
1523 	}
1524 
parseWhile(GrfBlock & block,ScpStream & script)1525 	void DtaScript::parseWhile(GrfBlock& block, ScpStream& script) {
1526 		GrfWhile* pWhile = new GrfWhile(&block);
1527 		if (requiresParsingInformation()) pWhile->setParsingInformation(getFilenamePtr(), script);
1528 		block.add(pWhile);
1529 		script.skipEmpty();
1530 		pWhile->setCondition(parseExpression(block, script));
1531 		parseBlock(script, *pWhile);
1532 	}
1533 
parseSwitch(GrfBlock & block,ScpStream & script)1534 	void DtaScript::parseSwitch(GrfBlock& block, ScpStream& script) {
1535 		GrfSwitch* pSwitch = new GrfSwitch(&block);
1536 		if (requiresParsingInformation()) pSwitch->setParsingInformation(getFilenamePtr(), script);
1537 		block.add(pSwitch);
1538 		script.skipEmpty();
1539 		if (!script.isEqualTo('(')) throw UtlException(script, "syntax error, '(' expected");
1540 		pSwitch->setExpression(parseExpression(block, script));
1541 		if (!script.isEqualTo(')')) throw UtlException(script, "syntax error, ')' expected");
1542 		script.skipEmpty();
1543 		if (!script.isEqualTo('{')) throw UtlException(script, "syntax error, '}' expected");
1544 		script.skipEmpty();
1545 		bool bDefault = false;
1546 		_stackOfParsedBlocks.push_front(pSwitch);
1547 		beforeParsingABlock(script, *pSwitch);
1548 		while (!script.isEqualTo('}')) {
1549 			std::string sWord;
1550 			if ((!script.readIdentifier(sWord)) || ((sWord != "case") && (sWord != "start") && (sWord != "default"))) {
1551 				if (bDefault) throw UtlException(script, "syntax error, 'case' or 'start' expected");
1552 				else throw UtlException(script, "syntax error, 'case', 'start' or 'default' expected");
1553 			}
1554 			if (sWord == "default") {
1555 				pSwitch->insertDefault();
1556 			} else {
1557 				std::string sConstant;
1558 				script.skipEmpty();
1559 				if (!script.readStringOrCharLiteral(sConstant)) throw UtlException(script, "syntax error, constant string expected after a '" + sWord + "'");
1560 				if (sWord == "case") {
1561 					if (pSwitch->equalString(sConstant.c_str())) throw UtlException(script, "syntax error, constant string \"" + sConstant + "\" already registered as a 'case'");
1562 					pSwitch->insertEqualString(sConstant.c_str());
1563 				} else {
1564 					if (pSwitch->startString(sConstant.c_str())) throw UtlException(script, "syntax error, constant string \"" + sConstant + "\" already registered as a 'start'");
1565 					pSwitch->insertStartString(sConstant.c_str());
1566 				}
1567 			}
1568 			script.skipEmpty();
1569 			if (!script.isEqualTo(':')) throw UtlException(script, "syntax error, ':' expected after a '" + sWord + "'");
1570 			script.skipEmpty();
1571 			betweenCommands(script, *pSwitch);
1572 			while (script.peekChar() != (int) '}') {
1573 				if (script.readIdentifier(sWord)) {
1574 					script.setInputLocation(script.getInputLocation() - sWord.size());
1575 					if ((sWord == "case") || (sWord == "start")) break;
1576 					if (sWord == "default") {
1577 						if (bDefault) throw UtlException(script, "'default' statement already defined");
1578 						bDefault = true;
1579 						break;
1580 					}
1581 				}
1582 				parseInstruction(script, *pSwitch);
1583 				script.skipEmpty();
1584 			}
1585 		}
1586 		afterParsingABlock(script, *pSwitch);
1587 		_stackOfParsedBlocks.pop_front();
1588 	}
1589 
parseTryCatch(GrfBlock & block,ScpStream & script)1590 	void DtaScript::parseTryCatch(GrfBlock& block, ScpStream& script) {
1591 		GrfTryCatch* pTryCatch = new GrfTryCatch;
1592 		if (requiresParsingInformation()) pTryCatch->setParsingInformation(getFilenamePtr(), script);
1593 		block.add(pTryCatch);
1594 		script.skipEmpty();
1595 		GrfBlock* pTryBlock = new GrfBlock(&block);
1596 		if (requiresParsingInformation()) pTryBlock->setParsingInformation(getFilenamePtr(), script);
1597 		pTryCatch->setTryBlock(pTryBlock);
1598 		parseBlock(script, *pTryBlock);
1599 		script.skipEmpty();
1600 		std::string sWord;
1601 		if (!script.readIdentifier(sWord)|| (sWord != "catch")) throw UtlException(script, "syntax error, 'catch' expected");
1602 		script.skipEmpty();
1603 		if (!script.isEqualTo('(')) throw UtlException(script, "syntax error, '(' expected after a 'catch'");
1604 		script.skipEmpty();
1605 		std::string sVariableName;
1606 		if (script.readIdentifier(sVariableName)) {
1607 			if (block.getVariable(sVariableName) == UNKNOWN_EXPRTYPE) block.addLocalVariable(sVariableName, VALUE_EXPRTYPE);
1608 			pTryCatch->setErrorVariable(parseVariableExpression(block, script, new ExprScriptVariable(sVariableName.c_str())));
1609 		} else {
1610 			pTryCatch->setErrorVariable(parseVariableExpression(block, script));
1611 		}
1612 		script.skipEmpty();
1613 		if (!script.isEqualTo(')')) throw UtlException(script, "syntax error, ')' expected after a 'catch'");
1614 		script.skipEmpty();
1615 		GrfBlock* pCatchBlock = new GrfBlock(&block);
1616 		if (requiresParsingInformation()) pCatchBlock->setParsingInformation(getFilenamePtr(), script);
1617 		pTryCatch->setCatchBlock(pCatchBlock);
1618 		parseBlock(script, *pCatchBlock);
1619 	}
1620 
parseIfThenElse(GrfBlock & block,ScpStream & script)1621 	void DtaScript::parseIfThenElse(GrfBlock& block, ScpStream& script) {
1622 		GrfIfThenElse* pIfThenElse = new GrfIfThenElse;
1623 		if (requiresParsingInformation()) pIfThenElse->setParsingInformation(getFilenamePtr(), script);
1624 		block.add(pIfThenElse);
1625 		script.skipEmpty();
1626 		pIfThenElse->setCondition(parseExpression(block, script));
1627 		script.skipEmpty();
1628 		GrfBlock* pThenBlock = new GrfBlock(&block);
1629 		if (requiresParsingInformation()) pThenBlock->setParsingInformation(getFilenamePtr(), script);
1630 		pIfThenElse->setThenBlock(pThenBlock);
1631 		parseBlock(script, *pThenBlock);
1632 		script.skipEmpty();
1633 		std::string sWord;
1634 		if (script.readIdentifier(sWord)) {
1635 			if (sWord == "else") {
1636 				script.skipEmpty();
1637 				GrfBlock* pElseBlock = new GrfBlock(&block);
1638 				if (requiresParsingInformation()) pElseBlock->setParsingInformation(getFilenamePtr(), script);
1639 				pIfThenElse->setElseBlock(pElseBlock);
1640 				parseBlock(script, *pElseBlock);
1641 			} else {
1642 				script.setInputLocation(script.getInputLocation() - sWord.size());
1643 			}
1644 		}
1645 	}
1646 
parseContinue(GrfBlock & block,ScpStream & script)1647 	void DtaScript::parseContinue(GrfBlock& block, ScpStream& script) {
1648 		GrfContinue* pContinue = new GrfContinue;
1649 		if (requiresParsingInformation()) pContinue->setParsingInformation(getFilenamePtr(), script);
1650 		block.add(pContinue);
1651 		script.skipEmpty();
1652 		if (!script.isEqualTo(';')) throw UtlException(script, "syntax error, ';' expected");
1653 	}
1654 
parseBreak(GrfBlock & block,ScpStream & script)1655 	void DtaScript::parseBreak(GrfBlock& block, ScpStream& script) {
1656 		GrfBreak* pBreak = new GrfBreak;
1657 		if (requiresParsingInformation()) pBreak->setParsingInformation(getFilenamePtr(), script);
1658 		block.add(pBreak);
1659 		script.skipEmpty();
1660 		if (!script.isEqualTo(';')) throw UtlException(script, "syntax error, ';' expected");
1661 	}
1662 
parseFinally(GrfBlock & block,ScpStream & script)1663 	void DtaScript::parseFinally(GrfBlock& block, ScpStream& script) {
1664 		if (_sCurrentFunctionBody.empty()) throw UtlException(script, "'finally' must be called inside a function's body!");
1665 		std::auto_ptr<ExprScriptFunction> pFuncExpr(ExprScriptFunction::create(block, script, _sCurrentFunctionBody, _sCurrentFunctionTemplateBody, _bCurrentFunctionGenericTemplateKey));
1666 		GrfFunction* pFunction = pFuncExpr->getUserBody();
1667 		if (pFunction->getFinally() != NULL) {
1668 			std::string sMessage = "an occurrence of 'finally' already exists inside function \"" + _sCurrentFunctionBody;
1669 			if (_sCurrentFunctionTemplateBody.empty()) sMessage += "\"";
1670 			else if (_bCurrentFunctionGenericTemplateKey) sMessage += "<" + _sCurrentFunctionTemplateBody + ">";
1671 			else sMessage += "<\"" + _sCurrentFunctionTemplateBody + "\">";
1672 			throw UtlException(script, sMessage);
1673 		}
1674 		GrfBlock* pFinallyBlock = new GrfBlock(pFunction);
1675 		if (requiresParsingInformation()) pFinallyBlock->setParsingInformation(getFilenamePtr(), script);
1676 		pFunction->setFinally(pFinallyBlock);
1677 		parseBlock(script, *pFinallyBlock);
1678 	}
1679 
parseReturn(GrfBlock & block,ScpStream & script)1680 	void DtaScript::parseReturn(GrfBlock& block, ScpStream& script) {
1681 		if (_sCurrentFunctionBody.empty()) throw UtlException(script, "'return' must be called inside a function's body!");
1682 		GrfReturn* pReturn = new GrfReturn(_sCurrentFunctionBody.c_str());
1683 		if (requiresParsingInformation()) pReturn->setParsingInformation(getFilenamePtr(), script);
1684 		block.add(pReturn);
1685 		script.skipEmpty();
1686 		if (!script.isEqualTo(';')) {
1687 			pReturn->setExpression(parseExpression(block, script));
1688 			script.skipEmpty();
1689 			if (!script.isEqualTo(';')) throw UtlException(script, "syntax error, ';' expected");
1690 		}
1691 	}
1692 
parseExit(GrfBlock & block,ScpStream & script)1693 	void DtaScript::parseExit(GrfBlock& block, ScpStream& script) {
1694 		GrfExit* pExit = new GrfExit;
1695 		if (requiresParsingInformation()) pExit->setParsingInformation(getFilenamePtr(), script);
1696 		block.add(pExit);
1697 		script.skipEmpty();
1698 		pExit->setCode(parseExpression(block, script));
1699 		script.skipEmpty();
1700 		if (!script.isEqualTo(';')) throw UtlException(script, "syntax error, ';' expected");
1701 	}
1702 
parseDeclare(GrfBlock & block,ScpStream & script)1703 	void DtaScript::parseDeclare(GrfBlock& block, ScpStream& script) {
1704 		std::string sWord;
1705 		script.skipEmpty();
1706 		if (!script.readIdentifier(sWord)) throw UtlException(script, "syntax error, type of declaration expected");
1707 		if (sWord == "function") {
1708 			parseFunction(block, script, true);
1709 		} else throw UtlException(script, std::string("unknown type of declaration: \"") + sWord + "\"");
1710 		script.skipEmpty();
1711 		if (!script.isEqualTo(';')) throw UtlException(script, "syntax error, ';' expected");
1712 	}
1713 
parseExternal(GrfBlock & block,ScpStream & script)1714 	void DtaScript::parseExternal(GrfBlock& block, ScpStream& script) {
1715 		std::string sWord;
1716 		script.skipEmpty();
1717 		if (!script.readIdentifier(sWord)) throw UtlException(script, "syntax error, type of external expected");
1718 		if (sWord == "function") {
1719 			GrfFunction* pFunction = parseFunction(block, script, true);
1720 			if (pFunction->isBodyDefined()) throw UtlException(script, "syntax error, function \"" + pFunction->getName() + "\" is expected external, but it has already a body");
1721 			if (!pFunction->isExternal()) {
1722 				pFunction->isExternal(true);
1723 				Workspace::addExternalFunction(pFunction);
1724 			}
1725 			if (pFunction->getTemplateFunction() != NULL) {
1726 				if (pFunction->getTemplateFunction()->isBodyDefined()) throw UtlException(script, "syntax error, function \"" + pFunction->getName() + "\" is expected external, but it has already a body");
1727 				if (!pFunction->getTemplateFunction()->isExternal()) {
1728 					pFunction->getTemplateFunction()->isExternal(true);
1729 					Workspace::addExternalFunction(pFunction->getTemplateFunction());
1730 				}
1731 			}
1732 		} else throw UtlException(script, std::string("unknown type of declaration: \"") + sWord + "\"");
1733 		script.skipEmpty();
1734 		if (!script.isEqualTo(';')) throw UtlException(script, "syntax error, ';' expected");
1735 	}
1736 
parseDelay(GrfBlock & block,ScpStream & script)1737 	void DtaScript::parseDelay(GrfBlock& block, ScpStream& script) {
1738 		GrfDelay* pDelayBlock = new GrfDelay(&block);
1739 		if (requiresParsingInformation()) pDelayBlock->setParsingInformation(getFilenamePtr(), script);
1740 		block.add(pDelayBlock);
1741 		parseBlock(script, *pDelayBlock);
1742 	}
1743 
parseNewProject(GrfBlock & block,ScpStream & script)1744 	void DtaScript::parseNewProject(GrfBlock& block, ScpStream& script) {
1745 		GrfNewProject* pNewProjectBlock = new GrfNewProject(&block);
1746 		if (requiresParsingInformation()) pNewProjectBlock->setParsingInformation(getFilenamePtr(), script);
1747 		block.add(pNewProjectBlock);
1748 		parseBlock(script, *pNewProjectBlock);
1749 	}
1750 
parseDebug(GrfBlock & block,ScpStream & script)1751 	void DtaScript::parseDebug(GrfBlock& block, ScpStream& script) {
1752 		GrfDebugExecution* pDebug = new GrfDebugExecution(&block);
1753 		if (requiresParsingInformation()) pDebug->setParsingInformation(getFilenamePtr(), script);
1754 		block.add(pDebug);
1755 		parseBlock(script, *pDebug);
1756 	}
1757 
parseQuantify(GrfBlock & block,ScpStream & script)1758 	void DtaScript::parseQuantify(GrfBlock& block, ScpStream& script) {
1759 		GrfQuantifyExecution* pQuantify = new GrfQuantifyExecution(&block);
1760 		if (requiresParsingInformation()) pQuantify->setParsingInformation(getFilenamePtr(), script);
1761 		block.add(pQuantify);
1762 		script.skipEmpty();
1763 		if (script.isEqualTo('(')) {
1764 			script.skipEmpty();
1765 			pQuantify->setFilename(parseExpression(block, script));
1766 			script.skipEmpty();
1767 			if (!script.isEqualTo(')')) throw UtlException(script, "syntax error: ')' expected");
1768 		}
1769 		parseBlock(script, *pQuantify);
1770 	}
1771 
parseQuiet(GrfBlock & block,ScpStream & script)1772 	void DtaScript::parseQuiet(GrfBlock& block, ScpStream& script) {
1773 		GrfQuiet* pQuietBlock = new GrfQuiet(&block);
1774 		if (requiresParsingInformation()) pQuietBlock->setParsingInformation(getFilenamePtr(), script);
1775 		block.add(pQuietBlock);
1776 		script.skipEmpty();
1777 		if (script.isEqualTo('(')) {
1778 			script.skipEmpty();
1779 			pQuietBlock->setVariable(parseVariableExpression(block, script));
1780 			script.skipEmpty();
1781 			if (!script.isEqualTo(')')) throw UtlException(script, "syntax error: ')' expected");
1782 		}
1783 		parseBlock(script, *pQuietBlock);
1784 	}
1785 
parseFileAsStandardInput(GrfBlock & block,ScpStream & script)1786 	void DtaScript::parseFileAsStandardInput(GrfBlock& block, ScpStream& script) {
1787 		GrfFileAsStandardInput* pFileAsStandardInputBlock = new GrfFileAsStandardInput(&block);
1788 		if (requiresParsingInformation()) pFileAsStandardInputBlock->setParsingInformation(getFilenamePtr(), script);
1789 		block.add(pFileAsStandardInputBlock);
1790 		script.skipEmpty();
1791 		if (script.isEqualTo('(')) {
1792 			script.skipEmpty();
1793 			pFileAsStandardInputBlock->setFilename(parseExpression(block, script));
1794 			script.skipEmpty();
1795 			if (!script.isEqualTo(')')) throw UtlException(script, "syntax error: ')' expected");
1796 		}
1797 		parseBlock(script, *pFileAsStandardInputBlock);
1798 	}
1799 
parseStringAsStandardInput(GrfBlock & block,ScpStream & script)1800 	void DtaScript::parseStringAsStandardInput(GrfBlock& block, ScpStream& script) {
1801 		GrfStringAsStandardInput* pStringAsStandardInputBlock = new GrfStringAsStandardInput(&block);
1802 		if (requiresParsingInformation()) pStringAsStandardInputBlock->setParsingInformation(getFilenamePtr(), script);
1803 		block.add(pStringAsStandardInputBlock);
1804 		script.skipEmpty();
1805 		if (script.isEqualTo('(')) {
1806 			script.skipEmpty();
1807 			pStringAsStandardInputBlock->setText(parseExpression(block, script));
1808 			script.skipEmpty();
1809 			if (!script.isEqualTo(')')) throw UtlException(script, "syntax error: ')' expected");
1810 		}
1811 		parseBlock(script, *pStringAsStandardInputBlock);
1812 	}
1813 
parseParsedFile(GrfBlock & block,ScpStream & script)1814 	void DtaScript::parseParsedFile(GrfBlock& block, ScpStream& script) {
1815 		if (!isAParseScript()) throw UtlException(script, "statement modifier 'parsed_file' is available on parsing scripts only");
1816 		GrfParsedFile* pParsedFileBlock = new GrfParsedFile(&block);
1817 		if (requiresParsingInformation()) pParsedFileBlock->setParsingInformation(getFilenamePtr(), script);
1818 		block.add(pParsedFileBlock);
1819 		script.skipEmpty();
1820 		if (script.isEqualTo('(')) {
1821 			script.skipEmpty();
1822 			pParsedFileBlock->setInputFile(parseExpression(block, script));
1823 			script.skipEmpty();
1824 			if (!script.isEqualTo(')')) throw UtlException(script, "syntax error: ')' expected");
1825 		}
1826 		parseBlock(script, *pParsedFileBlock);
1827 	}
1828 
parseParsedString(GrfBlock & block,ScpStream & script)1829 	void DtaScript::parseParsedString(GrfBlock& block, ScpStream& script) {
1830 		if (!isAParseScript()) throw UtlException(script, "statement modifier 'parsed_string' is available on parsing scripts only");
1831 		GrfParsedString* pParsedStringBlock = new GrfParsedString(&block);
1832 		if (requiresParsingInformation()) pParsedStringBlock->setParsingInformation(getFilenamePtr(), script);
1833 		block.add(pParsedStringBlock);
1834 		script.skipEmpty();
1835 		if (script.isEqualTo('(')) {
1836 			script.skipEmpty();
1837 			pParsedStringBlock->setInputString(parseExpression(block, script));
1838 			script.skipEmpty();
1839 			if (!script.isEqualTo(')')) throw UtlException(script, "syntax error: ')' expected");
1840 		}
1841 		parseBlock(script, *pParsedStringBlock);
1842 	}
1843 
parseGeneratedFile(GrfBlock &,ScpStream & script)1844 	void DtaScript::parseGeneratedFile(GrfBlock& /*block*/, ScpStream& script) {
1845 		throw UtlException(script, "statement modifier \"generated_file\" must be used into pattern scripts only");
1846 	}
1847 
parseAppendedFile(GrfBlock &,ScpStream & script)1848 	void DtaScript::parseAppendedFile(GrfBlock& /*block*/, ScpStream& script) {
1849 		throw UtlException(script, "statement modifier \"appended_file\" must be used into pattern scripts only");
1850 	}
1851 
parseGeneratedString(GrfBlock &,ScpStream & script)1852 	void DtaScript::parseGeneratedString(GrfBlock& /*block*/, ScpStream& script) {
1853 		throw UtlException(script, "statement modifier \"generated_string\" must be used into pattern scripts only");
1854 	}
1855 
parseVariableType(GrfBlock & block,ScpStream & script)1856 	EXPRESSION_TYPE DtaScript::parseVariableType(GrfBlock& block, ScpStream& script) {
1857 		EXPRESSION_TYPE exprType = VALUE_EXPRTYPE;
1858 		script.skipEmpty();
1859 		std::string sType;
1860 		if (!script.readIdentifier(sType)) {
1861 			throw UtlException(script, "syntax error, variable/parameter type expected (value, node, reference and index eventually)");
1862 		}
1863 		if (sType == "value") exprType = VALUE_EXPRTYPE;
1864 		else if (sType == "iterator") exprType = ITERATOR_EXPRTYPE;
1865 		else if (sType == "index") {
1866 			std::string sErrorMessage = script.getMessagePrefix() + "warning! parameter type 'index' is obsolete since version 3.11 -> replace it by 'iterator'";
1867 			if (DtaProject::getInstance().addWarning(sErrorMessage) == 1) CGRuntime::traceLine(sErrorMessage);
1868 			exprType = ITERATOR_EXPRTYPE;
1869 		} else if (sType == "node") exprType = NODE_EXPRTYPE;
1870 		else if (sType == "reference") exprType = REFERENCE_EXPRTYPE;
1871 		else if (sType == "variable") {
1872 			std::string sErrorMessage = script.getMessagePrefix() + "warning! parameter type 'variable' is obsolete since version 3.8.7 -> replace it by 'node'";
1873 			if (DtaProject::getInstance().addWarning(sErrorMessage) == 1) CGRuntime::traceLine(sErrorMessage);
1874 			exprType = NODE_EXPRTYPE;
1875 		} else throw UtlException(script, std::string("Unknown parameter type \"") + sType + "\"");
1876 		return parseClassType(block, script, exprType);
1877 	}
1878 
parseClassType(GrfBlock & block,ScpStream & script,EXPRESSION_TYPE exprType)1879 	EXPRESSION_TYPE DtaScript::parseClassType(GrfBlock& block, ScpStream& script, EXPRESSION_TYPE exprType) {
1880 		script.skipEmpty();
1881 		if (script.isEqualTo('<')) {
1882 			if (exprType == VALUE_EXPRTYPE) throw UtlException(script, "only a node or a reference parameter can point to a class");
1883 			script.skipEmpty();
1884 			if (hasTargetLanguage()) {
1885 				DtaScriptVariable parseTree(NULL, "parseTree");
1886 				parseTree.insertNode("type")->setValue("target_type");
1887 				getAlienParser().generate(script, parseTree);
1888 				DtaScriptVariable* pNode = parseTree.getNode("target_type");
1889 				if (pNode == NULL) throw UtlException(script, "instruction type 'target_type' is expected to have the attribute 'target_type'");
1890 				DtaTargetLanguageTypeSpecifier* pTypeSpec = block.addTargetLanguageTypeSpecifier(pNode->getValue());
1891 				exprType = pTypeSpec->composeExprType(exprType);
1892 			} else {
1893 				std::string sClassName;
1894 				if (!script.readIdentifier(sClassName)) throw UtlException(script, "syntax error, class name expected");
1895 				DtaClass* pClass = block.getClass(sClassName);
1896 				if (pClass == NULL) throw UtlException(script, "undefined class '" + sClassName + "'");
1897 				exprType = pClass->composeExprType(exprType);
1898 			}
1899 			script.skipEmpty();
1900 			if (!script.isEqualTo('>')) throw UtlException(script, "syntax error, '>' expected");
1901 		}
1902 		return exprType;
1903 	}
1904 
1905 	// declaration / definition of a user function function.
1906 	//   - bPrototypeOnly = true  -> declaration
1907 	//   - bPrototypeOnly = false -> definition
parseFunction(GrfBlock & block,ScpStream & script,bool bPrototypeOnly)1908 	GrfFunction* DtaScript::parseFunction(GrfBlock& block, ScpStream& script, bool bPrototypeOnly) {
1909 		std::string sFunctionName;
1910 		script.skipEmpty();
1911 		if (!script.readIdentifier(sFunctionName)) throw UtlException(script, "syntax error, function name expected");
1912 		if (getParsingFunctionRegister().find(sFunctionName) != getParsingFunctionRegister().end()) {
1913 			throw UtlException(script, "cannot use the reserved keyword '" + sFunctionName + "' as a function name");
1914 		}
1915 		script.skipEmpty();
1916 		std::string sTemplate;
1917 		bool bGenericKey = false;
1918 		if (script.isEqualTo('<')) {
1919 			script.skipEmpty();
1920 			if (!script.readString(sTemplate)) {
1921 				if (script.readIdentifier(sTemplate)) bGenericKey = true;
1922 				else {
1923 					double dValue;
1924 					if (script.readDouble(dValue)) {
1925 						sTemplate = CGRuntime::toString(dValue);
1926 					} else throw UtlException(script, "syntax error, template function \"" + sFunctionName + "\" expects a constant string or an identifier for instantiating");
1927 				}
1928 			}
1929 			script.skipEmpty();
1930 			if (!script.isEqualTo('>')) throw UtlException(script, "syntax error, template function \"" + sFunctionName + "\" expects '>' after constant string \"" + sTemplate + "\"");
1931 		}
1932 		int iArity;
1933 		GrfFunction* pFunction = NULL;
1934 		bool bAlreadyExist = false;
1935 		ExprScriptFunction* pFuncExpr = ExprScriptFunction::create(block, script, sFunctionName, sTemplate, bGenericKey);
1936 		if (pFuncExpr != NULL) {
1937 			// the function already exists
1938 			pFunction = pFuncExpr->getUserBody();
1939 			delete pFuncExpr;
1940 			if (pFunction == NULL) {
1941 				// this function isn't user-declared, so it's a reserved one:
1942 				// don't have the right to redefine a reserved function
1943 				throw UtlException(script, "syntax error, function \"" + sFunctionName + "\" is reserved");
1944 			}
1945 			iArity = pFunction->getArity();
1946 		}
1947 		GrfFunction* pTemplateFunction = NULL;
1948 		if (pFunction == NULL) {
1949 			// this function was never declared before
1950 			if (sTemplate.empty()) {
1951 				// a standard function: we'll discover its arity now!
1952 				iArity = -1;
1953 			} else {
1954 				// a generic/instantiated function: look for the root template function
1955 				pTemplateFunction = block.getFunction(sFunctionName, "", false);
1956 				if (pTemplateFunction == NULL) {
1957 					// it doesn't exist: no derivative template form of this function
1958 					// already declared, so we'll discover its arity now
1959 					iArity = -1;
1960 					pTemplateFunction = block.addFunction(sFunctionName, "", false);
1961 				} else {
1962 					// we know its arity
1963 					iArity = pTemplateFunction->getArity();
1964 				}
1965 			}
1966 			// declare this new function
1967 			pFunction = block.addFunction(sFunctionName, sTemplate, bGenericKey);
1968 			if (requiresParsingInformation()) pFunction->setParsingInformation(getFilenamePtr(), script);
1969 		} else {
1970 			// this function was already declared: we know the arity
1971 			bAlreadyExist = true;
1972 			iArity = pFunction->getArity();
1973 		}
1974 		std::string sOldFunctionBody = _sCurrentFunctionBody;
1975 		std::string sOldFunctionTemplateBody = _sCurrentFunctionTemplateBody;
1976 		bool bOldCurrentFunctionGenericTemplateKey = _bCurrentFunctionGenericTemplateKey;
1977 		_sCurrentFunctionBody = sFunctionName;
1978 		_sCurrentFunctionTemplateBody = sTemplate;
1979 		_bCurrentFunctionGenericTemplateKey = bGenericKey;
1980 		if (bAlreadyExist && (!bPrototypeOnly) && pFunction->isBodyDefined()) throw UtlException(script, "syntax error, function \"" + sFunctionName + "\" has already been defined");
1981 		script.skipEmpty();
1982 		if (!script.isEqualTo('(')) throw UtlException(script, "syntax error, '(' expected");
1983 		script.skipEmpty();
1984 		unsigned int i = 0;
1985 		if (!script.isEqualTo(')')) {
1986 			bool bHasDefaultValues = false;
1987 			do {
1988 				if (bAlreadyExist && (i >= pFunction->getArity())) throw UtlException(script, "too many parameters");
1989 				// parameter name
1990 				std::string sWord;
1991 				script.skipEmpty();
1992 				if (!script.readIdentifier(sWord)) throw UtlException(script, "syntax error, parameter name expected");
1993 				// parameter type
1994 				script.skipEmpty();
1995 				EXPRESSION_TYPE exprType = VALUE_EXPRTYPE;
1996 				if (script.isEqualTo(':')) {
1997 					exprType = parseVariableType(block, script);
1998 					script.skipEmpty();
1999 				}
2000 				// default value
2001 				script.skipEmpty();
2002 				ExprScriptExpression* pDefaultValue = NULL;
2003 				if (script.isEqualTo('=')) {
2004 					script.skipEmpty();
2005 					if ((exprType & 0xFF) == VALUE_EXPRTYPE) {
2006 						pDefaultValue = parseConstantLiteral(block, script);
2007 					} else if ((exprType & 0xFF) == NODE_EXPRTYPE) {
2008 						std::string sVarName;
2009 						if (!script.readIdentifier(sVarName) || ((sVarName != "this") && (sVarName != "project") && (sVarName != "null") && (DtaProject::getInstance().getGlobalVariableType(sVarName) == UNKNOWN_EXPRTYPE))) throw UtlException(script, "global variable name or 'null' expected");
2010 						pDefaultValue = new ExprScriptVariable(sVarName.c_str());
2011 					}
2012 					bHasDefaultValues = true;
2013 					script.skipEmpty();
2014 				} else if (bHasDefaultValues) {
2015 					throw UtlException(script, "default value expected for argument '" + sWord + "'");
2016 				}
2017 				if (bAlreadyExist) {
2018 					// we already know the prototype of the function: check only
2019 					if (pFunction->getParameterType(i) != exprType) throw UtlException(script, "wrong parameter type");
2020 				} else {
2021 					if (!pFunction->addParameterAndType(sWord.c_str(), exprType, pDefaultValue)) throw UtlException(script, "syntax error, two parameters with the same name");
2022 					if (pTemplateFunction != NULL) {
2023 						if (iArity < 0) {
2024 							if (pDefaultValue == NULL) {
2025 								pTemplateFunction->addParameterAndType(sWord.c_str(), exprType, NULL);
2026 							} else {
2027 								pTemplateFunction->addParameterAndType(sWord.c_str(), exprType, pDefaultValue->clone());
2028 							}
2029 						} else if ((unsigned int) iArity <= i) throw UtlException(script, "too many parameters");
2030 						else if (pTemplateFunction->getParameterType(i) != exprType) throw UtlException(script, "wrong parameter type");
2031 					}
2032 				}
2033 				i++;
2034 			} while (script.isEqualTo(','));
2035     		if (!script.isEqualTo(')')) throw UtlException(script, "syntax error, ')' expected");
2036 		}
2037 		if (iArity >= 0) {
2038 			// prototype was already given
2039 			if (i < (unsigned int) iArity) throw UtlException(script, "parameters are lacking");
2040 			if (i > (unsigned int) iArity) throw UtlException(script, "too many parameters");
2041 		}
2042 		if (!bPrototypeOnly) {
2043 			// definition of the function
2044 			if (pFunction->isExternal()) throw UtlException(script, "syntax error, function \"" + sFunctionName + "\" is external, so it shouldn't implement a body here");
2045 			script.skipEmpty();
2046 			pFunction->addLocalVariable(sFunctionName, VALUE_EXPRTYPE);
2047 			if (bGenericKey) pFunction->addLocalVariable(sTemplate, VALUE_EXPRTYPE);
2048 			if (bGenericKey && script.isEqualTo("{{")) {
2049 				script.goBack();
2050 				std::auto_ptr<DtaPatternScript> pPatternScript(new DtaPatternScript(&block));
2051 				pPatternScript->parseEmbeddedScript(script);
2052     			if (!script.isEqualTo('}')) throw UtlException(script, "syntax error, '}}' expected to close the pattern-template function");
2053 				pFunction->setPatternTemplateBody(getType(), pPatternScript.release());
2054 			} else {
2055 				pFunction->isBodyDefined(true);
2056 				parseBlock(script, *pFunction);
2057 			}
2058 		}
2059 		_sCurrentFunctionBody = sOldFunctionBody;
2060 		_sCurrentFunctionTemplateBody = sOldFunctionTemplateBody;
2061 		_bCurrentFunctionGenericTemplateKey = bOldCurrentFunctionGenericTemplateKey;
2062 		return pFunction;
2063 	}
2064 
parseClass(GrfBlock & block,ScpStream & script)2065 	DtaClass* DtaScript::parseClass(GrfBlock& block, ScpStream& script) {
2066 		std::string sClassName;
2067 		script.skipEmpty();
2068 		if (!script.readIdentifier(sClassName)) throw UtlException(script, "syntax error, class name expected");
2069 		DtaClass* pClass = block.getClass(sClassName);
2070 		if (pClass != NULL) {
2071 			if (!pClass->isForwardDeclaration()) throw UtlException(script, "the class '" + sClassName + "' cannot be declared twice");
2072 		} else {
2073 			pClass = block.addClass(sClassName);
2074 		}
2075 		script.skipEmpty();
2076 		if (script.isEqualTo(':')) {
2077 			script.skipEmpty();
2078 			std::string sExtendedClass;
2079 			if (!script.readIdentifier(sExtendedClass)) throw UtlException(script, "syntax error, extended class expected after ':'");
2080 			DtaClass* pExtendedClass = block.getClass(sExtendedClass);
2081 			if (pExtendedClass == NULL) throw UtlException(script, "the extended class '" + sExtendedClass + "' doesn't exist");
2082 			pClass->setExtendedClass(pExtendedClass);
2083 			script.skipEmpty();
2084 		}
2085 		if (script.isEqualTo(';')) {
2086 			// forward declaration
2087 			if (pClass->getExtendedClass() != NULL) throw UtlException(script, "a forward declaration of a class doesn't admit the specification of the extended class");
2088 		} else {
2089 			// a body
2090 			if (!script.isEqualTo('{')) throw UtlException(script, "syntax error, '{' expected");
2091 			script.skipEmpty();
2092 			while (!script.isEqualTo('}')) {
2093 				std::string sAttribute;
2094 				if (!script.readIdentifier(sAttribute)) {
2095 					if (script.isEqualTo('[') && script.skipEmpty() && script.isEqualTo(']')) {
2096 						sAttribute = "[]";
2097 					} else {
2098 						throw UtlException(script, "syntax error, attribute name or '}' expected");
2099 					}
2100 				}
2101 				if (pClass->getAttributeType(sAttribute) != UNKNOWN_EXPRTYPE) throw UtlException(script, "the attribute '" + sClassName + "::" + sAttribute + "' is declared twice");
2102 				script.skipEmpty();
2103 				if (!script.isEqualTo(':')) throw UtlException(script, "syntax error, ':' expected");
2104 				script.skipEmpty();
2105 				EXPRESSION_TYPE attributeType = parseVariableType(block, script);
2106 				DtaClass* pClassAttribute = DtaClass::getClass(attributeType);
2107 				script.skipEmpty();
2108 				if (script.isEqualTo('[') && script.skipEmpty() && script.isEqualTo(']')) {
2109 					pClass->addAttribute(sAttribute, (EXPRESSION_TYPE) (((int) attributeType) | ((int) ARRAY_EXPRTYPE)), pClassAttribute);
2110 					script.skipEmpty();
2111 				} else {
2112 					pClass->addAttribute(sAttribute, attributeType, pClassAttribute);
2113 				}
2114 				if (!script.isEqualTo(';')) throw UtlException(script, "syntax error, ';' expected");
2115 				script.skipEmpty();
2116 			}
2117 			script.skipEmpty();
2118 			script.isEqualTo(';');
2119 		}
2120 		return pClass;
2121 	}
2122 
parsePreprocessorExpression(GrfBlock & block,ScpStream & script)2123 	ExprScriptExpression* DtaScript::parsePreprocessorExpression(GrfBlock& block, ScpStream& script) {
2124 		std::string sWord;
2125 		int iLocation = script.getInputLocation();
2126 		script.skipEmpty();
2127 		if (!script.readIdentifier(sWord)) throw UtlException(script, "syntax error: preprocessor-like variable expected");
2128 		if (sWord == "LINE") {
2129 			return new ExprScriptConstant(script.getLineCount());
2130 		} else if (sWord == "FILE") {
2131 			if (getFilenamePtr() == NULL) return new ExprScriptConstant("");
2132 			return new ExprScriptConstant(getFilenamePtr());
2133 		} else if (sWord == "evaluateVariable") {
2134 			script.setInputLocation(iLocation - 1);
2135 			return parseVariableExpression(block, script);
2136 		} else {
2137 			throw UtlException(script, "syntax error: preprocessor-like variable expected");
2138 		}
2139 		return NULL;
2140 	}
2141 
parseConstantLiteral(GrfBlock & block,ScpStream & script)2142 	ExprScriptExpression* DtaScript::parseConstantLiteral(GrfBlock& block, ScpStream& script) {
2143 		std::string sWord;
2144 		if (script.readPythonString(sWord)) {
2145 			std::string sConstantString = sWord;
2146 			script.skipEmpty();
2147 			while (script.readPythonString(sWord)) {
2148 				sConstantString += sWord;
2149 				script.skipEmpty();
2150 			}
2151 			return new ExprScriptConstant(sConstantString.c_str());
2152 		}
2153 		int iChar;
2154 		if (script.readCharLiteral(iChar)) {
2155 			char tcText[] = {0, 0};
2156 			tcText[0] = (char) iChar;
2157 			return new ExprScriptConstant(tcText);
2158 		}
2159 		if (script.readIdentifier(sWord)) {
2160 			if (sWord == "true") return new ExprScriptConstant("true");
2161 			if (sWord == "false") return new ExprScriptConstant("");
2162 			if ((sWord == "this") || (sWord == "project") || (sWord == "null") || (DtaProject::getInstance().getGlobalVariableType(sWord) != UNKNOWN_EXPRTYPE)) {
2163 				return new ExprScriptVariable(sWord.c_str());
2164 			}
2165 			throw UtlException(script, "'" + sWord + "' isn't recognized as a constant literal");
2166 		}
2167 		double dValue;
2168 		if (script.readDouble(dValue)) {
2169 			return new ExprScriptConstant(dValue);
2170 		}
2171 		throw UtlException(script, "constant literal expected");
2172 	}
2173 
parseLiteralUnsignedExpression(GrfBlock & block,ScpStream & script)2174 	ExprScriptExpression* DtaScript::parseLiteralUnsignedExpression(GrfBlock& block, ScpStream& script) {
2175 		std::string sWord;
2176 		ExprScriptExpression* pExpr = NULL;
2177 		if (script.readPythonString(sWord)) {
2178 			std::string sConstantString = sWord;
2179 			script.skipEmpty();
2180 			while (script.readPythonString(sWord)) {
2181 				sConstantString += sWord;
2182 				script.skipEmpty();
2183 			}
2184 			pExpr = new ExprScriptConstant(sConstantString.c_str());
2185 		} else if (script.isEqualTo('(')) {
2186 			pExpr = parseExpression(block, script);
2187 			script.skipEmpty();
2188 			if (!script.isEqualTo(')')) throw UtlException(script, "syntax error, ')' expected");
2189 		} else if (script.isEqualTo('$')) {
2190 			if (_bNumericalExpression) throw UtlException(script, "syntax error, misplaced '$' character");
2191 			_bNumericalExpression = true;
2192 			try {
2193 				pExpr = parseExpression(block, script);
2194 			} catch(UtlException&/* exception*/) {
2195 				_bNumericalExpression = false;
2196 				throw/* UtlException(exception)*/;
2197 			}
2198 			_bNumericalExpression = false;
2199 			script.skipEmpty();
2200 			if (!script.isEqualTo('$')) throw UtlException(script, "syntax error, '$' expected to close a numerical expression");
2201 		} else if (script.isEqualTo('#')) {
2202 			pExpr = parsePreprocessorExpression(block, script);
2203 		} else if (script.isEqualTo('~')) {
2204 			if (!_bNumericalExpression) throw UtlException(script, "syntax error, bitwise not is an arithmetic operator to put between '$'");
2205 			pExpr = parseLiteralExpression(block, script);
2206 			pExpr = new ExprScriptBitwiseNot(pExpr);
2207 		} else {
2208 			int iChar;
2209 			if (script.readCharLiteral(iChar)) {
2210 				char tcText[] = {0, 0};
2211 				tcText[0] = (char) iChar;
2212 				pExpr = new ExprScriptConstant(tcText);
2213 			} else {
2214 				bool bWithoutBrackets = false;
2215 				if (script.isEqualTo('!')) {
2216 					bWithoutBrackets = true;
2217 					sWord = "not";
2218 				} else if (script.readIdentifier(sWord)) {
2219 					if (sWord == "true") return new ExprScriptConstant("true");
2220 					if (sWord == "false") return new ExprScriptConstant("");
2221 				} else {
2222 					double dValue;
2223 					if (script.readDouble(dValue))
2224 						return new ExprScriptConstant(dValue);
2225 					else {
2226 						std::string sMessage = "syntax error: literal expected (variable, function, string or number), instead of ";
2227 						int iChar = script.readChar();
2228 						if (iChar < 0) {
2229 							sMessage += "end of file";
2230 						} else {
2231 							char tcChar[] = {'\'', '\0', '\'', '\0'};
2232 							tcChar[1] = (char) iChar;
2233 							sMessage += tcChar;
2234 						}
2235 						throw UtlException(script, sMessage);
2236 					}
2237 				}
2238 				script.skipEmpty();
2239 				ExprScriptExpression* pTemplate = NULL;
2240 				int iLocation = script.getInputLocation();
2241 				if (!bWithoutBrackets && script.isEqualTo('<')) {
2242 					int a = script.peekChar();
2243 					if ((a == (int) '=') || (a == (int) '<')) {
2244 						script.goBack();
2245 					} else {
2246 						script.skipEmpty();
2247 						pTemplate = parseKeyTemplateExpression(block, script);
2248 						script.skipEmpty();
2249 						if (script.isEqualTo('>')) {
2250 							script.skipEmpty();
2251 							if (!script.isEqualTo('(')) {
2252 								delete pTemplate;
2253 								throw UtlException(script, "syntax error: '(' expected after declaring template function call '" + sWord + "<" + pTemplate->toString() + ">'");
2254 							}
2255 							script.goBack();
2256 						} else {
2257 							delete pTemplate;
2258 							pTemplate = NULL;
2259 							script.setInputLocation(iLocation);
2260 						}
2261 					}
2262 				}
2263 				if (bWithoutBrackets || script.isEqualTo('(')) {
2264 					ExprScriptFunction* pFunction;
2265 					try {
2266 						pFunction = ExprScriptFunction::create(block, script, sWord, "", false);
2267 					} catch(UtlException& exception) {
2268 						delete pTemplate;
2269 						throw UtlException(script, exception.getTraceStack(), exception.getMessage());
2270 					} catch(std::exception&) {
2271 						delete pTemplate;
2272 						throw;
2273 					}
2274 					if (pFunction == NULL) throw UtlException(script, "Unknown function name \"" + sWord + "\"");
2275 					checkIfAllowedFunction(script, *pFunction);
2276 					pExpr = parseFunctionExpression(block, script, NULL, pFunction, pTemplate, !bWithoutBrackets);
2277 				} else if (script.isEqualTo("::")) {
2278 					DynPackage* pPackage = DynPackage::getPackage(sWord);
2279 					if (pPackage == NULL) throw UtlException(script, "unknown module '" + sWord +"'; type '#use' to load the dynamic library");
2280 					script.skipEmpty();
2281 					std::string sFunction;
2282 					if (!script.readIdentifier(sFunction)) throw UtlException(script, "function or variable name expected after '" + sWord + "::'");
2283 					script.skipEmpty();
2284 					if (script.isEqualTo('(')) {
2285 						DynFunction* pFunction = pPackage->getFunction(sFunction);
2286 						if (pFunction == NULL) throw UtlException(script, "the module '" + sWord + "' doesn't export the function '" + sWord + "::" + sFunction + "'");
2287 						pExpr = parseFunctionExpression(block, script, NULL, new ExprScriptFunction(pFunction), NULL, true);
2288 					} else {
2289 						if (pPackage->getVariable(sFunction) == NULL) throw UtlException(script, "the module '" + sWord + "' doesn't export the variable '" + sWord + "::" + sFunction + "'");
2290 						ExprScriptExpression* pMethodFunction;
2291 						GrfCommand* pMethodProc;
2292 						pExpr = parseVariableExpression(block, script, new ExprScriptVariable(sFunction.c_str(), pPackage), pMethodFunction, pMethodProc);
2293 						if (pMethodFunction != NULL) pExpr = pMethodFunction;
2294 						else if (pMethodProc != NULL) throw UtlException("literal expected instead of procedure call as a method");
2295 					}
2296 				} else {
2297 					ExprScriptExpression* pMethodFunction;
2298 					GrfCommand* pMethodProc;
2299 					pExpr = parseVariableExpression(block, script, new ExprScriptVariable(sWord.c_str()), pMethodFunction, pMethodProc);
2300 					if (pMethodFunction != NULL) pExpr = pMethodFunction;
2301 					else if (pMethodProc != NULL) {
2302 						throw UtlException("literal expected instead of procedure call as a method");
2303 					} else {
2304 						// variable expression
2305 						script.skipEmpty();
2306 						if (script.isEqualTo("++")) {
2307 							std::string sTemplate;
2308 							ExprScriptFunction* pFunction = ExprScriptFunction::create(block, script, "increment", sTemplate, false);
2309 							pFunction->addParameter(pExpr);
2310 							pExpr = pFunction;
2311 						} else if (script.isEqualTo("--")) {
2312 							std::string sTemplate;
2313 							ExprScriptFunction* pFunction = ExprScriptFunction::create(block, script, "decrement", sTemplate, false);
2314 							pFunction->addParameter(pExpr);
2315 							pExpr = pFunction;
2316 /*						} else {
2317 							std::string sOperator;
2318 							if (script.isEqualTo("+=")) sOperator = "+=";
2319 							else if (script.isEqualTo("-=")) sOperator = "-=";
2320 							else if (script.isEqualTo("*=")) sOperator = "*=";
2321 							else if (script.isEqualTo("/=")) sOperator = "/=";
2322 */						}
2323 					}
2324 				}
2325 			}
2326 		}
2327 		return pExpr;
2328 	}
2329 
parseLiteralExpression(GrfBlock & block,ScpStream & script)2330 	ExprScriptExpression* DtaScript::parseLiteralExpression(GrfBlock& block, ScpStream& script) {
2331 		bool bUnaryMinus = script.isEqualTo('-');
2332 		if (bUnaryMinus) {
2333 			int a = script.peekChar();
2334 			if ((a >= (int) '0') && (a <= (int) '9')) {
2335 				script.goBack();
2336 				bUnaryMinus = false;
2337 			}
2338 		}
2339 		ExprScriptExpression* pExpr = parseLiteralUnsignedExpression(block, script);
2340 		if (bUnaryMinus) pExpr = new ExprScriptUnaryMinus(pExpr);
2341 		return pExpr;
2342 	}
2343 
parseConcatenationExpression(GrfBlock & block,ScpStream & script)2344 	ExprScriptExpression* DtaScript::parseConcatenationExpression(GrfBlock& block, ScpStream& script) {
2345 		ExprScriptExpression* pResultExpr = NULL;
2346 		for (;;) {
2347     		ExprScriptExpression* pExpr = NULL;
2348 			script.skipEmpty();
2349 			try {
2350 				pExpr = parseLiteralExpression(block, script);
2351 			} catch(std::exception&/* e*/) {
2352 				delete pResultExpr;
2353 				throw/* UtlException(e)*/;
2354 			}
2355 			if (pResultExpr == NULL) pResultExpr = pExpr;
2356 			else {
2357 				ExprScriptConstant* pLeftConstant = dynamic_cast<ExprScriptConstant*>(pResultExpr);
2358 				if (pLeftConstant != NULL) {
2359 					ExprScriptConstant* pRightConstant = dynamic_cast<ExprScriptConstant*>(pExpr);
2360 					if (pRightConstant != NULL) {
2361 						std::string sConcatenation = pLeftConstant->getConstant() + pRightConstant->getConstant();
2362 						pResultExpr = new ExprScriptConstant(sConcatenation.c_str());
2363 						delete pLeftConstant;
2364 						delete pRightConstant;
2365 					} else {
2366 						pResultExpr = new ExprScriptConcatenation(pResultExpr, pExpr);
2367 					}
2368 				} else {
2369 					pResultExpr = new ExprScriptConcatenation(pResultExpr, pExpr);
2370 				}
2371 			}
2372 			script.skipEmpty();
2373 			if (script.isEqualTo('+')) {
2374 				if (script.isEqualTo("=")) {
2375 					script.goBack();
2376 					script.goBack();
2377 					break;
2378 				}
2379 			} else {
2380 				break;
2381 			}
2382 		}
2383 		return pResultExpr;
2384 	}
2385 
parseKeyTemplateExpression(GrfBlock & block,ScpStream & script)2386 	ExprScriptExpression* DtaScript::parseKeyTemplateExpression(GrfBlock& block, ScpStream& script) {
2387 		if (!_bNumericalExpression) return parseConcatenationExpression(block, script);
2388 		ExprScriptExpression* pExpr;
2389 		try {
2390 			_bNumericalExpression = false;
2391 			pExpr = parseConcatenationExpression(block, script);
2392 			_bNumericalExpression = true;
2393 		} catch(UtlException&) {
2394 			_bNumericalExpression = true;
2395 			throw;
2396 		}
2397 		return pExpr;
2398 	}
2399 
parseFactorExpression(GrfBlock & block,ScpStream & script)2400 	ExprScriptExpression* DtaScript::parseFactorExpression(GrfBlock& block, ScpStream& script) {
2401 		ExprScriptExpression* pResultExpr = NULL;
2402 		char cComparison = '\0';
2403 		do {
2404     		ExprScriptExpression* pExpr = NULL;
2405 			script.skipEmpty();
2406 			try {
2407 				pExpr = parseLiteralExpression(block, script);
2408 			} catch(std::exception&/* e*/) {
2409 				delete pResultExpr;
2410 				throw/* UtlException(e)*/;
2411 			}
2412 			if (pResultExpr == NULL) pResultExpr = pExpr;
2413 			else pResultExpr = new ExprScriptArithmetic(pResultExpr, pExpr, cComparison);
2414 			script.skipEmpty();
2415 			if (script.isEqualTo('*')) cComparison = '*';
2416 			else if (script.isEqualTo('/')) cComparison = '/';
2417 			else if (script.isEqualTo('%')) cComparison = '%';
2418 			else break;
2419 		} while (true);
2420 		return pResultExpr;
2421 	}
2422 
parseShiftExpression(GrfBlock & block,ScpStream & script)2423 	ExprScriptExpression* DtaScript::parseShiftExpression(GrfBlock& block, ScpStream& script) {
2424 		ExprScriptExpression* pResultExpr = NULL;
2425 		char cComparison = '\0';
2426 		do {
2427     		ExprScriptExpression* pExpr = NULL;
2428 			script.skipEmpty();
2429 			try {
2430 				pExpr = parseFactorExpression(block, script);
2431 			} catch(std::exception&/* e*/) {
2432 				delete pResultExpr;
2433 				throw/* UtlException(e)*/;
2434 			}
2435 			if (pResultExpr == NULL) pResultExpr = pExpr;
2436 			else pResultExpr = new ExprScriptShift(pResultExpr, pExpr, cComparison);
2437 			script.skipEmpty();
2438 			if (script.isEqualTo("<<")) cComparison = '<';
2439 			else if (script.isEqualTo(">>")) cComparison = '>';
2440 			else break;
2441 		} while (true);
2442 		return pResultExpr;
2443 	}
2444 
parseArithmeticExpression(GrfBlock & block,ScpStream & script)2445 	ExprScriptExpression* DtaScript::parseArithmeticExpression(GrfBlock& block, ScpStream& script) {
2446 		ExprScriptExpression* pResultExpr = NULL;
2447 		char cComparison = '\0';
2448 		do {
2449     		ExprScriptExpression* pExpr = NULL;
2450 			script.skipEmpty();
2451 			try {
2452 				pExpr = parseShiftExpression(block, script);
2453 			} catch(std::exception&/* e*/) {
2454 				delete pResultExpr;
2455 				throw/* UtlException(e)*/;
2456 			}
2457 			if (pResultExpr == NULL) pResultExpr = pExpr;
2458 			else pResultExpr = new ExprScriptArithmetic(pResultExpr, pExpr, cComparison);
2459 			script.skipEmpty();
2460 			if (script.isEqualTo('+')) cComparison = '+';
2461 			else if (script.isEqualTo('-')) cComparison = '-';
2462 			else break;
2463 		} while (true);
2464 		return pResultExpr;
2465 	}
2466 
parseComparisonExpression(GrfBlock & block,ScpStream & script)2467 	ExprScriptExpression* DtaScript::parseComparisonExpression(GrfBlock& block, ScpStream& script) {
2468 		ExprScriptExpression* pResultExpr = NULL;
2469 		char cComparison = '\0';
2470 		do {
2471     		ExprScriptExpression* pExpr = NULL;
2472 			script.skipEmpty();
2473 			try {
2474 				if (_bNumericalExpression) pExpr = parseArithmeticExpression(block, script);
2475 				else pExpr = parseConcatenationExpression(block, script);
2476 			} catch(std::exception&/* e*/) {
2477 				delete pResultExpr;
2478 				throw/* UtlException(e)*/;
2479 			}
2480 			if (pResultExpr == NULL) pResultExpr = pExpr;
2481 			else if (_bNumericalExpression) pResultExpr = new ExprScriptNumericComparison(pResultExpr, pExpr, cComparison);
2482 			else pResultExpr = new ExprScriptComparison(pResultExpr, pExpr, cComparison);
2483 			script.skipEmpty();
2484 			if (script.isEqualTo('<')) {
2485 				if (script.isEqualTo('=')) cComparison = 'i';
2486 				else if (script.isEqualTo('>')) cComparison = '!';
2487 				else cComparison = '<';
2488 			} else if (script.isEqualTo('=')) {
2489 				script.isEqualTo('=');
2490 				cComparison = '=';
2491 			} else if (script.isEqualTo('>')) {
2492 				if (script.isEqualTo('=')) cComparison = 's';
2493 				else cComparison = '>';
2494 			} else if (script.isEqualTo('!')) {
2495 				if (script.isEqualTo('=')) cComparison = '!';
2496 				else {
2497 					delete pResultExpr;
2498 					throw UtlException(script, "binary operator '!=' expected, or syntax error on unary operator '!'");
2499 				}
2500 			} else if (script.isEqualToIdentifier("in")) {
2501 				script.skipEmpty();
2502 				if (!script.isEqualTo('{')) throw UtlException(script, "'{' expected");
2503 				script.skipEmpty();
2504 				std::set<std::string> listOfConstants;
2505 				std::string sConstant;
2506 				if (!script.readStringOrCharLiteral(sConstant)) throw UtlException(script, "syntax error, constant string expected");
2507 				listOfConstants.insert(sConstant);
2508 				script.skipEmpty();
2509 				while (script.isEqualTo(',')) {
2510 					script.skipEmpty();
2511 					if (!script.readStringOrCharLiteral(sConstant)) throw UtlException(script, "syntax error, constant string expected");
2512 					listOfConstants.insert(sConstant);
2513 					script.skipEmpty();
2514 				}
2515 				if (!script.isEqualTo('}')) throw UtlException(script, "'{' expected");
2516 				pResultExpr = new ExprScriptInSet(pResultExpr, listOfConstants);
2517 				break;
2518 			} else break;
2519 		} while (true);
2520 		return pResultExpr;
2521 	}
2522 
parseTernaryExpression(GrfBlock & block,ScpStream & script)2523 	ExprScriptExpression* DtaScript::parseTernaryExpression(GrfBlock& block, ScpStream& script) {
2524    		ExprScriptExpression* pResultExpr = parseComparisonExpression(block, script);
2525 		script.skipEmpty();
2526 		if (script.isEqualTo('?')) {
2527 			std::auto_ptr<ExprScriptExpression> noLeak(pResultExpr);
2528 	   		ExprScriptExpression* pTrueExpr = parseExpression(block, script);
2529 			script.skipEmpty();
2530 			if (!script.isEqualTo(':')) throw UtlException(script, "':' expected in the ternary operator");
2531 	   		ExprScriptExpression* pFalseExpr = parseExpression(block, script);
2532 			pResultExpr = new ExprScriptTernaryOperator(pResultExpr, pTrueExpr, pFalseExpr);
2533 			noLeak.release();
2534 		}
2535 		return pResultExpr;
2536 	}
2537 
parseBooleanExpression(GrfBlock & block,ScpStream & script)2538 	ExprScriptExpression* DtaScript::parseBooleanExpression(GrfBlock& block, ScpStream& script) {
2539 		ExprScriptExpression* pResultExpr = NULL;
2540 		char cOperator = '\0';
2541 		do {
2542     		ExprScriptExpression* pExpr = NULL;
2543 			script.skipEmpty();
2544 			try {
2545 				pExpr = parseTernaryExpression(block, script);
2546 			} catch(std::exception&/* e*/) {
2547 				delete pResultExpr;
2548 				throw/* UtlException(e)*/;
2549 			}
2550 			if (pResultExpr == NULL) pResultExpr = pExpr;
2551 			else pResultExpr = new ExprScriptBoolean(pResultExpr, pExpr, cOperator);
2552 			script.skipEmpty();
2553 			if (script.isEqualTo('&')) cOperator = '&';
2554 			else if (script.isEqualTo('|')) cOperator = '|';
2555 			else if (script.isEqualTo('^')) cOperator = '^';
2556 			else break;
2557 			script.isEqualTo(cOperator);
2558 		} while (true);
2559 		return pResultExpr;
2560 	}
2561 
parseExpression(GrfBlock & block,ScpStream & script)2562 	ExprScriptExpression* DtaScript::parseExpression(GrfBlock& block, ScpStream& script) {
2563 		if (hasTargetLanguage()) {
2564 			// expression embedded in a script written in a target language
2565 			if (script.isEqualTo('[')) {
2566 				// CodeWorker expression
2567 				std::auto_ptr<ExprScriptExpression> pExpr(parseBooleanExpression(block, script));
2568 				if (!script.isEqualTo(']')) throw UtlException(script, "syntax error, ']' expected");
2569 				return pExpr.release();
2570 			}
2571 			// alien expression
2572 			return parseAlienExpression(block, script);
2573 		}
2574 		return parseBooleanExpression(block, script);
2575 	}
2576 
parseScriptFileExpression(GrfBlock & block,ScpStream & script,DtaScriptFactory::SCRIPT_TYPE eScriptType)2577 	ExprScriptScriptFile* DtaScript::parseScriptFileExpression(GrfBlock& block, ScpStream& script, DtaScriptFactory::SCRIPT_TYPE eScriptType) {
2578 		ExprScriptScriptFile* pExpr;
2579 		script.skipEmpty();
2580 		if (script.isEqualTo('{')) {
2581 			script.goBack();
2582 			std::auto_ptr<DtaScript> pScript(DtaScriptFactory::create(eScriptType, block));
2583 			pScript->parseEmbeddedScript(script);
2584 			pExpr = new ExprScriptScriptFile(pScript.release());
2585 			script.skipEmpty();
2586 		} else {
2587 			ExprScriptExpression* pFileExpr = parseExpression(block, script);
2588 			pExpr = new ExprScriptScriptFile(pFileExpr);
2589 		}
2590 		return pExpr;
2591 	}
2592 
parseIndexExpression(GrfBlock &,ScpStream & script)2593 	ExprScriptVariable* DtaScript::parseIndexExpression(GrfBlock& /*block*/, ScpStream& script) {
2594 		std::string sWord;
2595 		script.skipEmpty();
2596 		if (!script.readIdentifier(sWord)) throw UtlException(script, "syntax error: index name expected");
2597 		ExprScriptVariable* pIndexExpr = new ExprScriptVariable(sWord.c_str());
2598 		return pIndexExpr;
2599 	}
2600 
parseReferenceExpression(GrfBlock &,ScpStream & script)2601 	ExprScriptVariable* DtaScript::parseReferenceExpression(GrfBlock& /*block*/, ScpStream& script) {
2602 		std::string sWord;
2603 		script.skipEmpty();
2604 		if (!script.readIdentifier(sWord)) throw UtlException(script, "syntax error: reference name expected");
2605 		script.skipEmpty();
2606 		if (script.isEqualTo('.') || script.isEqualTo('#') || script.isEqualTo('[') || (script.isEqualTo('$') && script.peekChar() == (int) '[')) throw UtlException(script, "syntax error: reference name expected (not a variable expression)");
2607 		ExprScriptVariable* pReferenceExpr = new ExprScriptVariable(sWord.c_str());
2608 		return pReferenceExpr;
2609 	}
2610 
parseVariableExpression(GrfBlock & block,ScpStream & script,ExprScriptVariable * pParentExpr)2611 	ExprScriptVariable* DtaScript::parseVariableExpression(GrfBlock& block, ScpStream& script, ExprScriptVariable* pParentExpr) {
2612 		ExprScriptExpression* pMethodExpr;
2613 		GrfCommand* pMethodProc;
2614 		ExprScriptVariable* pVariableExpr = parseVariableExpression(block, script, pParentExpr, pMethodExpr, pMethodProc);
2615 		if ((pMethodExpr != NULL) || (pMethodProc != NULL)) {
2616 			delete pVariableExpr;
2617 			throw UtlException(script, "variable expected, instead of method call");
2618 		}
2619 		return pVariableExpr;
2620 	}
2621 
parseVariableExpression(GrfBlock & block,ScpStream & script,ExprScriptVariable * pParentExpr,ExprScriptExpression * & pMethodExpr,GrfCommand * & pMethodProc)2622 	ExprScriptVariable* DtaScript::parseVariableExpression(GrfBlock& block, ScpStream& script, ExprScriptVariable* pParentExpr, ExprScriptExpression*& pMethodExpr, GrfCommand*& pMethodProc) {
2623 		std::string sWord;
2624 		pMethodExpr = NULL;
2625 		pMethodProc = NULL;
2626 		if (pParentExpr == NULL) {
2627 			script.skipEmpty();
2628 			bool bDirective = script.isEqualTo('#');
2629 			if (!script.readIdentifier(sWord)) throw UtlException(script, "syntax error: variable expression expected");
2630 			if (bDirective) {
2631 				if (sWord == "evaluateVariable") {
2632 					script.skipEmpty();
2633 					if (!script.isEqualTo('(')) throw UtlException(script, "syntax error: '(' expected");
2634 					pParentExpr = new ExprScriptVariable(sWord.c_str());
2635 					pParentExpr->setEvaluation(parseExpression(block, script));
2636 					script.skipEmpty();
2637 					if (!script.isEqualTo(')')) {
2638 						delete pParentExpr;
2639 						throw UtlException(script, "syntax error: ')' expected");
2640 					}
2641 					script.skipEmpty();
2642 					return pParentExpr;
2643 				} else {
2644 					throw UtlException(script, "syntax error: '#evaluateVariable' expected in a variable expression");
2645 				}
2646 			} else {
2647 				if (script.isEqualTo("::")) {
2648 					DynPackage* pPackage = DynPackage::getPackage(sWord);
2649 					if (pPackage == NULL) throw UtlException(script, "unknown module '" + sWord +"'; type '#use' to load the dynamic library");
2650 					script.skipEmpty();
2651 					std::string sVariable;
2652 					if (!script.readIdentifier(sVariable)) throw UtlException(script, "variable name expected after '" + sWord + "::'");
2653 					pParentExpr = new ExprScriptVariable(sVariable.c_str(), pPackage);
2654 				} else {
2655 					pParentExpr = new ExprScriptVariable(sWord.c_str());
2656 				}
2657 			}
2658 		} else {
2659 			// just for the following message
2660 			sWord = pParentExpr->getName();
2661 		}
2662 		if (!sWord.empty() && (&block != NULL) && (block.getVariable(sWord) == UNKNOWN_EXPRTYPE) && (pParentExpr->getPackage() == NULL)) {
2663 			if (!DtaProject::getInstance().noWarning("undeclvar")) {
2664 				std::string sErrorMessage = script.getMessagePrefix() + "warning! you haven't declared the variable '" + sWord + "' before ; interpreted as 'this." + sWord + "', but obsolete soon!";
2665 				CGRuntime::traceLine(sErrorMessage);
2666 			}
2667 		}
2668 		ExprScriptVariable* pExpr = pParentExpr;
2669 		ExprScriptVariable* pPrecExpr = pParentExpr;
2670 		bool bArrayIterator;
2671 		bool bNext = true;
2672 		do {
2673 			bool bArray = false;
2674 			bArrayIterator = script.isEqualTo('#');
2675 			if (script.isEqualTo('[')) {
2676 				bArray = true;
2677 				try {
2678 					if (bArrayIterator) pExpr->setArrayPosition(parseExpression(block, script));
2679 					else pExpr->setArrayKey(parseExpression(block, script));
2680 				} catch(std::exception&/* except*/) {
2681 					delete pParentExpr;
2682 					throw/* UtlException(except)*/;
2683 				}
2684 				if (!script.isEqualTo(']')) {
2685 					delete pParentExpr;
2686 					throw UtlException(script, "syntax error: ']' expected");
2687 				}
2688 			} else if (bArrayIterator) {
2689 				if (!script.readIdentifier(sWord) || ((sWord != "front") && (sWord != "back") && (sWord != "parent") && (sWord != "root"))) throw UtlException(script, "'[' or 'front' or 'back' expected after '#' to precise an array index");
2690 				if (sWord == "front") pExpr->setArrayPosition(new ExprScriptConstant("0"));
2691 				else pExpr->setArrayPosition(new ExprScriptConstant(sWord.c_str()));
2692 			}
2693 			bNext = script.isEqualTo('.');
2694 			if (bNext) {
2695 				if (!script.readIdentifier(sWord)) {
2696 					delete pParentExpr;
2697 					throw UtlException(script, "syntax error: variable expected");
2698 				}
2699 				std::auto_ptr<ExprScriptExpression> pTemplate;
2700 				int iLocation = script.getInputLocation();
2701 				if (script.isEqualTo('<')) {
2702 					std::auto_ptr<ExprScriptExpression> pTemplateExpression(parseKeyTemplateExpression(block, script));
2703 					pTemplate = pTemplateExpression;
2704 					script.skipEmpty();
2705 					if (script.isEqualTo('>')) {
2706 						script.skipEmpty();
2707 						if (!script.isEqualTo('(')) throw UtlException(script, "'(' expected after instantiating a template method");
2708 					} else {
2709 						std::auto_ptr<ExprScriptExpression> pTemplateExpression;
2710 						pTemplate = pTemplateExpression;
2711 						script.setInputLocation(iLocation);
2712 					}
2713 				}
2714 				if ((pTemplate.get() != NULL) || script.isEqualTo('(')) {
2715 					ExprScriptFunction* pFunction = ExprScriptFunction::createMethod(block, script, sWord, "", false);
2716 					if (pFunction != NULL) {
2717 						checkIfAllowedFunction(script, *pFunction);
2718 						pMethodExpr = parseFunctionExpression(block, script, pParentExpr, pFunction, pTemplate.release(), true);
2719 					} else {
2720 						script.goBack();
2721 						if (!parseKeyword(sWord, script, block, pParentExpr)) throw UtlException(script, "unknown method \"" + sWord + "\"");
2722 						pMethodProc = block.getCommands().back();
2723 					}
2724 					break;
2725 				}
2726 				pExpr = new ExprScriptVariable(pPrecExpr, sWord.c_str());
2727 				pPrecExpr = pExpr;
2728 			} else {
2729 				int iChar = script.peekChar();
2730 				bNext = (iChar == (int) '[') || (iChar == (int) '#');
2731 				if (bNext && (bArray || bArrayIterator)) {
2732 					pExpr = new ExprScriptVariable(pPrecExpr, "");
2733 					pPrecExpr = pExpr;
2734 				}
2735 			}
2736 		} while (bNext);
2737 		return pParentExpr;
2738 	}
2739 
parseMotifStepExpression(GrfBlock & block,ScpStream & script,ExprScriptMotifPath * & pPathExpr)2740 	ExprScriptMotifStep* DtaScript::parseMotifStepExpression(GrfBlock& block, ScpStream& script, ExprScriptMotifPath*& pPathExpr) {
2741 		std::auto_ptr<ExprScriptMotifStep> pParent;
2742 		std::string sIdentifier;
2743 		script.skipEmpty();
2744 		if (script.isEqualTo('*')) sIdentifier = "*";
2745 		else script.readIdentifier(sIdentifier);
2746 		if (!sIdentifier.empty()) {
2747 			std::auto_ptr<ExprScriptMotifStep> pMotifStep(new ExprScriptMotifStep(sIdentifier));
2748 			pParent = pMotifStep;
2749 			pPathExpr = pParent.get();
2750 			script.skipEmpty();
2751 			while (script.isEqualTo('[')) {
2752 				script.skipEmpty();
2753 				if (script.isEqualTo(']')) {
2754 					pPathExpr = new ExprScriptMotifArray(pPathExpr);
2755 				} else {
2756 					pPathExpr = new ExprScriptMotifArray(pPathExpr, parseExpression(block, script));
2757 					script.skipEmpty();
2758 					if (!script.isEqualTo(']')) throw UtlException(script, "']' expected to close an array in a motif");
2759 				}
2760 				script.skipEmpty();
2761 			}
2762 		} else {
2763 			throw UtlException(script, "location path expected");
2764 		}
2765 		return pParent.release();
2766 	}
2767 
parseMotifPathExpression(GrfBlock & block,ScpStream & script)2768 	ExprScriptMotifPath* DtaScript::parseMotifPathExpression(GrfBlock& block, ScpStream& script) {
2769 		ExprScriptMotifPath* pEndPath;
2770 		std::auto_ptr<ExprScriptMotifPath> pParent(parseMotifStepExpression(block, script, pEndPath));
2771 		script.skipEmpty();
2772 		while (script.isEqualTo('.')) {
2773 			ExprScriptMotifPath* pMotif = pEndPath;
2774 			if (script.isEqualTo("..")) {
2775 				new ExprScriptMotifEllipsis(pMotif, parseMotifStepExpression(block, script, pEndPath));
2776 			} else {
2777 				pMotif->setNextPath(parseMotifStepExpression(block, script, pEndPath));
2778 			}
2779 		}
2780 		return pParent.release();
2781 	}
2782 
parseMotifConcatExpression(GrfBlock & block,ScpStream & script)2783 	ExprScriptMotif* DtaScript::parseMotifConcatExpression(GrfBlock& block, ScpStream& script) {
2784 		std::auto_ptr<ExprScriptMotif> pParent(parseMotifPathExpression(block, script));
2785 		ExprScriptMotifBoolean* pBooleanMotif = NULL;
2786 		script.skipEmpty();
2787 		while (script.isEqualTo('+')) {
2788 			if (pBooleanMotif == NULL) {
2789 				pBooleanMotif = new ExprScriptMotifBoolean('+', pParent.release());
2790 				std::auto_ptr<ExprScriptMotif> pRef(pBooleanMotif);
2791 				pParent = pRef;
2792 			}
2793 			pBooleanMotif->addMember(parseMotifPathExpression(block, script));
2794 			script.skipEmpty();
2795 		}
2796 		return pParent.release();
2797 	}
2798 
parseMotifAndExpression(GrfBlock & block,ScpStream & script)2799 	ExprScriptMotif* DtaScript::parseMotifAndExpression(GrfBlock& block, ScpStream& script) {
2800 		std::auto_ptr<ExprScriptMotif> pParent(parseMotifConcatExpression(block, script));
2801 		ExprScriptMotifBoolean* pBooleanMotif = NULL;
2802 		script.skipEmpty();
2803 		while (script.isEqualTo("&&") || script.isEqualTo('&')) {
2804 			if (pBooleanMotif == NULL) {
2805 				pBooleanMotif = new ExprScriptMotifBoolean('&', pParent.release());
2806 				std::auto_ptr<ExprScriptMotif> pRef(pBooleanMotif);
2807 				pParent = pRef;
2808 			}
2809 			pBooleanMotif->addMember(parseMotifConcatExpression(block, script));
2810 			script.skipEmpty();
2811 		}
2812 		return pParent.release();
2813 	}
2814 
parseMotifExpression(GrfBlock & block,ScpStream & script)2815 	ExprScriptMotif* DtaScript::parseMotifExpression(GrfBlock& block, ScpStream& script) {
2816 		ExprScriptMotif* pMotif;
2817 		script.skipEmpty();
2818 		if (script.isEqualTo('(')) {
2819 			script.skipEmpty();
2820 			pMotif = parseMotifExpression(block, script);
2821 			script.skipEmpty();
2822 			if (!script.isEqualTo(')')) {
2823 				delete pMotif;
2824 				throw UtlException(script, "')' expected in a motif expression");
2825 			}
2826 			script.skipEmpty();
2827 		} else {
2828 			pMotif = parseMotifAndExpression(block, script);
2829 		}
2830 		std::auto_ptr<ExprScriptMotif> pParent(pMotif);
2831 		ExprScriptMotifBoolean* pBooleanMotif = NULL;
2832 		while (script.isEqualTo("||") || script.isEqualTo('|')) {
2833 			if (pBooleanMotif == NULL) {
2834 				pBooleanMotif = new ExprScriptMotifBoolean('|', pParent.release());
2835 				std::auto_ptr<ExprScriptMotif> pRef(pBooleanMotif);
2836 				pParent = pRef;
2837 			}
2838 			pBooleanMotif->addMember(parseMotifAndExpression(block, script));
2839 			script.skipEmpty();
2840 		}
2841 		return pParent.release();
2842 	}
2843 
parseFunctionExpression(GrfBlock & block,ScpStream & script,ExprScriptVariable * pMethodCaller,ExprScriptFunction * pFunction,ExprScriptExpression * pTemplate,bool bBracket)2844 	ExprScriptFunction* DtaScript::parseFunctionExpression(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller, ExprScriptFunction* pFunction, ExprScriptExpression* pTemplate, bool bBracket) {
2845 		std::string sWord;
2846 		unsigned int iIndex = 0;
2847 		pFunction->setTemplate(pTemplate);
2848 		if (pFunction->getArity() != 0) {
2849 			if (bBracket) {
2850 				script.skipEmpty();
2851 				if ((pFunction->getMinArity() > 0) || (script.peekChar() != ')')) {
2852 					// not in the case where the first parameter is optional and not provided
2853 					do {
2854 						try {
2855 							if ((pMethodCaller != NULL) && (iIndex == pFunction->getThisPosition())) {
2856 								EXPRESSION_TYPE parameterType = pFunction->getParameterType(pFunction->getThisPosition());
2857 								pFunction->addParameter(pMethodCaller);
2858 								iIndex++;
2859 								script.skipEmpty();
2860 								if (script.isEqualTo(')')) {
2861 									script.goBack();
2862 									break;
2863 								}
2864 							}
2865 							bool bOldArithmeticState = _bNumericalExpression;
2866 							_bNumericalExpression = false;
2867 							switch(pFunction->getParameterType(iIndex) & 0x00FF) {
2868 								case VALUE_EXPRTYPE: pFunction->addParameter(parseExpression(block, script));break;
2869 								case REFERENCE_EXPRTYPE: pFunction->addParameter(parseVariableExpression(block, script));break;
2870 								case NODE_EXPRTYPE: pFunction->addParameter(parseVariableExpression(block, script));break;
2871 								case ITERATOR_EXPRTYPE: pFunction->addParameter(parseIndexExpression(block, script));break;
2872 								case SCRIPTFILE_EXPRTYPE: pFunction->addParameter(parseScriptFileExpression(block, script, DtaScriptFactory::COMMON_SCRIPT));break;
2873 								case SCRIPTFILE_PATTERN_EXPRTYPE: pFunction->addParameter(parseScriptFileExpression(block, script, DtaScriptFactory::PATTERN_SCRIPT));break;
2874 								case SCRIPTFILE_FREE_EXPRTYPE: pFunction->addParameter(parseScriptFileExpression(block, script, DtaScriptFactory::FREE_SCRIPT));break;
2875 								case SCRIPTFILE_BNF_EXPRTYPE: pFunction->addParameter(parseScriptFileExpression(block, script, DtaScriptFactory::BNF_SCRIPT));break;
2876 								case SCRIPTFILE_TRANSLATE_EXPRTYPE: pFunction->addParameter(parseScriptFileExpression(block, script, DtaScriptFactory::TRANSLATE_SCRIPT));break;
2877 							}
2878 							_bNumericalExpression = bOldArithmeticState;
2879 						} catch(UtlExitException&) {
2880 							delete pFunction;
2881 							throw;
2882 						} catch(UtlException& e) {
2883 							std::string sMessage = e.getMessage();
2884 							char tcNumber[32];
2885 							sprintf(tcNumber, "%d", iIndex + 1);
2886 							sMessage += " while parsing parameter ";
2887 							sMessage += tcNumber;
2888 							sMessage += " of function '" + std::string(pFunction->getName()) + "'";
2889 							delete pFunction;
2890 							throw UtlException(e.getTraceStack(), sMessage);
2891 						}
2892 						script.skipEmpty();
2893 						iIndex++;
2894 					} while (script.isEqualTo(',') || ((pMethodCaller != NULL) && (iIndex == pFunction->getThisPosition())));
2895 				}
2896 			} else {
2897 				pFunction->addParameter(parseLiteralExpression(block, script));
2898 				iIndex++;
2899 			}
2900 		}
2901 		if (iIndex < pFunction->getMinArity()) {
2902 			std::string sMessageFormat = "Not enough parameters encountered";
2903 			if (pFunction != NULL) sMessageFormat += " for call to function '" + std::string(pFunction->getName()) + "'";
2904 			delete pFunction;
2905 			throw UtlException(script, sMessageFormat);
2906 		}
2907 		if (iIndex > pFunction->getArity()) {
2908 			std::string sMessageFormat = "too many parameters encountered";
2909 			if (pFunction != NULL) sMessageFormat += " for call to function '" + std::string(pFunction->getName()) + "'";
2910 			delete pFunction;
2911 			throw UtlException(script, sMessageFormat);
2912 		}
2913 		if (iIndex < pFunction->getArity()) {
2914 			// default parameters to populate
2915 			do {
2916 				ExprScriptExpression* pDefaultValue = pFunction->getDefaultParameter(iIndex);
2917 				pFunction->addParameter(pDefaultValue->clone());
2918 				++iIndex;
2919 			} while (iIndex < pFunction->getArity());
2920 		}
2921 		if (bBracket && !script.isEqualTo(')')) {
2922 			std::string sMessageFormat = "syntax error, ')' expected to close parameters";
2923 			if (pFunction != NULL) sMessageFormat += " of '" + std::string(pFunction->getName()) + "'";
2924 			int iChar = script.readChar();
2925 			if (iChar < 0) sMessageFormat += ", instead of end of file";
2926 			else {
2927 				sMessageFormat += ", instead of '";
2928 				sMessageFormat += (char) iChar;
2929 				sMessageFormat += "'";
2930 			}
2931 			delete pFunction;
2932 			throw UtlException(script, sMessageFormat);
2933 		}
2934 		pFunction->initializationDone();
2935 		return pFunction;
2936 	}
2937 
checkIfAllowedFunction(ScpStream & script,ExprScriptFunction & theFunction)2938 	void DtaScript::checkIfAllowedFunction(ScpStream& script, ExprScriptFunction& theFunction) {
2939 		if (theFunction.isAGenerateFunction() && !isAGenerateScript()) throw UtlException(script, "function '" + std::string(theFunction.getName()) + "' reserved for template-based scripts only");
2940 		if (theFunction.isAParseFunction() && !isAParseScript()) throw UtlException(script, "function '" + std::string(theFunction.getName()) + "' reserved for parse scripts only");
2941 	}
2942 
parseReadonlyHook(GrfBlock & block,ScpStream & script)2943 	void DtaScript::parseReadonlyHook(GrfBlock& block, ScpStream& script) {
2944 		if (DtaProject::getInstance().getReadonlyHook() != NULL) throw UtlException(script, "function 'readonlyHook(<filename>)' has already been defined and can't be implemented twice");
2945 		GrfReadonlyHook* pReadonlyHook = new GrfReadonlyHook(&block);
2946 		if (requiresParsingInformation()) pReadonlyHook->setParsingInformation(getFilenamePtr(), script);
2947 		block.addFunction(pReadonlyHook);
2948 		script.skipEmpty();
2949 		if (!script.isEqualTo('(')) throw UtlException(script, "syntax error: '(' expected");
2950 		script.skipEmpty();
2951 		std::string sIdentifier;
2952 		if (!script.readIdentifier(sIdentifier)) throw UtlException(script, "syntax error: argument name expected");
2953 		pReadonlyHook->setParameterName(sIdentifier.c_str());
2954 		script.skipEmpty();
2955 		if (!script.isEqualTo(')')) throw UtlException(script, "syntax error: ')' expected");
2956 		std::string _sOldFunctionBody = _sCurrentFunctionBody;
2957 		std::string _sOldFunctionTemplateBody = _sCurrentFunctionTemplateBody;
2958 		bool bOldCurrentFunctionGenericTemplateKey = _bCurrentFunctionGenericTemplateKey;
2959 		_sCurrentFunctionBody = pReadonlyHook->getFunctionName();
2960 		_sCurrentFunctionTemplateBody = "";
2961 		_bCurrentFunctionGenericTemplateKey = false;
2962 		pReadonlyHook->isBodyDefined(true);
2963 		parseBlock(script, *pReadonlyHook);
2964 		_sCurrentFunctionBody = _sOldFunctionBody;
2965 		_sCurrentFunctionTemplateBody = _sOldFunctionTemplateBody;
2966 		_bCurrentFunctionGenericTemplateKey = bOldCurrentFunctionGenericTemplateKey;
2967 	}
2968 
parseWritefileHook(GrfBlock & block,ScpStream & script)2969 	void DtaScript::parseWritefileHook(GrfBlock& block, ScpStream& script) {
2970 		if (DtaProject::getInstance().getWritefileHook() != NULL) throw UtlException(script, "hook 'writefileHook(<filename>, <position>, <creation>)' has already been defined and can't be implemented twice");
2971 		GrfWritefileHook* pWritefileHook = new GrfWritefileHook(&block);
2972 		if (requiresParsingInformation()) pWritefileHook->setParsingInformation(getFilenamePtr(), script);
2973 		block.addFunction(pWritefileHook);
2974 		script.skipEmpty();
2975 		if (!script.isEqualTo('(')) throw UtlException(script, "syntax error: '(' expected");
2976 		script.skipEmpty();
2977 		std::string sIdentifier;
2978 		if (!script.readIdentifier(sIdentifier)) throw UtlException(script, "syntax error: argument '<filename>' expected for hook 'writefileHook(<filename>, <position>, <creation>)'");
2979 		pWritefileHook->setFileNameArgument(sIdentifier.c_str());
2980 		script.skipEmpty();
2981 		if (!script.isEqualTo(',')) throw UtlException(script, "syntax error: ',' expected");
2982 		script.skipEmpty();
2983 		if (!script.readIdentifier(sIdentifier)) throw UtlException(script, "syntax error: argument '<position>' expected for hook 'writefileHook(<filename>, <position>, <creation>)'");
2984 		pWritefileHook->setPositionArgument(sIdentifier.c_str());
2985 		script.skipEmpty();
2986 		if (!script.isEqualTo(',')) throw UtlException(script, "syntax error: ',' expected");
2987 		script.skipEmpty();
2988 		if (!script.readIdentifier(sIdentifier)) throw UtlException(script, "syntax error: argument '<creation>' expected for hook 'writefileHook(<filename>, <position>, <creation>)'");
2989 		pWritefileHook->setCreationArgument(sIdentifier.c_str());
2990 		script.skipEmpty();
2991 		if (!script.isEqualTo(')')) throw UtlException(script, "syntax error: ')' expected");
2992 		std::string _sOldFunctionBody = _sCurrentFunctionBody;
2993 		std::string _sOldFunctionTemplateBody = _sCurrentFunctionTemplateBody;
2994 		bool bOldCurrentFunctionGenericTemplateKey = _bCurrentFunctionGenericTemplateKey;
2995 		_sCurrentFunctionBody = pWritefileHook->getFunctionName();
2996 		_sCurrentFunctionTemplateBody = "";
2997 		_bCurrentFunctionGenericTemplateKey = false;
2998 		pWritefileHook->isBodyDefined(true);
2999 		parseBlock(script, *pWritefileHook);
3000 		_sCurrentFunctionBody = _sOldFunctionBody;
3001 		_sCurrentFunctionTemplateBody = _sOldFunctionTemplateBody;
3002 		_bCurrentFunctionGenericTemplateKey = bOldCurrentFunctionGenericTemplateKey;
3003 	}
3004 
3005 //##markup##"parsing"
3006 //##begin##"parsing"
parseAppendFile(GrfBlock & block,ScpStream & script,ExprScriptVariable * pMethodCaller)3007 void DtaScript::parseAppendFile(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller) {
3008 	GrfAppendFile* pAppendFile = new GrfAppendFile;
3009 	if (requiresParsingInformation()) pAppendFile->setParsingInformation(getFilenamePtr(), script);
3010 	block.add(pAppendFile);
3011 	script.skipEmpty();
3012 	if (!script.isEqualTo('(')) throw UtlException(script, "syntax error: '(' expected");
3013 	script.skipEmpty();
3014 	if (pMethodCaller == NULL) pAppendFile->setFilename(parseExpression(block, script));
3015 	else pAppendFile->setFilename(pMethodCaller);
3016 	if ((pMethodCaller == NULL) && !script.isEqualTo(',')) throw UtlException(script, "syntax error: ',' expected");
3017 	script.skipEmpty();
3018 	pAppendFile->setContent(parseExpression(block, script));
3019 	script.skipEmpty();
3020 	if (!script.isEqualTo(')')) throw UtlException(script, "syntax error: ')' expected");
3021 	script.skipEmpty();
3022 	if (!script.isEqualTo(';')) throw UtlException(script, "syntax error: ';' expected");
3023 }
3024 
parseAutoexpand(GrfBlock & block,ScpStream & script,ExprScriptVariable * pMethodCaller)3025 void DtaScript::parseAutoexpand(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller) {
3026 	GrfAutoexpand* pAutoexpand = new GrfAutoexpand;
3027 	if (requiresParsingInformation()) pAutoexpand->setParsingInformation(getFilenamePtr(), script);
3028 	block.add(pAutoexpand);
3029 	script.skipEmpty();
3030 	if (!script.isEqualTo('(')) throw UtlException(script, "syntax error: '(' expected");
3031 	script.skipEmpty();
3032 	if (pMethodCaller == NULL) pAutoexpand->setOutputFileName(parseExpression(block, script));
3033 	else pAutoexpand->setOutputFileName(pMethodCaller);
3034 	if ((pMethodCaller == NULL) && !script.isEqualTo(',')) throw UtlException(script, "syntax error: ',' expected");
3035 	script.skipEmpty();
3036 	pAutoexpand->setThis(parseVariableExpression(block, script));
3037 	script.skipEmpty();
3038 	if (!script.isEqualTo(')')) throw UtlException(script, "syntax error: ')' expected");
3039 	script.skipEmpty();
3040 	if (!script.isEqualTo(';')) throw UtlException(script, "syntax error: ';' expected");
3041 }
3042 
parseClearVariable(GrfBlock & block,ScpStream & script,ExprScriptVariable * pMethodCaller)3043 void DtaScript::parseClearVariable(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller) {
3044 	GrfClearVariable* pClearVariable = new GrfClearVariable;
3045 	if (requiresParsingInformation()) pClearVariable->setParsingInformation(getFilenamePtr(), script);
3046 	block.add(pClearVariable);
3047 	script.skipEmpty();
3048 	if (!script.isEqualTo('(')) throw UtlException(script, "syntax error: '(' expected");
3049 	script.skipEmpty();
3050 	if (pMethodCaller == NULL) pClearVariable->setNode(parseVariableExpression(block, script));
3051 	else pClearVariable->setNode(pMethodCaller);
3052 	if (!script.isEqualTo(')')) throw UtlException(script, "syntax error: ')' expected");
3053 	script.skipEmpty();
3054 	if (!script.isEqualTo(';')) throw UtlException(script, "syntax error: ';' expected");
3055 }
3056 
parseCompileToCpp(GrfBlock & block,ScpStream & script,ExprScriptVariable * pMethodCaller)3057 void DtaScript::parseCompileToCpp(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller) {
3058 	GrfCompileToCpp* pCompileToCpp = new GrfCompileToCpp;
3059 	if (requiresParsingInformation()) pCompileToCpp->setParsingInformation(getFilenamePtr(), script);
3060 	block.add(pCompileToCpp);
3061 	script.skipEmpty();
3062 	if (!script.isEqualTo('(')) throw UtlException(script, "syntax error: '(' expected");
3063 	script.skipEmpty();
3064 	if (pMethodCaller == NULL) pCompileToCpp->setScriptFileName(parseExpression(block, script));
3065 	else pCompileToCpp->setScriptFileName(pMethodCaller);
3066 	if ((pMethodCaller == NULL) && !script.isEqualTo(',')) throw UtlException(script, "syntax error: ',' expected");
3067 	script.skipEmpty();
3068 	pCompileToCpp->setProjectDirectory(parseExpression(block, script));
3069 	script.skipEmpty();
3070 	if (!script.isEqualTo(',')) throw UtlException(script, "syntax error: ',' expected");
3071 	script.skipEmpty();
3072 	pCompileToCpp->setCodeWorkerDirectory(parseExpression(block, script));
3073 	script.skipEmpty();
3074 	if (!script.isEqualTo(')')) throw UtlException(script, "syntax error: ')' expected");
3075 	script.skipEmpty();
3076 	if (!script.isEqualTo(';')) throw UtlException(script, "syntax error: ';' expected");
3077 }
3078 
parseCopyFile(GrfBlock & block,ScpStream & script,ExprScriptVariable * pMethodCaller)3079 void DtaScript::parseCopyFile(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller) {
3080 	GrfCopyFile* pCopyFile = new GrfCopyFile;
3081 	if (requiresParsingInformation()) pCopyFile->setParsingInformation(getFilenamePtr(), script);
3082 	block.add(pCopyFile);
3083 	script.skipEmpty();
3084 	if (!script.isEqualTo('(')) throw UtlException(script, "syntax error: '(' expected");
3085 	script.skipEmpty();
3086 	if (pMethodCaller == NULL) pCopyFile->setSourceFileName(parseExpression(block, script));
3087 	else pCopyFile->setSourceFileName(pMethodCaller);
3088 	if ((pMethodCaller == NULL) && !script.isEqualTo(',')) throw UtlException(script, "syntax error: ',' expected");
3089 	script.skipEmpty();
3090 	pCopyFile->setDestinationFileName(parseExpression(block, script));
3091 	script.skipEmpty();
3092 	if (!script.isEqualTo(')')) throw UtlException(script, "syntax error: ')' expected");
3093 	script.skipEmpty();
3094 	if (!script.isEqualTo(';')) throw UtlException(script, "syntax error: ';' expected");
3095 }
3096 
parseCopyGenerableFile(GrfBlock & block,ScpStream & script,ExprScriptVariable * pMethodCaller)3097 void DtaScript::parseCopyGenerableFile(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller) {
3098 	GrfCopyGenerableFile* pCopyGenerableFile = new GrfCopyGenerableFile;
3099 	if (requiresParsingInformation()) pCopyGenerableFile->setParsingInformation(getFilenamePtr(), script);
3100 	block.add(pCopyGenerableFile);
3101 	script.skipEmpty();
3102 	if (!script.isEqualTo('(')) throw UtlException(script, "syntax error: '(' expected");
3103 	script.skipEmpty();
3104 	if (pMethodCaller == NULL) pCopyGenerableFile->setSourceFileName(parseExpression(block, script));
3105 	else pCopyGenerableFile->setSourceFileName(pMethodCaller);
3106 	if ((pMethodCaller == NULL) && !script.isEqualTo(',')) throw UtlException(script, "syntax error: ',' expected");
3107 	script.skipEmpty();
3108 	pCopyGenerableFile->setDestinationFileName(parseExpression(block, script));
3109 	script.skipEmpty();
3110 	if (!script.isEqualTo(')')) throw UtlException(script, "syntax error: ')' expected");
3111 	script.skipEmpty();
3112 	if (!script.isEqualTo(';')) throw UtlException(script, "syntax error: ';' expected");
3113 }
3114 
parseCopySmartDirectory(GrfBlock & block,ScpStream & script,ExprScriptVariable * pMethodCaller)3115 void DtaScript::parseCopySmartDirectory(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller) {
3116 	GrfCopySmartDirectory* pCopySmartDirectory = new GrfCopySmartDirectory;
3117 	if (requiresParsingInformation()) pCopySmartDirectory->setParsingInformation(getFilenamePtr(), script);
3118 	block.add(pCopySmartDirectory);
3119 	script.skipEmpty();
3120 	if (!script.isEqualTo('(')) throw UtlException(script, "syntax error: '(' expected");
3121 	script.skipEmpty();
3122 	if (pMethodCaller == NULL) pCopySmartDirectory->setSourceDirectory(parseExpression(block, script));
3123 	else pCopySmartDirectory->setSourceDirectory(pMethodCaller);
3124 	if ((pMethodCaller == NULL) && !script.isEqualTo(',')) throw UtlException(script, "syntax error: ',' expected");
3125 	script.skipEmpty();
3126 	pCopySmartDirectory->setDestinationPath(parseExpression(block, script));
3127 	script.skipEmpty();
3128 	if (!script.isEqualTo(')')) throw UtlException(script, "syntax error: ')' expected");
3129 	script.skipEmpty();
3130 	if (!script.isEqualTo(';')) throw UtlException(script, "syntax error: ';' expected");
3131 }
3132 
parseCutString(GrfBlock & block,ScpStream & script,ExprScriptVariable * pMethodCaller)3133 void DtaScript::parseCutString(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller) {
3134 	GrfCutString* pCutString = new GrfCutString;
3135 	if (requiresParsingInformation()) pCutString->setParsingInformation(getFilenamePtr(), script);
3136 	block.add(pCutString);
3137 	script.skipEmpty();
3138 	if (!script.isEqualTo('(')) throw UtlException(script, "syntax error: '(' expected");
3139 	script.skipEmpty();
3140 	if (pMethodCaller == NULL) pCutString->setText(parseExpression(block, script));
3141 	else pCutString->setText(pMethodCaller);
3142 	if ((pMethodCaller == NULL) && !script.isEqualTo(',')) throw UtlException(script, "syntax error: ',' expected");
3143 	script.skipEmpty();
3144 	pCutString->setSeparator(parseExpression(block, script));
3145 	script.skipEmpty();
3146 	if (!script.isEqualTo(',')) throw UtlException(script, "syntax error: ',' expected");
3147 	script.skipEmpty();
3148 	pCutString->setList(parseVariableExpression(block, script));
3149 	script.skipEmpty();
3150 	if (!script.isEqualTo(')')) throw UtlException(script, "syntax error: ')' expected");
3151 	script.skipEmpty();
3152 	if (!script.isEqualTo(';')) throw UtlException(script, "syntax error: ';' expected");
3153 }
3154 
parseEnvironTable(GrfBlock & block,ScpStream & script,ExprScriptVariable * pMethodCaller)3155 void DtaScript::parseEnvironTable(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller) {
3156 	GrfEnvironTable* pEnvironTable = new GrfEnvironTable;
3157 	if (requiresParsingInformation()) pEnvironTable->setParsingInformation(getFilenamePtr(), script);
3158 	block.add(pEnvironTable);
3159 	script.skipEmpty();
3160 	if (!script.isEqualTo('(')) throw UtlException(script, "syntax error: '(' expected");
3161 	script.skipEmpty();
3162 	if (pMethodCaller == NULL) pEnvironTable->setTable(parseVariableExpression(block, script));
3163 	else pEnvironTable->setTable(pMethodCaller);
3164 	if (!script.isEqualTo(')')) throw UtlException(script, "syntax error: ')' expected");
3165 	script.skipEmpty();
3166 	if (!script.isEqualTo(';')) throw UtlException(script, "syntax error: ';' expected");
3167 }
3168 
parseError(GrfBlock & block,ScpStream & script,ExprScriptVariable * pMethodCaller)3169 void DtaScript::parseError(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller) {
3170 	GrfError* pError = new GrfError;
3171 	if (requiresParsingInformation()) pError->setParsingInformation(getFilenamePtr(), script);
3172 	block.add(pError);
3173 	script.skipEmpty();
3174 	if (!script.isEqualTo('(')) throw UtlException(script, "syntax error: '(' expected");
3175 	script.skipEmpty();
3176 	if (pMethodCaller == NULL) pError->setErrorMessage(parseExpression(block, script));
3177 	else pError->setErrorMessage(pMethodCaller);
3178 	if (!script.isEqualTo(')')) throw UtlException(script, "syntax error: ')' expected");
3179 	script.skipEmpty();
3180 	if (!script.isEqualTo(';')) throw UtlException(script, "syntax error: ';' expected");
3181 }
3182 
parseExecuteString(GrfBlock & block,ScpStream & script,ExprScriptVariable * pMethodCaller)3183 void DtaScript::parseExecuteString(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller) {
3184 	GrfExecuteString* pExecuteString = new GrfExecuteString;
3185 	if (requiresParsingInformation()) pExecuteString->setParsingInformation(getFilenamePtr(), script);
3186 	block.add(pExecuteString);
3187 	script.skipEmpty();
3188 	if (!script.isEqualTo('(')) throw UtlException(script, "syntax error: '(' expected");
3189 	script.skipEmpty();
3190 	if (pMethodCaller == NULL) pExecuteString->setThis(parseVariableExpression(block, script));
3191 	else pExecuteString->setThis(pMethodCaller);
3192 	if ((pMethodCaller == NULL) && !script.isEqualTo(',')) throw UtlException(script, "syntax error: ',' expected");
3193 	script.skipEmpty();
3194 	pExecuteString->setCommand(parseExpression(block, script));
3195 	script.skipEmpty();
3196 	if (!script.isEqualTo(')')) throw UtlException(script, "syntax error: ')' expected");
3197 	script.skipEmpty();
3198 	if (!script.isEqualTo(';')) throw UtlException(script, "syntax error: ';' expected");
3199 }
3200 
parseExpand(GrfBlock & block,ScpStream & script,ExprScriptVariable * pMethodCaller)3201 void DtaScript::parseExpand(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller) {
3202 	GrfExpand* pExpand = new GrfExpand;
3203 	if (requiresParsingInformation()) pExpand->setParsingInformation(getFilenamePtr(), script);
3204 	block.add(pExpand);
3205 	script.skipEmpty();
3206 	if (!script.isEqualTo('(')) throw UtlException(script, "syntax error: '(' expected");
3207 	script.skipEmpty();
3208 	if (pMethodCaller == NULL) pExpand->setPatternFileName(parseScriptFileExpression(block, script, DtaScriptFactory::PATTERN_SCRIPT));
3209 	else pExpand->setPatternFileName(pMethodCaller);
3210 	if ((pMethodCaller == NULL) && !script.isEqualTo(',')) throw UtlException(script, "syntax error: ',' expected");
3211 	script.skipEmpty();
3212 	pExpand->setThis(parseVariableExpression(block, script));
3213 	script.skipEmpty();
3214 	if (!script.isEqualTo(',')) throw UtlException(script, "syntax error: ',' expected");
3215 	script.skipEmpty();
3216 	pExpand->setOutputFileName(parseExpression(block, script));
3217 	script.skipEmpty();
3218 	if (!script.isEqualTo(')')) throw UtlException(script, "syntax error: ')' expected");
3219 	script.skipEmpty();
3220 	if (!script.isEqualTo(';')) throw UtlException(script, "syntax error: ';' expected");
3221 }
3222 
parseExtendExecutedScript(GrfBlock & block,ScpStream & script,ExprScriptVariable * pMethodCaller)3223 void DtaScript::parseExtendExecutedScript(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller) {
3224 	GrfExtendExecutedScript* pExtendExecutedScript = new GrfExtendExecutedScript;
3225 	if (requiresParsingInformation()) pExtendExecutedScript->setParsingInformation(getFilenamePtr(), script);
3226 	block.add(pExtendExecutedScript);
3227 	script.skipEmpty();
3228 	if (!script.isEqualTo('(')) throw UtlException(script, "syntax error: '(' expected");
3229 	script.skipEmpty();
3230 	if (pMethodCaller == NULL) pExtendExecutedScript->setScriptContent(parseExpression(block, script));
3231 	else pExtendExecutedScript->setScriptContent(pMethodCaller);
3232 	if (!script.isEqualTo(')')) throw UtlException(script, "syntax error: ')' expected");
3233 	script.skipEmpty();
3234 	if (!script.isEqualTo(';')) throw UtlException(script, "syntax error: ';' expected");
3235 }
3236 
parseGenerate(GrfBlock & block,ScpStream & script,ExprScriptVariable * pMethodCaller)3237 void DtaScript::parseGenerate(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller) {
3238 	GrfGenerate* pGenerate = new GrfGenerate;
3239 	if (requiresParsingInformation()) pGenerate->setParsingInformation(getFilenamePtr(), script);
3240 	block.add(pGenerate);
3241 	script.skipEmpty();
3242 	if (!script.isEqualTo('(')) throw UtlException(script, "syntax error: '(' expected");
3243 	script.skipEmpty();
3244 	if (pMethodCaller == NULL) pGenerate->setPatternFileName(parseScriptFileExpression(block, script, DtaScriptFactory::PATTERN_SCRIPT));
3245 	else pGenerate->setPatternFileName(pMethodCaller);
3246 	if ((pMethodCaller == NULL) && !script.isEqualTo(',')) throw UtlException(script, "syntax error: ',' expected");
3247 	script.skipEmpty();
3248 	pGenerate->setThis(parseVariableExpression(block, script));
3249 	script.skipEmpty();
3250 	if (!script.isEqualTo(',')) throw UtlException(script, "syntax error: ',' expected");
3251 	script.skipEmpty();
3252 	pGenerate->setOutputFileName(parseExpression(block, script));
3253 	script.skipEmpty();
3254 	if (!script.isEqualTo(')')) throw UtlException(script, "syntax error: ')' expected");
3255 	script.skipEmpty();
3256 	if (!script.isEqualTo(';')) throw UtlException(script, "syntax error: ';' expected");
3257 }
3258 
parseGenerateString(GrfBlock & block,ScpStream & script,ExprScriptVariable * pMethodCaller)3259 void DtaScript::parseGenerateString(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller) {
3260 	GrfGenerateString* pGenerateString = new GrfGenerateString;
3261 	if (requiresParsingInformation()) pGenerateString->setParsingInformation(getFilenamePtr(), script);
3262 	block.add(pGenerateString);
3263 	script.skipEmpty();
3264 	if (!script.isEqualTo('(')) throw UtlException(script, "syntax error: '(' expected");
3265 	script.skipEmpty();
3266 	if (pMethodCaller == NULL) pGenerateString->setPatternFileName(parseScriptFileExpression(block, script, DtaScriptFactory::PATTERN_SCRIPT));
3267 	else pGenerateString->setPatternFileName(pMethodCaller);
3268 	if ((pMethodCaller == NULL) && !script.isEqualTo(',')) throw UtlException(script, "syntax error: ',' expected");
3269 	script.skipEmpty();
3270 	pGenerateString->setThis(parseVariableExpression(block, script));
3271 	script.skipEmpty();
3272 	if (!script.isEqualTo(',')) throw UtlException(script, "syntax error: ',' expected");
3273 	script.skipEmpty();
3274 	pGenerateString->setOutputString(parseVariableExpression(block, script));
3275 	script.skipEmpty();
3276 	if (!script.isEqualTo(')')) throw UtlException(script, "syntax error: ')' expected");
3277 	script.skipEmpty();
3278 	if (!script.isEqualTo(';')) throw UtlException(script, "syntax error: ';' expected");
3279 }
3280 
parseInsertElementAt(GrfBlock & block,ScpStream & script,ExprScriptVariable * pMethodCaller)3281 void DtaScript::parseInsertElementAt(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller) {
3282 	GrfInsertElementAt* pInsertElementAt = new GrfInsertElementAt;
3283 	if (requiresParsingInformation()) pInsertElementAt->setParsingInformation(getFilenamePtr(), script);
3284 	block.add(pInsertElementAt);
3285 	script.skipEmpty();
3286 	if (!script.isEqualTo('(')) throw UtlException(script, "syntax error: '(' expected");
3287 	script.skipEmpty();
3288 	if (pMethodCaller == NULL) pInsertElementAt->setList(parseVariableExpression(block, script));
3289 	else pInsertElementAt->setList(pMethodCaller);
3290 	if ((pMethodCaller == NULL) && !script.isEqualTo(',')) throw UtlException(script, "syntax error: ',' expected");
3291 	script.skipEmpty();
3292 	pInsertElementAt->setKey(parseExpression(block, script));
3293 	script.skipEmpty();
3294 	if (!script.isEqualTo(',')) throw UtlException(script, "syntax error: ',' expected");
3295 	script.skipEmpty();
3296 	pInsertElementAt->setPosition(parseExpression(block, script));
3297 	script.skipEmpty();
3298 	if (!script.isEqualTo(')')) throw UtlException(script, "syntax error: ')' expected");
3299 	script.skipEmpty();
3300 	if (!script.isEqualTo(';')) throw UtlException(script, "syntax error: ';' expected");
3301 }
3302 
parseInvertArray(GrfBlock & block,ScpStream & script,ExprScriptVariable * pMethodCaller)3303 void DtaScript::parseInvertArray(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller) {
3304 	GrfInvertArray* pInvertArray = new GrfInvertArray;
3305 	if (requiresParsingInformation()) pInvertArray->setParsingInformation(getFilenamePtr(), script);
3306 	block.add(pInvertArray);
3307 	script.skipEmpty();
3308 	if (!script.isEqualTo('(')) throw UtlException(script, "syntax error: '(' expected");
3309 	script.skipEmpty();
3310 	if (pMethodCaller == NULL) pInvertArray->setArray(parseVariableExpression(block, script));
3311 	else pInvertArray->setArray(pMethodCaller);
3312 	if (!script.isEqualTo(')')) throw UtlException(script, "syntax error: ')' expected");
3313 	script.skipEmpty();
3314 	if (!script.isEqualTo(';')) throw UtlException(script, "syntax error: ';' expected");
3315 }
3316 
parseListAllGeneratedFiles(GrfBlock & block,ScpStream & script,ExprScriptVariable * pMethodCaller)3317 void DtaScript::parseListAllGeneratedFiles(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller) {
3318 	GrfListAllGeneratedFiles* pListAllGeneratedFiles = new GrfListAllGeneratedFiles;
3319 	if (requiresParsingInformation()) pListAllGeneratedFiles->setParsingInformation(getFilenamePtr(), script);
3320 	block.add(pListAllGeneratedFiles);
3321 	script.skipEmpty();
3322 	if (!script.isEqualTo('(')) throw UtlException(script, "syntax error: '(' expected");
3323 	script.skipEmpty();
3324 	if (pMethodCaller == NULL) pListAllGeneratedFiles->setFiles(parseVariableExpression(block, script));
3325 	else pListAllGeneratedFiles->setFiles(pMethodCaller);
3326 	if (!script.isEqualTo(')')) throw UtlException(script, "syntax error: ')' expected");
3327 	script.skipEmpty();
3328 	if (!script.isEqualTo(';')) throw UtlException(script, "syntax error: ';' expected");
3329 }
3330 
parseLoadProject(GrfBlock & block,ScpStream & script,ExprScriptVariable * pMethodCaller)3331 void DtaScript::parseLoadProject(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller) {
3332 	GrfLoadProject* pLoadProject = new GrfLoadProject;
3333 	if (requiresParsingInformation()) pLoadProject->setParsingInformation(getFilenamePtr(), script);
3334 	block.add(pLoadProject);
3335 	script.skipEmpty();
3336 	if (!script.isEqualTo('(')) throw UtlException(script, "syntax error: '(' expected");
3337 	script.skipEmpty();
3338 	if (pMethodCaller == NULL) pLoadProject->setXMLorTXTFileName(parseExpression(block, script));
3339 	else pLoadProject->setXMLorTXTFileName(pMethodCaller);
3340 	do {
3341 		if (pMethodCaller != NULL) {
3342 			if (script.peekChar() == ')') break;
3343 		} else {
3344 			if (!script.isEqualTo(',')) break;
3345 		}
3346 		script.skipEmpty();
3347 		pLoadProject->setNodeToLoad(parseVariableExpression(block, script));
3348 		script.skipEmpty();
3349 	} while (false);
3350 	pLoadProject->populateDefaultParameters();
3351 	if (!script.isEqualTo(')')) throw UtlException(script, "syntax error: ')' expected");
3352 	script.skipEmpty();
3353 	if (!script.isEqualTo(';')) throw UtlException(script, "syntax error: ';' expected");
3354 }
3355 
parseOpenLogFile(GrfBlock & block,ScpStream & script,ExprScriptVariable * pMethodCaller)3356 void DtaScript::parseOpenLogFile(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller) {
3357 	GrfOpenLogFile* pOpenLogFile = new GrfOpenLogFile;
3358 	if (requiresParsingInformation()) pOpenLogFile->setParsingInformation(getFilenamePtr(), script);
3359 	block.add(pOpenLogFile);
3360 	script.skipEmpty();
3361 	if (!script.isEqualTo('(')) throw UtlException(script, "syntax error: '(' expected");
3362 	script.skipEmpty();
3363 	if (pMethodCaller == NULL) pOpenLogFile->setFilename(parseExpression(block, script));
3364 	else pOpenLogFile->setFilename(pMethodCaller);
3365 	if (!script.isEqualTo(')')) throw UtlException(script, "syntax error: ')' expected");
3366 	script.skipEmpty();
3367 	if (!script.isEqualTo(';')) throw UtlException(script, "syntax error: ';' expected");
3368 }
3369 
parseParseAsBNF(GrfBlock & block,ScpStream & script,ExprScriptVariable * pMethodCaller)3370 void DtaScript::parseParseAsBNF(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller) {
3371 	GrfParseAsBNF* pParseAsBNF = new GrfParseAsBNF;
3372 	if (requiresParsingInformation()) pParseAsBNF->setParsingInformation(getFilenamePtr(), script);
3373 	block.add(pParseAsBNF);
3374 	script.skipEmpty();
3375 	if (!script.isEqualTo('(')) throw UtlException(script, "syntax error: '(' expected");
3376 	script.skipEmpty();
3377 	if (pMethodCaller == NULL) pParseAsBNF->setBNFFileName(parseScriptFileExpression(block, script, DtaScriptFactory::BNF_SCRIPT));
3378 	else pParseAsBNF->setBNFFileName(pMethodCaller);
3379 	if ((pMethodCaller == NULL) && !script.isEqualTo(',')) throw UtlException(script, "syntax error: ',' expected");
3380 	script.skipEmpty();
3381 	pParseAsBNF->setThis(parseVariableExpression(block, script));
3382 	script.skipEmpty();
3383 	if (!script.isEqualTo(',')) throw UtlException(script, "syntax error: ',' expected");
3384 	script.skipEmpty();
3385 	pParseAsBNF->setInputFileName(parseExpression(block, script));
3386 	script.skipEmpty();
3387 	if (!script.isEqualTo(')')) throw UtlException(script, "syntax error: ')' expected");
3388 	script.skipEmpty();
3389 	if (!script.isEqualTo(';')) throw UtlException(script, "syntax error: ';' expected");
3390 }
3391 
parseParseStringAsBNF(GrfBlock & block,ScpStream & script,ExprScriptVariable * pMethodCaller)3392 void DtaScript::parseParseStringAsBNF(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller) {
3393 	GrfParseStringAsBNF* pParseStringAsBNF = new GrfParseStringAsBNF;
3394 	if (requiresParsingInformation()) pParseStringAsBNF->setParsingInformation(getFilenamePtr(), script);
3395 	block.add(pParseStringAsBNF);
3396 	script.skipEmpty();
3397 	if (!script.isEqualTo('(')) throw UtlException(script, "syntax error: '(' expected");
3398 	script.skipEmpty();
3399 	if (pMethodCaller == NULL) pParseStringAsBNF->setBNFFileName(parseScriptFileExpression(block, script, DtaScriptFactory::BNF_SCRIPT));
3400 	else pParseStringAsBNF->setBNFFileName(pMethodCaller);
3401 	if ((pMethodCaller == NULL) && !script.isEqualTo(',')) throw UtlException(script, "syntax error: ',' expected");
3402 	script.skipEmpty();
3403 	pParseStringAsBNF->setThis(parseVariableExpression(block, script));
3404 	script.skipEmpty();
3405 	if (!script.isEqualTo(',')) throw UtlException(script, "syntax error: ',' expected");
3406 	script.skipEmpty();
3407 	pParseStringAsBNF->setContent(parseExpression(block, script));
3408 	script.skipEmpty();
3409 	if (!script.isEqualTo(')')) throw UtlException(script, "syntax error: ')' expected");
3410 	script.skipEmpty();
3411 	if (!script.isEqualTo(';')) throw UtlException(script, "syntax error: ';' expected");
3412 }
3413 
parseParseFree(GrfBlock & block,ScpStream & script,ExprScriptVariable * pMethodCaller)3414 void DtaScript::parseParseFree(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller) {
3415 	GrfParseFree* pParseFree = new GrfParseFree;
3416 	if (requiresParsingInformation()) pParseFree->setParsingInformation(getFilenamePtr(), script);
3417 	block.add(pParseFree);
3418 	script.skipEmpty();
3419 	if (!script.isEqualTo('(')) throw UtlException(script, "syntax error: '(' expected");
3420 	script.skipEmpty();
3421 	if (pMethodCaller == NULL) pParseFree->setDesignFileName(parseScriptFileExpression(block, script, DtaScriptFactory::FREE_SCRIPT));
3422 	else pParseFree->setDesignFileName(pMethodCaller);
3423 	if ((pMethodCaller == NULL) && !script.isEqualTo(',')) throw UtlException(script, "syntax error: ',' expected");
3424 	script.skipEmpty();
3425 	pParseFree->setThis(parseVariableExpression(block, script));
3426 	script.skipEmpty();
3427 	if (!script.isEqualTo(',')) throw UtlException(script, "syntax error: ',' expected");
3428 	script.skipEmpty();
3429 	pParseFree->setInputFileName(parseExpression(block, script));
3430 	script.skipEmpty();
3431 	if (!script.isEqualTo(')')) throw UtlException(script, "syntax error: ')' expected");
3432 	script.skipEmpty();
3433 	if (!script.isEqualTo(';')) throw UtlException(script, "syntax error: ';' expected");
3434 }
3435 
parseProduceHTML(GrfBlock & block,ScpStream & script,ExprScriptVariable * pMethodCaller)3436 void DtaScript::parseProduceHTML(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller) {
3437 	GrfProduceHTML* pProduceHTML = new GrfProduceHTML;
3438 	if (requiresParsingInformation()) pProduceHTML->setParsingInformation(getFilenamePtr(), script);
3439 	block.add(pProduceHTML);
3440 	script.skipEmpty();
3441 	if (!script.isEqualTo('(')) throw UtlException(script, "syntax error: '(' expected");
3442 	script.skipEmpty();
3443 	if (pMethodCaller == NULL) pProduceHTML->setScriptFileName(parseExpression(block, script));
3444 	else pProduceHTML->setScriptFileName(pMethodCaller);
3445 	if ((pMethodCaller == NULL) && !script.isEqualTo(',')) throw UtlException(script, "syntax error: ',' expected");
3446 	script.skipEmpty();
3447 	pProduceHTML->setHTMLFileName(parseExpression(block, script));
3448 	script.skipEmpty();
3449 	if (!script.isEqualTo(')')) throw UtlException(script, "syntax error: ')' expected");
3450 	script.skipEmpty();
3451 	if (!script.isEqualTo(';')) throw UtlException(script, "syntax error: ';' expected");
3452 }
3453 
parsePutEnv(GrfBlock & block,ScpStream & script,ExprScriptVariable * pMethodCaller)3454 void DtaScript::parsePutEnv(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller) {
3455 	GrfPutEnv* pPutEnv = new GrfPutEnv;
3456 	if (requiresParsingInformation()) pPutEnv->setParsingInformation(getFilenamePtr(), script);
3457 	block.add(pPutEnv);
3458 	script.skipEmpty();
3459 	if (!script.isEqualTo('(')) throw UtlException(script, "syntax error: '(' expected");
3460 	script.skipEmpty();
3461 	if (pMethodCaller == NULL) pPutEnv->setName(parseExpression(block, script));
3462 	else pPutEnv->setName(pMethodCaller);
3463 	if ((pMethodCaller == NULL) && !script.isEqualTo(',')) throw UtlException(script, "syntax error: ',' expected");
3464 	script.skipEmpty();
3465 	pPutEnv->setValue(parseExpression(block, script));
3466 	script.skipEmpty();
3467 	if (!script.isEqualTo(')')) throw UtlException(script, "syntax error: ')' expected");
3468 	script.skipEmpty();
3469 	if (!script.isEqualTo(';')) throw UtlException(script, "syntax error: ';' expected");
3470 }
3471 
parseRandomSeed(GrfBlock & block,ScpStream & script,ExprScriptVariable * pMethodCaller)3472 void DtaScript::parseRandomSeed(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller) {
3473 	GrfRandomSeed* pRandomSeed = new GrfRandomSeed;
3474 	if (requiresParsingInformation()) pRandomSeed->setParsingInformation(getFilenamePtr(), script);
3475 	block.add(pRandomSeed);
3476 	script.skipEmpty();
3477 	if (!script.isEqualTo('(')) throw UtlException(script, "syntax error: '(' expected");
3478 	script.skipEmpty();
3479 	if (pMethodCaller == NULL) pRandomSeed->setSeed(parseExpression(block, script));
3480 	else pRandomSeed->setSeed(pMethodCaller);
3481 	if (!script.isEqualTo(')')) throw UtlException(script, "syntax error: ')' expected");
3482 	script.skipEmpty();
3483 	if (!script.isEqualTo(';')) throw UtlException(script, "syntax error: ';' expected");
3484 }
3485 
parseRemoveAllElements(GrfBlock & block,ScpStream & script,ExprScriptVariable * pMethodCaller)3486 void DtaScript::parseRemoveAllElements(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller) {
3487 	GrfRemoveAllElements* pRemoveAllElements = new GrfRemoveAllElements;
3488 	if (requiresParsingInformation()) pRemoveAllElements->setParsingInformation(getFilenamePtr(), script);
3489 	block.add(pRemoveAllElements);
3490 	script.skipEmpty();
3491 	if (!script.isEqualTo('(')) throw UtlException(script, "syntax error: '(' expected");
3492 	script.skipEmpty();
3493 	if (pMethodCaller == NULL) pRemoveAllElements->setVariable(parseVariableExpression(block, script));
3494 	else pRemoveAllElements->setVariable(pMethodCaller);
3495 	if (!script.isEqualTo(')')) throw UtlException(script, "syntax error: ')' expected");
3496 	script.skipEmpty();
3497 	if (!script.isEqualTo(';')) throw UtlException(script, "syntax error: ';' expected");
3498 }
3499 
parseRemoveElement(GrfBlock & block,ScpStream & script,ExprScriptVariable * pMethodCaller)3500 void DtaScript::parseRemoveElement(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller) {
3501 	GrfRemoveElement* pRemoveElement = new GrfRemoveElement;
3502 	if (requiresParsingInformation()) pRemoveElement->setParsingInformation(getFilenamePtr(), script);
3503 	block.add(pRemoveElement);
3504 	script.skipEmpty();
3505 	if (!script.isEqualTo('(')) throw UtlException(script, "syntax error: '(' expected");
3506 	script.skipEmpty();
3507 	if (pMethodCaller == NULL) pRemoveElement->setVariable(parseVariableExpression(block, script));
3508 	else pRemoveElement->setVariable(pMethodCaller);
3509 	if ((pMethodCaller == NULL) && !script.isEqualTo(',')) throw UtlException(script, "syntax error: ',' expected");
3510 	script.skipEmpty();
3511 	pRemoveElement->setKey(parseExpression(block, script));
3512 	script.skipEmpty();
3513 	if (!script.isEqualTo(')')) throw UtlException(script, "syntax error: ')' expected");
3514 	script.skipEmpty();
3515 	if (!script.isEqualTo(';')) throw UtlException(script, "syntax error: ';' expected");
3516 }
3517 
parseRemoveFirstElement(GrfBlock & block,ScpStream & script,ExprScriptVariable * pMethodCaller)3518 void DtaScript::parseRemoveFirstElement(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller) {
3519 	GrfRemoveFirstElement* pRemoveFirstElement = new GrfRemoveFirstElement;
3520 	if (requiresParsingInformation()) pRemoveFirstElement->setParsingInformation(getFilenamePtr(), script);
3521 	block.add(pRemoveFirstElement);
3522 	script.skipEmpty();
3523 	if (!script.isEqualTo('(')) throw UtlException(script, "syntax error: '(' expected");
3524 	script.skipEmpty();
3525 	if (pMethodCaller == NULL) pRemoveFirstElement->setList(parseVariableExpression(block, script));
3526 	else pRemoveFirstElement->setList(pMethodCaller);
3527 	if (!script.isEqualTo(')')) throw UtlException(script, "syntax error: ')' expected");
3528 	script.skipEmpty();
3529 	if (!script.isEqualTo(';')) throw UtlException(script, "syntax error: ';' expected");
3530 }
3531 
parseRemoveLastElement(GrfBlock & block,ScpStream & script,ExprScriptVariable * pMethodCaller)3532 void DtaScript::parseRemoveLastElement(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller) {
3533 	GrfRemoveLastElement* pRemoveLastElement = new GrfRemoveLastElement;
3534 	if (requiresParsingInformation()) pRemoveLastElement->setParsingInformation(getFilenamePtr(), script);
3535 	block.add(pRemoveLastElement);
3536 	script.skipEmpty();
3537 	if (!script.isEqualTo('(')) throw UtlException(script, "syntax error: '(' expected");
3538 	script.skipEmpty();
3539 	if (pMethodCaller == NULL) pRemoveLastElement->setList(parseVariableExpression(block, script));
3540 	else pRemoveLastElement->setList(pMethodCaller);
3541 	if (!script.isEqualTo(')')) throw UtlException(script, "syntax error: ')' expected");
3542 	script.skipEmpty();
3543 	if (!script.isEqualTo(';')) throw UtlException(script, "syntax error: ';' expected");
3544 }
3545 
parseRemoveRecursive(GrfBlock & block,ScpStream & script,ExprScriptVariable * pMethodCaller)3546 void DtaScript::parseRemoveRecursive(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller) {
3547 	GrfRemoveRecursive* pRemoveRecursive = new GrfRemoveRecursive;
3548 	if (requiresParsingInformation()) pRemoveRecursive->setParsingInformation(getFilenamePtr(), script);
3549 	block.add(pRemoveRecursive);
3550 	script.skipEmpty();
3551 	if (!script.isEqualTo('(')) throw UtlException(script, "syntax error: '(' expected");
3552 	script.skipEmpty();
3553 	if (pMethodCaller == NULL) pRemoveRecursive->setVariable(parseVariableExpression(block, script));
3554 	else pRemoveRecursive->setVariable(pMethodCaller);
3555 	if ((pMethodCaller == NULL) && !script.isEqualTo(',')) throw UtlException(script, "syntax error: ',' expected");
3556 	script.skipEmpty();
3557 	pRemoveRecursive->setAttribute(parseExpression(block, script));
3558 	script.skipEmpty();
3559 	if (!script.isEqualTo(')')) throw UtlException(script, "syntax error: ')' expected");
3560 	script.skipEmpty();
3561 	if (!script.isEqualTo(';')) throw UtlException(script, "syntax error: ';' expected");
3562 }
3563 
parseRemoveVariable(GrfBlock & block,ScpStream & script,ExprScriptVariable * pMethodCaller)3564 void DtaScript::parseRemoveVariable(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller) {
3565 	GrfRemoveVariable* pRemoveVariable = new GrfRemoveVariable;
3566 	if (requiresParsingInformation()) pRemoveVariable->setParsingInformation(getFilenamePtr(), script);
3567 	block.add(pRemoveVariable);
3568 	script.skipEmpty();
3569 	if (!script.isEqualTo('(')) throw UtlException(script, "syntax error: '(' expected");
3570 	script.skipEmpty();
3571 	if (pMethodCaller == NULL) pRemoveVariable->setNode(parseVariableExpression(block, script));
3572 	else pRemoveVariable->setNode(pMethodCaller);
3573 	if (!script.isEqualTo(')')) throw UtlException(script, "syntax error: ')' expected");
3574 	script.skipEmpty();
3575 	if (!script.isEqualTo(';')) throw UtlException(script, "syntax error: ';' expected");
3576 }
3577 
parseSaveBinaryToFile(GrfBlock & block,ScpStream & script,ExprScriptVariable * pMethodCaller)3578 void DtaScript::parseSaveBinaryToFile(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller) {
3579 	GrfSaveBinaryToFile* pSaveBinaryToFile = new GrfSaveBinaryToFile;
3580 	if (requiresParsingInformation()) pSaveBinaryToFile->setParsingInformation(getFilenamePtr(), script);
3581 	block.add(pSaveBinaryToFile);
3582 	script.skipEmpty();
3583 	if (!script.isEqualTo('(')) throw UtlException(script, "syntax error: '(' expected");
3584 	script.skipEmpty();
3585 	if (pMethodCaller == NULL) pSaveBinaryToFile->setFilename(parseExpression(block, script));
3586 	else pSaveBinaryToFile->setFilename(pMethodCaller);
3587 	if ((pMethodCaller == NULL) && !script.isEqualTo(',')) throw UtlException(script, "syntax error: ',' expected");
3588 	script.skipEmpty();
3589 	pSaveBinaryToFile->setContent(parseExpression(block, script));
3590 	script.skipEmpty();
3591 	if (!script.isEqualTo(')')) throw UtlException(script, "syntax error: ')' expected");
3592 	script.skipEmpty();
3593 	if (!script.isEqualTo(';')) throw UtlException(script, "syntax error: ';' expected");
3594 }
3595 
parseSaveProject(GrfBlock & block,ScpStream & script,ExprScriptVariable * pMethodCaller)3596 void DtaScript::parseSaveProject(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller) {
3597 	GrfSaveProject* pSaveProject = new GrfSaveProject;
3598 	if (requiresParsingInformation()) pSaveProject->setParsingInformation(getFilenamePtr(), script);
3599 	block.add(pSaveProject);
3600 	script.skipEmpty();
3601 	if (!script.isEqualTo('(')) throw UtlException(script, "syntax error: '(' expected");
3602 	script.skipEmpty();
3603 	if (pMethodCaller == NULL) pSaveProject->setXMLorTXTFileName(parseExpression(block, script));
3604 	else pSaveProject->setXMLorTXTFileName(pMethodCaller);
3605 	do {
3606 		if (pMethodCaller != NULL) {
3607 			if (script.peekChar() == ')') break;
3608 		} else {
3609 			if (!script.isEqualTo(',')) break;
3610 		}
3611 		script.skipEmpty();
3612 		pSaveProject->setNodeToSave(parseVariableExpression(block, script));
3613 		script.skipEmpty();
3614 	} while (false);
3615 	pSaveProject->populateDefaultParameters();
3616 	if (!script.isEqualTo(')')) throw UtlException(script, "syntax error: ')' expected");
3617 	script.skipEmpty();
3618 	if (!script.isEqualTo(';')) throw UtlException(script, "syntax error: ';' expected");
3619 }
3620 
parseSaveProjectTypes(GrfBlock & block,ScpStream & script,ExprScriptVariable * pMethodCaller)3621 void DtaScript::parseSaveProjectTypes(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller) {
3622 	GrfSaveProjectTypes* pSaveProjectTypes = new GrfSaveProjectTypes;
3623 	if (requiresParsingInformation()) pSaveProjectTypes->setParsingInformation(getFilenamePtr(), script);
3624 	block.add(pSaveProjectTypes);
3625 	script.skipEmpty();
3626 	if (!script.isEqualTo('(')) throw UtlException(script, "syntax error: '(' expected");
3627 	script.skipEmpty();
3628 	if (pMethodCaller == NULL) pSaveProjectTypes->setXMLFileName(parseExpression(block, script));
3629 	else pSaveProjectTypes->setXMLFileName(pMethodCaller);
3630 	if (!script.isEqualTo(')')) throw UtlException(script, "syntax error: ')' expected");
3631 	script.skipEmpty();
3632 	if (!script.isEqualTo(';')) throw UtlException(script, "syntax error: ';' expected");
3633 }
3634 
parseSaveToFile(GrfBlock & block,ScpStream & script,ExprScriptVariable * pMethodCaller)3635 void DtaScript::parseSaveToFile(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller) {
3636 	GrfSaveToFile* pSaveToFile = new GrfSaveToFile;
3637 	if (requiresParsingInformation()) pSaveToFile->setParsingInformation(getFilenamePtr(), script);
3638 	block.add(pSaveToFile);
3639 	script.skipEmpty();
3640 	if (!script.isEqualTo('(')) throw UtlException(script, "syntax error: '(' expected");
3641 	script.skipEmpty();
3642 	if (pMethodCaller == NULL) pSaveToFile->setFilename(parseExpression(block, script));
3643 	else pSaveToFile->setFilename(pMethodCaller);
3644 	if ((pMethodCaller == NULL) && !script.isEqualTo(',')) throw UtlException(script, "syntax error: ',' expected");
3645 	script.skipEmpty();
3646 	pSaveToFile->setContent(parseExpression(block, script));
3647 	script.skipEmpty();
3648 	if (!script.isEqualTo(')')) throw UtlException(script, "syntax error: ')' expected");
3649 	script.skipEmpty();
3650 	if (!script.isEqualTo(';')) throw UtlException(script, "syntax error: ';' expected");
3651 }
3652 
parseSetCommentBegin(GrfBlock & block,ScpStream & script,ExprScriptVariable * pMethodCaller)3653 void DtaScript::parseSetCommentBegin(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller) {
3654 	GrfSetCommentBegin* pSetCommentBegin = new GrfSetCommentBegin;
3655 	if (requiresParsingInformation()) pSetCommentBegin->setParsingInformation(getFilenamePtr(), script);
3656 	block.add(pSetCommentBegin);
3657 	script.skipEmpty();
3658 	if (!script.isEqualTo('(')) throw UtlException(script, "syntax error: '(' expected");
3659 	script.skipEmpty();
3660 	if (pMethodCaller == NULL) pSetCommentBegin->setCommentBegin(parseExpression(block, script));
3661 	else pSetCommentBegin->setCommentBegin(pMethodCaller);
3662 	if (!script.isEqualTo(')')) throw UtlException(script, "syntax error: ')' expected");
3663 	script.skipEmpty();
3664 	if (!script.isEqualTo(';')) throw UtlException(script, "syntax error: ';' expected");
3665 }
3666 
parseSetCommentEnd(GrfBlock & block,ScpStream & script,ExprScriptVariable * pMethodCaller)3667 void DtaScript::parseSetCommentEnd(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller) {
3668 	GrfSetCommentEnd* pSetCommentEnd = new GrfSetCommentEnd;
3669 	if (requiresParsingInformation()) pSetCommentEnd->setParsingInformation(getFilenamePtr(), script);
3670 	block.add(pSetCommentEnd);
3671 	script.skipEmpty();
3672 	if (!script.isEqualTo('(')) throw UtlException(script, "syntax error: '(' expected");
3673 	script.skipEmpty();
3674 	if (pMethodCaller == NULL) pSetCommentEnd->setCommentEnd(parseExpression(block, script));
3675 	else pSetCommentEnd->setCommentEnd(pMethodCaller);
3676 	if (!script.isEqualTo(')')) throw UtlException(script, "syntax error: ')' expected");
3677 	script.skipEmpty();
3678 	if (!script.isEqualTo(';')) throw UtlException(script, "syntax error: ';' expected");
3679 }
3680 
parseSetGenerationHeader(GrfBlock & block,ScpStream & script,ExprScriptVariable * pMethodCaller)3681 void DtaScript::parseSetGenerationHeader(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller) {
3682 	GrfSetGenerationHeader* pSetGenerationHeader = new GrfSetGenerationHeader;
3683 	if (requiresParsingInformation()) pSetGenerationHeader->setParsingInformation(getFilenamePtr(), script);
3684 	block.add(pSetGenerationHeader);
3685 	script.skipEmpty();
3686 	if (!script.isEqualTo('(')) throw UtlException(script, "syntax error: '(' expected");
3687 	script.skipEmpty();
3688 	if (pMethodCaller == NULL) pSetGenerationHeader->setComment(parseExpression(block, script));
3689 	else pSetGenerationHeader->setComment(pMethodCaller);
3690 	if (!script.isEqualTo(')')) throw UtlException(script, "syntax error: ')' expected");
3691 	script.skipEmpty();
3692 	if (!script.isEqualTo(';')) throw UtlException(script, "syntax error: ';' expected");
3693 }
3694 
parseSetIncludePath(GrfBlock & block,ScpStream & script,ExprScriptVariable * pMethodCaller)3695 void DtaScript::parseSetIncludePath(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller) {
3696 	GrfSetIncludePath* pSetIncludePath = new GrfSetIncludePath;
3697 	if (requiresParsingInformation()) pSetIncludePath->setParsingInformation(getFilenamePtr(), script);
3698 	block.add(pSetIncludePath);
3699 	script.skipEmpty();
3700 	if (!script.isEqualTo('(')) throw UtlException(script, "syntax error: '(' expected");
3701 	script.skipEmpty();
3702 	if (pMethodCaller == NULL) pSetIncludePath->setPath(parseExpression(block, script));
3703 	else pSetIncludePath->setPath(pMethodCaller);
3704 	if (!script.isEqualTo(')')) throw UtlException(script, "syntax error: ')' expected");
3705 	script.skipEmpty();
3706 	if (!script.isEqualTo(';')) throw UtlException(script, "syntax error: ';' expected");
3707 }
3708 
parseSetNow(GrfBlock & block,ScpStream & script,ExprScriptVariable * pMethodCaller)3709 void DtaScript::parseSetNow(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller) {
3710 	GrfSetNow* pSetNow = new GrfSetNow;
3711 	if (requiresParsingInformation()) pSetNow->setParsingInformation(getFilenamePtr(), script);
3712 	block.add(pSetNow);
3713 	script.skipEmpty();
3714 	if (!script.isEqualTo('(')) throw UtlException(script, "syntax error: '(' expected");
3715 	script.skipEmpty();
3716 	if (pMethodCaller == NULL) pSetNow->setConstantDateTime(parseExpression(block, script));
3717 	else pSetNow->setConstantDateTime(pMethodCaller);
3718 	if (!script.isEqualTo(')')) throw UtlException(script, "syntax error: ')' expected");
3719 	script.skipEmpty();
3720 	if (!script.isEqualTo(';')) throw UtlException(script, "syntax error: ';' expected");
3721 }
3722 
parseSetProperty(GrfBlock & block,ScpStream & script,ExprScriptVariable * pMethodCaller)3723 void DtaScript::parseSetProperty(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller) {
3724 	GrfSetProperty* pSetProperty = new GrfSetProperty;
3725 	if (requiresParsingInformation()) pSetProperty->setParsingInformation(getFilenamePtr(), script);
3726 	block.add(pSetProperty);
3727 	script.skipEmpty();
3728 	if (!script.isEqualTo('(')) throw UtlException(script, "syntax error: '(' expected");
3729 	script.skipEmpty();
3730 	if (pMethodCaller == NULL) pSetProperty->setDefine(parseExpression(block, script));
3731 	else pSetProperty->setDefine(pMethodCaller);
3732 	if ((pMethodCaller == NULL) && !script.isEqualTo(',')) throw UtlException(script, "syntax error: ',' expected");
3733 	script.skipEmpty();
3734 	pSetProperty->setValue(parseExpression(block, script));
3735 	script.skipEmpty();
3736 	if (!script.isEqualTo(')')) throw UtlException(script, "syntax error: ')' expected");
3737 	script.skipEmpty();
3738 	if (!script.isEqualTo(';')) throw UtlException(script, "syntax error: ';' expected");
3739 }
3740 
parseSetTextMode(GrfBlock & block,ScpStream & script,ExprScriptVariable * pMethodCaller)3741 void DtaScript::parseSetTextMode(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller) {
3742 	GrfSetTextMode* pSetTextMode = new GrfSetTextMode;
3743 	if (requiresParsingInformation()) pSetTextMode->setParsingInformation(getFilenamePtr(), script);
3744 	block.add(pSetTextMode);
3745 	script.skipEmpty();
3746 	if (!script.isEqualTo('(')) throw UtlException(script, "syntax error: '(' expected");
3747 	script.skipEmpty();
3748 	if (pMethodCaller == NULL) pSetTextMode->setTextMode(parseExpression(block, script));
3749 	else pSetTextMode->setTextMode(pMethodCaller);
3750 	if (!script.isEqualTo(')')) throw UtlException(script, "syntax error: ')' expected");
3751 	script.skipEmpty();
3752 	if (!script.isEqualTo(';')) throw UtlException(script, "syntax error: ';' expected");
3753 }
3754 
parseSetVersion(GrfBlock & block,ScpStream & script,ExprScriptVariable * pMethodCaller)3755 void DtaScript::parseSetVersion(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller) {
3756 	GrfSetVersion* pSetVersion = new GrfSetVersion;
3757 	if (requiresParsingInformation()) pSetVersion->setParsingInformation(getFilenamePtr(), script);
3758 	block.add(pSetVersion);
3759 	script.skipEmpty();
3760 	if (!script.isEqualTo('(')) throw UtlException(script, "syntax error: '(' expected");
3761 	script.skipEmpty();
3762 	if (pMethodCaller == NULL) pSetVersion->setVersion(parseExpression(block, script));
3763 	else pSetVersion->setVersion(pMethodCaller);
3764 	if (!script.isEqualTo(')')) throw UtlException(script, "syntax error: ')' expected");
3765 	script.skipEmpty();
3766 	if (!script.isEqualTo(';')) throw UtlException(script, "syntax error: ';' expected");
3767 }
3768 
parseSetWriteMode(GrfBlock & block,ScpStream & script,ExprScriptVariable * pMethodCaller)3769 void DtaScript::parseSetWriteMode(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller) {
3770 	GrfSetWriteMode* pSetWriteMode = new GrfSetWriteMode;
3771 	if (requiresParsingInformation()) pSetWriteMode->setParsingInformation(getFilenamePtr(), script);
3772 	block.add(pSetWriteMode);
3773 	script.skipEmpty();
3774 	if (!script.isEqualTo('(')) throw UtlException(script, "syntax error: '(' expected");
3775 	script.skipEmpty();
3776 	if (pMethodCaller == NULL) pSetWriteMode->setMode(parseExpression(block, script));
3777 	else pSetWriteMode->setMode(pMethodCaller);
3778 	if (!script.isEqualTo(')')) throw UtlException(script, "syntax error: ')' expected");
3779 	script.skipEmpty();
3780 	if (!script.isEqualTo(';')) throw UtlException(script, "syntax error: ';' expected");
3781 }
3782 
parseSetWorkingPath(GrfBlock & block,ScpStream & script,ExprScriptVariable * pMethodCaller)3783 void DtaScript::parseSetWorkingPath(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller) {
3784 	GrfSetWorkingPath* pSetWorkingPath = new GrfSetWorkingPath;
3785 	if (requiresParsingInformation()) pSetWorkingPath->setParsingInformation(getFilenamePtr(), script);
3786 	block.add(pSetWorkingPath);
3787 	script.skipEmpty();
3788 	if (!script.isEqualTo('(')) throw UtlException(script, "syntax error: '(' expected");
3789 	script.skipEmpty();
3790 	if (pMethodCaller == NULL) pSetWorkingPath->setPath(parseExpression(block, script));
3791 	else pSetWorkingPath->setPath(pMethodCaller);
3792 	if (!script.isEqualTo(')')) throw UtlException(script, "syntax error: ')' expected");
3793 	script.skipEmpty();
3794 	if (!script.isEqualTo(';')) throw UtlException(script, "syntax error: ';' expected");
3795 }
3796 
parseSleep(GrfBlock & block,ScpStream & script,ExprScriptVariable * pMethodCaller)3797 void DtaScript::parseSleep(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller) {
3798 	GrfSleep* pSleep = new GrfSleep;
3799 	if (requiresParsingInformation()) pSleep->setParsingInformation(getFilenamePtr(), script);
3800 	block.add(pSleep);
3801 	script.skipEmpty();
3802 	if (!script.isEqualTo('(')) throw UtlException(script, "syntax error: '(' expected");
3803 	script.skipEmpty();
3804 	if (pMethodCaller == NULL) pSleep->setMillis(parseExpression(block, script));
3805 	else pSleep->setMillis(pMethodCaller);
3806 	if (!script.isEqualTo(')')) throw UtlException(script, "syntax error: ')' expected");
3807 	script.skipEmpty();
3808 	if (!script.isEqualTo(';')) throw UtlException(script, "syntax error: ';' expected");
3809 }
3810 
parseSlideNodeContent(GrfBlock & block,ScpStream & script,ExprScriptVariable * pMethodCaller)3811 void DtaScript::parseSlideNodeContent(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller) {
3812 	GrfSlideNodeContent* pSlideNodeContent = new GrfSlideNodeContent;
3813 	if (requiresParsingInformation()) pSlideNodeContent->setParsingInformation(getFilenamePtr(), script);
3814 	block.add(pSlideNodeContent);
3815 	script.skipEmpty();
3816 	if (!script.isEqualTo('(')) throw UtlException(script, "syntax error: '(' expected");
3817 	script.skipEmpty();
3818 	if (pMethodCaller == NULL) pSlideNodeContent->setOrgNode(parseVariableExpression(block, script));
3819 	else pSlideNodeContent->setOrgNode(pMethodCaller);
3820 	if ((pMethodCaller == NULL) && !script.isEqualTo(',')) throw UtlException(script, "syntax error: ',' expected");
3821 	script.skipEmpty();
3822 	{
3823 		CGQuietOutput quiet;
3824 		pSlideNodeContent->setDestNode(parseVariableExpression(block, script));
3825 		script.skipEmpty();
3826 	}
3827 	if (!script.isEqualTo(')')) throw UtlException(script, "syntax error: ')' expected");
3828 	script.skipEmpty();
3829 	if (!script.isEqualTo(';')) throw UtlException(script, "syntax error: ';' expected");
3830 }
3831 
parseSortArray(GrfBlock & block,ScpStream & script,ExprScriptVariable * pMethodCaller)3832 void DtaScript::parseSortArray(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller) {
3833 	GrfSortArray* pSortArray = new GrfSortArray;
3834 	if (requiresParsingInformation()) pSortArray->setParsingInformation(getFilenamePtr(), script);
3835 	block.add(pSortArray);
3836 	script.skipEmpty();
3837 	if (!script.isEqualTo('(')) throw UtlException(script, "syntax error: '(' expected");
3838 	script.skipEmpty();
3839 	if (pMethodCaller == NULL) pSortArray->setArray(parseVariableExpression(block, script));
3840 	else pSortArray->setArray(pMethodCaller);
3841 	if (!script.isEqualTo(')')) throw UtlException(script, "syntax error: ')' expected");
3842 	script.skipEmpty();
3843 	if (!script.isEqualTo(';')) throw UtlException(script, "syntax error: ';' expected");
3844 }
3845 
parseTraceEngine(GrfBlock & block,ScpStream & script,ExprScriptVariable * pMethodCaller)3846 void DtaScript::parseTraceEngine(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller) {
3847 	GrfTraceEngine* pTraceEngine = new GrfTraceEngine;
3848 	if (requiresParsingInformation()) pTraceEngine->setParsingInformation(getFilenamePtr(), script);
3849 	block.add(pTraceEngine);
3850 	script.skipEmpty();
3851 	if (!script.isEqualTo('(')) throw UtlException(script, "syntax error: '(' expected");
3852 	script.skipEmpty();
3853 	if (!script.isEqualTo(')')) throw UtlException(script, "syntax error: ')' expected");
3854 	script.skipEmpty();
3855 	if (!script.isEqualTo(';')) throw UtlException(script, "syntax error: ';' expected");
3856 }
3857 
parseTraceLine(GrfBlock & block,ScpStream & script,ExprScriptVariable * pMethodCaller)3858 void DtaScript::parseTraceLine(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller) {
3859 	GrfTraceLine* pTraceLine = new GrfTraceLine;
3860 	if (requiresParsingInformation()) pTraceLine->setParsingInformation(getFilenamePtr(), script);
3861 	block.add(pTraceLine);
3862 	script.skipEmpty();
3863 	if (!script.isEqualTo('(')) throw UtlException(script, "syntax error: '(' expected");
3864 	script.skipEmpty();
3865 	if (pMethodCaller == NULL) pTraceLine->setLine(parseExpression(block, script));
3866 	else pTraceLine->setLine(pMethodCaller);
3867 	if (!script.isEqualTo(')')) throw UtlException(script, "syntax error: ')' expected");
3868 	script.skipEmpty();
3869 	if (!script.isEqualTo(';')) throw UtlException(script, "syntax error: ';' expected");
3870 }
3871 
parseTraceObject(GrfBlock & block,ScpStream & script,ExprScriptVariable * pMethodCaller)3872 void DtaScript::parseTraceObject(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller) {
3873 	GrfTraceObject* pTraceObject = new GrfTraceObject;
3874 	if (requiresParsingInformation()) pTraceObject->setParsingInformation(getFilenamePtr(), script);
3875 	block.add(pTraceObject);
3876 	script.skipEmpty();
3877 	if (!script.isEqualTo('(')) throw UtlException(script, "syntax error: '(' expected");
3878 	script.skipEmpty();
3879 	if (pMethodCaller == NULL) pTraceObject->setObject(parseVariableExpression(block, script));
3880 	else pTraceObject->setObject(pMethodCaller);
3881 	do {
3882 		if (pMethodCaller != NULL) {
3883 			if (script.peekChar() == ')') break;
3884 		} else {
3885 			if (!script.isEqualTo(',')) break;
3886 		}
3887 		script.skipEmpty();
3888 		pTraceObject->setDepth(parseExpression(block, script));
3889 		script.skipEmpty();
3890 	} while (false);
3891 	pTraceObject->populateDefaultParameters();
3892 	if (!script.isEqualTo(')')) throw UtlException(script, "syntax error: ')' expected");
3893 	script.skipEmpty();
3894 	if (!script.isEqualTo(';')) throw UtlException(script, "syntax error: ';' expected");
3895 }
3896 
parseTraceStack(GrfBlock & block,ScpStream & script,ExprScriptVariable * pMethodCaller)3897 void DtaScript::parseTraceStack(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller) {
3898 	GrfTraceStack* pTraceStack = new GrfTraceStack;
3899 	if (requiresParsingInformation()) pTraceStack->setParsingInformation(getFilenamePtr(), script);
3900 	block.add(pTraceStack);
3901 	script.skipEmpty();
3902 	if (!script.isEqualTo('(')) throw UtlException(script, "syntax error: '(' expected");
3903 	script.skipEmpty();
3904 	if (!script.isEqualTo(')')) throw UtlException(script, "syntax error: ')' expected");
3905 	script.skipEmpty();
3906 	if (!script.isEqualTo(';')) throw UtlException(script, "syntax error: ';' expected");
3907 }
3908 
parseTraceText(GrfBlock & block,ScpStream & script,ExprScriptVariable * pMethodCaller)3909 void DtaScript::parseTraceText(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller) {
3910 	GrfTraceText* pTraceText = new GrfTraceText;
3911 	if (requiresParsingInformation()) pTraceText->setParsingInformation(getFilenamePtr(), script);
3912 	block.add(pTraceText);
3913 	script.skipEmpty();
3914 	if (!script.isEqualTo('(')) throw UtlException(script, "syntax error: '(' expected");
3915 	script.skipEmpty();
3916 	if (pMethodCaller == NULL) pTraceText->setText(parseExpression(block, script));
3917 	else pTraceText->setText(pMethodCaller);
3918 	if (!script.isEqualTo(')')) throw UtlException(script, "syntax error: ')' expected");
3919 	script.skipEmpty();
3920 	if (!script.isEqualTo(';')) throw UtlException(script, "syntax error: ';' expected");
3921 }
3922 
parseTranslate(GrfBlock & block,ScpStream & script,ExprScriptVariable * pMethodCaller)3923 void DtaScript::parseTranslate(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller) {
3924 	GrfTranslate* pTranslate = new GrfTranslate;
3925 	if (requiresParsingInformation()) pTranslate->setParsingInformation(getFilenamePtr(), script);
3926 	block.add(pTranslate);
3927 	script.skipEmpty();
3928 	if (!script.isEqualTo('(')) throw UtlException(script, "syntax error: '(' expected");
3929 	script.skipEmpty();
3930 	if (pMethodCaller == NULL) pTranslate->setPatternFileName(parseScriptFileExpression(block, script, DtaScriptFactory::TRANSLATE_SCRIPT));
3931 	else pTranslate->setPatternFileName(pMethodCaller);
3932 	if ((pMethodCaller == NULL) && !script.isEqualTo(',')) throw UtlException(script, "syntax error: ',' expected");
3933 	script.skipEmpty();
3934 	pTranslate->setThis(parseVariableExpression(block, script));
3935 	script.skipEmpty();
3936 	if (!script.isEqualTo(',')) throw UtlException(script, "syntax error: ',' expected");
3937 	script.skipEmpty();
3938 	pTranslate->setInputFileName(parseExpression(block, script));
3939 	script.skipEmpty();
3940 	if (!script.isEqualTo(',')) throw UtlException(script, "syntax error: ',' expected");
3941 	script.skipEmpty();
3942 	pTranslate->setOutputFileName(parseExpression(block, script));
3943 	script.skipEmpty();
3944 	if (!script.isEqualTo(')')) throw UtlException(script, "syntax error: ')' expected");
3945 	script.skipEmpty();
3946 	if (!script.isEqualTo(';')) throw UtlException(script, "syntax error: ';' expected");
3947 }
3948 
parseAttachInputToSocket(GrfBlock &,ScpStream & script,ExprScriptVariable *)3949 void DtaScript::parseAttachInputToSocket(GrfBlock& /*block*/, ScpStream& script, ExprScriptVariable* /*pMethodCaller*/) {
3950 	throw UtlException(script, "command \"attachInputToSocket\" must be used into design format files only");
3951 }
3952 
parseDetachInputFromSocket(GrfBlock &,ScpStream & script,ExprScriptVariable *)3953 void DtaScript::parseDetachInputFromSocket(GrfBlock& /*block*/, ScpStream& script, ExprScriptVariable* /*pMethodCaller*/) {
3954 	throw UtlException(script, "command \"detachInputFromSocket\" must be used into design format files only");
3955 }
3956 
parseGoBack(GrfBlock &,ScpStream & script,ExprScriptVariable *)3957 void DtaScript::parseGoBack(GrfBlock& /*block*/, ScpStream& script, ExprScriptVariable* /*pMethodCaller*/) {
3958 	throw UtlException(script, "command \"goBack\" must be used into design format files only");
3959 }
3960 
parseSetInputLocation(GrfBlock &,ScpStream & script,ExprScriptVariable *)3961 void DtaScript::parseSetInputLocation(GrfBlock& /*block*/, ScpStream& script, ExprScriptVariable* /*pMethodCaller*/) {
3962 	throw UtlException(script, "command \"setInputLocation\" must be used into design format files only");
3963 }
3964 
parseAllFloatingLocations(GrfBlock &,ScpStream & script,ExprScriptVariable *)3965 void DtaScript::parseAllFloatingLocations(GrfBlock& /*block*/, ScpStream& script, ExprScriptVariable* /*pMethodCaller*/) {
3966 	throw UtlException(script, "command \"allFloatingLocations\" must be used into pattern files only");
3967 }
3968 
parseAttachOutputToSocket(GrfBlock &,ScpStream & script,ExprScriptVariable *)3969 void DtaScript::parseAttachOutputToSocket(GrfBlock& /*block*/, ScpStream& script, ExprScriptVariable* /*pMethodCaller*/) {
3970 	throw UtlException(script, "command \"attachOutputToSocket\" must be used into pattern files only");
3971 }
3972 
parseDetachOutputFromSocket(GrfBlock &,ScpStream & script,ExprScriptVariable *)3973 void DtaScript::parseDetachOutputFromSocket(GrfBlock& /*block*/, ScpStream& script, ExprScriptVariable* /*pMethodCaller*/) {
3974 	throw UtlException(script, "command \"detachOutputFromSocket\" must be used into pattern files only");
3975 }
3976 
parseIncrementIndentLevel(GrfBlock &,ScpStream & script,ExprScriptVariable *)3977 void DtaScript::parseIncrementIndentLevel(GrfBlock& /*block*/, ScpStream& script, ExprScriptVariable* /*pMethodCaller*/) {
3978 	throw UtlException(script, "command \"incrementIndentLevel\" must be used into pattern files only");
3979 }
3980 
parseInsertText(GrfBlock &,ScpStream & script,ExprScriptVariable *)3981 void DtaScript::parseInsertText(GrfBlock& /*block*/, ScpStream& script, ExprScriptVariable* /*pMethodCaller*/) {
3982 	throw UtlException(script, "command \"insertText\" must be used into pattern files only");
3983 }
3984 
parseInsertTextOnce(GrfBlock &,ScpStream & script,ExprScriptVariable *)3985 void DtaScript::parseInsertTextOnce(GrfBlock& /*block*/, ScpStream& script, ExprScriptVariable* /*pMethodCaller*/) {
3986 	throw UtlException(script, "command \"insertTextOnce\" must be used into pattern files only");
3987 }
3988 
parseInsertTextToFloatingLocation(GrfBlock &,ScpStream & script,ExprScriptVariable *)3989 void DtaScript::parseInsertTextToFloatingLocation(GrfBlock& /*block*/, ScpStream& script, ExprScriptVariable* /*pMethodCaller*/) {
3990 	throw UtlException(script, "command \"insertTextToFloatingLocation\" must be used into pattern files only");
3991 }
3992 
parseInsertTextOnceToFloatingLocation(GrfBlock &,ScpStream & script,ExprScriptVariable *)3993 void DtaScript::parseInsertTextOnceToFloatingLocation(GrfBlock& /*block*/, ScpStream& script, ExprScriptVariable* /*pMethodCaller*/) {
3994 	throw UtlException(script, "command \"insertTextOnceToFloatingLocation\" must be used into pattern files only");
3995 }
3996 
parseOverwritePortion(GrfBlock &,ScpStream & script,ExprScriptVariable *)3997 void DtaScript::parseOverwritePortion(GrfBlock& /*block*/, ScpStream& script, ExprScriptVariable* /*pMethodCaller*/) {
3998 	throw UtlException(script, "command \"overwritePortion\" must be used into pattern files only");
3999 }
4000 
parsePopulateProtectedArea(GrfBlock &,ScpStream & script,ExprScriptVariable *)4001 void DtaScript::parsePopulateProtectedArea(GrfBlock& /*block*/, ScpStream& script, ExprScriptVariable* /*pMethodCaller*/) {
4002 	throw UtlException(script, "command \"populateProtectedArea\" must be used into pattern files only");
4003 }
4004 
parseResizeOutputStream(GrfBlock &,ScpStream & script,ExprScriptVariable *)4005 void DtaScript::parseResizeOutputStream(GrfBlock& /*block*/, ScpStream& script, ExprScriptVariable* /*pMethodCaller*/) {
4006 	throw UtlException(script, "command \"resizeOutputStream\" must be used into pattern files only");
4007 }
4008 
parseSetFloatingLocation(GrfBlock &,ScpStream & script,ExprScriptVariable *)4009 void DtaScript::parseSetFloatingLocation(GrfBlock& /*block*/, ScpStream& script, ExprScriptVariable* /*pMethodCaller*/) {
4010 	throw UtlException(script, "command \"setFloatingLocation\" must be used into pattern files only");
4011 }
4012 
parseSetOutputLocation(GrfBlock &,ScpStream & script,ExprScriptVariable *)4013 void DtaScript::parseSetOutputLocation(GrfBlock& /*block*/, ScpStream& script, ExprScriptVariable* /*pMethodCaller*/) {
4014 	throw UtlException(script, "command \"setOutputLocation\" must be used into pattern files only");
4015 }
4016 
parseSetProtectedArea(GrfBlock &,ScpStream & script,ExprScriptVariable *)4017 void DtaScript::parseSetProtectedArea(GrfBlock& /*block*/, ScpStream& script, ExprScriptVariable* /*pMethodCaller*/) {
4018 	throw UtlException(script, "command \"setProtectedArea\" must be used into pattern files only");
4019 }
4020 
parseWriteBytes(GrfBlock &,ScpStream & script,ExprScriptVariable *)4021 void DtaScript::parseWriteBytes(GrfBlock& /*block*/, ScpStream& script, ExprScriptVariable* /*pMethodCaller*/) {
4022 	throw UtlException(script, "command \"writeBytes\" must be used into pattern files only");
4023 }
4024 
parseWriteText(GrfBlock &,ScpStream & script,ExprScriptVariable *)4025 void DtaScript::parseWriteText(GrfBlock& /*block*/, ScpStream& script, ExprScriptVariable* /*pMethodCaller*/) {
4026 	throw UtlException(script, "command \"writeText\" must be used into pattern files only");
4027 }
4028 
parseWriteTextOnce(GrfBlock &,ScpStream & script,ExprScriptVariable *)4029 void DtaScript::parseWriteTextOnce(GrfBlock& /*block*/, ScpStream& script, ExprScriptVariable* /*pMethodCaller*/) {
4030 	throw UtlException(script, "command \"writeTextOnce\" must be used into pattern files only");
4031 }
4032 
parseCloseSocket(GrfBlock & block,ScpStream & script,ExprScriptVariable * pMethodCaller)4033 void DtaScript::parseCloseSocket(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller) {
4034 	GrfCloseSocket* pCloseSocket = new GrfCloseSocket;
4035 	if (requiresParsingInformation()) pCloseSocket->setParsingInformation(getFilenamePtr(), script);
4036 	block.add(pCloseSocket);
4037 	script.skipEmpty();
4038 	if (!script.isEqualTo('(')) throw UtlException(script, "syntax error: '(' expected");
4039 	script.skipEmpty();
4040 	if (pMethodCaller == NULL) pCloseSocket->setSocket(parseExpression(block, script));
4041 	else pCloseSocket->setSocket(pMethodCaller);
4042 	if (!script.isEqualTo(')')) throw UtlException(script, "syntax error: ')' expected");
4043 	script.skipEmpty();
4044 	if (!script.isEqualTo(';')) throw UtlException(script, "syntax error: ';' expected");
4045 }
4046 
4047 //##end##"parsing"
4048 
parseNop(GrfBlock & block,ScpStream & script)4049 	void DtaScript::parseNop(GrfBlock& block, ScpStream& script) {
4050 		GrfNop* pNop = new GrfNop;
4051 		if (requiresParsingInformation()) pNop->setParsingInformation(getFilenamePtr(), script);
4052 		block.add(pNop);
4053 		script.skipEmpty();
4054 		if (!script.isEqualTo('(')) throw UtlException(script, "syntax error: '(' expected");
4055 		script.skipEmpty();
4056 		pNop->setExpression(parseExpression(block, script));
4057 		script.skipEmpty();
4058 		if (!script.isEqualTo(')')) throw UtlException(script, "syntax error: ')' expected");
4059 		script.skipEmpty();
4060 		if (!script.isEqualTo(';')) throw UtlException(script, "syntax error: ';' expected");
4061 	}
4062 
parseLocalVariable(GrfBlock & block,ScpStream & script)4063 	void DtaScript::parseLocalVariable(GrfBlock& block, ScpStream& script) {
4064 		EXPRESSION_TYPE exprType = parseClassType(block, script, NODE_EXPRTYPE);
4065 		do {
4066 			GrfLocalVariable* pLocalVariable = new GrfLocalVariable;
4067 			if (requiresParsingInformation()) pLocalVariable->setParsingInformation(getFilenamePtr(), script);
4068 			block.add(pLocalVariable);
4069 			script.skipEmpty();
4070 			std::string sVariable;
4071 			if (!script.readIdentifier(sVariable)) throw UtlException(script, "syntax error: name of the local variable expected");
4072 			if ((sVariable == "project") || (sVariable == "null") || (sVariable == "this")) throw UtlException(script, "'" + sVariable + "' is a reserved variable, and cannot be redeclared");
4073 			ExprScriptVariable* pVarExpr = new ExprScriptVariable(sVariable.c_str());
4074 			pLocalVariable->setLocalVariable(pVarExpr, exprType);
4075 			script.skipEmpty();
4076 			if (script.isEqualTo('=')) {
4077 				script.skipEmpty();
4078 				pLocalVariable->setValue(parseAssignmentExpression(block, script));
4079 				script.skipEmpty();
4080 			}
4081 		} while (script.isEqualTo(','));
4082 		if (!script.isEqualTo(';')) throw UtlException(script, "syntax error: ';' expected");
4083 	}
4084 
parseLocalReference(GrfBlock & block,ScpStream & script)4085 	void DtaScript::parseLocalReference(GrfBlock& block, ScpStream& script) {
4086 		EXPRESSION_TYPE exprType = parseClassType(block, script, REFERENCE_EXPRTYPE);
4087 		do {
4088 			GrfLocalReference* pLocalReference = new GrfLocalReference;
4089 			if (requiresParsingInformation()) pLocalReference->setParsingInformation(getFilenamePtr(), script);
4090 			block.add(pLocalReference);
4091 			script.skipEmpty();
4092 			std::string sVariable;
4093 			if (!script.readIdentifier(sVariable)) throw UtlException(script, "syntax error: name of the local variable expected");
4094 			if ((sVariable == "project") || (sVariable == "null") || (sVariable == "this")) throw UtlException(script, "'" + sVariable + "' is a reserved variable, and cannot be redeclared");
4095 			ExprScriptVariable* pVarExpr = new ExprScriptVariable(sVariable.c_str());
4096 			pLocalReference->setLocalVariable(pVarExpr, exprType);
4097 			script.skipEmpty();
4098 			if (!script.isEqualTo('=')) throw UtlException(script, "syntax error: '=' expected");
4099 			script.skipEmpty();
4100 			pLocalReference->setReference(parseVariableExpression(block, script));
4101 			script.skipEmpty();
4102 		} while (script.isEqualTo(','));
4103 		if (!script.isEqualTo(';')) throw UtlException(script, "syntax error: ';' expected");
4104 	}
4105 
parseGlobalVariable(GrfBlock & block,ScpStream & script)4106 	void DtaScript::parseGlobalVariable(GrfBlock& block, ScpStream& script) {
4107 		EXPRESSION_TYPE exprType = parseClassType(block, script, NODE_EXPRTYPE);
4108 		do {
4109 			GrfGlobalVariable* pGlobalVariable = new GrfGlobalVariable;
4110 			if (requiresParsingInformation()) pGlobalVariable->setParsingInformation(getFilenamePtr(), script);
4111 			block.add(pGlobalVariable);
4112 			script.skipEmpty();
4113 			std::string sVariable;
4114 			if (!script.readIdentifier(sVariable)) throw UtlException(script, "syntax error: name of the global variable expected");
4115 			if ((sVariable == "project") || (sVariable == "null") || (sVariable == "this")) throw UtlException(script, "'" + sVariable + "' is a reserved variable, and cannot be redeclared");
4116 			pGlobalVariable->setVariable(sVariable, exprType);
4117 			script.skipEmpty();
4118 			if (script.isEqualTo('=')) {
4119 				script.skipEmpty();
4120 				pGlobalVariable->setValue(parseAssignmentExpression(block, script));
4121 				script.skipEmpty();
4122 			}
4123 		} while (script.isEqualTo(','));
4124 		if (!script.isEqualTo(';')) throw UtlException(script, "syntax error: ';' expected");
4125 	}
4126 
parseSetAssignment(GrfBlock & block,ScpStream & script)4127 	void DtaScript::parseSetAssignment(GrfBlock& block, ScpStream& script) {
4128 		GrfSetAssignment* pAssignment = new GrfSetAssignment;
4129 		if (requiresParsingInformation()) pAssignment->setParsingInformation(getFilenamePtr(), script);
4130 		block.add(pAssignment);
4131 		pAssignment->setVariable(parseVariableExpression(block, script));
4132 		script.skipEmpty();
4133 		bool bConcat = script.isEqualTo('+');
4134 		if (!script.isEqualTo('=')) throw UtlException(script, "syntax error: assignment expected ('+=' or '=' operator)");
4135 		script.skipEmpty();
4136 		pAssignment->setValue(parseAssignmentExpression(block, script), bConcat);
4137 		script.skipEmpty();
4138 		if (!script.isEqualTo(';')) throw UtlException(script, "syntax error: ';' expected");
4139 	}
4140 
parseInsertAssignment(GrfBlock & block,ScpStream & script)4141 	void DtaScript::parseInsertAssignment(GrfBlock& block, ScpStream& script) {
4142 		GrfInsertAssignment* pAssignment = new GrfInsertAssignment;
4143 		if (requiresParsingInformation()) pAssignment->setParsingInformation(getFilenamePtr(), script);
4144 		block.add(pAssignment);
4145 		pAssignment->setVariable(parseVariableExpression(block, script));
4146 		script.skipEmpty();
4147 		if (!script.isEqualTo(';')) {
4148 			bool bConcat = script.isEqualTo('+');
4149 			if (!script.isEqualTo('=')) throw UtlException(script, "syntax error: assignment expected ('+=' or '=' operator)");
4150 			script.skipEmpty();
4151 			pAssignment->setValue(parseAssignmentExpression(block, script), bConcat);
4152 			script.skipEmpty();
4153 			if (!script.isEqualTo(';')) throw UtlException(script, "syntax error: ';' expected");
4154 		}
4155 	}
4156 
parseSetAll(GrfBlock & block,ScpStream & script)4157 	void DtaScript::parseSetAll(GrfBlock& block, ScpStream& script) {
4158 		GrfSetAll* pAffectation = new GrfSetAll;
4159 		if (requiresParsingInformation()) pAffectation->setParsingInformation(getFilenamePtr(), script);
4160 		block.add(pAffectation);
4161 		pAffectation->setVariable(parseVariableExpression(block, script));
4162 		script.skipEmpty();
4163 		if (!script.isEqualTo('=')) throw UtlException(script, "syntax error: assignation expected ('=' operator)");
4164 		script.skipEmpty();
4165 		pAffectation->setSource(parseVariableExpression(block, script));
4166 		script.skipEmpty();
4167 		if (!script.isEqualTo(';')) throw UtlException(script, "syntax error: ';' expected");
4168 	}
4169 
parseMerge(GrfBlock & block,ScpStream & script)4170 	void DtaScript::parseMerge(GrfBlock& block, ScpStream& script) {
4171 		GrfMerge* pAffectation = new GrfMerge;
4172 		if (requiresParsingInformation()) pAffectation->setParsingInformation(getFilenamePtr(), script);
4173 		block.add(pAffectation);
4174 		pAffectation->setVariable(parseVariableExpression(block, script));
4175 		script.skipEmpty();
4176 		if (!script.isEqualTo('=')) throw UtlException(script, "syntax error: assignation expected ('=' operator)");
4177 		script.skipEmpty();
4178 		pAffectation->setSource(parseVariableExpression(block, script));
4179 		script.skipEmpty();
4180 		if (!script.isEqualTo(';')) throw UtlException(script, "syntax error: ';' expected");
4181 	}
4182 
parsePushItem(GrfBlock & block,ScpStream & script)4183 	void DtaScript::parsePushItem(GrfBlock& block, ScpStream& script) {
4184 		GrfPushItem* pAffectation = new GrfPushItem;
4185 		if (requiresParsingInformation()) pAffectation->setParsingInformation(getFilenamePtr(), script);
4186 		block.add(pAffectation);
4187 		pAffectation->setVariable(parseVariableExpression(block, script));
4188 		script.skipEmpty();
4189 		if (script.isEqualTo('=')) {
4190 			script.skipEmpty();
4191 			pAffectation->setValue(parseExpression(block, script));
4192 			script.skipEmpty();
4193 		}
4194 		if (!script.isEqualTo(';')) throw UtlException(script, "syntax error: ';' expected");
4195 	}
4196 
parseReference(GrfBlock & block,ScpStream & script)4197 	void DtaScript::parseReference(GrfBlock& block, ScpStream& script) {
4198 		GrfReference* pReference = new GrfReference;
4199 		if (requiresParsingInformation()) pReference->setParsingInformation(getFilenamePtr(), script);
4200 		block.add(pReference);
4201 	/*	std::string sWord;
4202 		skipEmpty(script);
4203 		if (!readIdentifier(script, sWord)) throw UtlException(script, "syntax error: variable expected");
4204 		pReference->setVariable(sWord.c_str());
4205 	*/
4206 		pReference->setVariable(parseVariableExpression(block, script));
4207 		script.skipEmpty();
4208 		if (!script.isEqualTo('=')) throw UtlException(script, "syntax error: '=' expected");
4209 		script.skipEmpty();
4210 		pReference->setReference(parseVariableExpression(block, script));
4211 		script.skipEmpty();
4212 		if (!script.isEqualTo(';')) throw UtlException(script, "syntax error: ';' expected");
4213 	}
4214 
parseSyntax(GrfBlock & block,ScpStream & script)4215 	void DtaScript::parseSyntax(GrfBlock& block, ScpStream& script) {
4216 		script.skipEmpty();
4217 		std::string sParsingMode;
4218 		std::string sParsingScript;
4219 		if (script.readIdentifier(sParsingMode)) {
4220 			script.skipLineBlanks();
4221 			if (script.isEqualTo(':')) {
4222 				script.skipEmpty();
4223 				if (!script.readString(sParsingScript) || sParsingScript.empty()) {
4224 					throw UtlException(script, "directive '#syntax', BNF script file expected after ':'");
4225 				}
4226 			}
4227 		} else if (!script.readString(sParsingScript) || sParsingScript.empty()) {
4228 			throw UtlException(script, "syntax error on directive '#syntax': parsing mode or BNF script file expected");
4229 		}
4230 		if (!sParsingMode.empty()) {
4231 			std::map<std::string, std::string>::const_iterator cursor = _mapOfSyntaxModes.find(sParsingMode);
4232 			if (cursor != _mapOfSyntaxModes.end()) {
4233 				if (sParsingScript.empty()) sParsingScript = cursor->second;
4234 				else if (sParsingScript != cursor->second) {
4235 					throw UtlException("on directive '#syntax': the BNF script file attached to the parsing mode '" + sParsingMode + "' cannot change");
4236 				}
4237 			} else {
4238 				if (sParsingScript.empty()) throw UtlException("on directive '#syntax': no BNF script file attached to the parsing mode '" + sParsingMode + "'");
4239 				_mapOfSyntaxModes[sParsingMode] = sParsingScript;
4240 			}
4241 		}
4242 		if (!script.findString("\n")) throw UtlException(script, "syntax error on directive '#syntax': expected end of file");
4243 		std::string sText;
4244 		std::string sLine;
4245 		while (script.readLine(sLine)) {
4246 			if (strncmp(sLine.c_str(), "#end", 4) == 0) {
4247 				register int iIndex = 4;
4248 				register char a = sLine[4];
4249 				while ((a == ' ') || (a == '\t')) {
4250 					iIndex++;
4251 					a = sLine[iIndex];
4252 				}
4253 				if ((iIndex > 4) && (strncmp(sLine.c_str() + iIndex, "syntax", 6) == 0)) break;
4254 			}
4255 			sText += sLine + CGRuntime::endl();
4256 		}
4257 		GrfParseStringAsBNF* pParseStringAsBNF = new GrfParseStringAsBNF;
4258 		if (requiresParsingInformation()) pParseStringAsBNF->setParsingInformation(getFilenamePtr(), script);
4259 		block.add(pParseStringAsBNF);
4260 		pParseStringAsBNF->setBNFFileName(new ExprScriptConstant(sParsingScript.c_str()));
4261 		pParseStringAsBNF->setThis(new ExprScriptVariable("this"));
4262 		pParseStringAsBNF->setContent(new ExprScriptConstant(sText.c_str()));
4263 	}
4264 
execute(DtaScriptVariable & thisContext)4265 	SEQUENCE_INTERRUPTION_LIST DtaScript::execute(DtaScriptVariable& thisContext) {
4266 		SEQUENCE_INTERRUPTION_LIST result;
4267 		CGThisModifier thisModifier(&thisContext);
4268 		DtaScriptVariable stackScript(&thisContext, "##stack## script");
4269 		if (GrfCommand::getCurrentExecutionContext() != NULL) {
4270 			try {
4271 				GrfCommand::getCurrentExecutionContext()->handleBeforeScriptExecutionCBK(&_graph, stackScript);
4272 				result = _graph.execute(stackScript);
4273 			} catch(std::exception&) {
4274 				GrfCommand::getCurrentExecutionContext()->handleAfterScriptExecutionCBK(&_graph, stackScript);
4275 				throw;
4276 			}
4277 			GrfCommand::getCurrentExecutionContext()->handleAfterScriptExecutionCBK(&_graph, stackScript);
4278 		} else {
4279 			DtaScript* pOldScript = DtaProject::getInstance().getScript();
4280 			try {
4281 				DtaProject::getInstance().setScript(this);
4282 				result = _graph.execute(stackScript);
4283 				DtaProject::getInstance().setScript(pOldScript);
4284 			} catch(std::exception&) {
4285 				DtaProject::getInstance().setScript(pOldScript);
4286 				throw;
4287 			}
4288 		}
4289 		return result;
4290 	}
4291 
compileCpp(CppCompilerEnvironment & theCompilerEnvironment,const std::string & sScriptFilename) const4292 	void DtaScript::compileCpp(CppCompilerEnvironment& theCompilerEnvironment, const std::string& sScriptFilename) const {
4293 		if (theCompilerEnvironment.pushFilename(sScriptFilename)) {
4294 			try {
4295 				std::string sOldIndentation = theCompilerEnvironment.getIndentation();
4296 				theCompilerEnvironment.setIndentation("");
4297 				std::string sIdentifier = convertFilenameAsIdentifier(theCompilerEnvironment.getRadical());
4298 				theCompilerEnvironment.getHeader() << "#ifndef _" << sIdentifier << "_h_";
4299 				theCompilerEnvironment.getHeader().endl();
4300 				theCompilerEnvironment.getHeader() << "#define _" << sIdentifier << "_h_";
4301 				theCompilerEnvironment.getHeader().endl();
4302 				theCompilerEnvironment.getHeader().endl();
4303 				compileCppHeaderIncludes(theCompilerEnvironment);
4304 				theCompilerEnvironment.getHeader().endl();
4305 				theCompilerEnvironment.getHeader().endl();
4306 				theCompilerEnvironment.getHeader() << "class " << sIdentifier << " {";
4307 				theCompilerEnvironment.getHeader().endl();
4308 				theCompilerEnvironment.getHeader() << "\tpublic:";
4309 				theCompilerEnvironment.getHeader().endl();
4310 
4311 				CW_BODY_STREAM << "#ifdef WIN32";CW_BODY_ENDL;
4312 				CW_BODY_STREAM << "#pragma warning(disable: 4786)";CW_BODY_ENDL;
4313 				CW_BODY_STREAM << "#endif";CW_BODY_ENDL;
4314 				CW_BODY_ENDL;
4315 				CW_BODY_STREAM << "#include <exception>";CW_BODY_ENDL;
4316 				CW_BODY_STREAM << "#include <iostream>";CW_BODY_ENDL;
4317 				CW_BODY_STREAM << "#include <map>";CW_BODY_ENDL;
4318 				CW_BODY_STREAM << "#include <set>";CW_BODY_ENDL;
4319 				CW_BODY_STREAM << "#include <time.h>";CW_BODY_ENDL;
4320 				CW_BODY_STREAM << "#include \"UtlException.h\"";CW_BODY_ENDL;
4321 				CW_BODY_STREAM << "#include \"CGRuntime.h\"";CW_BODY_ENDL;
4322 				CW_BODY_ENDL;
4323 				if (hasTargetLanguage()) {
4324 					CW_BODY_STREAM << "// The two following preprocessor definitions delimit the " << getTargetLanguage() << " code";CW_BODY_ENDL;
4325 					CW_BODY_STREAM << "// you have written in the original CodeWorker script. They do nothing but";CW_BODY_ENDL;
4326 					CW_BODY_STREAM << "// to inform you about the position of this piece of code in the script:";CW_BODY_ENDL;
4327 					CW_BODY_STREAM << "//     - lang: target language (certainly " << getTargetLanguage() << " here),";CW_BODY_ENDL;
4328 					CW_BODY_STREAM << "//     - file: CodeWorker script file the piece of code is coming from,";CW_BODY_ENDL;
4329 					CW_BODY_STREAM << "//     - line: line number of the piece of code in the script,";CW_BODY_ENDL;
4330 					CW_BODY_STREAM << "#define BEGIN_TARGET_LANGUAGE_CODE(lang, file, line)";CW_BODY_ENDL;
4331 					CW_BODY_STREAM << "#define END_TARGET_LANGUAGE_CODE(lang)";CW_BODY_ENDL;
4332 					CW_BODY_STREAM << "// The next preprocessor definitions indicate a syntactic entity,";CW_BODY_ENDL;
4333 					CW_BODY_STREAM << "// defined in the target language:";CW_BODY_ENDL;
4334 					CW_BODY_STREAM << "#define TARGET_LANGUAGE_TYPE_SPECIFIER(type_specifier) type_specifier";CW_BODY_ENDL;
4335 					CW_BODY_STREAM << "#define TARGET_LANGUAGE_VARIABLE(var) var";CW_BODY_ENDL;
4336 					CW_BODY_STREAM << "#define TARGET_LANGUAGE_EXPRESSION(expr) expr";CW_BODY_ENDL;
4337 					CW_BODY_ENDL;
4338 				}
4339 				CW_BODY_STREAM << "#include \"" << theCompilerEnvironment.getRadical() << ".h\"";CW_BODY_ENDL;
4340 				CW_BODY_ENDL;
4341 				CW_BODY_STREAM << "using namespace CodeWorker;";CW_BODY_ENDL;
4342 				CW_BODY_ENDL;
4343 				int iInsertAreaLocation = CW_BODY_STREAM.getOutputLocation();
4344 				CW_BODY_ENDL;
4345 				CW_BODY_STREAM.setFloatingLocation("INSERT AREA", iInsertAreaLocation);
4346 				compileCppFunctions(theCompilerEnvironment);
4347 				CW_BODY_STREAM << "Execute" << sIdentifier << "& Execute" << sIdentifier << "::instance() {";CW_BODY_ENDL;
4348 				CW_BODY_STREAM << "\tstatic Execute" << sIdentifier << " theInstance;";CW_BODY_ENDL;
4349 				CW_BODY_STREAM << "\treturn theInstance;";CW_BODY_ENDL;
4350 				CW_BODY_STREAM << "}";CW_BODY_ENDL;
4351 				CW_BODY_ENDL;
4352 				CW_BODY_STREAM << "void Execute" << sIdentifier << "::run() ";
4353 				int iGlobalInitializationPosition = CW_BODY_STREAM.getOutputLocation();
4354 				CW_BODY_STREAM.setFloatingLocation("GLOBAL INIT", iGlobalInitializationPosition);
4355 				_graph.compileCpp(theCompilerEnvironment);
4356 				theCompilerEnvironment.getHeader() << "};";
4357 				theCompilerEnvironment.getHeader().endl();
4358 				if (theCompilerEnvironment.getIncludeParentScript().empty()) {
4359 					// dynamic packages?
4360 					{
4361 						const std::map<std::string, DynPackage*>& allPackages = DynPackage::allPackages();
4362 						if (!allPackages.empty()) {
4363 							ScpStream* pOwner = NULL;
4364 							iGlobalInitializationPosition = CW_BODY_STREAM.getFloatingLocation("INSERT AREA", pOwner);
4365 							CW_BODY_STREAM.insertText(ScpStream::ENDL, iGlobalInitializationPosition);
4366 							for (std::map<std::string, DynPackage*>::const_iterator i = allPackages.begin(); i != allPackages.end(); ++i) {
4367 								CW_BODY_STREAM.insertTextOnce("#include \"" + i->first + ".h\"" + ScpStream::ENDL, iGlobalInitializationPosition);
4368 							}
4369 							CW_BODY_STREAM.insertText("// header files for all dynamic packages" + ScpStream::ENDL, iGlobalInitializationPosition);
4370 						}
4371 					}
4372 					// global variables?
4373 					const std::set<std::string>& globalVars = theCompilerEnvironment.getGlobalVariables();
4374 					ScpStream* pOwner;
4375 					if (!globalVars.empty()) {
4376 						iGlobalInitializationPosition = CW_BODY_STREAM.getFloatingLocation("GLOBAL INIT", pOwner);
4377 						while (CW_BODY_STREAM.readBuffer()[iGlobalInitializationPosition] != '\n') {
4378 							iGlobalInitializationPosition++;
4379 						}
4380 						CW_BODY_STREAM.setFloatingLocation("GLOBAL INIT", iGlobalInitializationPosition + 1);
4381 						{
4382 							theCompilerEnvironment.getHeader() << "// global variables:" << CGRuntime::endl();
4383 							for (std::set<std::string>::const_iterator i = globalVars.begin(); i != globalVars.end(); ++i) {
4384 								theCompilerEnvironment.getHeader() << "extern CodeWorker::CppParsingTree_global " << *i << ";" << CGRuntime::endl();
4385 							}
4386 							theCompilerEnvironment.getHeader().endl();
4387 							theCompilerEnvironment.getHeader().endl();
4388 						}
4389 						CW_BODY_STREAM.insertText("// global variables:" + CGRuntime::endl(), CW_BODY_STREAM.getFloatingLocation("INSERT AREA", pOwner));
4390 						for (std::set<std::string>::const_iterator i = globalVars.begin(); i != globalVars.end(); ++i) {
4391 							CW_BODY_STREAM.insertText("CppParsingTree_global " + *i + ";" + CGRuntime::endl(), CW_BODY_STREAM.getFloatingLocation("INSERT AREA", pOwner));
4392 						}
4393 					}
4394 
4395 					CW_BODY_ENDL;
4396 					CW_BODY_ENDL;
4397 					if (DtaProject::getInstance().getReadonlyHook() != NULL) {
4398 						DtaProject::getInstance().getReadonlyHook()->compileCpp(theCompilerEnvironment);
4399 					}
4400 					if (DtaProject::getInstance().getWritefileHook() != NULL) {
4401 						DtaProject::getInstance().getWritefileHook()->compileCpp(theCompilerEnvironment);
4402 					}
4403 					CW_BODY_STREAM << "int main(int iNargs, char** tsArgs) {";CW_BODY_ENDL;
4404 					CW_BODY_STREAM << "\tint iReturnCode = -1;";CW_BODY_ENDL;
4405 					CW_BODY_STREAM << "\ttry {";CW_BODY_ENDL;
4406 					{
4407 						// initialization of global variables
4408 						for (std::set<std::string>::const_iterator i = globalVars.begin(); i != globalVars.end(); ++i) {
4409 							CW_BODY_STREAM.insertText("\t" + *i + ".initialize(\"" + *i + "\");" + CGRuntime::endl(), CW_BODY_STREAM.getFloatingLocation("GLOBAL INIT", pOwner));
4410 						}
4411 					}
4412 					if (DtaProject::getInstance().getReadonlyHook() != NULL) {
4413 						CW_BODY_STREAM << "\t\tCGRuntime::registerReadonlyHook(" << DtaProject::getInstance().getReadonlyHook()->getFunctionName() << ");";CW_BODY_ENDL;
4414 					}
4415 					if (DtaProject::getInstance().getWritefileHook() != NULL) {
4416 						CW_BODY_STREAM << "\t\tCGRuntime::registerWritefileHook(" << DtaProject::getInstance().getWritefileHook()->getFunctionName() << ");";CW_BODY_ENDL;
4417 					}
4418 					const std::list<std::string>& listOfModules = theCompilerEnvironment.getProjectModules();
4419 					std::list<std::string>::const_iterator i;
4420 					for (i = listOfModules.begin(); i != listOfModules.end(); i++) {
4421 						CW_BODY_STREAM << "\t\tCGRuntime::registerScript(\"" << CppCompilerEnvironment::getRadical(*i) << "\", &Execute" << convertFilenameAsIdentifier(CppCompilerEnvironment::getRadical(*i)) << "::instance());";CW_BODY_ENDL;
4422 					}
4423 					{
4424 						const std::map<std::string, DynPackage*>& allPackages = DynPackage::allPackages();
4425 						for (std::map<std::string, DynPackage*>::const_iterator i = allPackages.begin(); i != allPackages.end(); ++i) {
4426 							CW_BODY_STREAM << "\t\t" << i->first << " initializeDynamicPackage" << i->first << ";";CW_BODY_ENDL;
4427 						}
4428 					}
4429 					CW_BODY_STREAM << "\t\tiReturnCode = CGRuntime::entryPoint(iNargs, tsArgs, &Execute" << sIdentifier <<"::instance());";
4430 					CW_BODY_ENDL;
4431 					CW_BODY_STREAM << "\t} catch(UtlExitException& exit) {";CW_BODY_ENDL;
4432 					CW_BODY_STREAM << "\t\tiReturnCode = exit.getCode();";CW_BODY_ENDL;
4433 					CW_BODY_STREAM << "\t} catch(std::exception& exception) {";CW_BODY_ENDL;
4434 					CW_BODY_STREAM << "\t\tCGRuntime::traceLine(exception.what());";CW_BODY_ENDL;
4435 					CW_BODY_STREAM << "\t}";CW_BODY_ENDL;
4436 					CW_BODY_STREAM << "\treturn iReturnCode;";CW_BODY_ENDL;
4437 					CW_BODY_STREAM << "}";CW_BODY_ENDL;
4438 					theCompilerEnvironment.getMainHeader().endl();
4439 					for (i = listOfModules.begin(); i != listOfModules.end(); i++) {
4440 						std::string sIdentifier = convertFilenameAsIdentifier(CppCompilerEnvironment::getRadical(*i));
4441 						theCompilerEnvironment.getMainHeader() << "class Execute" << sIdentifier << " : public CodeWorker::EXECUTE_FUNCTION {";
4442 						theCompilerEnvironment.getMainHeader().endl();
4443 						theCompilerEnvironment.getMainHeader() << "\tpublic:";theCompilerEnvironment.getMainHeader().endl();
4444 						theCompilerEnvironment.getMainHeader() << "\t\tstatic Execute" << sIdentifier << "& instance();";theCompilerEnvironment.getMainHeader().endl();
4445 						theCompilerEnvironment.getMainHeader() << "\t\tvirtual void run();";theCompilerEnvironment.getMainHeader().endl();
4446 						theCompilerEnvironment.getMainHeader() << "};";theCompilerEnvironment.getMainHeader().endl();
4447 						theCompilerEnvironment.getMainHeader().endl();
4448 					}
4449 				}
4450 
4451 				theCompilerEnvironment.getHeader().endl();
4452 				theCompilerEnvironment.getHeader() << "#endif";
4453 				theCompilerEnvironment.getHeader().endl();
4454 
4455 				theCompilerEnvironment.setIndentation(sOldIndentation);
4456 			} catch(UtlException& exception) {
4457 				theCompilerEnvironment.catchFilename(exception);
4458 			}
4459 			theCompilerEnvironment.popFilename();
4460 		}
4461 	}
4462 
compileCppHeaderIncludes(CppCompilerEnvironment & theCompilerEnvironment) const4463 	void DtaScript::compileCppHeaderIncludes(CppCompilerEnvironment& theCompilerEnvironment) const {
4464 		if (!theCompilerEnvironment.getIncludeParentScript().empty()) {
4465 			std::string sCppParent = theCompilerEnvironment.getIncludeParentScript();
4466 			theCompilerEnvironment.getHeader() << "#include \"" << CppCompilerEnvironment::getRelativePath(sCppParent) << ".h\"";
4467 			theCompilerEnvironment.getHeader().endl();
4468 		} else {
4469 			theCompilerEnvironment.getHeader() << "#include <string>";
4470 			theCompilerEnvironment.getHeader().endl();
4471 			theCompilerEnvironment.getHeader() << "#include \"CppParsingTree.h\"";
4472 			theCompilerEnvironment.getHeader().endl();
4473 			theCompilerEnvironment.getHeader() << "#include \"CGExternalHandling.h\"";
4474 			theCompilerEnvironment.getHeader().endl();
4475 		}
4476 	}
4477 
compileCppFunctions(CppCompilerEnvironment & theCompilerEnvironment) const4478 	void DtaScript::compileCppFunctions(CppCompilerEnvironment& theCompilerEnvironment) const {
4479 		_graph.compileCppFunctions(theCompilerEnvironment);
4480 	}
4481 
convertFilenameAsIdentifier(const std::string & sFilename)4482 	std::string DtaScript::convertFilenameAsIdentifier(const std::string& sFilename) {
4483 		std::string sIdentifier;
4484 		std::string::size_type iIndex = sFilename.find(".");
4485 		if (iIndex == std::string::npos) sIdentifier = sFilename;
4486 		else sIdentifier = sFilename.substr(0, iIndex);
4487 		for (std::string::size_type i = 0; i < sIdentifier.size(); i++) {
4488 			char a = sIdentifier[i];
4489 			if (((a < 'a') || (a > 'z')) && ((a < 'A') || (a > 'Z')) && ((a < '0') || (a > '9')) && (a != '_')) {
4490 				if (a == '+') a = 'p';
4491 				else a = '_';
4492 				sIdentifier[i] = a;
4493 			}
4494 		}
4495 		return sIdentifier;
4496 	}
4497 
equalsIgnoringGenerationHeader(ScpStream & theInputStream,ScpStream & theOutputStream,int & iPosition)4498 	bool DtaScript::equalsIgnoringGenerationHeader(ScpStream& theInputStream, ScpStream& theOutputStream, int& iPosition) {
4499 		std::string sGenerator;
4500 		std::string sVersion;
4501 		std::string sDate;
4502 		std::string sComment1;
4503 		CGRuntime::extractGenerationHeader(theInputStream, sGenerator, sVersion, sDate, sComment1);
4504 		std::string sComment2;
4505 		CGRuntime::extractGenerationHeader(theOutputStream, sGenerator, sVersion, sDate, sComment2);
4506 		if (sComment1 != sComment2) {
4507 			iPosition = theInputStream.getInputLocation();
4508 			return false;
4509 		}
4510 		return theInputStream.equalsFromInputLocations(theOutputStream, iPosition);
4511 	}
4512 
computeReferenceMagicNumber(ScpStream & script,const char * tcFilename,const std::string & sKey)4513 	int DtaScript::computeReferenceMagicNumber(ScpStream& script, const char* tcFilename, const std::string& sKey) {
4514 		int iChar;
4515 		int iOldChar = '\0';
4516 		int iMagicNumber = 0;
4517 		for(;;) {
4518 			iChar = script.readChar();
4519 			if (iChar == -1)  throw UtlException(script, "syntax error on '#reference' area: '#end " + sKey + "' expected before end of file");
4520 			if ((iChar == '#') && (iOldChar == '\n')) {
4521 				std::string sDirective;
4522 				if (!script.readIdentifier(sDirective)) throw UtlException(script, "preprocessor directive expected after '#' symbol");
4523 				if (sDirective == "reference") {
4524 					script.skipLineBlanks();
4525 					std::string sEmbeddedKey;
4526 					if (!script.readIdentifier(sEmbeddedKey)) throw UtlException(script, "syntax error on '#reference': identifier expected");
4527 					if (!script.findString("\n")) throw UtlException(script, "syntax error on '#reference " + sEmbeddedKey + "': end of line expected");
4528 					int iEmbeddedMagicNumber = computeReferenceMagicNumber(script, tcFilename, sKey);
4529 					iMagicNumber = (31*iMagicNumber + iEmbeddedMagicNumber) & 0x03FFFFFF;
4530 				} else if (sDirective == "end") {
4531 					script.skipLineBlanks();
4532 					if (script.isEqualToIdentifier(sKey.c_str())) {
4533 						if (!script.findString("\n")) throw UtlException(script, "syntax error on '#end " + sKey + "': end of line expected");
4534 						break;
4535 					}
4536 				}
4537 			} else {
4538 				iMagicNumber = (31*iMagicNumber + iChar) & 0x03FFFFFF;
4539 			}
4540 			iOldChar = iChar;
4541 		}
4542 		std::string sFileName = tcFilename;
4543 		std::string::size_type iIndex = sFileName.find_last_of("/\\");
4544 		if (iIndex != std::string::npos) sFileName = sFileName.substr(iIndex + 1);
4545 		_mapOfReferenceMagicNumbers[sKey + ":" + sFileName] = iMagicNumber;
4546 		return iMagicNumber;
4547 	}
4548 
computeReferenceMagicNumber(ScpStream & theStream,const std::string & sKey)4549 	int DtaScript::computeReferenceMagicNumber(ScpStream& theStream, const std::string& sKey) {
4550 		int iChar;
4551 		int iOldChar = '\0';
4552 		int iMagicNumber = 0;
4553 		for(;;) {
4554 			iChar = theStream.readChar();
4555 			if (iChar == -1)  throw UtlException(theStream, "syntax error on '#reference' area: '#end " + sKey + "' expected before end of file");
4556 			if ((iChar == '#') && (iOldChar == '\n')) {
4557 				std::string sDirective;
4558 				if (!theStream.readIdentifier(sDirective)) throw UtlException(theStream, "preprocessor directive expected after '#' symbol");
4559 				if (sDirective == "reference") {
4560 					theStream.skipLineBlanks();
4561 					std::string sEmbeddedKey;
4562 					if (!theStream.readIdentifier(sEmbeddedKey)) throw UtlException(theStream, "syntax error on '#reference': identifier expected");
4563 					if (!theStream.findString("\n")) throw UtlException(theStream, "syntax error on '#reference " + sEmbeddedKey + "': end of line expected");
4564 					int iEmbeddedMagicNumber = computeReferenceMagicNumber(theStream, sKey);
4565 					iMagicNumber = (31*iMagicNumber + iEmbeddedMagicNumber) & 0x03FFFFFF;
4566 				} else if (sDirective == "end") {
4567 					theStream.skipLineBlanks();
4568 					if (theStream.isEqualToIdentifier(sKey.c_str())) {
4569 						if (!theStream.findString("\n")) throw UtlException(theStream, "syntax error on '#end " + sKey + "': end of line expected");
4570 						break;
4571 					}
4572 				}
4573 			} else {
4574 				iMagicNumber = (31*iMagicNumber + iChar) & 0x03FFFFFF;
4575 			}
4576 			iOldChar = iChar;
4577 		}
4578 		std::string sFileName = theStream.getFilename();
4579 		std::string::size_type iIndex = sFileName.find_last_of("/\\");
4580 		if (iIndex != std::string::npos) sFileName = sFileName.substr(iIndex + 1);
4581 		_mapOfReferenceMagicNumbers[sKey + ":" + sFileName] = iMagicNumber;
4582 		return iMagicNumber;
4583 	}
4584 
extractReferenceMagicNumber(const std::string & sReferenceFile,const std::string & sKey,int & iMagicNumber)4585 	bool DtaScript::extractReferenceMagicNumber(const std::string& sReferenceFile, const std::string& sKey, int& iMagicNumber) {
4586 		std::auto_ptr<ScpStream> pScriptFile(new ScpStream(sReferenceFile, ScpStream::IN | ScpStream::PATH));
4587 		while (pScriptFile->findString("#reference")) {
4588 			int iLocation = pScriptFile->getInputLocation();
4589 			bool bToHandle = (iLocation <= 10);
4590 			if (!bToHandle) {
4591 				pScriptFile->setInputLocation(iLocation - 11);
4592 				bToHandle = (pScriptFile->readChar() == (int) '\n');
4593 				pScriptFile->setInputLocation(iLocation);
4594 			}
4595 			if (bToHandle) {
4596 				pScriptFile->skipLineBlanks();
4597 				if (pScriptFile->isEqualToIdentifier(sKey.c_str())) {
4598 					if (!pScriptFile->findString("\n")) return false;
4599 					iMagicNumber = computeReferenceMagicNumber(*pScriptFile, sKey);
4600 					return true;
4601 				}
4602 			}
4603 		}
4604 		return false;
4605 	}
4606 }
4607