void LoadFromString( Variable variable, Object src ) { variable.ClearValues(); AString varValue= variable.AddString(); Substring subs= null; if( src is Substring) subs= (Substring) src; else if ( src is AString ) { subs= tmpSubs; subs.Set( (AString) src ); } else { tmpAS._()._( src ); tmpSubs.Set( tmpAS ); subs= tmpSubs; } // tokenize bool inQuote= false; bool lastWasSlash= false; int idx= 0; while( idx < subs.Length() ) { char c= subs.CharAt( idx++ ); if( lastWasSlash ) { lastWasSlash= false; continue; } if( c== '\\' ) { lastWasSlash= true; continue; } if( c== '"' ) { inQuote= !inQuote; continue; } if( !inQuote && c == variable.Delim ) { tmpSubs2.Set( subs, 0, idx - 1 ); InternalizeValue( tmpSubs2, varValue ); varValue= variable.AddString(); subs.Consume( idx ); subs.TrimStart(); idx= 0; } } if ( subs.IsNotEmpty() ) { InternalizeValue( subs, varValue ); } }
public void ConfigDefaultAndProtected() { UT_INIT(); String[] args= { "COMMANDLINE", "--TEST_VARIABLE=fromCommandLine", }; Configuration cfg= new Configuration(); cfg.SetCommandLineArgs( args ); Variable var= new Variable(); // command line UT_EQ( Configuration.PrioCmdLine, cfg.Load ( var.Define( "TEST", "VARIABLE" ) ) ); UT_EQ( "fromCommandLine" ,var.GetString() ); // set default, does not overwrite cfg.DefaultValues.Store( var.Define("TEST", "VARIABLE"), "not overwriting" ); UT_EQ( Configuration.PrioCmdLine, cfg.Load ( var.Define( "TEST", "VARIABLE" ) ) ); UT_EQ( "fromCommandLine" ,var.GetString() ); // set protected, overwrites command line cfg.ProtectedValues.Store( var.Define("TEST", "VARIABLE"), "does overwrite" ); UT_EQ( Configuration.PrioProtected, cfg.Load ( var.Define( "TEST", "VARIABLE" ) ) ); UT_EQ( "does overwrite" ,var.GetString() ); // set default, something else cfg.DefaultValues.Store( var.Define("TEST", "VAR2"), "this is var 2" ); UT_EQ( Configuration.PrioDefault, cfg.Load ( var.Define( "TEST", "VAR2" ) ) ); UT_EQ( "this is var 2" ,var.GetString() ); // set and remove an entry using plugin interface var.Define( "TEST", "Remove" ); UT_EQ( 0, var.Size() ); UT_EQ( -1 ,var.Priority ); cfg.DefaultValues.Load( var ); UT_EQ( 0, var.Size() ); UT_EQ( -1 ,var.Priority ); var.AddString("To be deleted"); UT_EQ( 1, var.Size() ); UT_EQ( -1 ,var.Priority ); cfg.DefaultValues.Store( var ); UT_EQ( 1, var.Size() ); UT_EQ( -1 ,var.Priority ); var.Define( "TEST", "Remove" ); UT_EQ( 0, var.Size() ); UT_EQ( -1 ,var.Priority ); cfg.DefaultValues.Load( var ); UT_EQ( 1, var.Size() ); UT_EQ( -1 ,var.Priority ); var.ClearValues(); UT_EQ( 0, var.Size() ); UT_EQ( -1 ,var.Priority ); cfg.DefaultValues.Store( var ); UT_EQ( 0, var.Size() ); UT_EQ( -1 ,var.Priority ); var.Define( "TEST", "Remove" ); UT_EQ( 0, var.Size() ); UT_EQ( -1 ,var.Priority ); cfg.DefaultValues.Load( var ); UT_EQ( 0, var.Size() ); UT_EQ( -1 ,var.Priority ); // set and remove an entry using configuration interface cfg .Load ( var ); UT_EQ( 0, var.Size() ); UT_EQ( 0 ,var.Priority ); cfg .Store( var ); UT_EQ( 0, var.Size() ); UT_EQ( 0 ,var.Priority ); var.AddString("To be deleted"); UT_EQ( 1, var.Size() ); UT_EQ( 0 ,var.Priority ); cfg .Store( var ); UT_EQ( 1, var.Size() ); UT_EQ( Configuration.PrioDefault ,var.Priority ); var.Define( "TEST", "Remove" ); UT_EQ( 0, var.Size() ); UT_EQ( -1 ,var.Priority ); cfg .Load ( var ); UT_EQ( 1, var.Size() ); UT_EQ( Configuration.PrioDefault ,var.Priority ); var.Define( "TEST", "Remove" ); UT_EQ( 0, var.Size() ); UT_EQ( -1 ,var.Priority ); cfg .Store( var ); UT_EQ( 0, var.Size() ); UT_EQ( Configuration.PrioDefault ,var.Priority ); cfg .Load ( var ); UT_EQ( 0, var.Size() ); UT_EQ( 0 ,var.Priority ); var.Define( "TEST", "Remove" ); UT_EQ( 0, var.Size() ); UT_EQ( -1 ,var.Priority ); cfg .Load ( var ); UT_EQ( 0, var.Size() ); UT_EQ( 0 ,var.Priority ); // protected var.Define( "TEST", "Protected"); UT_EQ( 0, var.Size() ); UT_EQ( -1 ,var.Priority ); var.DefaultValue._( "Default" ); var.StoreDefault( "def par"); UT_EQ( "def par", var.GetString() ); UT_EQ( Configuration.PrioDefault ,var.Priority ); var.ClearValues(); var.AddString( "def var" ); var.StoreDefault(); UT_EQ( "def var", var.GetString() ); UT_EQ( Configuration.PrioDefault ,var.Priority ); var.ClearValues(); var.StoreDefault(); UT_EQ( "Default", var.GetString() ); UT_EQ( Configuration.PrioDefault ,var.Priority ); var.ClearValues(); var.AddString( "def var" ); var.Protect(); UT_EQ( "def var", var.GetString() ); UT_EQ( Configuration.PrioProtected ,var.Priority ); var.Protect("prot par"); UT_EQ( "prot par", var.GetString() ); UT_EQ( Configuration.PrioProtected ,var.Priority ); var.ClearValues(); var.Protect(); UT_EQ( "Default", var.GetString() ); UT_EQ( Configuration.PrioProtected ,var.Priority ); var.DefaultValue.SetNull(); var.ClearValues(); var.Protect(); UT_EQ( 0, var.Size() ); UT_EQ( Configuration.PrioProtected ,var.Priority ); var.Load(); UT_EQ( "Default", var.GetString() ); UT_EQ( Configuration.PrioDefault ,var.Priority ); }
// ############################################################################################# // internal methods // ############################################################################################# /** **************************************************************************************** * Implementation of get method. No locking is performed (has to be done before * invoking this method) * * @param variable The variable to get. * @param substitute If \c false, automatic variable substitutions are suppressed. * * @return Zero if the variable was not found. Otherwise it returns the priority of the * (first) plug-in that contained the variable. ******************************************************************************************/ public int loadImpl( Variable variable, bool substitute ) { variable.ClearValues(); // search variable int priority= 0; foreach ( PluginAndPrio ppp in plugins ) if ( ppp.plugin.Load( variable ) ) { priority= ppp.prio; 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; Variable replVar= null; 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(); if( replVar == null ) replVar= new Variable(); 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( "End of substitution variable not found (while start was found). Variable name: " + variable.Fullname + " Value: \"" + value + "\"." ); break; } varLen= idx - varStart; repLen= idx + SubstitutionVariableEnd.Length() - repStart; } // get variable name string tmpReplVarCategory.Clear(); if ( tmpReplVarAll.Set( value, varStart, varLen ).IsEmpty() ) { searchStartIdx+= SubstitutionVariableStart.Length() + SubstitutionVariableEnd.Length(); continue; } // parse category from name int catSeparatorIdx= tmpReplVarAll.IndexOf( '_' ); if (catSeparatorIdx >= 0 ) { tmpReplVarCategory.Set( tmpReplVarAll, 0 , catSeparatorIdx ); tmpReplVarName .Set( tmpReplVarAll, catSeparatorIdx + 1 ); } else tmpReplVarName .Set( tmpReplVarAll ); if ( tmpReplVarName.IsNotEmpty() ) { replVar.Define( tmpReplVarCategory, tmpReplVarName, 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 > 0 ); // warn if max replacements if( maxReplacements <= 0 ) ALIB.WARNING( "Too many substitutions in variable " + variable.Fullname + ". Probably a recursive variable definition was made. "); } return priority; }
/** **************************************************************************************** * Implements functionality for configuration variable \c LOXNAME_LOGGERNAME_VERBOSITY. * Is called when a logger is removed. * @param logger The logger to write the verbosity for. ******************************************************************************************/ protected void writeVerbositiesOnLoggerRemoval( Logger logger ) { // When writing back we will use this priority as the maximum to write. This way, if this was // an automatic default value, we will not write back into the user's variable store. // As always, only if the app fetches new variables on termination, this is entry is copied. Variable variable= new Variable( ALox.VERBOSITY, GetName(), logger.GetName() ); variable.Load(); // first token is "writeback" ? if ( variable.Size() == 0 ) return; Substring firstArg= new Substring( variable.GetString() ); if ( !firstArg.Consume( "writeback", Case.Ignore, Whitespaces.Trim ) ) return; // optionally read a destination variable name Substring destVarCategory = new Substring(); Substring destVarName = new Substring(); if( firstArg.Trim().IsNotEmpty() ) { // separate category from variable name int catSeparatorIdx= firstArg.IndexOf( '_' ); if (catSeparatorIdx >= 0 ) { destVarCategory.Set( firstArg, 0 , catSeparatorIdx ); destVarName .Set( firstArg, catSeparatorIdx + 1); } else destVarName.Set( firstArg ); if ( destVarName.IsEmpty() ) { logInternal( Verbosity.Error, "VAR", intMsg._() ._( "Argument 'writeback' in variable " ) ._( variable.Fullname) ._( "\n Error: Wrong destination variable name format\"" ) ._( firstArg )._( "\"" ) ); return; } } // either write directly into LOX_LOGGER_VERBOSITY variable... Variable destVar= null; if( destVarName.IsEmpty() ) { variable.ClearValues( 1 ); destVar= variable; } // ...or into a new given variable else { destVar= new Variable( destVarCategory, destVarName, ALox.VERBOSITY.Delim ); destVar.FormatHints= variable.FormatHints; destVar.FormatAttrAlignment= variable.FormatAttrAlignment; destVar.Comments._("Created at runtime through config option 'writeback' in variable \"")._( variable.Fullname )._("\"."); } // collect verbosities { int loggerNoMainDom= domains .GetLoggerNo( logger ); int loggerNoIntDom= internalDomains.GetLoggerNo( logger ); if ( loggerNoMainDom >= 0 ) verbositySettingToVariable( domains , loggerNoMainDom, destVar ); if ( loggerNoIntDom >= 0 ) verbositySettingToVariable( internalDomains, loggerNoIntDom , destVar ); } // now store using the same plug-in as original variable has destVar.Priority= variable.Priority; destVar.Store(); // internal logging intMsg._()._( "Argument 'writeback' in variable " )._( variable.Fullname ) ._( ":\n Verbosities for logger \"" ) ._( logger.GetName() ) ._( "\" written " ); if( destVarName.IsEmpty() ) intMsg._( "(to source variable)." ); else intMsg._( "to variable \"" ) ._( destVar.Fullname ) ._("\".") ; logInternal( Verbosity.Info, "VAR", intMsg._( destVarName )._( "\"." ) ); // verbose logging of the value written intMsg._()._(" Value:"); for( int i= 0; i< destVar.Size() ; i++ ) intMsg._( "\n " )._( destVar.GetString(i) ); logInternal( Verbosity.Verbose, "VAR", intMsg ); }