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 #pragma warning (disable : 4503) 25 #endif 26 27 #ifndef WIN32 28 # include <cstdio> // for Debian/gcc 2.95.4 29 #endif 30 31 #include <string.h> 32 33 #include "ScpStream.h" 34 35 #include "UtlException.h" 36 #include "UtlTrace.h" 37 #include "UtlString.h" 38 39 #include "CGRuntime.h" 40 #include "DtaArrayIterator.h" 41 #include "ExprScriptVariable.h" 42 #include "Workspace.h" 43 #include "DtaProject.h" 44 #include "ExternalValueNode.h" 45 #include "DynPackage.h" 46 #include "CGExternalHandling.h" // for CGQuietOutput 47 #include "DtaScriptVariable.h" 48 49 namespace CodeWorker { ~DtaNodeListener()50 DtaNodeListener::~DtaNodeListener() {} 51 52 class DtaNodeListeners { 53 private: 54 DtaScriptVariable* _pNode; 55 std::list<DtaNodeListener*> _listeners; 56 57 public: DtaNodeListeners(DtaScriptVariable * pNode)58 inline DtaNodeListeners(DtaScriptVariable* pNode) : _pNode(pNode) {} ~DtaNodeListeners()59 ~DtaNodeListeners() { 60 for (std::list<DtaNodeListener*>::iterator i = _listeners.begin(); i != _listeners.end(); ++i) { 61 (*i)->onDelete(); 62 delete *i; 63 } 64 } 65 addListener(DtaNodeListener * pListener)66 void addListener(DtaNodeListener* pListener) { 67 pListener->_pNode = _pNode; 68 _listeners.push_back(pListener); 69 } 70 removeListener(DtaNodeListener * pListener)71 bool removeListener(DtaNodeListener* pListener) { 72 if (pListener->_pNode != _pNode) return false; 73 _listeners.remove(pListener); 74 delete pListener; 75 return true; 76 } 77 onSetValue(const char * tcValue)78 void onSetValue(const char* tcValue) { 79 for (std::list<DtaNodeListener*>::iterator i = _listeners.begin(); i != _listeners.end(); ++i) { 80 (*i)->onSetValue(tcValue); 81 } 82 } 83 onConcatValue(const char * tcValue)84 void onConcatValue(const char* tcValue) { 85 for (std::list<DtaNodeListener*>::iterator i = _listeners.begin(); i != _listeners.end(); ++i) { 86 (*i)->onConcatValue(tcValue); 87 } 88 } 89 onSetReference(DtaScriptVariable * pReference)90 void onSetReference(DtaScriptVariable* pReference) { 91 for (std::list<DtaNodeListener*>::iterator i = _listeners.begin(); i != _listeners.end(); ++i) { 92 (*i)->onSetReference(pReference); 93 } 94 } 95 onSetExternal(ExternalValueNode * pExternalValue)96 void onSetExternal(ExternalValueNode* pExternalValue) { 97 for (std::list<DtaNodeListener*>::iterator i = _listeners.begin(); i != _listeners.end(); ++i) { 98 (*i)->onSetExternal(pExternalValue); 99 } 100 } 101 onSetIterator(DtaArrayIterator ** pIteratorData)102 void onSetIterator(DtaArrayIterator** pIteratorData) { 103 for (std::list<DtaNodeListener*>::iterator i = _listeners.begin(); i != _listeners.end(); ++i) { 104 (*i)->onSetIterator(pIteratorData); 105 } 106 } 107 onAddAttribute(DtaScriptVariable * pAttribute)108 void onAddAttribute(DtaScriptVariable* pAttribute) { 109 for (std::list<DtaNodeListener*>::iterator i = _listeners.begin(); i != _listeners.end(); ++i) { 110 (*i)->onAddAttribute(pAttribute); 111 } 112 } 113 onRemoveAttribute(DtaScriptVariable * pAttribute)114 void onRemoveAttribute(DtaScriptVariable* pAttribute) { 115 for (std::list<DtaNodeListener*>::iterator i = _listeners.begin(); i != _listeners.end(); ++i) { 116 (*i)->onRemoveAttribute(pAttribute); 117 } 118 } 119 onArrayHasChanged()120 void onArrayHasChanged() { 121 for (std::list<DtaNodeListener*>::iterator i = _listeners.begin(); i != _listeners.end(); ++i) { 122 (*i)->onArrayHasChanged(); 123 } 124 } 125 onClearContent()126 void onClearContent() { 127 for (std::list<DtaNodeListener*>::iterator i = _listeners.begin(); i != _listeners.end(); ++i) { 128 (*i)->onClearContent(); 129 } 130 } 131 }; 132 pushBack(DtaScriptVariable * pVariable)133 void DtaScriptVariableList::pushBack(DtaScriptVariable* pVariable) { 134 register DtaScriptVariableList* pList = this; 135 while (pList->getNext() != NULL) pList = pList->getNext(); 136 pList->setNext(new DtaScriptVariableList(pVariable)); 137 } 138 139 ~NodeArrayType()140 DtaScriptVariable::NodeArrayType::~NodeArrayType() { 141 for (std::list<DtaScriptVariable*>::iterator i = items.begin(); i != items.end(); i++) { 142 delete (*i); 143 } 144 delete cache; 145 } 146 NodeArrayType(DtaScriptVariable * pElt)147 DtaScriptVariable::NodeArrayType::NodeArrayType(DtaScriptVariable* pElt) : cache(NULL) { 148 items.push_back(pElt); 149 } 150 151 ~DtaScriptVariable()152 DtaScriptVariable::~DtaScriptVariable() { 153 delete _pListeners; 154 _pListeners = NULL; 155 clearContent(); 156 if (_pReferencedByVariables != NULL) { 157 while (!_pReferencedByVariables->empty()) { 158 DtaScriptVariable* pReferencedBy = *(_pReferencedByVariables->begin()); 159 pReferencedBy->removeReference(); 160 /* 161 std::string sErrorMessage = "warning: variable '"; 162 sErrorMessage += pReferencedBy->getCompleteName(); 163 sErrorMessage += "' refers to '"; 164 sErrorMessage += getCompleteName(); 165 sErrorMessage += "' that is being removed from the stack" + CGRuntime::endl(); 166 sErrorMessage += UtlTrace::getTraceStack(); 167 if (DtaProject::getInstance().addWarning(sErrorMessage) == 1) CGRuntime::traceLine(sErrorMessage); 168 */ 169 } 170 delete _pReferencedByVariables; 171 _pReferencedByVariables = NULL; 172 } 173 free((char*) _tcName); 174 } 175 addListener(DtaNodeListener * pListener)176 void DtaScriptVariable::addListener(DtaNodeListener* pListener) { 177 if (_pListeners == NULL) _pListeners = new DtaNodeListeners(this); 178 _pListeners->addListener(pListener); 179 } 180 removeListener(DtaNodeListener * pListener)181 bool DtaScriptVariable::removeListener(DtaNodeListener* pListener) { 182 if (_pListeners == NULL) return false; 183 return _pListeners->removeListener(pListener); 184 } 185 getReferencedVariable() const186 DtaScriptVariable* DtaScriptVariable::getReferencedVariable() const { 187 if (_eValueNode == REFERENCE_VALUE_NODE) return _value.var; 188 if (_eValueNode == INDEX_VALUE_NODE) { 189 DtaScriptVariable* pVariable = (*_value.ind.var)->itemNoRef(); 190 return pVariable; 191 } 192 return NULL; 193 } 194 getRoot() const195 DtaScriptVariable* DtaScriptVariable::getRoot() const { 196 DtaScriptVariable* pVariable = const_cast<DtaScriptVariable*>(this); 197 register DtaScriptVariable* pParent = _pParent; 198 while ((pParent != NULL) && (strncmp(pParent->_tcName, "##stack##", 9) != 0)) { 199 pVariable = pParent; 200 pParent = pVariable->getParent(); 201 } 202 return pVariable; 203 } 204 changeName(const char * tcName)205 void DtaScriptVariable::changeName(const char* tcName) { 206 if ((_pParent != NULL) && (_pParent->_pArray != NULL)) { 207 if (_pParent->getNode(_tcName) != this) { 208 // this node belongs to the array of its parent: 209 // purge the cache: the key will change! 210 delete _pParent->_pArray->cache; 211 _pParent->_pArray->cache = NULL; 212 } 213 } 214 delete _tcName; 215 #ifdef WIN32 216 _tcName = ::_strdup(tcName); 217 #else 218 _tcName = ::strdup(tcName); 219 #endif 220 } 221 isLocal() const222 bool DtaScriptVariable::isLocal() const { 223 const DtaScriptVariable* pVariable = this; 224 while (pVariable->getReferencedVariable() != NULL) pVariable = pVariable->getReferencedVariable(); 225 if (pVariable->_pParent == NULL || pVariable->_pParent->getName() == NULL) return false; 226 return (strncmp(pVariable->_pParent->getName(), "##", 2) == 0); 227 } 228 detachAttribute(const char * tcName)229 DtaScriptVariable* DtaScriptVariable::detachAttribute(const char* tcName) { 230 DtaScriptVariable* pNode = NULL; 231 DtaScriptVariableList* pAttributes = _pAttributes; 232 DtaScriptVariableList* pLastAttribute = NULL; 233 while (pAttributes != NULL) { 234 if (strcmp(pAttributes->getNode()->_tcName, tcName) == 0) { 235 pNode = pAttributes->getNode(); 236 if (pLastAttribute == NULL) _pAttributes = pAttributes->getNext(); 237 else pLastAttribute->setNext(pAttributes->getNext()); 238 pAttributes->setNext(NULL); 239 delete pAttributes; 240 break; 241 } 242 pLastAttribute = pAttributes; 243 pAttributes = pAttributes->getNext(); 244 } 245 return pNode; 246 } 247 getArray() const248 const std::list<DtaScriptVariable*>* DtaScriptVariable::getArray() const { 249 const DtaScriptVariable* pVariable = this; 250 while (pVariable->getReferencedVariable() != NULL) pVariable = pVariable->getReferencedVariable(); 251 return &(pVariable->_pArray->items); 252 } 253 getArraySize() const254 int DtaScriptVariable::getArraySize() const { 255 const DtaScriptVariable* pVariable = this; 256 while (pVariable->getReferencedVariable() != NULL) pVariable = pVariable->getReferencedVariable(); 257 if (pVariable->_pArray == NULL) return 0; 258 return pVariable->_pArray->items.size(); 259 } 260 getSortedArray() const261 const std::map<std::string, DtaScriptVariable*>* DtaScriptVariable::getSortedArray() const { 262 const DtaScriptVariable* pVariable = this; 263 while (pVariable->getReferencedVariable() != NULL) pVariable = pVariable->getReferencedVariable(); 264 NodeArrayType* pANT = pVariable->_pArray; 265 if (pANT == NULL) return NULL; 266 if (pANT->cache == NULL) { 267 pANT->cache = new std::map<std::string, DtaScriptVariable*>(); 268 for (std::list<DtaScriptVariable*>::const_iterator i = pANT->items.begin(); i != pANT->items.end(); i++) { 269 (*(pANT->cache))[(*i)->_tcName] = (*i); 270 } 271 } 272 return pVariable->_pArray->cache; 273 } 274 getSortedNoCaseArray() const275 std::auto_ptr<std::vector<DtaScriptVariable*> > DtaScriptVariable::getSortedNoCaseArray() const { 276 const DtaScriptVariable* pVariable = this; 277 while (pVariable->getReferencedVariable() != NULL) pVariable = pVariable->getReferencedVariable(); 278 std::vector<DtaScriptVariable*>* pListOfNodes = NULL; 279 NodeArrayType* pANT = pVariable->_pArray; 280 if (pANT != NULL) { 281 std::map<std::string, std::map<std::string, DtaScriptVariable*> > mapOfNodes; 282 for (std::list<DtaScriptVariable*>::const_iterator i = pANT->items.begin(); i != pANT->items.end(); i++) { 283 std::string sKey = toLowercase((*i)->_tcName); 284 mapOfNodes[sKey][(*i)->_tcName] = *i; 285 } 286 pListOfNodes = new std::vector<DtaScriptVariable*>(pANT->items.size()); 287 int iPosition = 0; 288 for (std::map<std::string, std::map<std::string, DtaScriptVariable*> >::const_iterator j = mapOfNodes.begin(); j != mapOfNodes.end(); ++j) { 289 for (std::map<std::string, DtaScriptVariable*>::const_iterator k = j->second.begin(); k != j->second.end(); ++k) { 290 (*pListOfNodes)[iPosition++] = k->second; 291 } 292 } 293 } 294 return std::auto_ptr<std::vector<DtaScriptVariable*> >(pListOfNodes); 295 } 296 getSortedArrayOnValue() const297 std::auto_ptr<std::vector<DtaScriptVariable*> > DtaScriptVariable::getSortedArrayOnValue() const { 298 const DtaScriptVariable* pVariable = this; 299 while (pVariable->getReferencedVariable() != NULL) pVariable = pVariable->getReferencedVariable(); 300 std::vector<DtaScriptVariable*>* pListOfNodes = NULL; 301 NodeArrayType* pANT = pVariable->_pArray; 302 if (pANT != NULL) { 303 std::map<std::string, std::map<std::string, DtaScriptVariable*> > mapOfNodes; 304 for (std::list<DtaScriptVariable*>::const_iterator i = pANT->items.begin(); i != pANT->items.end(); i++) { 305 std::string sKey = (*i)->getValue(); 306 mapOfNodes[sKey][(*i)->_tcName] = *i; 307 } 308 pListOfNodes = new std::vector<DtaScriptVariable*>(pANT->items.size()); 309 int iPosition = 0; 310 for (std::map<std::string, std::map<std::string, DtaScriptVariable*> >::const_iterator j = mapOfNodes.begin(); j != mapOfNodes.end(); ++j) { 311 for (std::map<std::string, DtaScriptVariable*>::const_iterator k = j->second.begin(); k != j->second.end(); ++k) { 312 (*pListOfNodes)[iPosition++] = k->second; 313 } 314 } 315 } 316 return std::auto_ptr<std::vector<DtaScriptVariable*> >(pListOfNodes); 317 } 318 getSortedNoCaseArrayOnValue() const319 std::auto_ptr<std::vector<DtaScriptVariable*> > DtaScriptVariable::getSortedNoCaseArrayOnValue() const { 320 const DtaScriptVariable* pVariable = this; 321 while (pVariable->getReferencedVariable() != NULL) pVariable = pVariable->getReferencedVariable(); 322 std::vector<DtaScriptVariable*>* pListOfNodes = NULL; 323 NodeArrayType* pANT = pVariable->_pArray; 324 if (pANT != NULL) { 325 std::map<std::string, std::map<std::string, DtaScriptVariable*> > mapOfNodes; 326 for (std::list<DtaScriptVariable*>::const_iterator i = pANT->items.begin(); i != pANT->items.end(); i++) { 327 std::string sKey = toLowercase((*i)->getValue()); 328 mapOfNodes[sKey][(*i)->_tcName] = *i; 329 } 330 pListOfNodes = new std::vector<DtaScriptVariable*>(pANT->items.size()); 331 int iPosition = 0; 332 for (std::map<std::string, std::map<std::string, DtaScriptVariable*> >::const_iterator j = mapOfNodes.begin(); j != mapOfNodes.end(); ++j) { 333 for (std::map<std::string, DtaScriptVariable*>::const_iterator k = j->second.begin(); k != j->second.end(); ++k) { 334 (*pListOfNodes)[iPosition++] = k->second; 335 } 336 } 337 } 338 return std::auto_ptr<std::vector<DtaScriptVariable*> >(pListOfNodes); 339 } 340 getArrayElement(const std::string & sPosition) const341 DtaScriptVariable* DtaScriptVariable::getArrayElement(const std::string& sPosition) const { 342 if (getReferencedVariable() != NULL) return getReferencedVariable()->getArrayElement(sPosition); 343 if (_pArray == NULL) return NULL; 344 if (_pArray->cache != NULL) { 345 std::map<std::string, DtaScriptVariable*>::const_iterator i = _pArray->cache->find(sPosition); 346 if (i != _pArray->cache->end()) return i->second; 347 } else if (_pArray->items.size() >= 12) { 348 DtaScriptVariable* pVariable = NULL; 349 _pArray->cache = new std::map<std::string, DtaScriptVariable*>(); 350 for (std::list<DtaScriptVariable*>::const_iterator i = _pArray->items.begin(); i != _pArray->items.end(); i++) { 351 if (strcmp((*i)->_tcName, sPosition.c_str()) == 0) pVariable = (*i); 352 (*_pArray->cache)[(*i)->_tcName] = (*i); 353 } 354 return pVariable; 355 } else { 356 for (std::list<DtaScriptVariable*>::const_iterator i = _pArray->items.begin(); i != _pArray->items.end(); i++) { 357 if (strcmp((*i)->_tcName, sPosition.c_str()) == 0) return (*i); 358 } 359 } 360 return NULL; 361 } 362 getArrayElement(int iPosition) const363 DtaScriptVariable* DtaScriptVariable::getArrayElement(int iPosition) const { 364 if (getReferencedVariable() != NULL) return getReferencedVariable()->getArrayElement(iPosition); 365 if (_pArray == NULL) return NULL; 366 if (iPosition >= 0) { 367 for (std::list<DtaScriptVariable*>::const_iterator i = _pArray->items.begin(); i != _pArray->items.end(); i++) { 368 if (iPosition == 0) return (*i); 369 iPosition--; 370 } 371 } 372 return NULL; 373 } 374 invertArray()375 void DtaScriptVariable::invertArray() { 376 if (getReferencedVariable() != NULL) { 377 getReferencedVariable()->invertArray(); 378 } else if (_pArray != NULL) { 379 std::list<DtaScriptVariable*> array; 380 for (std::list<DtaScriptVariable*>::iterator i = _pArray->items.begin(); i != _pArray->items.end(); i++) { 381 array.push_front(*i); 382 } 383 _pArray->items = array; 384 if (_pListeners != NULL) _pListeners->onArrayHasChanged(); 385 } 386 } 387 insertElementAt(const std::string & sProposedKey,int iPosition)388 DtaScriptVariable* DtaScriptVariable::insertElementAt(const std::string& sProposedKey, int iPosition) { 389 if (getReferencedVariable() != NULL) { 390 return getReferencedVariable()->insertElementAt(sProposedKey, iPosition); 391 } 392 DtaScriptVariable* pVariable = NULL; 393 std::string sKey; 394 if (sProposedKey.empty()) { 395 char tcNumber[32]; 396 int iKey = ((_pArray != NULL) ? _pArray->items.size() : 0); 397 do { 398 sprintf(tcNumber, "%d", iKey); 399 sKey = tcNumber; 400 ++iKey; 401 } while (getArrayElement(sKey) != NULL); 402 } else { 403 sKey = sProposedKey; 404 if (getArrayElement(sKey) != NULL) return NULL; 405 } 406 if (_pArray != NULL) { 407 if (iPosition >= 0) { 408 for (std::list<DtaScriptVariable*>::iterator i = _pArray->items.begin(); i != _pArray->items.end(); i++) { 409 if (iPosition == 0) { 410 pVariable = new DtaScriptVariable(this, sKey); 411 _pArray->items.insert(i, pVariable); 412 if (_pArray->cache != NULL) (*_pArray->cache)[sKey] = pVariable; 413 if (_pListeners != NULL) _pListeners->onArrayHasChanged(); 414 return pVariable; 415 } 416 iPosition--; 417 } 418 if (iPosition == 0) { 419 pVariable = addInternalElement(sKey); 420 } 421 } 422 } else if (iPosition == 0) { 423 pVariable = addInternalElement(sKey); 424 } 425 return pVariable; 426 } 427 removeArrayElement()428 void DtaScriptVariable::removeArrayElement() { 429 if (getReferencedVariable() != NULL) { 430 getReferencedVariable()->removeArrayElement(); 431 } else { 432 delete _pArray; 433 _pArray = NULL; 434 if (_pListeners != NULL) _pListeners->onArrayHasChanged(); 435 } 436 } 437 removeArrayElement(const char * sPosition)438 void DtaScriptVariable::removeArrayElement(const char* sPosition) { 439 if (getReferencedVariable() != NULL) getReferencedVariable()->removeArrayElement(sPosition); 440 else if (_pArray != NULL) { 441 for (std::list<DtaScriptVariable*>::iterator i = _pArray->items.begin(); i != _pArray->items.end(); i++) { 442 if (strcmp((*i)->_tcName, sPosition) == 0) { 443 delete (*i); 444 _pArray->items.erase(i); 445 if (_pArray->cache != NULL) _pArray->cache->erase(sPosition); 446 if (_pListeners != NULL) _pListeners->onArrayHasChanged(); 447 break; 448 } 449 } 450 } 451 } 452 removeArrayElement(int iPosition)453 void DtaScriptVariable::removeArrayElement(int iPosition) { 454 if (getReferencedVariable() != NULL) getReferencedVariable()->removeArrayElement(iPosition); 455 else if (_pArray != NULL) { 456 if (iPosition >= 0) { 457 for (std::list<DtaScriptVariable*>::iterator i = _pArray->items.begin(); i != _pArray->items.end(); i++) { 458 if (iPosition == 0) { 459 if (_pArray->cache != NULL) _pArray->cache->erase((*i)->_tcName); 460 delete *i; 461 _pArray->items.erase(i); 462 if (_pListeners != NULL) _pListeners->onArrayHasChanged(); 463 break; 464 } 465 iPosition--; 466 } 467 } 468 } 469 } 470 removeFirstElement()471 void DtaScriptVariable::removeFirstElement() { 472 if (getReferencedVariable() != NULL) getReferencedVariable()->removeFirstElement(); 473 else if (_pArray != NULL) { 474 std::list<DtaScriptVariable*>::iterator cursor = _pArray->items.begin(); 475 if (cursor != _pArray->items.end()) { 476 if (_pArray->cache != NULL) _pArray->cache->erase((*cursor)->_tcName); 477 delete *cursor; 478 _pArray->items.erase(cursor); 479 if (_pListeners != NULL) _pListeners->onArrayHasChanged(); 480 } 481 } 482 } 483 removeLastElement()484 void DtaScriptVariable::removeLastElement() { 485 if (getReferencedVariable() != NULL) getReferencedVariable()->removeLastElement(); 486 else if ((_pArray != NULL) && !_pArray->items.empty()) { 487 DtaScriptVariable* pElt = _pArray->items.back(); 488 if (_pArray->cache != NULL) _pArray->cache->erase(pElt->_tcName); 489 _pArray->items.remove(pElt); 490 delete pElt; 491 if (_pListeners != NULL) _pListeners->onArrayHasChanged(); 492 } 493 } 494 getCompleteName() const495 std::string DtaScriptVariable::getCompleteName() const { 496 std::string sName; 497 if (_pParent != NULL) { 498 sName = _pParent->getCompleteName(); 499 DtaScriptVariableList* pAttributes = _pParent->_pAttributes; 500 while (pAttributes != NULL) { 501 if (strcmp(pAttributes->getNode()->_tcName, _tcName) == 0) { 502 if (!sName.empty()) sName += "."; 503 sName += _tcName; 504 return sName; 505 } 506 pAttributes = pAttributes->getNext(); 507 } 508 if (_pParent->_pArray != NULL) { 509 const std::list<DtaScriptVariable*>& pList = _pParent->_pArray->items; 510 for (std::list<DtaScriptVariable*>::const_iterator i = pList.begin(); i != pList.end(); i++) { 511 if (((*i) != NULL) && (strcmp((*i)->_tcName, _tcName) == 0)) { 512 sName += "[\"" + std::string(_tcName) + "\"]"; 513 return sName; 514 } 515 } 516 } 517 sName = ""; 518 } else if (_tcName != NULL) { 519 sName = _tcName; 520 } else { 521 sName = "<unnamed>"; 522 } 523 return sName; 524 } 525 clearArray()526 void DtaScriptVariable::clearArray() { 527 delete _pArray; 528 _pArray = NULL; 529 if (_pListeners != NULL) _pListeners->onArrayHasChanged(); 530 } 531 sortArray()532 void DtaScriptVariable::sortArray() { 533 DtaScriptVariable* pVariable = this; 534 while (pVariable->getReferencedVariable() != NULL) pVariable = pVariable->getReferencedVariable(); 535 NodeArrayType* pANT = pVariable->_pArray; 536 if (pANT == NULL) return; 537 bool bPurgeCacheAfter = (pANT->cache == NULL); 538 if (bPurgeCacheAfter) { 539 pANT->cache = new std::map<std::string, DtaScriptVariable*>(); 540 for (std::list<DtaScriptVariable*>::const_iterator i = pANT->items.begin(); i != pANT->items.end(); i++) { 541 (*(pANT->cache))[(*i)->_tcName] = (*i); 542 } 543 } 544 pANT->items = std::list<DtaScriptVariable*>(); 545 std::map<std::string, DtaScriptVariable*>* mapOfElts = pANT->cache; 546 for (std::map<std::string, DtaScriptVariable*>::const_iterator j = mapOfElts->begin(); j != mapOfElts->end(); ++j) { 547 pANT->items.push_back(j->second); 548 } 549 if (bPurgeCacheAfter) { 550 delete pANT->cache; 551 pANT->cache = NULL; 552 } 553 if (_pListeners != NULL) _pListeners->onArrayHasChanged(); 554 } 555 removeReference()556 void DtaScriptVariable::removeReference() { 557 _value.var->_pReferencedByVariables->erase(this); 558 _eValueNode = NO_VALUE_NODE; 559 if (_pListeners != NULL) _pListeners->onSetValue(NULL); 560 } 561 addReferencedBy(DtaScriptVariable * pVariable)562 void DtaScriptVariable::addReferencedBy(DtaScriptVariable* pVariable) { 563 if (pVariable != NULL) { 564 if (_pReferencedByVariables == NULL) _pReferencedByVariables = new std::set<DtaScriptVariable*>(); 565 _pReferencedByVariables->insert(pVariable); 566 } 567 } 568 getInternalVariableExtraction(DtaScriptVariable & visibility,const ExprScriptVariable & exprVariable,bool bRecursiveSearch,bool bCreateIfUnknown,bool bReferencedVariable)569 DtaScriptVariable* DtaScriptVariable::getInternalVariableExtraction(DtaScriptVariable& visibility, const ExprScriptVariable& exprVariable, bool bRecursiveSearch, bool bCreateIfUnknown, bool bReferencedVariable) { 570 DtaScriptVariable* pVariable = NULL; 571 if (exprVariable.isEvaluation()) { 572 std::string sCommand = exprVariable.getExpression()->getValue(visibility); 573 ScpStream theCommand(sCommand); 574 DtaScript script; 575 CGQuietOutput quiet; 576 std::auto_ptr<ExprScriptVariable> pExprVariable(script.parseVariableExpression(script.getBlock(), theCommand)); 577 pVariable = getInternalVariableExtraction(visibility, *pExprVariable, bRecursiveSearch, bCreateIfUnknown, bReferencedVariable); 578 return pVariable; 579 } 580 if (exprVariable.getPackage() != NULL) { 581 // the variable comes from a package 582 pVariable = exprVariable.getPackage()->getVariable(exprVariable.getName()); 583 if (pVariable == NULL) return NULL; 584 if (bReferencedVariable || exprVariable.isNext()) { 585 DtaScriptVariable* pRefVar = pVariable->getReferencedVariable(); 586 if (pRefVar != NULL) pVariable = pRefVar; 587 } 588 } else { 589 if (bReferencedVariable || exprVariable.isNext()) pVariable = getReferencedVariable(); 590 if (pVariable == NULL) { 591 bool bExtractVariableWithReference = bReferencedVariable || !exprVariable.isAttributeOnly(); 592 std::string sName = exprVariable.getName(); 593 pVariable = getVariable(sName.c_str(), bRecursiveSearch, bCreateIfUnknown, bExtractVariableWithReference); 594 if (pVariable == NULL) return NULL; 595 } 596 } 597 if (exprVariable.isArrayKey()) { 598 std::string sPosition = exprVariable.getExpression()->getValue(visibility); 599 DtaScriptVariable* pArrayElement = pVariable->getArrayElement(sPosition); 600 if (pArrayElement == NULL) { 601 if (bCreateIfUnknown) { 602 pArrayElement = pVariable->addInternalElement(sPosition); 603 } else { 604 return NULL; 605 } 606 pVariable = pArrayElement; 607 } else { 608 if (bReferencedVariable || exprVariable.isNext()) { 609 pVariable = pArrayElement->getReferencedVariable(); 610 if (pVariable == NULL) pVariable = pArrayElement; 611 } else { 612 pVariable = pArrayElement; 613 } 614 } 615 } else if (exprVariable.isArrayPosition()) { 616 std::string sPosition = exprVariable.getExpression()->getValue(visibility); 617 if (sPosition == "parent") { 618 register DtaScriptVariable* pParent = pVariable->getParent(); 619 if ((pParent != NULL) && (strncmp(pParent->_tcName, "##stack##", 9) != 0)) pVariable = pParent; 620 } else if (sPosition == "root") { 621 register DtaScriptVariable* pParent = pVariable->getParent(); 622 while ((pParent != NULL) && (strncmp(pParent->_tcName, "##stack##", 9) != 0)) { 623 pVariable = pParent; 624 pParent = pVariable->getParent(); 625 } 626 } else { 627 int iPosition; 628 if (sPosition == "back") iPosition = pVariable->getArraySize() - 1; 629 else iPosition = atoi(sPosition.c_str()); 630 DtaScriptVariable* pArrayElement = pVariable->getArrayElement(iPosition); 631 if (pArrayElement == NULL) throw UtlException(std::string("Array index is out of bounds on variable '" + exprVariable.toString() + "': \"") + sPosition + "\""); 632 pVariable = pArrayElement; 633 if (bReferencedVariable || exprVariable.isNext()) { 634 pVariable = pVariable->getReferencedVariable(); 635 if (pVariable == NULL) pVariable = pArrayElement; 636 } 637 } 638 } 639 if (exprVariable.isNext()) { 640 pVariable = pVariable->getInternalVariableExtraction(visibility, *(exprVariable.getNext()), false, bCreateIfUnknown, bReferencedVariable); 641 } 642 return pVariable; 643 } 644 getVariable(const ExprScriptVariable & exprVariable)645 DtaScriptVariable* DtaScriptVariable::getVariable(const ExprScriptVariable& exprVariable) { 646 return getInternalVariableExtraction(*this, exprVariable, true, true, true); 647 } 648 getNonRecursiveVariable(DtaScriptVariable & visibility,const ExprScriptVariable & exprVariable)649 DtaScriptVariable* DtaScriptVariable::getNonRecursiveVariable(DtaScriptVariable& visibility, const ExprScriptVariable& exprVariable) { 650 return getInternalVariableExtraction(visibility, exprVariable, false, true, true); 651 } 652 getNonRecursiveNonReferencedVariable(DtaScriptVariable & visibility,const ExprScriptVariable & exprVariable)653 DtaScriptVariable* DtaScriptVariable::getNonRecursiveNonReferencedVariable(DtaScriptVariable& visibility, const ExprScriptVariable& exprVariable) { 654 return getInternalVariableExtraction(visibility, exprVariable, false, true, false); 655 } 656 getVariableForReferenceAssignment(const ExprScriptVariable & exprVariable)657 DtaScriptVariable* DtaScriptVariable::getVariableForReferenceAssignment(const ExprScriptVariable& exprVariable) { 658 return getInternalVariableExtraction(*this, exprVariable, true, true, false); 659 } 660 getExistingVariable(const ExprScriptVariable & exprVariable)661 DtaScriptVariable* DtaScriptVariable::getExistingVariable(const ExprScriptVariable& exprVariable) { 662 DtaScriptVariable* pVariable = getInternalVariableExtraction(*this, exprVariable, true, false, true); 663 if ((pVariable == NULL) && Workspace::warningOnUnknownVariables()) { 664 std::string sErrorMessage = "warning: variable '" + exprVariable.toString() + "' doesn't exist yet" + CGRuntime::endl(); 665 sErrorMessage += UtlTrace::getTraceStack(); 666 if (DtaProject::getInstance().addWarning(sErrorMessage) == 1) CGRuntime::traceLine(sErrorMessage); 667 } 668 return pVariable; 669 } 670 getNoWarningExistingVariable(const ExprScriptVariable & exprVariable)671 DtaScriptVariable* DtaScriptVariable::getNoWarningExistingVariable(const ExprScriptVariable& exprVariable) { 672 return getInternalVariableExtraction(*this, exprVariable, true, false, true); 673 } 674 675 getNonRecursiveVariable(const char * sName)676 DtaScriptVariable* DtaScriptVariable::getNonRecursiveVariable(const char* sName) { 677 return getVariable(sName, false, true, true); 678 } 679 getVariable(const char * sName,bool bRecursiveSearch,bool bCreateIfUnknown,bool bReferencedVariable)680 DtaScriptVariable* DtaScriptVariable::getVariable(const char* sName, bool bRecursiveSearch, bool bCreateIfUnknown, bool bReferencedVariable) { 681 DtaScriptVariable* pVariable = NULL; 682 if (*sName == '\0') return this; 683 if (bRecursiveSearch) { 684 if (strcmp(sName, "project") == 0) return &(DtaProject::getInstance()); 685 if (strcmp(sName, "this") == 0) { 686 DtaScriptVariable* pThis = &CGRuntime::getThisInternalNode(); 687 if (pThis == NULL) throw UtlException("INTERNAL ERROR: NULL 'this'!"); 688 return pThis; 689 } 690 if (strcmp(sName, "null") == 0) return NULL; 691 } 692 DtaScriptVariableList* pAttributes = _pAttributes; 693 DtaScriptVariableList* pLastAttribute = _pAttributes; 694 while (pAttributes != NULL) { 695 if (strcmp(pAttributes->getNode()->_tcName, sName) == 0) { 696 pVariable = pAttributes->getNode(); 697 if (bReferencedVariable && (pVariable->getReferencedVariable() != NULL)) { 698 do pVariable = pVariable->getReferencedVariable(); while (pVariable->getReferencedVariable() != NULL); 699 } 700 break; 701 } 702 if (pAttributes->getNext() == NULL) pLastAttribute = pAttributes; 703 pAttributes = pAttributes->getNext(); 704 } 705 if (pAttributes == NULL) { 706 if (bRecursiveSearch) { 707 // pVariable = _pParent->getVariable(sName, true, false, bReferencedVariable); 708 // we are looking for the variable into local variables, above the function call 709 DtaScriptVariable* pLocalScope = NULL; 710 bool bClause = false; 711 if ((strncmp(_tcName, "##stack## ", 10) == 0) && (strncmp(_tcName + 10, "function", 8) != 0) && (strncmp(_tcName + 10, "clause", 6) != 0)) { 712 pLocalScope = getParent(); 713 while ((pVariable == NULL) && (pLocalScope != NULL) && (pLocalScope->_tcName != NULL) && (strncmp(pLocalScope->_tcName, "##stack##", 9) == 0)) { 714 pVariable = pLocalScope->getVariable(sName, false, false, bReferencedVariable); 715 const char* tcFunction = pLocalScope->_tcName + 10; 716 if (strncmp(tcFunction, "function", 8) == 0) break; 717 if (strncmp(tcFunction, "clause", 6) == 0) { 718 bClause = true; 719 break; 720 } 721 pLocalScope = pLocalScope->getParent(); 722 } 723 } 724 if ((pVariable == NULL) && !bClause) { 725 // the variable doesn't belong to the stack, perhaps it is a node of the current subtree 726 DtaScriptVariable* pThis = &CGRuntime::getThisInternalNode(); 727 if (pThis == 0) throw UtlException("INTERNAL ERROR: NULL 'this'!"); 728 pVariable = pThis->getVariable(sName, false, false, bReferencedVariable); 729 int tiVersion[] = {1, 13, -1}; 730 if ((pVariable == NULL) && (pLocalScope != NULL) && DtaProject::getInstance().isScriptVersionOlderThan(tiVersion)) { 731 // this is an old version of scripts, so variable may be stored 732 // into the stack, above the function call 733 while ((pVariable == NULL) && (pLocalScope->_tcName != NULL) && (strncmp(pLocalScope->_tcName, "##stack##", 9) == 0)) { 734 pVariable = pLocalScope->getVariable(sName, false, false, bReferencedVariable); 735 pLocalScope = pLocalScope->getParent(); 736 } 737 if (pVariable != NULL) { 738 std::string sErrorMessage = "since version 1.13, the scope of a local variable is restricted to the function it is declared into, so a change of behaviour may occur when looking at local variable '"; 739 sErrorMessage += sName; 740 sErrorMessage += "'" + UtlTrace::getTraceStack(); 741 if (DtaProject::getInstance().addWarning(sErrorMessage) == 1) CGRuntime::traceLine(sErrorMessage); 742 pVariable = NULL; 743 } 744 } 745 } 746 } 747 if (pVariable == NULL) { 748 if (bRecursiveSearch) pVariable = DtaProject::getInstance().getGlobalVariable(sName); 749 if ((pVariable == NULL) && bCreateIfUnknown) { 750 pVariable = new DtaScriptVariable(this, sName); 751 if (_pAttributes == NULL) _pAttributes = new DtaScriptVariableList(pVariable); 752 else pLastAttribute->pushBack(pVariable); 753 if (_pListeners != NULL) _pListeners->onAddAttribute(pVariable); 754 } 755 } 756 } 757 return pVariable; 758 } 759 getNode(const char * sName)760 DtaScriptVariable* DtaScriptVariable::getNode(const char* sName) { 761 DtaScriptVariable* pVariable = this; 762 while (pVariable->getReferencedVariable() != NULL) pVariable = pVariable->getReferencedVariable(); 763 return pVariable->getVariable(sName, false, false, true); 764 } 765 insertNode(const char * sName)766 DtaScriptVariable* DtaScriptVariable::insertNode(const char* sName) { 767 DtaScriptVariable* pVariable = this; 768 while (pVariable->getReferencedVariable() != NULL) pVariable = pVariable->getReferencedVariable(); 769 return pVariable->getVariable(sName, false, true, true); 770 } 771 getEvaluatedNode(const std::string & sDynamicVariable)772 DtaScriptVariable* DtaScriptVariable::getEvaluatedNode(const std::string& sDynamicVariable) { 773 ScpStream theCommand(sDynamicVariable); 774 DtaScript script; 775 std::auto_ptr<ExprScriptVariable> pExprVariable(script.parseVariableExpression(script.getBlock(), theCommand)); 776 DtaScriptVariable* pVariable = getInternalVariableExtraction(*this, *pExprVariable, true/*bRecursiveSearch*/, false/*bCreateIfUnknown*/, true/*bReferencedVariable*/); 777 return pVariable; 778 } 779 getOrCreateLocalEvaluatedNode(const std::string & sDynamicVariable)780 DtaScriptVariable* DtaScriptVariable::getOrCreateLocalEvaluatedNode(const std::string& sDynamicVariable) { 781 ScpStream theCommand(sDynamicVariable); 782 DtaScript script; 783 std::auto_ptr<ExprScriptVariable> pExprVariable(script.parseVariableExpression(script.getBlock(), theCommand)); 784 DtaScriptVariable* pVariable = getInternalVariableExtraction(*this, *pExprVariable, true/*bRecursiveSearch*/, true/*bCreateIfUnknown*/, true/*bReferencedVariable*/); 785 return pVariable; 786 } 787 insertEvaluatedNode(const std::string & sDynamicVariable)788 DtaScriptVariable* DtaScriptVariable::insertEvaluatedNode(const std::string& sDynamicVariable) { 789 ScpStream theCommand(sDynamicVariable); 790 DtaScript script; 791 std::auto_ptr<ExprScriptVariable> pExprVariable(script.parseVariableExpression(script.getBlock(), theCommand)); 792 DtaScriptVariable* pVariable = getInternalVariableExtraction(*this, *pExprVariable, true/*bRecursiveSearch*/, true/*bCreateIfUnknown*/, true/*bReferencedVariable*/); 793 return pVariable; 794 } 795 insertClassicalEvaluatedNode(const std::string & sDynamicVariable)796 DtaScriptVariable* DtaScriptVariable::insertClassicalEvaluatedNode(const std::string& sDynamicVariable) { 797 ScpStream theCommand(sDynamicVariable); 798 DtaScript script; 799 std::auto_ptr<ExprScriptVariable> pExprVariable(script.parseVariableExpression(script.getBlock(), theCommand)); 800 DtaScriptVariable* pVariable = getInternalVariableExtraction(*this, *pExprVariable, true/*bRecursiveSearch*/, true/*bCreateIfUnknown*/, true/*bReferencedVariable*/); 801 return pVariable; 802 } 803 moveToNode(DtaScriptVariable & node)804 void DtaScriptVariable::moveToNode(DtaScriptVariable& node) { 805 if (node._pAttributes == NULL) { 806 node._pAttributes = _pAttributes; 807 } else { 808 DtaScriptVariableList* pAttributes = node._pAttributes; 809 while (pAttributes->getNext() != NULL) pAttributes = pAttributes->getNext(); 810 pAttributes->setNext(_pAttributes); 811 } 812 _pAttributes = NULL; 813 if (node._pArray == NULL) { 814 node._pArray = _pArray; 815 } else { 816 while (!_pArray->items.empty()) { 817 node._pArray->items.push_back(_pArray->items.back()); 818 _pArray->items.pop_back(); 819 } 820 delete node._pArray->cache; 821 node._pArray->cache = NULL; 822 delete _pArray; 823 } 824 _pArray = NULL; 825 node._eValueNode = _eValueNode; 826 node._value = _value; 827 _eValueNode = NO_VALUE_NODE; 828 } 829 createNodeArgument(const char * sName,DtaScriptVariable * pParameter)830 DtaScriptVariable* DtaScriptVariable::createNodeArgument(const char* sName, DtaScriptVariable* pParameter) { 831 DtaScriptVariable* pIndex = NULL; 832 DtaScriptVariableList* pAttributes = _pAttributes; 833 DtaScriptVariableList* pLastAttribute = _pAttributes; 834 while (pAttributes != NULL) { 835 if (strcmp(pAttributes->getNode()->_tcName, sName) == 0) { 836 pIndex = pAttributes->getNode(); 837 break; 838 } 839 if (pAttributes->getNext() == NULL) pLastAttribute = pAttributes; 840 pAttributes = pAttributes->getNext(); 841 } 842 if (pAttributes == NULL) { 843 pIndex = new DtaScriptVariable(this, sName); 844 if (_pAttributes == NULL) _pAttributes = new DtaScriptVariableList(pIndex); 845 else pLastAttribute->pushBack(pIndex); 846 if (_pListeners != NULL) _pListeners->onAddAttribute(pIndex); 847 } 848 pIndex->setValue(pParameter); 849 return pIndex; 850 } 851 getNodeArgument(const char * sName) const852 DtaScriptVariable* DtaScriptVariable::getNodeArgument(const char* sName) const { 853 DtaScriptVariable* pIndex = NULL; 854 DtaScriptVariableList* pAttributes = _pAttributes; 855 DtaScriptVariableList* pLastAttribute = _pAttributes; 856 while (pAttributes != NULL) { 857 if (strcmp(pAttributes->getNode()->_tcName, sName) == 0) { 858 pIndex = pAttributes->getNode(); 859 break; 860 } 861 if (pAttributes->getNext() == NULL) pLastAttribute = pAttributes; 862 pAttributes = pAttributes->getNext(); 863 } 864 if (pAttributes == NULL) { 865 if (_pParent != NULL) pIndex = _pParent->getNodeArgument(sName); 866 if (pIndex == NULL) { 867 throw UtlException(std::string("unable to find argument called '") + sName + "'"); 868 } 869 } 870 return pIndex; 871 } 872 createIterator(const char * sName,DtaArrayIterator ** pIteratorData)873 DtaScriptVariable* DtaScriptVariable::createIterator(const char* sName, DtaArrayIterator** pIteratorData) { 874 DtaScriptVariable* pIndex = NULL; 875 DtaScriptVariableList* pAttributes = _pAttributes; 876 DtaScriptVariableList* pLastAttribute = _pAttributes; 877 while (pAttributes != NULL) { 878 if (strcmp(pAttributes->getNode()->_tcName, sName) == 0) { 879 pIndex = pAttributes->getNode(); 880 break; 881 } 882 if (pAttributes->getNext() == NULL) pLastAttribute = pAttributes; 883 pAttributes = pAttributes->getNext(); 884 } 885 if (pAttributes == NULL) { 886 pIndex = new DtaScriptVariable(this, sName); 887 if (_pAttributes == NULL) _pAttributes = new DtaScriptVariableList(pIndex); 888 else pLastAttribute->pushBack(pIndex); 889 if (_pListeners != NULL) _pListeners->onAddAttribute(pIndex); 890 } 891 pIndex->setIteratorData(pIteratorData); 892 return pIndex; 893 } 894 getIterator(const char * sName) const895 DtaScriptVariable* DtaScriptVariable::getIterator(const char* sName) const { 896 DtaScriptVariable* pIndex = NULL; 897 DtaScriptVariableList* pAttributes = _pAttributes; 898 DtaScriptVariableList* pLastAttribute = _pAttributes; 899 while (pAttributes != NULL) { 900 if (strcmp(pAttributes->getNode()->_tcName, sName) == 0) { 901 pIndex = pAttributes->getNode(); 902 break; 903 } 904 if (pAttributes->getNext() == NULL) pLastAttribute = pAttributes; 905 pAttributes = pAttributes->getNext(); 906 } 907 if (pAttributes == NULL) { 908 if (_pParent != NULL) pIndex = _pParent->getIterator(sName); 909 } 910 if (pIndex != NULL) { 911 while (pIndex->_eValueNode == REFERENCE_VALUE_NODE) pIndex = pIndex->_value.var; 912 if (pIndex->_eValueNode != INDEX_VALUE_NODE) return NULL; 913 } 914 return pIndex; 915 } 916 getIteratorData() const917 DtaArrayIterator* DtaScriptVariable::getIteratorData() const { 918 if (_eValueNode != INDEX_VALUE_NODE) return NULL; 919 return *_value.ind.var; 920 } 921 addElement(int iKey)922 DtaScriptVariable* DtaScriptVariable::addElement(int iKey) { 923 char tcKey[32]; 924 sprintf(tcKey, "%d", iKey); 925 return addElement(tcKey); 926 } 927 addElement(const std::string & sName)928 DtaScriptVariable* DtaScriptVariable::addElement(const std::string& sName) { 929 DtaScriptVariable* pVariable = getArrayElement(sName); 930 if (pVariable == NULL) pVariable = addInternalElement(sName); 931 return pVariable; 932 } 933 addInternalElement(const std::string & sName)934 DtaScriptVariable* DtaScriptVariable::addInternalElement(const std::string& sName) { 935 DtaScriptVariable* pVariable = new DtaScriptVariable(this, sName); 936 if (_pArray == NULL) _pArray = new NodeArrayType(pVariable); 937 else { 938 _pArray->items.push_back(pVariable); 939 if (_pArray->cache != NULL) (*_pArray->cache)[sName] = pVariable; 940 } 941 if (_pListeners != NULL) _pListeners->onArrayHasChanged(); 942 return pVariable; 943 } 944 setValueAtVariable(const char * sVariable,const char * sValue,bool bRecursiveSearch,bool bCreateIfUnknown)945 void DtaScriptVariable::setValueAtVariable(const char* sVariable, const char* sValue, bool bRecursiveSearch, bool bCreateIfUnknown) { 946 getVariable(sVariable, bRecursiveSearch, bCreateIfUnknown)->setValue(sValue); 947 } 948 getValue() const949 const char* DtaScriptVariable::getValue() const { 950 if (_eValueNode == STRING_VALUE_NODE) return _value.str.text; 951 if (_eValueNode == REFERENCE_VALUE_NODE) return _value.var->getValue(); 952 if (_eValueNode == EXTERNAL_VALUE_NODE) return _value.ext->getValue(); 953 if (_eValueNode == INDEX_VALUE_NODE) return (*_value.ind.var)->item()->getValue(); 954 return NULL; 955 } 956 getValueLength() const957 size_t DtaScriptVariable::getValueLength() const { 958 if (_eValueNode == STRING_VALUE_NODE) return _value.str.length; 959 if (_eValueNode == REFERENCE_VALUE_NODE) return _value.var->getValueLength(); 960 if (_eValueNode == EXTERNAL_VALUE_NODE) return _value.ext->getValueLength(); 961 if (_eValueNode == INDEX_VALUE_NODE) return (*_value.ind.var)->item()->getValueLength(); 962 return 0; 963 } 964 getDoubleValue() const965 double DtaScriptVariable::getDoubleValue() const { 966 if (_eValueNode == STRING_VALUE_NODE) return atof(_value.str.text); 967 if (_eValueNode == REFERENCE_VALUE_NODE) return _value.var->getDoubleValue(); 968 if (_eValueNode == EXTERNAL_VALUE_NODE) return _value.ext->getDoubleValue(); 969 if (_eValueNode == INDEX_VALUE_NODE) return (*_value.ind.var)->item()->getDoubleValue(); 970 return 0.0; 971 } 972 getBooleanValue() const973 bool DtaScriptVariable::getBooleanValue() const { 974 if (_eValueNode == STRING_VALUE_NODE) return (_value.str.length != 0); 975 if (_eValueNode == REFERENCE_VALUE_NODE) return _value.var->getBooleanValue(); 976 if (_eValueNode == EXTERNAL_VALUE_NODE) return _value.ext->getBooleanValue(); 977 if (_eValueNode == INDEX_VALUE_NODE) return (*_value.ind.var)->item()->getBooleanValue(); 978 return false; 979 } 980 getIntValue() const981 int DtaScriptVariable::getIntValue() const { 982 if (_eValueNode == STRING_VALUE_NODE) return atoi(_value.str.text); 983 if (_eValueNode == REFERENCE_VALUE_NODE) return _value.var->getIntValue(); 984 if (_eValueNode == EXTERNAL_VALUE_NODE) return _value.ext->getIntValue(); 985 if (_eValueNode == INDEX_VALUE_NODE) return (*_value.ind.var)->item()->getIntValue(); 986 return 0; 987 } 988 clearValue()989 void DtaScriptVariable::clearValue() { 990 if (_eValueNode == REFERENCE_VALUE_NODE) { 991 removeReference(); 992 } else if (_eValueNode == INDEX_VALUE_NODE) { 993 if (_value.ind.own) { 994 delete *_value.ind.var; 995 delete _value.ind.var; 996 } 997 } else if (_eValueNode == STRING_VALUE_NODE) { 998 delete [] _value.str.text; 999 } else if (_eValueNode == EXTERNAL_VALUE_NODE) { 1000 EXTERNAL_VALUE_NODE_DESTRUCTOR f = _value.ext->getDestructor(); 1001 if (f != NULL) f(_value.ext); 1002 } 1003 _eValueNode = NO_VALUE_NODE; 1004 } 1005 setValue(const char * tcValue)1006 void DtaScriptVariable::setValue(const char* tcValue) { 1007 if (_pListeners != NULL) _pListeners->onSetValue(tcValue); 1008 if ((tcValue == NULL) || (*tcValue == '\0')) { 1009 clearValue(); 1010 } else { 1011 size_t iLength = strlen(tcValue); 1012 if (_eValueNode == STRING_VALUE_NODE) { 1013 if (iLength > _value.str.length) { 1014 delete [] _value.str.text; 1015 _value.str.text = new char[iLength + 1]; 1016 } 1017 } else { 1018 if (_eValueNode == REFERENCE_VALUE_NODE) { 1019 removeReference(); 1020 } else if (_eValueNode == INDEX_VALUE_NODE) { 1021 if (_value.ind.own) { 1022 delete *_value.ind.var; 1023 delete _value.ind.var; 1024 } 1025 } else if (_eValueNode == EXTERNAL_VALUE_NODE) { 1026 EXTERNAL_VALUE_NODE_DESTRUCTOR f = _value.ext->getDestructor(); 1027 if (f != NULL) f(_value.ext); 1028 } 1029 _value.str.text = new char[iLength + 1]; 1030 } 1031 strcpy(_value.str.text, tcValue); 1032 _value.str.length = iLength; 1033 _eValueNode = STRING_VALUE_NODE; 1034 } 1035 } 1036 setValue(bool bValue)1037 void DtaScriptVariable::setValue(bool bValue) { 1038 setValue(((bValue) ? "true" : NULL)); 1039 } 1040 setValue(double dValue)1041 void DtaScriptVariable::setValue(double dValue) { 1042 std::string sDouble = CGRuntime::toString(dValue); 1043 setValue(sDouble.c_str()); 1044 } 1045 setValue(int iValue)1046 void DtaScriptVariable::setValue(int iValue) { 1047 char tcNumber[16]; 1048 sprintf(tcNumber, "%d", iValue); 1049 setValue(tcNumber); 1050 } 1051 setValue(const std::list<std::string> & listOfValues)1052 void DtaScriptVariable::setValue(const std::list<std::string>& listOfValues) { 1053 int iIndex = 0; 1054 char sNumber[16]; 1055 clearArray(); 1056 for (std::list<std::string>::const_iterator i = listOfValues.begin(); i != listOfValues.end(); i++) { 1057 sprintf(sNumber, "%d", iIndex); 1058 addElement(sNumber)->setValue(i->c_str()); 1059 iIndex++; 1060 } 1061 if (_pListeners != NULL) _pListeners->onArrayHasChanged(); 1062 } 1063 setValue(DtaScriptVariable * pVariable)1064 void DtaScriptVariable::setValue(DtaScriptVariable* pVariable) { 1065 if (pVariable != NULL) { 1066 if (pVariable == this) throw UtlException("DtaScriptVariable::setValue() cyclic reference"); 1067 while (pVariable->_eValueNode == REFERENCE_VALUE_NODE) { 1068 pVariable = pVariable->getReferencedVariable(); 1069 if (pVariable == this) throw UtlException("DtaScriptVariable::setValue() cyclic reference"); 1070 } 1071 } 1072 clearValue(); 1073 if (pVariable != NULL) { 1074 _eValueNode = REFERENCE_VALUE_NODE; 1075 _value.var = pVariable; 1076 _value.var->addReferencedBy(this); 1077 if (_pListeners != NULL) _pListeners->onSetReference(pVariable); 1078 } 1079 } 1080 setValue(ExternalValueNode * pExternalValue)1081 void DtaScriptVariable::setValue(ExternalValueNode* pExternalValue) { 1082 if ((_eValueNode == EXTERNAL_VALUE_NODE) && (pExternalValue == _value.ext)) return; 1083 clearValue(); 1084 _eValueNode = EXTERNAL_VALUE_NODE; 1085 _value.ext = pExternalValue; 1086 if (_pListeners != NULL) _pListeners->onSetExternal(pExternalValue); 1087 } 1088 setValue(DtaArrayIterator * pIteratorData)1089 void DtaScriptVariable::setValue(DtaArrayIterator* pIteratorData) { 1090 DtaArrayIterator** ppIteratorData = new DtaArrayIterator*; 1091 *ppIteratorData = pIteratorData; 1092 setIteratorData(ppIteratorData); 1093 _value.ind.own = true; 1094 } 1095 setIteratorData(DtaArrayIterator ** pIteratorData)1096 void DtaScriptVariable::setIteratorData(DtaArrayIterator** pIteratorData) { 1097 clearValue(); 1098 _eValueNode = INDEX_VALUE_NODE; 1099 _value.ind.var = pIteratorData; 1100 _value.ind.own = false; 1101 if (_pListeners != NULL) _pListeners->onSetIterator(pIteratorData); 1102 } 1103 concatValue(const char * tcValue)1104 void DtaScriptVariable::concatValue(const char* tcValue) { 1105 if (_pListeners != NULL) _pListeners->onConcatValue(tcValue); 1106 if ((tcValue != NULL) && (*tcValue != '\0')) { 1107 size_t iLength = strlen(tcValue); 1108 if (_eValueNode == STRING_VALUE_NODE) { 1109 char* tcOld = _value.str.text; 1110 _value.str.text = new char[_value.str.length + iLength + 1]; 1111 memcpy(_value.str.text, tcOld, _value.str.length); 1112 strcpy(_value.str.text + _value.str.length, tcValue); 1113 _value.str.length += iLength; 1114 delete [] tcOld; 1115 } else { 1116 if (_eValueNode == REFERENCE_VALUE_NODE) { 1117 removeReference(); 1118 } else if (_eValueNode == INDEX_VALUE_NODE) { 1119 if (_value.ind.own) { 1120 delete *_value.ind.var; 1121 delete _value.ind.var; 1122 } 1123 } else if (_eValueNode == EXTERNAL_VALUE_NODE) { 1124 EXTERNAL_VALUE_NODE_DESTRUCTOR f = _value.ext->getDestructor(); 1125 if (f != NULL) f(_value.ext); 1126 } 1127 _value.str.text = new char[iLength + 1]; 1128 strcpy(_value.str.text, tcValue); 1129 _value.str.length = iLength; 1130 _eValueNode = STRING_VALUE_NODE; 1131 } 1132 } 1133 } 1134 remove(DtaScriptVariable * pVariable)1135 void DtaScriptVariable::remove(DtaScriptVariable* pVariable) { 1136 if (getReferencedVariable() != NULL) getReferencedVariable()->remove(pVariable); 1137 else { 1138 if (_pAttributes != NULL) { 1139 if (_pAttributes->getNode() == pVariable) { 1140 DtaScriptVariableList* pNext = _pAttributes->getNext(); 1141 if (_pListeners != NULL) _pListeners->onRemoveAttribute(pVariable); 1142 delete pVariable; 1143 _pAttributes->setNext(NULL); 1144 delete _pAttributes; 1145 _pAttributes = pNext; 1146 return; 1147 } else { 1148 DtaScriptVariableList* pAttributes = _pAttributes; 1149 DtaScriptVariableList* pNext = pAttributes->getNext(); 1150 while (pNext != NULL) { 1151 if (pNext->getNode() == pVariable) { 1152 if (_pListeners != NULL) _pListeners->onRemoveAttribute(pVariable); 1153 pAttributes->setNext(pNext->getNext()); 1154 delete pVariable; 1155 pNext->setNext(NULL); 1156 delete pNext; 1157 return; 1158 } 1159 pAttributes = pNext; 1160 pNext = pNext->getNext(); 1161 } 1162 } 1163 } 1164 if (_pArray != NULL) { 1165 for (std::list<DtaScriptVariable*>::iterator i = _pArray->items.begin(); i != _pArray->items.end(); i++) { 1166 if ((*i) == pVariable) { 1167 std::string sPosition = pVariable->getName(); 1168 delete (*i); 1169 _pArray->items.erase(i); 1170 if (_pArray->cache != NULL) _pArray->cache->erase(sPosition); 1171 if (_pListeners != NULL) _pListeners->onArrayHasChanged(); 1172 return; 1173 } 1174 } 1175 } 1176 } 1177 } 1178 remove(const char * sAttribute)1179 void DtaScriptVariable::remove(const char* sAttribute) { 1180 if (_pAttributes != NULL) { 1181 if (strcmp(_pAttributes->getNode()->_tcName, sAttribute) == 0) { 1182 if (_pListeners != NULL) _pListeners->onRemoveAttribute(_pAttributes->getNode()); 1183 DtaScriptVariableList* pNext = _pAttributes->getNext(); 1184 delete _pAttributes->getNode(); 1185 _pAttributes->setNext(NULL); 1186 delete _pAttributes; 1187 _pAttributes = pNext; 1188 } else { 1189 DtaScriptVariableList* pAttributes = _pAttributes; 1190 DtaScriptVariableList* pNext = pAttributes->getNext(); 1191 while (pNext != NULL) { 1192 if (strcmp(pNext->getNode()->_tcName, sAttribute) == 0) { 1193 if (_pListeners != NULL) _pListeners->onRemoveAttribute(pNext->getNode()); 1194 pAttributes->setNext(pNext->getNext()); 1195 delete pNext->getNode(); 1196 pNext->setNext(NULL); 1197 delete pNext; 1198 break; 1199 } 1200 pAttributes = pNext; 1201 pNext = pNext->getNext(); 1202 } 1203 } 1204 } 1205 } 1206 removeRecursive(const char * sAttribute)1207 void DtaScriptVariable::removeRecursive(const char* sAttribute) { 1208 remove(sAttribute); 1209 if (_pAttributes != NULL) { 1210 DtaScriptVariableList* pAttributes = _pAttributes; 1211 while (pAttributes != NULL) { 1212 pAttributes->getNode()->removeRecursive(sAttribute); 1213 pAttributes = pAttributes->getNext(); 1214 } 1215 } 1216 if (_pArray != NULL) { 1217 for (std::list<DtaScriptVariable*>::iterator j = _pArray->items.begin(); j != _pArray->items.end(); j++) { 1218 if ((*j)->getParent() == this) (*j)->removeRecursive(sAttribute); 1219 } 1220 } 1221 } 1222 clearContent()1223 void DtaScriptVariable::clearContent() { 1224 clearValue(); 1225 while (_pAttributes != NULL) { 1226 DtaScriptVariableList* pCurrent = _pAttributes; 1227 _pAttributes = pCurrent->getNext(); 1228 delete pCurrent->getNode(); 1229 pCurrent->setNext(NULL); 1230 delete pCurrent; 1231 } 1232 clearArray(); 1233 if (_pListeners != NULL) _pListeners->onClearContent(); 1234 } 1235 addArrayElements(const DtaScriptVariable & variable)1236 void DtaScriptVariable::addArrayElements(const DtaScriptVariable& variable) { 1237 NodeArrayType* pANT = variable._pArray; 1238 if ((pANT != NULL) && !pANT->items.empty()) { 1239 if (_pArray == NULL) _pArray = new NodeArrayType; 1240 for (std::list<DtaScriptVariable*>::const_iterator j = pANT->items.begin(); j != pANT->items.end(); j++) { 1241 DtaScriptVariable* pVariable = new DtaScriptVariable(this, (*j)->_tcName); 1242 pVariable->copyAll(*(*j), false); 1243 pVariable->setValue((*j)->getValue()); 1244 _pArray->items.push_back(pVariable); 1245 if (_pArray->cache != NULL) (*_pArray->cache)[pVariable->_tcName] = pVariable; 1246 } 1247 if (_pListeners != NULL) _pListeners->onArrayHasChanged(); 1248 } 1249 } 1250 getNumberOfAttributes() const1251 int DtaScriptVariable::getNumberOfAttributes() const { 1252 int iSize = 0; 1253 DtaScriptVariableList* pVariableAttributes = _pAttributes; 1254 while (pVariableAttributes != NULL) { 1255 iSize++; 1256 pVariableAttributes = pVariableAttributes->getNext(); 1257 } 1258 return iSize; 1259 } 1260 equal(const DtaScriptVariable & variable)1261 bool DtaScriptVariable::equal(const DtaScriptVariable& variable) { 1262 if (_pArray == NULL) { 1263 if (variable._pArray != NULL) { 1264 if (!variable._pArray->items.empty()) return false; 1265 } 1266 } else if (variable._pArray == NULL) { 1267 if (!_pArray->items.empty()) return false; 1268 delete _pArray; 1269 _pArray = NULL; 1270 } else if (_pArray->items.size() != variable._pArray->items.size()) return false; 1271 if (_eValueNode != variable._eValueNode) return false; 1272 if (_eValueNode == REFERENCE_VALUE_NODE) { 1273 if (_value.var != variable._value.var) return false; 1274 } else if (_eValueNode == INDEX_VALUE_NODE) { 1275 if ((*_value.ind.var)->item() != (*variable._value.ind.var)->item()) return false; 1276 } else if (_eValueNode == STRING_VALUE_NODE) { 1277 if (strcmp(_value.str.text, variable._value.str.text) != 0) return false; 1278 } else if (_eValueNode == EXTERNAL_VALUE_NODE) { 1279 if (_value.ext != variable._value.ext) return false; 1280 } 1281 DtaScriptVariableList* pAttributes = _pAttributes; 1282 if (getNumberOfAttributes() != variable.getNumberOfAttributes()) return false; 1283 while (pAttributes != NULL) { 1284 DtaScriptVariableList* pVariableAttributes = variable._pAttributes; 1285 DtaScriptVariable* pVariable = pAttributes->getNode(); 1286 while (pVariableAttributes != NULL) { 1287 if (strcmp(pVariable->_tcName, pVariableAttributes->getNode()->_tcName) == 0) { 1288 if (!pVariable->equal(*(pVariableAttributes->getNode()))) return false; 1289 break; 1290 } 1291 pVariableAttributes = pVariableAttributes->getNext(); 1292 } 1293 if (pVariableAttributes == NULL) return false; 1294 pAttributes = pAttributes->getNext(); 1295 } 1296 std::list<DtaScriptVariable*>::iterator i; 1297 std::list<DtaScriptVariable*>::const_iterator j; 1298 if (_pArray != NULL) { 1299 if (getArraySize() != variable.getArraySize()) return false; 1300 for (i = _pArray->items.begin(); i != _pArray->items.end(); i++) { 1301 for (j = variable._pArray->items.begin(); j != variable._pArray->items.end(); ++j) { 1302 if (strcmp((*i)->_tcName, (*j)->_tcName) == 0) { 1303 if (!(*i)->equal(*(*j))) return false; 1304 break; 1305 } 1306 } 1307 if (j == variable._pArray->items.end()) return false; 1308 } 1309 } 1310 return true; 1311 } 1312 copyAll(const DtaScriptVariable & variable,bool bMerge)1313 void DtaScriptVariable::copyAll(const DtaScriptVariable& variable, bool bMerge) { 1314 if (!bMerge) clearContent(); 1315 const char* tcValue = variable.getValue(); 1316 if ((tcValue != NULL) && (*tcValue != '\0')) setValue(tcValue); 1317 DtaScriptVariableList* pVariableAttributes = variable._pAttributes; 1318 while (pVariableAttributes != NULL) { 1319 const char* tcName = pVariableAttributes->getNode()->_tcName; 1320 DtaScriptVariable* pVariable = NULL; 1321 DtaScriptVariableList* pAttributes = _pAttributes; 1322 DtaScriptVariableList* pLastAttribute = NULL; 1323 while (pAttributes != NULL) { 1324 if (strcmp(pAttributes->getNode()->_tcName, tcName) == 0) { 1325 pVariable = pAttributes->getNode(); 1326 break; 1327 } 1328 if (pAttributes->getNext() == NULL) pLastAttribute = pAttributes; 1329 pAttributes = pAttributes->getNext(); 1330 } 1331 if (pVariable == NULL) { 1332 pVariable = new DtaScriptVariable(this, tcName); 1333 if (pLastAttribute == NULL) _pAttributes = new DtaScriptVariableList(pVariable); 1334 else pLastAttribute->pushBack(pVariable); 1335 if (_pListeners != NULL) _pListeners->onAddAttribute(pVariable); 1336 } 1337 if (pVariableAttributes->getNode()->_eValueNode == REFERENCE_VALUE_NODE) { 1338 pVariable->_eValueNode = REFERENCE_VALUE_NODE; 1339 pVariable->_value.var = pVariableAttributes->getNode()->_value.var; 1340 pVariable->_value.var->addReferencedBy(pVariable); 1341 } else if (pVariableAttributes->getNode()->_eValueNode == INDEX_VALUE_NODE) { 1342 pVariable->_eValueNode = REFERENCE_VALUE_NODE; 1343 pVariable->_value.var = (*pVariableAttributes->getNode()->_value.ind.var)->item(); 1344 pVariable->_value.var->addReferencedBy(pVariable); 1345 } else { 1346 pVariable->copyAll(*(pVariableAttributes->getNode()), bMerge); 1347 } 1348 pVariableAttributes = pVariableAttributes->getNext(); 1349 } 1350 NodeArrayType* pANT = variable._pArray; 1351 if ((pANT != NULL) && !pANT->items.empty()) { 1352 if (_pArray == NULL) { 1353 _pArray = new NodeArrayType; 1354 _pArray->cache = new std::map<std::string, DtaScriptVariable*>(); 1355 } else if (_pArray->cache == NULL) { 1356 _pArray->cache = new std::map<std::string, DtaScriptVariable*>(); 1357 for (std::list<DtaScriptVariable*>::const_iterator i = _pArray->items.begin(); i != _pArray->items.end(); i++) (*_pArray->cache)[(*i)->_tcName] = (*i); 1358 } 1359 for (std::list<DtaScriptVariable*>::const_iterator i = pANT->items.begin(); i != pANT->items.end(); i++) { 1360 const char* tcName = (*i)->_tcName; 1361 std::map<std::string, DtaScriptVariable*>::const_iterator cursor = _pArray->cache->find(tcName); 1362 DtaScriptVariable* pVariable = NULL; 1363 if (cursor != _pArray->cache->end()) { 1364 pVariable = cursor->second; 1365 } else { 1366 pVariable = new DtaScriptVariable(this, tcName); 1367 _pArray->items.push_back(pVariable); 1368 (*_pArray->cache)[tcName] = pVariable; 1369 } 1370 if ((*i)->_eValueNode == REFERENCE_VALUE_NODE) { 1371 pVariable->_eValueNode = REFERENCE_VALUE_NODE; 1372 pVariable->_value.var = (*i)->_value.var; 1373 pVariable->_value.var->addReferencedBy(pVariable); 1374 } else if ((*i)->_eValueNode == INDEX_VALUE_NODE) { 1375 pVariable->_eValueNode = REFERENCE_VALUE_NODE; 1376 pVariable->_value.var = (*(*i)->_value.ind.var)->item(); 1377 pVariable->_value.var->addReferencedBy(pVariable); 1378 } else { 1379 pVariable->copyAll(*(*i), bMerge); 1380 } 1381 } 1382 } 1383 } 1384 pushItem(const std::string & sValue)1385 DtaScriptVariable* DtaScriptVariable::pushItem(const std::string& sValue) { 1386 char tcNumber[32]; 1387 if (_pArray == NULL) _pArray = new NodeArrayType; 1388 sprintf(tcNumber, "%d", _pArray->items.size()); 1389 std::string sNumber = tcNumber; 1390 DtaScriptVariable* pVariable = new DtaScriptVariable(this, sNumber); 1391 _pArray->items.push_back(pVariable); 1392 if (_pArray->cache != NULL) { 1393 (*_pArray->cache)[sNumber] = pVariable; 1394 } 1395 if (!sValue.empty()) pVariable->setValue(sValue.c_str()); 1396 if (_pListeners != NULL) _pListeners->onArrayHasChanged(); 1397 return pVariable; 1398 } 1399 slideNodeContent(DtaScriptVariable & visibility,const ExprScriptVariable & varExpr)1400 void DtaScriptVariable::slideNodeContent(DtaScriptVariable& visibility, const ExprScriptVariable& varExpr) { 1401 DtaScriptVariable* pTemporary = new DtaScriptVariable; 1402 pTemporary->copyAll(*this); 1403 clearContent(); 1404 DtaScriptVariable* pDestVariable = getNonRecursiveVariable(visibility, varExpr); 1405 DtaScriptVariable* pParent = pDestVariable->getParent(); 1406 DtaScriptVariableList* pParentAttributes = pParent->_pAttributes; 1407 while (pParentAttributes != NULL) { 1408 if (pParentAttributes->getNode() == pDestVariable) { 1409 pParentAttributes->setNode(pTemporary); 1410 free((char*) pTemporary->_tcName); 1411 #ifdef WIN32 1412 pTemporary->_tcName = ::_strdup(pDestVariable->_tcName); 1413 #else 1414 pTemporary->_tcName = ::strdup(pDestVariable->_tcName); 1415 #endif 1416 pTemporary->_pParent = pParent; 1417 break; 1418 } 1419 pParentAttributes = pParentAttributes->getNext(); 1420 } 1421 if (pParentAttributes == NULL) { 1422 NodeArrayType* pANT = pParent->_pArray; 1423 if (pANT != NULL) { 1424 std::list<DtaScriptVariable*>::iterator i; 1425 for (i = pANT->items.begin(); i != pANT->items.end(); i++) { 1426 if ((*i) == pDestVariable) { 1427 (*i) = pTemporary; 1428 free((char*) pTemporary->_tcName); 1429 #ifdef WIN32 1430 pTemporary->_tcName = ::_strdup(pDestVariable->_tcName); 1431 #else 1432 pTemporary->_tcName = ::strdup(pDestVariable->_tcName); 1433 #endif 1434 pTemporary->_pParent = pParent; 1435 break; 1436 } 1437 } 1438 if (i == pANT->items.end()) { 1439 delete pTemporary; 1440 throw UtlException("internal error: unable to slide a node content because destination node isn't attached to its parent properly"); 1441 } 1442 } else { 1443 delete pTemporary; 1444 throw UtlException("internal error: unable to slide a node content because destination node isn't attached to its parent properly"); 1445 } 1446 } 1447 delete pDestVariable; 1448 } 1449 traceValue(int iDepth,const std::string & sIndent,const std::string & sPrefix)1450 bool DtaScriptVariable::traceValue(int iDepth, const std::string& sIndent, const std::string& sPrefix) { 1451 if (_eValueNode == STRING_VALUE_NODE) { 1452 if (_value.str.length != 0) CGRuntime::traceLine(sPrefix + "\"" + std::string(_value.str.text) + "\""); 1453 else return false; 1454 } else if ((_eValueNode & 0x0FF) == INDEX_VALUE_NODE) { 1455 DtaScriptVariable* pNode = (*_value.ind.var)->item(); 1456 const char* tcValue = pNode->getValue(); 1457 if (tcValue != NULL) { 1458 CGRuntime::traceLine(sPrefix + "<index> '" + pNode->getCompleteName() + "' = \"" + std::string(tcValue) + "\""); 1459 } else { 1460 CGRuntime::traceLine(sPrefix + "<index> '" + pNode->getCompleteName() + "'"); 1461 } 1462 pNode->traceObject(iDepth, sIndent); 1463 } else if ((_eValueNode & 0x0FF) == REFERENCE_VALUE_NODE) { 1464 const char* tcValue = _value.var->getValue(); 1465 if (tcValue != NULL) { 1466 CGRuntime::traceLine(sPrefix + "-> '" + _value.var->getCompleteName() + "' = \"" + std::string(tcValue) + "\""); 1467 } else { 1468 CGRuntime::traceLine(sPrefix + "-> '" + _value.var->getCompleteName() + "'"); 1469 } 1470 _value.var->traceObject(iDepth, sIndent); 1471 } else if (_eValueNode == EXTERNAL_VALUE_NODE) { 1472 const char* tcValue = _value.ext->getValue(); 1473 if (tcValue != NULL) { 1474 CGRuntime::traceLine(sPrefix + ">> external value node = \"" + std::string(tcValue) + "\""); 1475 } else { 1476 CGRuntime::traceLine(sPrefix + ">> external value node"); 1477 } 1478 } else { 1479 return false; 1480 } 1481 return true; 1482 } 1483 traceObject(int iDepth,const std::string & sIndent)1484 void DtaScriptVariable::traceObject(int iDepth, const std::string& sIndent) { 1485 if (iDepth < 0) return; 1486 std::string sCurrentIndent = sIndent + " "; 1487 std::string sNextIndent = sCurrentIndent; 1488 if (sIndent.empty()) { 1489 char tcMessage[64]; 1490 if (iDepth > 0) sprintf(tcMessage, "' to depth %d:", iDepth); 1491 else strcpy(tcMessage, "':"); 1492 CGRuntime::traceLine("Tracing variable '" + getCompleteName() + tcMessage); 1493 if (_eValueNode == INDEX_VALUE_NODE) traceValue(iDepth, sNextIndent, "\t"); 1494 else traceValue(iDepth - 1, sNextIndent, "\t"); 1495 } else if (_pAttributes != NULL) { 1496 CGRuntime::traceLine(sNextIndent + "|--+"); 1497 sNextIndent += " "; 1498 } 1499 DtaScriptVariableList* pAttributes = _pAttributes; 1500 while (pAttributes != NULL) { 1501 DtaScriptVariable* pNode = pAttributes->getNode(); 1502 const char* tcValue = pNode->getValue(); 1503 std::string sAttribute = sNextIndent + pNode->_tcName; 1504 if (!pNode->traceValue(iDepth - 1, sNextIndent, sAttribute + " = ")) { 1505 CGRuntime::traceLine(sAttribute); 1506 } 1507 if (iDepth > 0) { 1508 pNode->traceObject(iDepth - 1, sNextIndent); 1509 } else { 1510 NodeArrayType* pANT = pNode->_pArray; 1511 if ((pANT != NULL) && !pANT->items.empty()) { 1512 CGRuntime::traceText(sCurrentIndent + std::string(pNode->_tcName) + "["); 1513 for (std::list<DtaScriptVariable*>::iterator j = pANT->items.begin(); j != pANT->items.end(); j++) { 1514 if (j != pANT->items.begin()) CGRuntime::traceText(", "); 1515 CGRuntime::traceText("\"" + std::string((*j)->_tcName) + "\""); 1516 } 1517 CGRuntime::traceLine("]"); 1518 } 1519 } 1520 pAttributes = pAttributes->getNext(); 1521 } 1522 if ((_pArray != NULL) && !_pArray->items.empty()) { 1523 if (iDepth <= 0) { 1524 CGRuntime::traceText(sCurrentIndent + "["); 1525 for (std::list<DtaScriptVariable*>::iterator k = _pArray->items.begin(); k != _pArray->items.end(); k++) { 1526 if (k != _pArray->items.begin()) CGRuntime::traceText(", "); 1527 CGRuntime::traceText("\"" + std::string((*k)->_tcName) + "\""); 1528 const char* tcValue = (*k)->getValue(); 1529 if ((tcValue != NULL) && (*tcValue != '\0')) CGRuntime::traceText(" -> \"" + std::string(tcValue) + "\""); 1530 } 1531 CGRuntime::traceLine("]"); 1532 } else { 1533 for (std::list<DtaScriptVariable*>::iterator k = _pArray->items.begin(); k != _pArray->items.end(); k++) { 1534 CGRuntime::traceText(sCurrentIndent + "[\"" + std::string((*k)->_tcName) + "\"]"); 1535 if (!(*k)->traceValue(iDepth - 1, sCurrentIndent, " = ")) CGRuntime::traceLine(""); 1536 (*k)->traceObject(iDepth - 1, sCurrentIndent); 1537 } 1538 } 1539 } 1540 if (sIndent.empty()) { 1541 CGRuntime::traceLine("End of variable's trace '" + getCompleteName() + "'."); 1542 } 1543 } 1544 traceStack()1545 void DtaScriptVariable::traceStack() { 1546 if (strcmp(_tcName, "project") == 0) return; 1547 if (_pParent != 0) _pParent->traceStack(); 1548 CGRuntime::traceLine(std::string(_tcName) + ":"); 1549 DtaScriptVariableList* pAttributes = _pAttributes; 1550 while (pAttributes != NULL) { 1551 DtaScriptVariable* pNode = pAttributes->getNode(); 1552 if (pNode->getReferencedVariable() != NULL) { 1553 std::string sReference = pNode->getReferencedVariable()->getCompleteName(); 1554 CGRuntime::traceLine(std::string(pNode->_tcName) + " = " + sReference); 1555 } else { 1556 const char* tcValue = pNode->getValue(); 1557 if (tcValue != NULL) { 1558 CGRuntime::traceLine(std::string(pNode->_tcName) + " = \"" + std::string(tcValue) + "\""); 1559 } else { 1560 CGRuntime::traceLine(pNode->_tcName); 1561 } 1562 } 1563 NodeArrayType* pANT = pNode->_pArray; 1564 if ((pANT != NULL) && !pANT->items.empty()) { 1565 CGRuntime::traceText("\t" + std::string(pNode->_tcName) + "["); 1566 for (std::list<DtaScriptVariable*>::iterator j = pANT->items.begin(); j != pANT->items.end(); j++) { 1567 if (j != pANT->items.begin()) CGRuntime::traceText(", "); 1568 CGRuntime::traceText("\"" + std::string((*j)->_tcName) + "\""); 1569 } 1570 CGRuntime::traceLine("]"); 1571 } 1572 pAttributes = pAttributes->getNext(); 1573 } 1574 if ((_pArray != NULL) && !_pArray->items.empty()) { 1575 CGRuntime::traceText("\t" + std::string(_tcName) + "["); 1576 for (std::list<DtaScriptVariable*>::iterator k = _pArray->items.begin(); k != _pArray->items.end(); k++) { 1577 if (k != _pArray->items.begin()) CGRuntime::traceText(", "); 1578 CGRuntime::traceText("\"" + std::string((*k)->_tcName) + "\""); 1579 } 1580 CGRuntime::traceLine("]"); 1581 } 1582 } 1583 } 1584