Foam::string Foam::functionEntries::negEntry::negateVariable ( const dictionary& parentDict, Istream& is ) { // Read variable name as a word including the '$' const word varWord(is); if (varWord[0] != '$') { FatalIOErrorInFunction ( parentDict ) << "Expected variable name beginning with a '$' but found '" << varWord << "'" << exit(FatalIOError); return string::null; } // Strip the leading '$' from the variable name const string varName = varWord(1, varWord.size()-1); // Lookup the variable name in the parent dictionary.... const entry* ePtr = parentDict.lookupScopedEntryPtr(varName, true, false); if (ePtr && ePtr->isStream()) { const token variable(ePtr->stream()); // Convert to a string OStringStream os(is.format()); os << variable; const string str(os.str()); // Negate if (str[0] == '-') { return str(1, str.size() - 1); } else { return '-' + str; } } else { FatalIOErrorInFunction ( parentDict ) << "Illegal dictionary variable name " << varName << endl << "Valid dictionary entries are " << parentDict.toc() << exit(FatalIOError); return string::null; } }
Foam::string Foam::stringOps::getVariable ( const word& name, const dictionary& dict, const bool allowEnvVars, const bool allowEmpty ) { string value; const entry* ePtr = dict.lookupScopedEntryPtr ( name, true, false ); if (ePtr) { OStringStream buf; // Force floating point numbers to be printed with at least // some decimal digits. buf << fixed; buf.precision(IOstream::defaultPrecision()); // fail for non-primitiveEntry dynamicCast<const primitiveEntry> ( *ePtr ).write(buf, true); value = buf.str(); } else if (allowEnvVars) { value = getEnv(name); if (value.empty()) { FatalIOErrorInFunction ( dict ) << "Cannot find dictionary or environment variable " << name << exit(FatalIOError); } } else { FatalIOErrorInFunction ( dict ) << "Cannot find dictionary variable " << name << exit(FatalIOError); } return value; }
Foam::token Foam::functionEntries::ifeqEntry::expand ( const dictionary& dict, const string& keyword, const token& t ) { if (keyword[0] == '$') { word varName = keyword(1, keyword.size()-1); // lookup the variable name in the given dictionary const entry* ePtr = dict.lookupScopedEntryPtr ( varName, true, true ); if (ePtr) { return token(ePtr->stream()); } else { // String expansion. Allow unset variables string expanded(keyword); stringOps::inplaceExpand(expanded, dict, true, true); // Re-form as a string token so we can compare to string return token(expanded, t.lineNumber()); } } else if (!t.isString()) { // Re-form as a string token so we can compare to string return token(keyword, t.lineNumber()); } else { return t; } }
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 ); } } } }
void setScoped ( dictionary& dict, const word& keyword, const bool overwrite, entry* d ) { if (keyword[0] == ':') { // Go up to top level and recurse to find entries setScoped ( const_cast<dictionary&>(dict.topDict()), keyword.substr(1, keyword.size()-1), overwrite, d ); return; } else { string::size_type dotPos = keyword.find('.'); if (dotPos == string::npos) { // Non-scoped lookup if (overwrite) { dict.set(d); } else { dict.add(d, false); } return; } else { if (dotPos == 0) { // Starting with a '.'. Go up for every 2nd '.' found const dictionary* dictPtr = &dict; string::size_type begVar = dotPos + 1; string::const_iterator iter = keyword.begin() + begVar; string::size_type endVar = begVar; while ( iter != keyword.end() && *iter == '.' ) { ++iter; ++endVar; // Go to parent if (&dictPtr->parent() == &dictionary::null) { FatalIOErrorInFunction(dict) << "No parent of current dictionary" << " when searching for " << keyword.substr ( begVar, keyword.size() - begVar ) << exit(FatalIOError); } dictPtr = &dictPtr->parent(); } setScoped ( const_cast<dictionary&>(*dictPtr), keyword.substr(endVar), overwrite, d ); return; } else { // Extract the first word word firstWord = keyword.substr(0, dotPos); const entry* entPtr = dict.lookupScopedEntryPtr ( firstWord, false, // Recursive false ); if (!entPtr || !entPtr->isDict()) { FatalIOErrorInFunction(dict) << "keyword " << firstWord << " is undefined in dictionary " << dict.name() << " or is not a dictionary" << endl << "Valid keywords are " << dict.keys() << exit(FatalIOError); } const dictionary& firstDict = entPtr->dict(); setScoped ( const_cast<dictionary&>(firstDict), keyword.substr(dotPos, keyword.size()-dotPos), overwrite, d ); return; } } } }