1 /* "CodeWorker": a scripting language for parsing and generating text. 2 3 Copyright (C) 1996-1997, 1999-2002 C�dric Lemaire 4 5 This library is free software; you can redistribute it and/or 6 modify it under the terms of the GNU Lesser General Public 7 License as published by the Free Software Foundation; either 8 version 2.1 of the License, or (at your option) any later version. 9 10 This library is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 Lesser General Public License for more details. 14 15 You should have received a copy of the GNU Lesser General Public 16 License along with this library; if not, write to the Free Software 17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 19 To contact the author: codeworker@free.fr 20 */ 21 22 #ifdef WIN32 23 #pragma warning (disable : 4786) 24 #endif 25 26 #include <set> 27 28 #include "ScpStream.h" 29 #include "UtlException.h" 30 31 #include "CGRuntime.h" 32 #include "DtaProject.h" 33 #include "DtaPatternScript.h" 34 #include "GrfFunction.h" 35 #include "BNFClause.h" 36 #include "DynFunction.h" 37 #include "DynPackage.h" 38 #include "CGCompiler.h" 39 #include "CppCompilerEnvironment.h" 40 41 namespace CodeWorker { 42 class CppStack { 43 private: 44 std::set<std::string> _setOfVariables; 45 46 public: CppStack()47 CppStack() {} ~CppStack()48 ~CppStack() {} 49 50 bool addVariable(const std::string& sVariable); 51 bool existVariable(const std::string& sVariable) const; 52 }; 53 addVariable(const std::string & sVariable)54 bool CppStack::addVariable(const std::string& sVariable) { 55 std::set<std::string>::const_iterator cursor = _setOfVariables.find(sVariable); 56 if (cursor != _setOfVariables.end()) return false; 57 _setOfVariables.insert(sVariable); 58 return true; 59 } 60 existVariable(const std::string & sVariable) const61 bool CppStack::existVariable(const std::string& sVariable) const { 62 std::set<std::string>::const_iterator cursor = _setOfVariables.find(sVariable); 63 return (cursor != _setOfVariables.end()); 64 } 65 66 67 class CppVariableScope { 68 private: 69 std::list<CppStack*> _stack; 70 std::string _sClauseReturnValue; 71 bool _bHasEvaluatedExpressionInScope; 72 73 public: CppVariableScope()74 CppVariableScope() : _bHasEvaluatedExpressionInScope(false) { addStack(); } ~CppVariableScope()75 ~CppVariableScope() { removeStack(); } 76 addVariable(const std::string & sVariable)77 bool addVariable(const std::string& sVariable) { return _stack.front()->addVariable(sVariable); } 78 bool existVariable(const std::string& sVariable) const; addStack()79 void addStack() { _stack.push_front(new CppStack); } removeStack()80 void removeStack() { delete _stack.front(); _stack.pop_front(); } 81 void setClauseReturnValue(const std::string& sClauseName); 82 bool isClauseReturnValue(const std::string& sVariableName) const; hasEvaluatedExpressionInScope(bool bEvaluated)83 void hasEvaluatedExpressionInScope(bool bEvaluated) { _bHasEvaluatedExpressionInScope = bEvaluated; } hasEvaluatedExpressionInScope() const84 bool hasEvaluatedExpressionInScope() const { return _bHasEvaluatedExpressionInScope; } 85 86 private: 87 CppVariableScope(const CppVariableScope&); 88 CppVariableScope& operator =(const CppVariableScope&); 89 }; 90 existVariable(const std::string & sVariable) const91 bool CppVariableScope::existVariable(const std::string& sVariable) const { 92 for (std::list<CppStack*>::const_iterator i = _stack.begin(); i != _stack.end(); i++) { 93 if ((*i)->existVariable(sVariable)) return true; 94 } 95 return false; 96 } 97 setClauseReturnValue(const std::string & sClauseName)98 void CppVariableScope::setClauseReturnValue(const std::string& sClauseName) { 99 _sClauseReturnValue = sClauseName; 100 } 101 isClauseReturnValue(const std::string & sVariableName) const102 bool CppVariableScope::isClauseReturnValue(const std::string& sVariableName) const { 103 return (_sClauseReturnValue == sVariableName); 104 } 105 106 CppScriptSession(const std::string & sFilename,const std::string & sCppRadical)107 CppScriptSession::CppScriptSession(const std::string& sFilename, const std::string& sCppRadical) : _sFilename(sFilename), _sCppRadical(sCppRadical), _header(0), _body(0) { 108 _header = new DtaPatternScript; 109 std::string sSourceFile = sCppRadical + ".h"; 110 ScpStream* pOldStream; 111 _header->openGenerate(false, sSourceFile.c_str(), pOldStream); 112 _body = new DtaPatternScript; 113 sSourceFile = sCppRadical + ".cpp"; 114 _body->openGenerate(false, sSourceFile.c_str(), pOldStream); 115 pushVariableScope(); 116 } CppScriptSession(const CppScriptSession & copy)117 CppScriptSession::CppScriptSession(const CppScriptSession& copy) : _header(copy._header), _body(copy._body) { 118 _sIndentation = copy._sIndentation; 119 _setOfProjectFunctions = copy._setOfProjectFunctions; 120 _setOfProjectClauses = copy._setOfProjectClauses; 121 _sFilename = copy._sFilename; 122 _sCppRadical = copy._sCppRadical; 123 copy._header = 0; 124 copy._body = 0; 125 _stackOfScopes = copy._stackOfScopes; 126 copy._stackOfScopes = std::list<CppVariableScope*>(); 127 } operator =(const CppScriptSession & copy)128 CppScriptSession& CppScriptSession::operator =(const CppScriptSession& copy) { 129 _sIndentation = copy._sIndentation; 130 _setOfProjectFunctions = copy._setOfProjectFunctions; 131 _setOfProjectClauses = copy._setOfProjectClauses; 132 _sFilename = copy._sFilename; 133 _sCppRadical = copy._sCppRadical; 134 _header = copy._header; 135 _body = copy._body; 136 copy._header = 0; 137 copy._body = 0; 138 _stackOfScopes = copy._stackOfScopes; 139 copy._stackOfScopes = std::list<CppVariableScope*>(); 140 return *this; 141 } ~CppScriptSession()142 CppScriptSession::~CppScriptSession() { 143 std::string sExceptionMessage; 144 std::string sExceptionStack; 145 if (_header != 0) { 146 try { 147 ScpStream* pOldStream = NULL; 148 std::string sSourceFile = _sCppRadical + ".h"; 149 _header->closeGenerate(false, sSourceFile.c_str(), pOldStream); 150 } catch(UtlException& exception) { 151 sExceptionMessage = exception.getMessage(); 152 sExceptionStack = exception.getTraceStack(); 153 } 154 delete _header; 155 } 156 if (_body != 0) { 157 try { 158 ScpStream* pOldStream = NULL; 159 std::string sSourceFile = _sCppRadical + ".cpp"; 160 _body->closeGenerate(false, sSourceFile.c_str(), pOldStream); 161 } catch(UtlException& exception) { 162 if (!sExceptionMessage.empty() || !sExceptionStack.empty()) sExceptionMessage += "\n"; 163 sExceptionMessage += exception.getMessage(); 164 sExceptionStack += exception.getTraceStack(); 165 } 166 delete _body; 167 } 168 169 for (std::list<CppVariableScope*>::iterator i = _stackOfScopes.begin(); i != _stackOfScopes.end(); ++i) { 170 delete *i; 171 } 172 173 if (!sExceptionMessage.empty() || !sExceptionStack.empty()) throw UtlException(sExceptionMessage, sExceptionStack); 174 } 175 incrementIndentation()176 void CppScriptSession::incrementIndentation() { 177 _sIndentation += "\t"; 178 _stackOfScopes.front()->addStack(); 179 } 180 decrementIndentation()181 void CppScriptSession::decrementIndentation() { 182 if (_sIndentation.size() == 1) _sIndentation = ""; 183 else _sIndentation = _sIndentation.substr(1); 184 _stackOfScopes.front()->removeStack(); 185 } 186 pushVariableScope() const187 void CppScriptSession::pushVariableScope() const { 188 _stackOfScopes.push_front(new CppVariableScope); 189 } 190 popVariableScope() const191 void CppScriptSession::popVariableScope() const { 192 delete _stackOfScopes.front(); 193 _stackOfScopes.pop_front(); 194 } 195 pushForeach(GrfForeach * pForeach)196 void CppScriptSession::pushForeach(GrfForeach* pForeach) { 197 _listOfForeachStatements.push_front(pForeach); 198 } 199 getLastForeach() const200 GrfForeach* CppScriptSession::getLastForeach() const { 201 return _listOfForeachStatements.front(); 202 } 203 popForeach()204 void CppScriptSession::popForeach() { 205 _listOfForeachStatements.pop_front(); 206 } 207 catchFilename()208 void CppScriptSession::catchFilename() { 209 ScpStream* pOldStream = NULL; 210 _header->catchGenerateExecution(false, pOldStream, NULL); 211 delete _header; 212 _header = 0; 213 _body->catchGenerateExecution(false, pOldStream, NULL); 214 delete _body; 215 _body = 0; 216 } 217 218 CppNewVariableScopeEnvironment(CppCompilerEnvironment & env)219 CppNewVariableScopeEnvironment::CppNewVariableScopeEnvironment(CppCompilerEnvironment& env) : _session(env.getCurrentScriptSession()) { 220 _stackOfScopes = _session._stackOfScopes; 221 _session._stackOfScopes = std::list<CppVariableScope*>(); 222 _session.pushVariableScope(); 223 } 224 ~CppNewVariableScopeEnvironment()225 CppNewVariableScopeEnvironment::~CppNewVariableScopeEnvironment() { 226 _session.popVariableScope(); 227 _session._stackOfScopes = _stackOfScopes; 228 } 229 230 231 CppCompilerEnvironment(const std::string & sCppProjectDirectory)232 CppCompilerEnvironment::CppCompilerEnvironment(const std::string& sCppProjectDirectory) : _bBracketsToNextBlock(true), _bCarriageReturnAfterBlock(true), _iSwitchNumber(0), _iCursorNumber(0), _bErrorEncountered(false), _iPointerToDeclarations(0), _pCurrentClause(NULL), _iBNFStepperCursor(0), _iInlineScriptCounter(0) { 233 _sCodeWorkerDirectory = DtaProject::getInstance().getCodeWorkerHome(); 234 if ((sCppProjectDirectory[0] == '/') || (!sCppProjectDirectory.empty() && (sCppProjectDirectory[1] == ':'))) _sCppProjectDirectory = CGRuntime::canonizePath(sCppProjectDirectory); 235 else _sCppProjectDirectory = CGRuntime::relativePath(sCppProjectDirectory, CGRuntime::getWorkingPath()); 236 if (_sCppProjectDirectory[_sCppProjectDirectory.size() - 1] != '/') _sCppProjectDirectory += "/"; 237 CGRuntime::setProperty("c++2target-path", _sCppProjectDirectory); 238 addGlobalVariable("_ARGS"); 239 addGlobalVariable("_REQUEST"); // for CGI program 240 try { 241 std::string sCWIncludeDir = _sCodeWorkerDirectory; 242 if (CGRuntime::existFile(sCWIncludeDir + "include/UtlException.h")) sCWIncludeDir += "include/"; 243 CGRuntime::copySmartFile(sCWIncludeDir + "UtlException.h", _sCppProjectDirectory + "UtlException.h"); 244 CGRuntime::copySmartFile(sCWIncludeDir + "CppParsingTree.h", _sCppProjectDirectory + "CppParsingTree.h"); 245 CGRuntime::copySmartFile(sCWIncludeDir + "CGRuntime.h", _sCppProjectDirectory + "CGRuntime.h"); 246 CGRuntime::copySmartFile(sCWIncludeDir + "CGExternalHandling.h", _sCppProjectDirectory + "CGExternalHandling.h"); 247 CGRuntime::copySmartFile(sCWIncludeDir + "DynPackage.h", _sCppProjectDirectory + "DynPackage.h"); 248 } catch(UtlException&) { 249 CGRuntime::traceLine("WARNING: (considering '" + _sCodeWorkerDirectory + "' as the root path of 'CodeWorker') unable to copy files 'UtlException.h' + 'CppParsingTree.h' + 'CGRuntime.h' in the project directory '" + _sCppProjectDirectory + "'"); 250 } 251 } 252 ~CppCompilerEnvironment()253 CppCompilerEnvironment::~CppCompilerEnvironment() { 254 if (!_bErrorEncountered) { 255 generateDynamicPackages(); 256 generateDSP(); 257 generateMakefile(); 258 } 259 } 260 pushLastRepeatCursor(int iCursor)261 void CppCompilerEnvironment::pushLastRepeatCursor(int iCursor) { 262 _listOfLastRepeatCursors.push_back(iCursor); 263 _listOfLastRepeatCursorUsed.push_back(false); 264 } 265 getLastRepeatCursor(bool bUsed)266 int CppCompilerEnvironment::getLastRepeatCursor(bool bUsed) { 267 if (_listOfLastRepeatCursors.empty()) return -1; 268 if (bUsed) _listOfLastRepeatCursorUsed.back() = true; 269 return _listOfLastRepeatCursors.back(); 270 } 271 popLastRepeatCursor()272 bool CppCompilerEnvironment::popLastRepeatCursor() { 273 bool bUsed = _listOfLastRepeatCursorUsed.back(); 274 _listOfLastRepeatCursors.pop_back(); 275 _listOfLastRepeatCursorUsed.pop_back(); 276 return bUsed; 277 } 278 generateDynamicPackages()279 void CppCompilerEnvironment::generateDynamicPackages() { 280 const std::map<std::string, DynPackage*>& allPackages = DynPackage::allPackages(); 281 for (std::map<std::string, DynPackage*>::const_iterator i = allPackages.begin(); i != allPackages.end(); ++i) { 282 std::auto_ptr<ScpStream> pModuleHeader(new ScpStream(_sCppProjectDirectory + i->first + ".h", ScpStream::OUT)); 283 std::auto_ptr<ScpStream> pModuleBody(new ScpStream(_sCppProjectDirectory + i->first + ".cpp", ScpStream::OUT)); 284 (*pModuleHeader) << "#ifndef _" << i->first << "_h_" << ScpStream::ENDL; 285 (*pModuleHeader) << "#define _" << i->first << "_h_" << ScpStream::ENDL << ScpStream::ENDL; 286 (*pModuleHeader) << "#include <string>" << ScpStream::ENDL; 287 (*pModuleHeader) << "#include \"DynPackage.h\"" << ScpStream::ENDL; 288 (*pModuleHeader) << ScpStream::ENDL << "namespace CodeWorker {" << ScpStream::ENDL; 289 (*pModuleHeader) << "\tclass CppParsingTree_value;" << ScpStream::ENDL; 290 (*pModuleHeader) << "\tclass CppParsingTree_var;" << ScpStream::ENDL; 291 (*pModuleHeader) << ScpStream::ENDL << "\tclass " << i->first << " : public CodeWorker::DynPackage {" << ScpStream::ENDL; 292 (*pModuleHeader) << "\t\tpublic:" << ScpStream::ENDL; 293 (*pModuleHeader) << "\t\t\t" << i->first << "();" << ScpStream::ENDL; 294 (*pModuleHeader) << "\t\t\tstatic " << i->first << "& instance();" << ScpStream::ENDL; 295 (*pModuleBody) << "#ifdef WIN32" << ScpStream::ENDL; 296 (*pModuleBody) << "#pragma warning(disable: 4786)" << ScpStream::ENDL; 297 (*pModuleBody) << "#endif" << ScpStream::ENDL << ScpStream::ENDL; 298 (*pModuleBody) << "#include \"UtlException.h\"" << ScpStream::ENDL; 299 (*pModuleBody) << "#include \"CppParsingTree.h\"" << ScpStream::ENDL; 300 (*pModuleBody) << "#include \"" << i->first << ".h\"" << ScpStream::ENDL; 301 (*pModuleBody) << ScpStream::ENDL << "namespace CodeWorker {" << ScpStream::ENDL; 302 (*pModuleBody) << "\t" << i->first << "* " << i->first << "::pInstance_ = NULL;" << ScpStream::ENDL << ScpStream::ENDL; 303 (*pModuleBody) << "\t" << i->first << "::" << i->first << "() : CodeWorker::DynPackage(\"" << i->first << "\") {" << ScpStream::ENDL; 304 (*pModuleBody) << "\t\tpInstance_ = this;" << ScpStream::ENDL; 305 (*pModuleBody) << "\t}" << ScpStream::ENDL << ScpStream::ENDL; 306 (*pModuleBody) << "\t" << i->first << "& " << i->first << "::instance() {" << ScpStream::ENDL; 307 (*pModuleBody) << "\t\tif (pInstance_ == NULL) throw UtlException(\"The dynamic package '" << i->first << "' should have been initialized before use!\");" << ScpStream::ENDL; 308 (*pModuleBody) << "\t\treturn *pInstance_;" << ScpStream::ENDL; 309 (*pModuleBody) << "\t}" << ScpStream::ENDL << ScpStream::ENDL; 310 for (std::map<std::string, DynFunction*>::const_iterator j = i->second->allFunctions().begin(); j != i->second->allFunctions().end(); ++j) { 311 (*pModuleHeader) << "\t\t\tstd::string _compilerFunction_" << j->first << "("; 312 (*pModuleBody) << "\tstd::string " + i->first + "::_compilerFunction_" << j->first << "("; 313 int iIndex = 0; 314 std::list<std::string>::const_iterator k; 315 for (k = j->second->getParameters().begin(); k != j->second->getParameters().end(); ++k) { 316 if (iIndex > 0) { 317 (*pModuleHeader) << ", "; 318 (*pModuleBody) << ", "; 319 } 320 switch(j->second->getParameterType(iIndex) & 0x00FF) { 321 case VALUE_EXPRTYPE: 322 (*pModuleHeader) << "const CodeWorker::CppParsingTree_value& "; 323 (*pModuleBody) << "const CodeWorker::CppParsingTree_value& "; 324 break; 325 case NODE_EXPRTYPE: 326 (*pModuleHeader) << "const CodeWorker::CppParsingTree_var& "; 327 (*pModuleBody) << "const CodeWorker::CppParsingTree_var& "; 328 break; 329 default: 330 throw UtlException("fatal error while generating the C++ layer of the dynamic module '" + i->first + "': unrecognized parameter type of variable '" + *k + "'"); 331 } 332 (*pModuleHeader) << *k; 333 (*pModuleBody) << *k; 334 iIndex++; 335 } 336 (*pModuleHeader) << ");" << ScpStream::ENDL; 337 (*pModuleBody) << ") {" << ScpStream::ENDL; 338 (*pModuleBody) << "\t\tstatic CALL" << iIndex << "_FUNCTION pfFunctionCall = (CALL" << iIndex << "_FUNCTION) findFunction(_hHandle, \"" << j->first << "\");" << ScpStream::ENDL; 339 (*pModuleBody) << "\t\tif (pfFunctionCall == NULL) throw UtlException(\"the module '" << i->first << "' doesn't export the function '" << i->first << "::" << j->first << "'\");" << ScpStream::ENDL; 340 iIndex = 0; 341 if (j->second->getParameters().size() <= 4) { 342 (*pModuleBody) << "\t\tconst char* tcResult = pfFunctionCall(_pInterpreter"; 343 for (k = j->second->getParameters().begin(); k != j->second->getParameters().end(); ++k) { 344 (*pModuleBody) << ", "; 345 switch(j->second->getParameterType(iIndex) & 0x00FF) { 346 case VALUE_EXPRTYPE: 347 (*pModuleBody) << "(char*) " << *k << ".getValue()"; 348 break; 349 case NODE_EXPRTYPE: 350 (*pModuleBody) << *k << ".getInternalNode()"; 351 break; 352 default: 353 throw UtlException("fatal error while generating the C++ layer of the dynamic module '" + i->first + "': unrecognized parameter type of variable '" + *k + "'"); 354 } 355 iIndex++; 356 } 357 (*pModuleBody) << ");" << ScpStream::ENDL; 358 } else { 359 (*pModuleBody) << "\t\tCodeWorker::Parameter* tParams = new CodeWorker::Parameter[" << (int) j->second->getParameters().size() << "];"; 360 for (k = j->second->getParameters().begin(); k != j->second->getParameters().end(); ++k) { 361 (*pModuleBody) << ", "; 362 switch(j->second->getParameterType(iIndex) & 0x00FF) { 363 case VALUE_EXPRTYPE: 364 (*pModuleBody) << "\t\ttParams[" << iIndex << "] = (char*) " << *k << ".getValue();" << ScpStream::ENDL; 365 break; 366 case NODE_EXPRTYPE: 367 (*pModuleBody) << "\t\ttParams[" << iIndex << "] = " << *k << ".getInternalNode();" << ScpStream::ENDL; 368 break; 369 default: 370 throw UtlException("fatal error while generating the C++ layer of the dynamic module '" + i->first + "': unrecognized parameter type of variable '" + *k + "'"); 371 } 372 iIndex++; 373 } 374 (*pModuleBody) << "\t\tconst char* tcResult = pfFunctionCall(_pInterpreter, tParams);" << ScpStream::ENDL; 375 (*pModuleBody) << "\t\tdelete [] tParams;" << ScpStream::ENDL; 376 } 377 (*pModuleBody) << "\t\tif (tcResult == NULL) return \"\";" << ScpStream::ENDL; 378 (*pModuleBody) << "\t\treturn tcResult;" << ScpStream::ENDL; 379 (*pModuleBody) << "\t}" << ScpStream::ENDL << ScpStream::ENDL; 380 } 381 (*pModuleBody) << "}" << ScpStream::ENDL; 382 (*pModuleHeader) << "\t\tprivate:" << ScpStream::ENDL; 383 (*pModuleHeader) << "\t\t\tstatic " << i->first << "* " << "pInstance_;" << ScpStream::ENDL; 384 (*pModuleHeader) << "\t};" << ScpStream::ENDL; 385 (*pModuleHeader) << "}" << ScpStream::ENDL; 386 (*pModuleHeader) << "#endif" << ScpStream::ENDL; 387 { 388 std::auto_ptr<ScpStream> pOldHeader(new ScpStream(_sCppProjectDirectory + i->first + ".h", ScpStream::IN | ScpStream::OUT)); 389 int iPosition; 390 if (!pModuleHeader->equals(*pOldHeader, iPosition)) pModuleHeader->saveIntoFile(_sCppProjectDirectory + i->first + ".h", true); 391 } 392 { 393 std::auto_ptr<ScpStream> pOldBody(new ScpStream(_sCppProjectDirectory + i->first + ".cpp", ScpStream::IN | ScpStream::OUT)); 394 int iPosition; 395 if (!pModuleBody->equals(*pOldBody, iPosition)) pModuleBody->saveIntoFile(_sCppProjectDirectory + i->first + ".cpp", true); 396 } 397 } 398 } 399 generateDSP()400 void CppCompilerEnvironment::generateDSP() { 401 std::string sBinDir = _sCodeWorkerDirectory; 402 if (CGRuntime::existFile(sBinDir + "bin/CodeWorker.lib")) sBinDir += "bin/"; 403 else if (CGRuntime::existFile(sBinDir + "../bin/CodeWorker.lib")) sBinDir += "../bin/"; 404 else if (CGRuntime::existFile(sBinDir + "lib/CodeWorker.lib")) sBinDir += "lib/"; 405 else if (CGRuntime::existFile(sBinDir + "../lib/CodeWorker.lib")) sBinDir += "../lib/"; 406 else sBinDir += "Release/"; 407 std::string sProjectName = getRadical(_listOfProjectModules.front()); 408 std::string::size_type iIndex = sProjectName.find_last_of('_'); 409 if ((iIndex != std::string::npos) && (iIndex != 0)) sProjectName = sProjectName.substr(0, iIndex); 410 std::auto_ptr<ScpStream> pMakeFile(new ScpStream(_sCppProjectDirectory + sProjectName + ".dsp", ScpStream::IN | ScpStream::OUT)); 411 if (pMakeFile->empty()) { 412 (*pMakeFile) << "# Microsoft Developer Studio Project File - Name=\"" << sProjectName << "\" - Package Owner=<4>\r\n"; 413 (*pMakeFile) << "# Microsoft Developer Studio Generated Build File, Format Version 6.00\r\n"; 414 (*pMakeFile) << "# ** DO NOT EDIT **\r\n"; 415 (*pMakeFile) << "\r\n"; 416 (*pMakeFile) << "# TARGTYPE \"Win32 (x86) Console Application\" 0x0103\r\n"; 417 (*pMakeFile) << "\r\n"; 418 (*pMakeFile) << "CFG=" << sProjectName << " - Win32 Debug\r\n"; 419 (*pMakeFile) << "!MESSAGE This is not a valid makefile. To build this project using NMAKE,\r\n"; 420 (*pMakeFile) << "!MESSAGE use the Export Makefile command and run\r\n"; 421 (*pMakeFile) << "!MESSAGE \r\n"; 422 (*pMakeFile) << "!MESSAGE NMAKE /f \"" << sProjectName << ".mak\".\r\n"; 423 (*pMakeFile) << "!MESSAGE \r\n"; 424 (*pMakeFile) << "!MESSAGE You can specify a configuration when running NMAKE\r\n"; 425 (*pMakeFile) << "!MESSAGE by defining the macro CFG on the command line. For example:\r\n"; 426 (*pMakeFile) << "!MESSAGE \r\n"; 427 (*pMakeFile) << "!MESSAGE NMAKE /f \"" << sProjectName << ".mak\" CFG=\"" << sProjectName << " - Win32 Debug\"\r\n"; 428 (*pMakeFile) << "!MESSAGE \r\n"; 429 (*pMakeFile) << "!MESSAGE Possible choices for configuration are:\r\n"; 430 (*pMakeFile) << "!MESSAGE \r\n"; 431 (*pMakeFile) << "!MESSAGE \"" << sProjectName << " - Win32 Release\" (based on \"Win32 (x86) Console Application\")\r\n"; 432 (*pMakeFile) << "!MESSAGE \"" << sProjectName << " - Win32 Debug\" (based on \"Win32 (x86) Console Application\")\r\n"; 433 (*pMakeFile) << "!MESSAGE \r\n"; 434 (*pMakeFile) << "\r\n"; 435 (*pMakeFile) << "# Begin Project\r\n"; 436 (*pMakeFile) << "# PROP AllowPerConfigDependencies 0\r\n"; 437 (*pMakeFile) << "# PROP Scc_ProjName \"\"\r\n"; 438 (*pMakeFile) << "# PROP Scc_LocalPath \"\"\r\n"; 439 (*pMakeFile) << "CPP=cl.exe\r\n"; 440 (*pMakeFile) << "RSC=rc.exe\r\n"; 441 (*pMakeFile) << "\r\n"; 442 (*pMakeFile) << "!IF \"$(CFG)\" == \"" << sProjectName << " - Win32 Release\"\r\n"; 443 (*pMakeFile) << "\r\n"; 444 (*pMakeFile) << "# PROP BASE Use_MFC 0\r\n"; 445 (*pMakeFile) << "# PROP BASE Use_Debug_Libraries 0\r\n"; 446 (*pMakeFile) << "# PROP BASE Output_Dir \"Release\"\r\n"; 447 (*pMakeFile) << "# PROP BASE Intermediate_Dir \"Release\"\r\n"; 448 (*pMakeFile) << "# PROP BASE Target_Dir \"\"\r\n"; 449 (*pMakeFile) << "# PROP Use_MFC 0\r\n"; 450 (*pMakeFile) << "# PROP Use_Debug_Libraries 0\r\n"; 451 (*pMakeFile) << "# PROP Output_Dir \"Release\"\r\n"; 452 (*pMakeFile) << "# PROP Intermediate_Dir \"Release\"\r\n"; 453 (*pMakeFile) << "# PROP Ignore_Export_Lib 0\r\n"; 454 (*pMakeFile) << "# PROP Target_Dir \"\"\r\n"; 455 (*pMakeFile) << "# ADD BASE CPP /nologo /W3 /GX /O2 /D \"WIN32\" /D \"NDEBUG\" /D \"_CONSOLE\" /D \"_MBCS\" /YX /FD /c\r\n"; 456 (*pMakeFile) << "# ADD CPP /nologo /MD /W3 /GR /GX /O2 /D \"NDEBUG\" /D \"WIN32\" /D \"_CONSOLE\" /D \"_MBCS\" /FD /c\r\n"; 457 (*pMakeFile) << "# SUBTRACT CPP /YX\r\n"; 458 (*pMakeFile) << "# ADD BASE RSC /l 0x40c /d \"NDEBUG\"\r\n"; 459 (*pMakeFile) << "# ADD RSC /l 0x40c /d \"NDEBUG\"\r\n"; 460 (*pMakeFile) << "BSC32=bscmake.exe\r\n"; 461 (*pMakeFile) << "# ADD BASE BSC32 /nologo\r\n"; 462 (*pMakeFile) << "# ADD BSC32 /nologo\r\n"; 463 (*pMakeFile) << "LINK32=link.exe\r\n"; 464 (*pMakeFile) << "# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386\r\n"; 465 (*pMakeFile) << "# ADD LINK32 " << sBinDir << "CodeWorker.lib ws2_32.lib rpcrt4.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386\r\n"; 466 (*pMakeFile) << "\r\n"; 467 (*pMakeFile) << "!ELSEIF \"$(CFG)\" == \"" << sProjectName << " - Win32 Debug\"\r\n"; 468 (*pMakeFile) << "\r\n"; 469 (*pMakeFile) << "# PROP BASE Use_MFC 0\r\n"; 470 (*pMakeFile) << "# PROP BASE Use_Debug_Libraries 1\r\n"; 471 (*pMakeFile) << "# PROP BASE Output_Dir \"Debug\"\r\n"; 472 (*pMakeFile) << "# PROP BASE Intermediate_Dir \"Debug\"\r\n"; 473 (*pMakeFile) << "# PROP BASE Target_Dir \"\"\r\n"; 474 (*pMakeFile) << "# PROP Use_MFC 0\r\n"; 475 (*pMakeFile) << "# PROP Use_Debug_Libraries 1\r\n"; 476 (*pMakeFile) << "# PROP Output_Dir \"Debug\"\r\n"; 477 (*pMakeFile) << "# PROP Intermediate_Dir \"Debug\"\r\n"; 478 (*pMakeFile) << "# PROP Ignore_Export_Lib 0\r\n"; 479 (*pMakeFile) << "# PROP Target_Dir \"\"\r\n"; 480 (*pMakeFile) << "# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D \"WIN32\" /D \"_DEBUG\" /D \"_CONSOLE\" /D \"_MBCS\" /YX /FD /GZ /c\r\n"; 481 (*pMakeFile) << "# ADD CPP /nologo /MDd /W3 /Gm /GR /GX /ZI /Od /D \"_DEBUG\" /D \"WIN32\" /D \"_CONSOLE\" /D \"_MBCS\" /FD /GZ /c\r\n"; 482 (*pMakeFile) << "# SUBTRACT CPP /YX\r\n"; 483 (*pMakeFile) << "# ADD BASE RSC /l 0x40c /d \"_DEBUG\"\r\n"; 484 (*pMakeFile) << "# ADD RSC /l 0x40c /d \"_DEBUG\"\r\n"; 485 (*pMakeFile) << "BSC32=bscmake.exe\r\n"; 486 (*pMakeFile) << "# ADD BASE BSC32 /nologo\r\n"; 487 (*pMakeFile) << "# ADD BSC32 /nologo\r\n"; 488 (*pMakeFile) << "LINK32=link.exe\r\n"; 489 (*pMakeFile) << "# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept\r\n"; 490 (*pMakeFile) << "# ADD LINK32 " << _sCodeWorkerDirectory << "Debug/CodeWorkerD.lib ws2_32.lib rpcrt4.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept\r\n"; 491 (*pMakeFile) << "\r\n"; 492 (*pMakeFile) << "!ENDIF \r\n"; 493 (*pMakeFile) << "\r\n"; 494 (*pMakeFile) << "# Begin Target\r\n"; 495 (*pMakeFile) << "\r\n"; 496 (*pMakeFile) << "# Name \"" << sProjectName << " - Win32 Release\"\r\n"; 497 (*pMakeFile) << "# Name \"" << sProjectName << " - Win32 Debug\"\r\n"; 498 (*pMakeFile) << "# Begin Group \"Source Files\"\r\n"; 499 (*pMakeFile) << "\r\n"; 500 (*pMakeFile) << "# PROP Default_Filter \"cpp;c;cxx;rc;def;r;odl;idl;hpj;bat\"\r\n"; 501 } else { 502 if (!pMakeFile->findString("# Begin Source File")) throw UtlException("bad format encountered into Visual C++ project \"" + sProjectName + ".dsp\": unable to find tag '# Begin Source File'"); 503 pMakeFile->setOutputLocation(pMakeFile->getInputLocation() - 19); 504 } 505 std::list<std::string>::const_iterator i; 506 for (i = _listOfProjectModules.begin(); i != _listOfProjectModules.end(); i++) { 507 (*pMakeFile) << "# Begin Source File\r\n"; 508 (*pMakeFile) << "\r\n"; 509 (*pMakeFile) << "SOURCE=\".\\" << getRelativePath(*i) << ".cpp\"\r\n"; 510 (*pMakeFile) << "# End Source File\r\n"; 511 } 512 { 513 const std::map<std::string, DynPackage*>& allPackages = DynPackage::allPackages(); 514 for (std::map<std::string, DynPackage*>::const_iterator i = allPackages.begin(); i != allPackages.end(); ++i) { 515 (*pMakeFile) << "# Begin Source File\r\n"; 516 (*pMakeFile) << "\r\n"; 517 (*pMakeFile) << "SOURCE=\".\\" << i->first << ".cpp\"\r\n"; 518 (*pMakeFile) << "# End Source File\r\n"; 519 } 520 } 521 (*pMakeFile) << "# End Group\r\n"; 522 (*pMakeFile) << "# Begin Group \"Header Files\"\r\n"; 523 (*pMakeFile) << "\r\n"; 524 (*pMakeFile) << "# PROP Default_Filter \"h;hpp;hxx;hm;inl\"\r\n"; 525 for (i = _listOfProjectModules.begin(); i != _listOfProjectModules.end(); i++) { 526 std::string::size_type iIndex = i->find_last_of("/\\"); 527 std::string sFile; 528 if (iIndex != std::string::npos) sFile = i->substr(iIndex + 1); 529 else sFile = *i; 530 (*pMakeFile) << "# Begin Source File\r\n"; 531 (*pMakeFile) << "\r\n"; 532 (*pMakeFile) << "SOURCE=\".\\" << getRelativePath(*i) << ".h\"\r\n"; 533 (*pMakeFile) << "# End Source File\r\n"; 534 } 535 { 536 const std::map<std::string, DynPackage*>& allPackages = DynPackage::allPackages(); 537 for (std::map<std::string, DynPackage*>::const_iterator i = allPackages.begin(); i != allPackages.end(); ++i) { 538 (*pMakeFile) << "# Begin Source File\r\n"; 539 (*pMakeFile) << "\r\n"; 540 (*pMakeFile) << "SOURCE=\".\\" << i->first << ".h\"\r\n"; 541 (*pMakeFile) << "# End Source File\r\n"; 542 } 543 } 544 (*pMakeFile) << "# Begin Source File\r\n"; 545 (*pMakeFile) << "\r\n"; 546 (*pMakeFile) << "SOURCE=.\\CppParsingTree.h\r\n"; 547 (*pMakeFile) << "# End Source File\r\n"; 548 (*pMakeFile) << "# Begin Source File\r\n"; 549 (*pMakeFile) << "\r\n"; 550 (*pMakeFile) << "SOURCE=.\\UtlException.h\r\n"; 551 (*pMakeFile) << "# End Source File\r\n"; 552 (*pMakeFile) << "# End Group\r\n"; 553 (*pMakeFile) << "# Begin Group \"Resource Files\"\r\n"; 554 (*pMakeFile) << "\r\n"; 555 (*pMakeFile) << "# PROP Default_Filter \"ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe\"\r\n"; 556 (*pMakeFile) << "# End Group\r\n"; 557 (*pMakeFile) << "# End Target\r\n"; 558 (*pMakeFile) << "# End Project\r\n"; 559 std::auto_ptr<ScpStream> pOldMakeFile(new ScpStream(_sCppProjectDirectory + sProjectName + ".dsp", ScpStream::IN | ScpStream::OUT)); 560 int iPosition; 561 if (!pMakeFile->equals(*pOldMakeFile, iPosition)) pMakeFile->saveIntoFile(_sCppProjectDirectory + sProjectName + ".dsp", true); 562 } 563 generateMakefile()564 void CppCompilerEnvironment::generateMakefile() { 565 std::string sBinDir = _sCodeWorkerDirectory; 566 if (CGRuntime::existFile(sBinDir + "bin/libCodeWorker.a")) sBinDir += "bin/"; 567 else if (CGRuntime::existFile(sBinDir + "../bin/libCodeWorker.a")) sBinDir += "../bin/"; 568 else if (CGRuntime::existFile(sBinDir + "lib/libCodeWorker.a")) sBinDir += "lib/"; 569 else if (CGRuntime::existFile(sBinDir + "../lib/libCodeWorker.a")) sBinDir += "../lib/"; 570 std::string sProjectName = getRadical(_listOfProjectModules.front()); 571 std::string::size_type iIndex = sProjectName.find_last_of('_'); 572 if ((iIndex != std::string::npos) && (iIndex != 0)) sProjectName = sProjectName.substr(0, iIndex); 573 std::auto_ptr<ScpStream> pMakeFile(new ScpStream(_sCppProjectDirectory + "Makefile", ScpStream::IN | ScpStream::OUT)); 574 std::auto_ptr<ScpStream> pOldMakeFile(new ScpStream(_sCppProjectDirectory + "Makefile", ScpStream::IN | ScpStream::OUT)); 575 (*pMakeFile) << "INCDIRS = -I.\n"; 576 (*pMakeFile) << "CXXFLAGS = -O2 -g $(INCDIRS)\n"; 577 (*pMakeFile) << "LFLAGS = -g -lm -ldl -L" << sBinDir << " -lcodeworker\n"; 578 (*pMakeFile) << "CC = g++\n"; 579 (*pMakeFile) << "\n"; 580 (*pMakeFile) << "OBJECTS = "; 581 std::list<std::string>::const_iterator i; 582 for (i = _listOfProjectModules.begin(); i != _listOfProjectModules.end(); i++) { 583 std::string sRadical = getRelativePath(*i); 584 if (pMakeFile->getColCount() + sRadical.size() > 70) { 585 (*pMakeFile) << "\\\n\t\t "; 586 } else { 587 (*pMakeFile) << " "; 588 } 589 (*pMakeFile) << sRadical << ".o"; 590 } 591 { 592 const std::map<std::string, DynPackage*>& allPackages = DynPackage::allPackages(); 593 for (std::map<std::string, DynPackage*>::const_iterator i = allPackages.begin(); i != allPackages.end(); ++i) { 594 if (pMakeFile->getColCount() + i->first.size() > 70) { 595 (*pMakeFile) << "\\\n\t\t "; 596 } else { 597 (*pMakeFile) << " "; 598 } 599 (*pMakeFile) << i->first << ".o"; 600 } 601 } 602 (*pMakeFile) << "\n\n"; 603 (*pMakeFile) << "all: build\n"; 604 (*pMakeFile) << "build: $(OBJECTS)\n"; 605 (*pMakeFile) << "\t$(CC) -o " << sProjectName << " $(OBJECTS) $(LFLAGS)\n"; 606 (*pMakeFile) << "clean:\n"; 607 (*pMakeFile) << "\t-rm -f *.o " << sProjectName << " core\n"; 608 int iPosition; 609 if (!pMakeFile->equals(*pOldMakeFile, iPosition)) pMakeFile->saveIntoFile(_sCppProjectDirectory + "Makefile", true); 610 } 611 optimizeSources()612 void CppCompilerEnvironment::optimizeSources() { 613 std::string sOptimizerScript = DtaProject::getTargetScriptFilename(DtaProject::getInstance().getTargetLanguage(), "cppOptimizer.cwp"); 614 if (sOptimizerScript.empty()) return; 615 CGCompiledTranslationScript script(sOptimizerScript); 616 DtaScriptVariable parseTree(NULL, "parseTree"); 617 for (std::list<std::string>::const_iterator i = _listOfProjectModules.begin(); i != _listOfProjectModules.end(); i++) { 618 std::string sRadical = _sCppProjectDirectory + *i; 619 std::string sInputFile = sRadical + ".cpp"; 620 std::string sOutputFile = sRadical + ".out"; 621 DtaScriptVariable* pLast = parseTree.pushItem(sRadical); 622 script.translate(pLast, sInputFile, sOutputFile); 623 if (pLast->getNode("implicit_copy") != NULL) parseTree.insertNode("implicit_copy")->setValue(true); 624 } 625 if (parseTree.getNode("implicit_copy") == NULL) parseTree.insertNode("explicit_copy")->setValue(true); 626 const std::list<DtaScriptVariable*>* pList = parseTree.getArray(); 627 if (pList != NULL) { 628 for (std::list<DtaScriptVariable*>::const_iterator i = pList->begin(); i != pList->end(); ++i) { 629 std::string sRadical = (*i)->getValue(); 630 std::string sInputFile = sRadical + ".out"; 631 std::string sOutputFile = sRadical + ".out"; 632 DtaScriptVariable* pVariables = (*i)->getNode("variables"); 633 if ((pVariables != NULL) && (parseTree.getNode("explicit_copy") != NULL)) { 634 const std::list<DtaScriptVariable*>* pVariablesList = pVariables->getArray(); 635 if (pVariablesList != NULL) { 636 for (std::list<DtaScriptVariable*>::const_iterator j = pVariablesList->begin(); j != pVariablesList->end(); ++j) { 637 if (CGRuntime::startString((*j)->getName(), "_compilerClauseImplicitCopy_")) { 638 (*j)->insertNode("used")->setValue(false); 639 (*j)->insertNode("active")->setValue(true); 640 } 641 } 642 } 643 } 644 if (parseTree.getNode("explicit_copy") != NULL) (*i)->insertNode("explicit_copy")->setValue(true); 645 if ((*i)->getNode("explicit_copy") != NULL) { 646 script.translate(*i, sInputFile, sOutputFile); 647 } 648 } 649 } 650 for (std::list<std::string>::const_iterator i = _listOfProjectModules.begin(); i != _listOfProjectModules.end(); i++) { 651 std::string sRadical = _sCppProjectDirectory + *i; 652 std::string sInputFile = sRadical + ".out"; 653 std::string sOutputFile = sRadical + ".cpp"; 654 DtaScriptVariable* pLast = parseTree.pushItem(sRadical); 655 pLast->insertNode("rules")->setValue(true); 656 script.translate(pLast, sInputFile, sOutputFile); 657 } 658 } 659 translateToTargetLanguage(const std::string & sTargetLanguage)660 void CppCompilerEnvironment::translateToTargetLanguage(const std::string& sTargetLanguage) { 661 std::string sParserScript = DtaProject::getTargetScriptFilename(sTargetLanguage, "CWcpp-parser.cwp"); 662 if (sParserScript.empty()) throw UtlException("C++-to-" + sTargetLanguage + " translation error: unable to find the BNF-parse script \"CWcpp-parser.cwp\""); 663 std::string sTranslatorScript = DtaProject::getTargetScriptFilename(sTargetLanguage, "CWcpp2" + sTargetLanguage + ".cws"); 664 if (sTranslatorScript.empty()) { 665 if (sTargetLanguage == "cpp") return; 666 throw UtlException("C++-to-" + sTargetLanguage + " translation error: unable to find the translation script \"CWcpp2" + sTargetLanguage + ".cws\""); 667 } 668 CGCompiledBNFScript parser(sParserScript); 669 CGCompiledCommonScript translator; 670 translator.buildFromFile(sTranslatorScript); 671 DtaScriptVariable parseTree(NULL, "parseTree"); 672 for (std::list<std::string>::const_iterator i = _listOfProjectModules.begin(); i != _listOfProjectModules.end(); i++) { 673 std::string sCppFile = _sCppProjectDirectory + *i + ".cpp"; 674 parser.parse(&parseTree, sCppFile); 675 } 676 translator.execute(&parseTree); 677 } 678 getHeader() const679 ScpStream& CppCompilerEnvironment::getHeader() const { 680 DtaPatternScript* pScript = getCurrentScriptSession()._header; 681 return *(pScript->getOutputStream()); 682 } 683 getMainHeader() const684 ScpStream& CppCompilerEnvironment::getMainHeader() const { 685 DtaPatternScript* pScript = _listOfScriptSessions.back()._header; 686 return *(pScript->getOutputStream()); 687 } 688 getBody() const689 ScpStream& CppCompilerEnvironment::getBody() const { 690 DtaPatternScript* pScript = getCurrentScriptSession()._body; 691 return *(pScript->getOutputStream()); 692 } 693 filename2Module(const std::string & sFilename)694 std::string CppCompilerEnvironment::filename2Module(const std::string& sFilename) { 695 std::string sModule; 696 std::string::size_type iIndex = sFilename.find('.'); 697 if (iIndex != std::string::npos) { 698 sModule = sFilename.substr(0, iIndex) + '_' + filename2Module(sFilename.substr(iIndex + 1)); 699 } else sModule = sFilename; 700 return sModule; 701 } 702 pushFilename(const std::string & sFilename)703 bool CppCompilerEnvironment::pushFilename(const std::string& sFilename) { 704 std::string sModule = filename2Module(sFilename); 705 for (std::list<std::string>::const_iterator i = _listOfProjectModules.begin(); i != _listOfProjectModules.end(); i++) { 706 if ((*i) == sModule) return false; 707 } 708 CppScriptSession session(sFilename, _sCppProjectDirectory + getRadical(sModule)); 709 _listOfScriptSessions.push_front(session); 710 _listOfProjectModules.push_back(sModule); 711 return true; 712 } 713 getRadical() const714 std::string CppCompilerEnvironment::getRadical() const { 715 return getRadical(getCurrentScriptSession()._sCppRadical); 716 } 717 getMainRadical() const718 std::string CppCompilerEnvironment::getMainRadical() const { 719 return getRadical(_listOfScriptSessions.back()._sCppRadical); 720 } 721 getRadical(const std::string & sFile)722 std::string CppCompilerEnvironment::getRadical(const std::string& sFile) { 723 std::string sRadical = sFile; 724 std::string::size_type iIndex = sRadical.find_last_of("/\\"); 725 if (iIndex != std::string::npos) sRadical = sRadical.substr(iIndex + 1); 726 iIndex = sRadical.find('.'); 727 if (iIndex != std::string::npos) sRadical = sRadical.substr(0, iIndex); 728 return sRadical; 729 } 730 getRelativePath(const std::string & sFile)731 std::string CppCompilerEnvironment::getRelativePath(const std::string& sFile) { 732 std::string sRadical; 733 std::string::size_type iIndex = sFile.find_last_of("/\\"); 734 if (iIndex != std::string::npos) sRadical = sFile.substr(iIndex + 1); 735 else sRadical = sFile; 736 return sRadical; 737 } 738 convertTemplateKey(const std::string & sKey)739 std::string CppCompilerEnvironment::convertTemplateKey(const std::string& sKey) { 740 std::string sText; 741 for (std::string::size_type i = 0; i < sKey.size(); i++) { 742 char a = sKey[i]; 743 if (((a >= 'A') && (a <= 'Z')) || ((a >= 'a') && (a <= 'z')) || ((a >= '0') && (a <= '9'))) sText += a; 744 else switch(a) { 745 case '+': sText += "_compilerPlus_";break; 746 case '-': sText += "_compilerMinus_";break; 747 case '.': sText += "_compilerDot_";break; 748 case ',': sText += "_compilerComma_";break; 749 default: sText += '_'; 750 } 751 } 752 return sText; 753 } 754 convertToCppVariable(const std::string & sVariable)755 std::string CppCompilerEnvironment::convertToCppVariable(const std::string& sVariable) { 756 if ((sVariable == "namespace") || (sVariable == "class")) return "_compilerCppVariable_" + sVariable; 757 return sVariable; 758 } 759 getIncludeParentScript() const760 std::string CppCompilerEnvironment::getIncludeParentScript() const { 761 std::string sRadical; 762 if (_listOfScriptSessions.front()._sFilename != _listOfScriptSessions.back()._sFilename) { 763 std::list<CppScriptSession>::const_iterator cursor = _listOfScriptSessions.begin(); 764 ++cursor; 765 sRadical = filename2Module(cursor->_sFilename); 766 } 767 return sRadical; 768 } 769 incrementIndentation()770 void CppCompilerEnvironment::incrementIndentation() { 771 _listOfScriptSessions.front().incrementIndentation(); 772 } 773 pushVariableScope()774 void CppCompilerEnvironment::pushVariableScope() { 775 _listOfScriptSessions.front().pushVariableScope(); 776 } 777 newInlineScriptFilename()778 std::string CppCompilerEnvironment::newInlineScriptFilename() { 779 _iInlineScriptCounter++; 780 char tcFile[80]; 781 sprintf(tcFile, "InlineScript2File_%d", _iInlineScriptCounter); 782 return tcFile; 783 } 784 newFunction(const GrfFunction * pFunction)785 void CppCompilerEnvironment::newFunction(const GrfFunction* pFunction) { 786 _listOfScriptSessions.front()._setOfProjectFunctions.insert(pFunction->getFunctionName()); 787 _pCurrentFunction = pFunction; 788 } 789 newClause(const BNFClause * pClause)790 void CppCompilerEnvironment::newClause(const BNFClause* pClause) { 791 _listOfScriptSessions.front()._setOfProjectFunctions.insert(pClause->getName()); 792 _pCurrentClause = pClause; 793 } 794 getFunctionModule(const std::string & sFunction) const795 std::string CppCompilerEnvironment::getFunctionModule(const std::string& sFunction) const { 796 for (std::list<CppScriptSession>::const_iterator i = _listOfScriptSessions.begin(); i != _listOfScriptSessions.end(); i++) { 797 if (i->_setOfProjectFunctions.find(sFunction) != i->_setOfProjectFunctions.end()) return i->_sCppRadical; 798 } 799 return _listOfScriptSessions.front()._sCppRadical; 800 } 801 getClauseModule(const std::string & sClause) const802 std::string CppCompilerEnvironment::getClauseModule(const std::string& sClause) const { 803 for (std::list<CppScriptSession>::const_iterator i = _listOfScriptSessions.begin(); i != _listOfScriptSessions.end(); i++) { 804 if (i->_setOfProjectClauses.find(sClause) != i->_setOfProjectClauses.end()) return i->_sCppRadical; 805 } 806 return _listOfScriptSessions.front()._sCppRadical; 807 } 808 popVariableScope()809 void CppCompilerEnvironment::popVariableScope() { 810 _listOfScriptSessions.front().popVariableScope(); 811 } 812 addVariable(const std::string & sVariable)813 bool CppCompilerEnvironment::addVariable(const std::string& sVariable) { 814 return _listOfScriptSessions.front()._stackOfScopes.front()->addVariable(sVariable); 815 } 816 existVariable(const std::string & sVariable) const817 bool CppCompilerEnvironment::existVariable(const std::string& sVariable) const { 818 return _listOfScriptSessions.front()._stackOfScopes.front()->existVariable(sVariable) | (_globalVariables.find(sVariable) != _globalVariables.end()); 819 } 820 addGlobalVariable(const std::string & sVariable)821 void CppCompilerEnvironment::addGlobalVariable(const std::string& sVariable) { 822 _globalVariables.insert(sVariable); 823 } 824 setClauseReturnValue(const std::string & sClauseName)825 void CppCompilerEnvironment::setClauseReturnValue(const std::string& sClauseName) { 826 _listOfScriptSessions.front()._stackOfScopes.front()->setClauseReturnValue(sClauseName); 827 } 828 isClauseReturnValue(const std::string & sVariableName) const829 bool CppCompilerEnvironment::isClauseReturnValue(const std::string& sVariableName) const { 830 return _listOfScriptSessions.front()._stackOfScopes.front()->isClauseReturnValue(sVariableName); 831 } 832 hasEvaluatedExpressionInScope(bool bEvaluated)833 void CppCompilerEnvironment::hasEvaluatedExpressionInScope(bool bEvaluated) { 834 _listOfScriptSessions.front()._stackOfScopes.front()->hasEvaluatedExpressionInScope(bEvaluated); 835 } 836 hasEvaluatedExpressionInScope() const837 bool CppCompilerEnvironment::hasEvaluatedExpressionInScope() const { 838 return _listOfScriptSessions.front()._stackOfScopes.front()->hasEvaluatedExpressionInScope(); 839 } 840 newSwitch()841 int CppCompilerEnvironment::newSwitch() { 842 _iSwitchNumber++; 843 return _iSwitchNumber; 844 } 845 newCursor()846 int CppCompilerEnvironment::newCursor() { 847 _iCursorNumber++; 848 return _iCursorNumber; 849 } 850 decrementIndentation()851 void CppCompilerEnvironment::decrementIndentation() { 852 _listOfScriptSessions.front().decrementIndentation(); 853 } 854 pushForeach(GrfForeach * pForeach)855 void CppCompilerEnvironment::pushForeach(GrfForeach* pForeach) { 856 _listOfScriptSessions.front().pushForeach(pForeach); 857 } 858 getLastForeach() const859 GrfForeach* CppCompilerEnvironment::getLastForeach() const { 860 return _listOfScriptSessions.front().getLastForeach(); 861 } 862 popForeach()863 void CppCompilerEnvironment::popForeach() { 864 _listOfScriptSessions.front().popForeach(); 865 } 866 catchFilename(UtlException & exception)867 void CppCompilerEnvironment::catchFilename(UtlException& exception) { 868 _listOfScriptSessions.front().catchFilename(); 869 _bErrorEncountered = true; 870 throw UtlException(exception.getTraceStack(), exception.getMessage()); 871 } 872 popFilename()873 void CppCompilerEnvironment::popFilename() { 874 _listOfScriptSessions.pop_front(); 875 } 876 } 877 //##markup##"build C++ headers" 878