int Configuration::Store( Variable& variable, const String& externalizedValue ) { OWN(*this); // checks if( externalizedValue.IsNull() ) { if ( variable.Name.IsEmpty()) { ALIB_ERROR( "Trying to store an undefined variable." ); return 0; } if ( variable.Size() > 1 && variable.Delim == '\0' ) { ALIB_ERROR_S512( "Trying to store variable \"" << variable.Fullname << "\" which has multiple values set but no delimiter defined." ); return 0; } } // store us as config variable.Config= this; // detect? bool detected= variable.Priority < 0; if ( detected ) { variable.Priority= 0; for ( auto& ppp : plugins ) if ( ppp.second->Load( variable, true ) ) { variable.Priority= ppp.first; break; } } // new variables go to default if ( variable.Priority == 0 ) variable.Priority= Configuration::PrioDefault; // we do not store if detected priority is protected else if( detected && variable.Priority == Configuration::PrioProtected ) return (variable.Priority= 0); // store for ( auto& ppp : plugins ) if ( ppp.first <= variable.Priority && ppp.second->Store( variable, externalizedValue ) ) { return (variable.Priority= ppp.first); } return (variable.Priority= 0); }
int Configuration::loadImpl( Variable& variable, bool substitute ) { variable.ClearValues(); if ( variable.Name.IsEmpty() ) { ALIB_WARNING( "Empty variable name given" ); return 0; } // search variable int priority= 0; for ( auto& ppp : plugins ) if ( ppp.second->Load( variable ) ) { priority= ppp.first; break; } // not found? if ( !substitute || priority == 0 ) return 0; // substitution in all values of variable for ( int valueNo= 0; valueNo < variable.Size(); valueNo++ ) { int searchStartIdx= 0; int maxReplacements = 50; do { AString& value= *variable.GetString( valueNo ); // search start int repStart= value.IndexOf( SubstitutionVariableStart, searchStartIdx ); if ( repStart < 0 ) break; searchStartIdx= repStart; int varStart= repStart + SubstitutionVariableStart.Length(); Variable replVar; int repLen; int varLen; // search end in two different ways depending on setting of public field "SubstitutionVariableEnd" if ( SubstitutionVariableEnd.IsEmpty() ) { int idx= value.IndexOfAny( SubstitutionVariableDelimiters, Inclusion::Include, varStart ); if ( idx < 0 ) idx= value.Length(); varLen= idx - varStart; repLen= idx - repStart; } else { int idx= value.IndexOf ( SubstitutionVariableEnd, varStart ); if (idx < 0 ) { ALIB_WARNING_S512( "End of substitution variable not found (while start was found). Variable name: " << variable.Fullname << " Value: \"" << variable.GetString() << "\"." ); break; } varLen= idx - varStart; repLen= idx + SubstitutionVariableEnd.Length() - repStart; } // get variable name string Substring replVarCategory; Substring replVarName( value, varStart, varLen ); if ( replVarName.IsEmpty() ) { searchStartIdx+= SubstitutionVariableStart.Length() + SubstitutionVariableEnd.Length(); continue; } // parse category from name int catSeparatorIdx= replVarName.IndexOf( '_' ); if (catSeparatorIdx >= 0 ) { replVarCategory.Set( replVarName, 0 , catSeparatorIdx ); replVarName .Set( replVarName, catSeparatorIdx + 1); } // load replacement variable if ( replVarName.IsNotEmpty() ) { replVar.Define( replVarCategory, replVarName, variable.Delim ); loadImpl( replVar, false ); } else replVar.ClearValues(); // do the replacement (even if no variable was found) if ( replVar.Size() == 1 ) value.ReplaceSubstring( replVar.GetString(), repStart, repLen ); else if ( replVar.Size() > 1 ) { variable.ReplaceValue( valueNo, replVar ); // repeat replacements in current value, as current value changed valueNo--; break; } else value.ReplaceSubstring( "", repStart, repLen ); } while( --maxReplacements ); // warn if max replacements if( maxReplacements <= 0 ) ALIB_WARNING_S512( "Too many substitutions in variable " << variable.Fullname << ". Probably a recursive variable definition was made. "); } return priority; }