// check for identical dictionary content, regardless of the order bool checkDictionaryContent(const dictionary& dict1, const dictionary& dict2) { // trivial cases first if (&dict1 == &dict2) { return true; } else if (dict1.size() != dict2.size()) { return false; } forAllConstIter(dictionary, dict1, iter1) { const entry* entryPtr = dict2.lookupEntryPtr ( iter1().keyword(), false, false ); if (!entryPtr) { return false; } const entry& entry1 = iter1(); const entry& entry2 = *entryPtr; bool ok = false; if (entry1.isDict()) { if (entry2.isDict()) { ok = checkDictionaryContent(entry1.dict(), entry2.dict()); } } else { ok = (entry1 == entry2); } if (!ok) { return false; } } return true; }
Foam::coordinateSystem::coordinateSystem ( const dictionary& dict, const objectRegistry& obr ) : name_(type()), note_(), origin_(point::zero), R_(), Rtr_(sphericalTensor::I) { const entry* entryPtr = dict.lookupEntryPtr(typeName_(), false, false); // non-dictionary entry is a lookup into global coordinateSystems if (entryPtr && !entryPtr->isDict()) { keyType key(entryPtr->stream()); const coordinateSystems& lst = coordinateSystems::New(obr); const label index = lst.findIndex(key); if (debug) { Info<< "coordinateSystem::coordinateSystem" "(const dictionary&, const objectRegistry&):" << nl << "using global coordinate system: " << key << "=" << index << endl; } if (index < 0) { FatalErrorIn ( "coordinateSystem::coordinateSystem" "(const dictionary&, const objectRegistry&)" ) << "could not find coordinate system: " << key << nl << "available coordinate systems: " << lst.toc() << nl << nl << exit(FatalError); } // copy coordinateSystem, but assign the name as the typeName // to avoid strange things in writeDict() operator=(lst[index]); name_ = typeName_(); } else { operator=(dict); } }
Foam::coordinateSystem::coordinateSystem ( const dictionary& dict, const objectRegistry& obr ) : name_(type()), note_(), origin_(point::zero), R_(), Rtr_(sphericalTensor::I) { const entry* entryPtr = dict.lookupEntryPtr(typeName_(), false, false); // a simple entry is a lookup into global coordinateSystems if (entryPtr && !entryPtr->isDict()) { word csName; entryPtr->stream() >> csName; const coordinateSystems& csLst = coordinateSystems::New(obr); label csId = csLst.find(csName); if (debug) { Info<< "coordinateSystem::coordinateSystem" "(const dictionary&, const objectRegistry&):" << nl << "using global coordinate system: " << csName << "=" << csId << endl; } if (csId < 0) { FatalErrorIn ( "coordinateSystem::coordinateSystem" "(const dictionary&, const objectRegistry&)" ) << "could not find coordinate system: " << csName << nl << "available coordinate systems: " << csLst.toc() << nl << nl << exit(FatalError); } // copy coordinateSystem, but assign the name as the typeName // to avoid strange things in writeDict() operator=(csLst[csId]); name_ = typeName_(); }
bool Foam::entry::New(dictionary& parentDict, Istream& is) { is.fatalCheck("entry::New(const dictionary& parentDict, Istream&)"); keyType keyword; // Get the next keyword and if invalid return false if (!getKeyword(keyword, is)) { return false; } else // Keyword starts entry ... { if ( !disableFunctionEntries && keyword[0] == '#' ) // ... Function entry { word functionName = keyword(1, keyword.size()-1); return functionEntry::execute(functionName, parentDict, is); } else if ( !disableFunctionEntries && keyword[0] == '$' ) // ... Substitution entry { token nextToken(is); is.putBack(nextToken); if (keyword.size() > 2 && keyword[1] == token::BEGIN_BLOCK) { // Recursive substitution mode. Replace between {} with // expansion and then let standard variable expansion deal // with rest. string s(keyword(2, keyword.size()-3)); // Substitute dictionary and environment variables. Do not allow // empty substitutions. stringOps::inplaceExpand(s, parentDict, true, false); keyword.std::string::replace(1, keyword.size()-1, s); } if (nextToken == token::BEGIN_BLOCK) { word varName = keyword(1, keyword.size()-1); // lookup the variable name in the given dictionary const entry* ePtr = parentDict.lookupScopedEntryPtr ( varName, true, true ); if (ePtr) { // Read as primitiveEntry const keyType newKeyword(ePtr->stream()); return parentDict.add ( new dictionaryEntry(newKeyword, parentDict, is), false ); } else { FatalIOErrorInFunction(is) << "Attempt to use undefined variable " << varName << " as keyword" << exit(FatalIOError); return false; } } else { parentDict.substituteScopedKeyword(keyword); } return true; } else if ( !disableFunctionEntries && keyword == "include" ) // ... For backward compatibility { return functionEntries::includeEntry::execute(parentDict, is); } else // ... Data entries { token nextToken(is); is.putBack(nextToken); // Deal with duplicate entries bool mergeEntry = false; // See (using exact match) if entry already present entry* existingPtr = parentDict.lookupEntryPtr ( keyword, false, false ); if (existingPtr) { if (functionEntries::inputModeEntry::merge()) { mergeEntry = true; } else if (functionEntries::inputModeEntry::overwrite()) { // clear dictionary so merge acts like overwrite if (existingPtr->isDict()) { existingPtr->dict().clear(); } mergeEntry = true; } else if (functionEntries::inputModeEntry::protect()) { // read and discard the entry if (nextToken == token::BEGIN_BLOCK) { dictionaryEntry dummy(keyword, parentDict, is); } else { primitiveEntry dummy(keyword, parentDict, is); } return true; } else if (functionEntries::inputModeEntry::error()) { FatalIOErrorInFunction(is) << "ERROR! duplicate entry: " << keyword << exit(FatalIOError); return false; } } if (nextToken == token::BEGIN_BLOCK) { return parentDict.add ( new dictionaryEntry(keyword, parentDict, is), mergeEntry ); } else { return parentDict.add ( new primitiveEntry(keyword, parentDict, is), mergeEntry ); } } } }
Foam::dynamicCodeContext::dynamicCodeContext(const dictionary& dict) : dict_(dict), code_(), localCode_(), include_(), options_(), libs_() { // expand dictionary entries { const entry& codeEntry = dict.lookupEntry("code", false, false); code_ = stringOps::trim(codeEntry.stream()); stringOps::inplaceExpand(code_, dict); } // note: removes any leading/trailing whitespace // - necessary for compilation options, convenient for includes // and body. // optional const entry* includePtr = dict.lookupEntryPtr ( "codeInclude", false, false ); if (includePtr) { include_ = stringOps::trim(includePtr->stream()); stringOps::inplaceExpand(include_, dict); } // optional const entry* optionsPtr = dict.lookupEntryPtr ( "codeOptions", false, false ); if (optionsPtr) { options_ = stringOps::trim(optionsPtr->stream()); stringOps::inplaceExpand(options_, dict); } // optional const entry* libsPtr = dict.lookupEntryPtr("codeLibs", false, false); if (libsPtr) { libs_ = stringOps::trim(libsPtr->stream()); stringOps::inplaceExpand(libs_, dict); } // optional const entry* localPtr = dict.lookupEntryPtr("localCode", false, false); if (localPtr) { localCode_ = stringOps::trim(localPtr->stream()); stringOps::inplaceExpand(localCode_, dict); } // calculate SHA1 digest from include, options, localCode, code OSHA1stream os; os << include_ << options_ << libs_ << localCode_ << code_; sha1_ = os.digest(); // Add line number after calculating sha1 since includes processorDDD // in path which differs between processors. { const entry& codeEntry = dict.lookupEntry("code", false, false); addLineDirective(code_, codeEntry.startLineNumber(), dict.name()); } if (includePtr) { addLineDirective(include_, includePtr->startLineNumber(), dict.name()); } // Do not add line directive to options_ (Make/options) and libs since // they are preprocessed as a single line at this point. Can be fixed. if (localPtr) { addLineDirective(localCode_, localPtr->startLineNumber(), dict.name()); } }
bool Foam::entry::New(dictionary& parentDict, Istream& is) { is.fatalCheck("entry::New(const dictionary& parentDict, Istream&)"); keyType keyword; // Get the next keyword and if invalid return false if (!getKeyword(keyword, is)) { return false; } else // Keyword starts entry ... { if (keyword[0] == '#') // ... Function entry { word functionName = keyword(1, keyword.size()-1); return functionEntry::execute(functionName, parentDict, is); } else if (keyword[0] == '$') // ... Substitution entry { parentDict.substituteKeyword(keyword); return true; } else if (keyword == "include") // ... For backward compatibility { return functionEntries::includeEntry::execute(parentDict, is); } else // ... Data entries { token nextToken(is); is.putBack(nextToken); // Deal with duplicate entries bool mergeEntry = false; // See (using exact match) if entry already present entry* existingPtr = parentDict.lookupEntryPtr ( keyword, false, false ); if (existingPtr) { if (functionEntries::inputModeEntry::merge()) { mergeEntry = true; } else if (functionEntries::inputModeEntry::overwrite()) { // clear dictionary so merge acts like overwrite if (existingPtr->isDict()) { existingPtr->dict().clear(); } mergeEntry = true; } else if (functionEntries::inputModeEntry::protect()) { // read and discard the entry if (nextToken == token::BEGIN_BLOCK) { dictionaryEntry dummy(keyword, parentDict, is); } else { primitiveEntry dummy(keyword, parentDict, is); } return true; } else if (functionEntries::inputModeEntry::error()) { FatalIOErrorIn ( "entry::New(const dictionary& parentDict, Istream&)", is ) << "ERROR! duplicate entry: " << keyword << exit(FatalIOError); return false; } } if (nextToken == token::BEGIN_BLOCK) { return parentDict.add ( new dictionaryEntry(keyword, parentDict, is), mergeEntry ); } else { return parentDict.add ( new primitiveEntry(keyword, parentDict, is), mergeEntry ); } } } }