public void CommandLineArgs() { String[] args= { "-SingleHyphen=12", "--DoubleHyphen=yes", "--Empty", "--Whitespaces = Hello Test ", "--integer = 42", "--double = 3.14", "-Home=overwritten", "--ALIB_TEST=passed", }; Configuration cfg= new Configuration(); cfg.SetCommandLineArgs( args ); Variable var= new Variable(); UT_EQ( Configuration.PrioCmdLine, cfg.Load ( var.Define( "", "SingleHyphen" )) ); UT_EQ( "12", var.GetString() ); cfg.Load ( var.Define( "", "DoubleHyphen" )); UT_EQ( true, var.IsTrue() ); UT_EQ( Configuration.PrioCmdLine, var.Priority); UT_EQ( Configuration.PrioCmdLine, cfg.Load ( var.Define( "", "Empty" )) ); UT_EQ( "", var.GetString() ); UT_EQ( Configuration.PrioCmdLine, cfg.Load ( var.Define( "", "Whitespaces" )) ); UT_EQ( "Hello Test", var.GetString() ); UT_EQ( Configuration.PrioCmdLine, cfg.Load ( var.Define( "", "HOME" )) ); UT_EQ( "overwritten", var.GetString() ); UT_EQ( Configuration.PrioCmdLine, cfg.Load ( var.Define( "", "integer" )) ); UT_EQ( 42, var.GetInteger() ); UT_EQ( 0, cfg.Load ( var.Define( "", "notexistent" )) ); UT_EQ( 0, var.GetInteger() ); UT_EQ( Configuration.PrioCmdLine, cfg.Load ( var.Define( "", "integer" )) ); UT_EQ( 42, var.GetInteger() ); UT_EQ( Configuration.PrioCmdLine, cfg.Load ( var.Define( "", "double" )) ); UT_EQ( 3.14, var.GetFloat() ); UT_EQ( 0, cfg.Load ( var.Define( "", "notexistent" )) ); UT_EQ( 0.0, var.GetFloat() ); UT_EQ( Configuration.PrioCmdLine, cfg.Load ( var.Define( "", "double" )) ); UT_EQ( 3.14, var.GetFloat() ); UT_EQ( Configuration.PrioCmdLine, cfg.Load ( var.Define( "ALIB", "test" )) ); UT_EQ( "passed", var.GetString() ); }
/** * Simple constructor copying values * @param categoryFallback Value for field #CategoryFallback (treated as reference, value not copied) * @param category Value for field #Category * @param name Value for field #Name * @param defaultValue Value for field #DefaultValue * @param delim Value for field #Delim * @param formatAttrAlignment Value for field #FormatAttrAlignment * @param formatHints Value for field #FormatHints * @param comments Value for field #Comments */ public VariableDefinition( AString categoryFallback, String category, String name, String defaultValue, char delim, String formatAttrAlignment, Variable.FormatHint formatHints, String comments ) { this.CategoryFallback= categoryFallback; this.Category= category; this.Name= name; this.DefaultValue= defaultValue; this.Delim= delim; this.FormatAttrAlignment= formatAttrAlignment; this.FormatHints= formatHints; this.Comments= comments; }
/** * Virtual method that copies the values of an entry to the given \p variable. * * @param parent The plug-in we belong to. * @param variable The variable to fill with our values. */ public virtual void ToVariable( InMemoryPlugin parent, Variable variable ) { ALIB.ASSERT( Delim != '\0' || Values.Count <= 1); if ( Delim != '\0' ) variable.Delim= Delim; if ( FormatHints != 0 ) variable.FormatHints= FormatHints; if ( FormatAttrAlignment != null ) variable.FormatAttrAlignment= FormatAttrAlignment; variable.Comments._()._( Comments ); foreach( AString val in Values ) variable.AddString( val ); }
/** ******************************************************************************************** * Creates a ConsoleLogger. * @param name (Optional) The name of the \e Logger, defaults to "COLOR_CONSOLE" **********************************************************************************************/ public ColorConsoleLogger( String name= null ) : base( name, "COLOR_CONSOLE", true ) { // get actual console foreground color ConsoleColor fgCol= Console.ForegroundColor; // evaluate environment variable "ALOX_CONSOLE_HAS_LIGHT_BACKGROUND" Variable variable= new Variable( ALox.CONSOLE_HAS_LIGHT_BACKGROUND ); variable.Load(); if ( variable.Size() > 0 ) IsBackgroundLight= variable.IsTrue(); else { IsBackgroundLight= fgCol == ConsoleColor.Black || fgCol == ConsoleColor.DarkBlue || fgCol == ConsoleColor.DarkCyan || fgCol == ConsoleColor.DarkGray || fgCol == ConsoleColor.DarkGreen || fgCol == ConsoleColor.DarkMagenta || fgCol == ConsoleColor.DarkRed || fgCol == ConsoleColor.DarkYellow ; } // remove verbosity information and colorize the whole line MetaInfo.Format.SearchAndReplace( " %V ", " " ); MsgColorInfo = fgCol; if ( IsBackgroundLight ) { MsgColorError = ConsoleColor.DarkRed; MsgColorWarning = ConsoleColor.DarkBlue; MsgColorVerbose = ConsoleColor.DarkGray; } else { MsgColorError = ConsoleColor.Red; MsgColorWarning = ConsoleColor.Blue; MsgColorVerbose = ConsoleColor.Gray; } }
// ############################################################################################# // Constructor // ############################################################################################# /** **************************************************************************************** * Creates an AnsiLogger. * @param textWriter The TextWriter object to write into. * @param usesStdStreams Denotes whether this logger writes to the * <em>standard output streams</em>. * @param name The name of the \e Logger, defaults to what is provided with * parameter \p typeName. * @param typeName The type of the \e Logger, defaults to "ANSI". ******************************************************************************************/ public AnsiLogger( System.IO.TextWriter textWriter, bool usesStdStreams, String name= null, String typeName= "ANSI" ) : base( name, typeName, usesStdStreams ) { this.textWriter= textWriter; // evaluate environment variable "ALOX_CONSOLE_HAS_LIGHT_BACKGROUND" Variable variable= new Variable( ALox.CONSOLE_HAS_LIGHT_BACKGROUND ); variable.Load(); if ( variable.Size() > 0 ) IsBackgroundLight= variable.IsTrue(); else { // on ANSI terminals we can only guess. Our guess is: console windows have dark background IsBackgroundLight= false; } // remove verbosity information and colorize the whole line MetaInfo.Format.SearchAndReplace( "]%V[", "][" ); if ( IsBackgroundLight ) { MsgPrefixError = ANSI_RED; MsgPrefixWarning = ANSI_BLUE; MsgPrefixVerbose = ANSI_GRAY; } else { MsgPrefixError = ANSI_LIGHT_RED; MsgPrefixWarning = ANSI_LIGHT_BLUE; MsgPrefixVerbose = ANSI_LIGHT_GRAY; } // set source file background to gray AString ansiBGGray= new AString( ESC.BG_GRAY ); ansiBGGray._( "%SF(%SL):" )._( ANSI_BG_STD_COL ); MetaInfo.Format.SearchAndReplace( "%SF(%SL):", ansiBGGray.ToString() ); }
// ############################################################################################# // ConfigurationPlugin interface implementation // ############################################################################################# /** **************************************************************************************** * Searches the variable in our storage. * * @param variable The variable to retrieve. * @param searchOnly If \c true, the variable is not read. Defaults to \c false. * @return \c true if variable was found, \c false if not. ******************************************************************************************/ public override bool Load( Variable variable, bool searchOnly= false ) { ALIB.ASSERT_WARNING( variable.Name.IsNotEmpty(), "Empty name given" ); Section section; Entry entry= null; if ( (section= SearchSection ( variable.Category ) ) != null && (entry= section.GetEntry ( variable.Name, false ) ) != null && !searchOnly ) { entry.ToVariable( this, variable ); } return entry != null; }
/** * Overrides default method. Clears the raw value, and calls base method. * * @param parent The plug-in we belong to. * @param variable The variable to fill with our values. */ public override void FromVariable( InMemoryPlugin parent, Variable variable ) { RawValue._(); base.FromVariable( parent, variable ); }
// ############################################################################################# // static entrance (Main) // ############################################################################################# //! [DOXYGEN_CREATE_INIFILE] static void Main( string[] args ) { // first attach INI file to config system... IniFile iniFile= new IniFile(); ALIB.Config.InsertPlugin( iniFile, Configuration.PrioIniFile ); // .. then initialize ALox Logging Library ALox.Init( args ); //... //! [DOXYGEN_CREATE_INIFILE] if ( iniFile.FileComments.IsEmpty() ) { iniFile.FileComments._( "##################################################################################################\n" + "# ALox Samples INI file (created when running ALox Samples)\n" + "#\n" + "# (c) 2013-2016 A-Worx GmbH, Germany\n" + "# Published under MIT License (Open Source License, see LICENSE.txt)\n" + "##################################################################################################\n" ); } // Suppress setting "writeback" as default verbosities. We need to do this as this main() // method invokes a list of independent samples. Those would now read from the INI file wrong // values written in other sample methods and thus the samples would not work any more // (because INI file settings overrules settings in the code) Variable var= new Variable(); var.Define( "ALOX", "LOG_DEBUG_LOGGER_VERBOSITY" ).Store( "" ); var.Define( "ALOX", "RELEASELOX_CONSOLE_VERBOSITY").Store( "" ); var.Define( "ALOX", "LOG_MEMORY_VERBOSITY" ).Store( "" ); var.Define( "ALOX", "RELEASELOX_MEMORY_VERBOSITY" ).Store( "" ); var.Define( "ALOX", "LOG_TEXTFILE_VERBOSITY" ).Store( "" ); // do some release logging tests. Console.WriteLine( "PRINT: Debug logging:" ); AloxSamples.DebugLogging(); ALoxSampleReset(); // do some release logging tests. Console.WriteLine( "PRINT: Release logging:" ); AloxSamples.ReleaseLogging(); ALoxSampleReset(); // do some performance tests. Console.WriteLine( "PRINT: Performance test (debug logging):" ); AloxSamples.PerformanceTest(); ALoxSampleReset(); // do some performance tests. Console.WriteLine( "PRINT: Performance test (release logging):" ); AloxSamples.PerformanceTestRL(); ALoxSampleReset(); // test class TextFileLogger Console.WriteLine( "PRINT: test class TextFileLogger:" ); AloxSamples.TextFileLogger(); ALoxSampleReset(); // test class terminal test (colors and styles) Console.WriteLine( "PRINT: Colors (depending on detected terminal):" ); AloxSamples.ColorTest(); ALoxSampleReset(); Console.WriteLine( "PRINT: Thats it!" ); // sample ALib report facility through ALox AloxSamples.SampleALibReport(); //! [DOXYGEN_REMOVE_INIFILE] //... ALIB.Config.RemovePlugin( iniFile ); ALIB.Config.FetchFromDefault( iniFile ); iniFile.WriteFile(); ALIB.TerminationCleanUp(); }
// ############################################################################################# // public interface // ############################################################################################# /** **************************************************************************************** * Constructs a scope info. * @param name The name of the Lox we belong to. * Will be converted to upper case. * @param threadDictionary A dictionary to map thread IDs to user friendly names which is * managed outside of this class. ******************************************************************************************/ public ScopeInfo( String name, Dictionary<int, String> threadDictionary ) { loxName= name.ToUpper(); ALIB.ASSERT_ERROR( !loxName.Equals( "GLOBAL" ), "Name \"GLOBAL\" not allowed for Lox instances" ); this.threadDictionary= threadDictionary; cache= new SourceFile[cacheSize= DefaultCacheSize]; for ( int i= 0; i< cacheSize; i++ ) cache[i]= new SourceFile(); actual= cache[0]; // read trim rules from config // do 2 times, 0== local list, 1== global list List<SourcePathTrimRule> trimInfoList; for( int trimInfoNo= 0; trimInfoNo < 2 ; trimInfoNo++ ) { // check if done... or set list Variable variable= new Variable(); if ( trimInfoNo == 0 ) { trimInfoList= LocalSPTRs; variable.Define(ALox.SPTR_LOX, loxName).Load(); } else { if ( GlobalSPTRsReadFromConfig ) continue; GlobalSPTRsReadFromConfig= true; trimInfoList= GlobalSPTRs; variable.Define(ALox.SPTR_GLOBAL).Load(); } if( variable.Priority != 0 ) { Tokenizer ruleTok = new Tokenizer(); for( int ruleNo= 0; ruleNo< variable.Size(); ruleNo++ ) { try { ruleTok.Set( variable.GetString( ruleNo ), ',' ); SourcePathTrimRule rule= new SourcePathTrimRule(); rule.Priority= variable.Priority; rule.Path= new AString(); ruleTok.Next(); if( ! ( rule.IsPrefix= !ruleTok.Actual.StartsWith( "*" ) ) ) ruleTok.Actual.Consume(1); rule.Path._( ruleTok.Actual ); if ( rule.Path.CharAtEnd() == '*' ) rule.Path.DeleteEnd( 1 ); if ( rule.Path.IsEmpty() ) continue; if( Path.DirectorySeparatorChar == '/' ) rule.Path.SearchAndReplaceAll( "\\", "/" ); else rule.Path.SearchAndReplaceAll( "/" , "\\" ); rule.IncludeString = ALIB.ReadInclusion( ruleTok.Next() ); if ( ruleTok.HasNext () ) ruleTok.Next().ConsumeInteger( out rule.TrimOffset ); rule.Sensitivity = ALIB.ReadCase( ruleTok.Next() ); if ( ruleTok.HasNext () ) rule.TrimReplacement= ruleTok.Next().ToString(); trimInfoList.Add( rule ); } catch( Exception ) { ALIB.ERROR( "Error reading source path trim rule from configuration. Invalid String: " + variable.GetString( ruleNo ).ToString() ); } } } } }
/** **************************************************************************************** * Writes a variable to the configuration. * This default implementation just returns \c false. If this method is not overwritten * in descendants, those descendants are not designed to write data. * * @param variable The variable to store. * @return \c true if the variable was written, \c false if not which typically indicates * that this plug-in is not able to write values. ******************************************************************************************/ public virtual bool Store( Variable variable ) { return false; }
// ############################################################################################# // abstract/virtual interface // ############################################################################################# /** **************************************************************************************** * Abstract method that has to be overwritten by descendants. * Searches and by default retrieves the value of a configuration variable. * If \p searchOnly is \c true, then the variable value is not read. * * @param variable The variable to retrieve. * @param searchOnly If \c true, the variable must not be read. Defaults to \c false. * @return \c true if variable was found within this configuration source, \c false if not. ******************************************************************************************/ public abstract bool Load( Variable variable, bool searchOnly= false );
// ############################################################################################# // 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; }
public int Store( Variable variable, Object externalizedValue= null ) { // checks if( externalizedValue == null || ( externalizedValue is AString && ((AString) 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( "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; foreach ( PluginAndPrio ppp in plugins ) if ( ppp.plugin.Load( variable, true ) ) { variable.Priority= ppp.prio; 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 foreach ( PluginAndPrio ppp in plugins ) if ( ppp.prio <= variable.Priority && ppp.plugin.Store( variable, externalizedValue ) ) { return (variable.Priority= ppp.prio); } return (variable.Priority= 0); }
public int Load( Variable variable ) { variable.Config= this; variable.Priority= loadImpl( variable, true ); if ( variable.Priority == 0 && variable.DefaultValue.IsNotNull() ) Store( variable, variable.DefaultValue ); return variable.Priority; }
public int FetchFromDefault( ConfigurationPlugin dest) { int cntCopied= 0; Variable variable= new Variable(); for( int sNo= 0; sNo < DefaultValues.Sections.Count ; sNo++ ) { InMemoryPlugin.Section section= DefaultValues.Sections[sNo]; for( int vNo= 0; vNo < section.Entries.Count ; vNo++ ) { InMemoryPlugin.Entry entry= section.Entries[vNo]; if( !dest.Load( variable.Define(section.Name, entry.Name ), true ) ) { DefaultValues.Load ( variable ); dest.Store( variable ); cntCopied++; } } } return cntCopied; }
/** **************************************************************************************** * This method must be called prior to using ALib, e.g. at the beginning of * the \c main() method of an application. It is OK, to call this method more than once, which * allows independent code blocks (e.g. libraries) to bootstrap %ALIB independently. * However, only the first invocation is effective with the exclamation that if * command line parameters are provided with a call, those are set. * Also, the very first invocation should not be interrupted by a parallel invocation of a * second thread. Consequently, it has to be assured that this method is invoked once on * the real bootstrap an app. * * In the C# version of the AWorx library, the invocation of this method is optional. * However, it is good practice to invoke this method in the main() method of a process * and provide the command line arguments. If no invocation is performed, no * configuration plug-ins are set. * * \note * If other, custom configuration data sources should be used already with this method * (in the current implementation, the only configuration variable read with this method * is \c WAIT_FOR_KEY_PRESS), then such plug-in(s) have to be added to * public, static field #Config prior to invoking this method. * * @param args Parameters taken from <em>standard C#</em> method \c main() * (the list of command line arguments). * Defaults to null. ******************************************************************************************/ public static void Init( String[] args= null ) { Config.SetCommandLineArgs( args ); if ( isInitialized ) return; isInitialized= true; // set the system's locale as the default for our static default number format NumberFormat.Global.SetFromLocale(); // --- determine if we want to wait for a keypress upon termination --- { Variable variable= new Variable( ALIB.WAIT_FOR_KEY_PRESS ); variable.Load(); if ( variable.Size() > 0 ) WaitForKeyPressOnTermination= variable.IsTrue(); else { #if ALIB_VSTUDIO WaitForKeyPressOnTermination= ALIB.SysInfo_HasConsoleWindow && System.Diagnostics.Debugger.IsAttached; #else WaitForKeyPressOnTermination= false; #endif // WIN32 } } }
/** **************************************************************************************** * Replaces the value at \p idx with the values of the given other variable. * * @param idx The index of the value to replace. * @param replVariable The variable providing the replacement values. ******************************************************************************************/ public void ReplaceValue( int idx, Variable replVariable ) { if( idx < 0 || idx >= qtyValues ) { ALIB.WARNING( "Index out of range: " + idx + " ( 0 - " + qtyValues + " allowed)." ); return; } int replSize= replVariable.Size(); if( replSize == 0 ) { values.RemoveAt( idx ); return; } values[ idx ]._()._( replVariable.GetString(0) ); for( int i= 1 ; i < replSize; i++ ) { values.Insert( idx + i, new AString( replVariable.GetString(i) ) ); qtyValues++; } }
/** **************************************************************************************** * Convenience method that parses the values from the given string using field * #StringConverter and then invokes \ref Store(Variable) "Store". * * @param variable The variable to store. * @param externalizedValue The value to parse into the variable before storing * * @return \c true if the variable was written, \c false if not which typically indicates * that this plug-in is not able to write values. ******************************************************************************************/ public virtual bool Store( Variable variable, Object externalizedValue ) { if( externalizedValue != null && ( !(externalizedValue is AString) || ((AString) externalizedValue).IsNotNull() ) ) { StringConverter.LoadFromString( variable, externalizedValue ); } return Store( variable ); }
public static void AddDebugLogger( Lox lox= null, [CallerLineNumber] int cln= 0,[CallerFilePath] String csf="",[CallerMemberName] String cmn="" ) { #if ALOX_DBG_LOG if ( lox == null ) lox= LOX; ALIB.ASSERT_ERROR( DebugLogger == null, "Illeagal repeated invocation." ); // add a CLR logger if this a debug session if( System.Diagnostics.Debugger.IsAttached ) { Variable variable= new Variable(ALox.NO_IDE_LOGGER); variable.Load(); if( !variable.IsTrue() ) { IDELogger= new CLRDebuggerLogger( "IDE_LOGGER" ); // add logger lox.SetVerbosity( IDELogger , Verbosity.Verbose, "/" , Configuration.PrioDefault ,cln,csf,cmn ); lox.SetVerbosity( IDELogger , Verbosity.Warning, ALox.InternalDomains, Configuration.PrioDefault ,cln,csf,cmn ); } } // add a default console logger DebugLogger= Lox.CreateConsoleLogger("DEBUG_LOGGER"); lox.SetVerbosity( DebugLogger, Verbosity.Verbose, "/" , Configuration.PrioDefault ,cln,csf,cmn ); lox.SetVerbosity( DebugLogger, Verbosity.Warning, ALox.InternalDomains, Configuration.PrioDefault ,cln,csf,cmn ); // replace the ReportWriter Log.AddALibReportWriter( lox ); #endif }
bool Load( Variable variable, bool searchOnly= false ) { if ( args == null ) return false; int optionLength= variable.Fullname.Length(); Substring actVar= new Substring(); for ( int i= 0; i < args.Length ; i++ ) { // remove whitespaces (if somebody would work with quotation marks...) // and request '-' and allow a second '-' if ( !actVar.Set( args[i] ).Trim().Consume('-') ) continue; actVar.Consume( '-' ); if ( variable.Fullname.CompareTo( args[i], Case.Ignore, actVar.Start, optionLength, 0, optionLength ) == 0) { //again, lets trim before searching the = sign (really almost unnecessary) actVar.Start+= optionLength; if ( actVar.IsEmpty() ) { if ( !searchOnly ) variable.AddString(); return true; } if ( actVar.Consume( '=', Case.Sensitive, Whitespaces.Trim ) ) { if ( !searchOnly ) { actVar.Trim(); StringConverter.LoadFromString( variable, actVar ); } return true; } } } return false; }
/** * Overrides default method. If we have not parsed the INI file text value, yet, * we do this now. * * @param parent The plug-in we belong to. * @param variable The variable to fill with our values. */ public override void ToVariable( InMemoryPlugin parent, Variable variable ) { // if we are still raw, then parse the INI file content if ( Values.Count == 0 ) { ALIB.ASSERT( Delim == '\0' ); Delim= variable.Delim; variable.Comments._()._( Comments ); //----- remove INI-File specific from raw value ----- AString raw= new AString(); raw._( RawValue ); // remove '=' raw.TrimStart(); if ( raw.CharAtStart() != '=' ) { ALIB.WARNING( "No equal sign in variable \"" + variable.Fullname + "\" of INI file." ); } else raw.DeleteStart(1).TrimStart(); // remove "\\n" int startIdx= 0; while ( (startIdx= raw.IndexOf( '\n', startIdx )) >= 0 ) { // find \\n and trim around this location int delLen= 2; if ( raw.CharAt( --startIdx) == '\r' ) { delLen= 3; --startIdx; } ALIB.ASSERT( raw.CharAt(startIdx) == '\\' ); raw.Delete( startIdx, delLen ); startIdx= raw.TrimAt( startIdx ); // if now the next value is starting with a comment symbol, we remove to the next \n for(;;) { char c= raw.CharAt( startIdx ); if ( c != '#' && c != ';' && ( c != '/' || raw.CharAt( startIdx + 1 ) != '/' ) ) break; int idx= raw.IndexOf( '\n' ); if (idx < 0 ) idx= raw.Length(); raw.Delete( startIdx, idx - startIdx + 1 ); if( startIdx >= raw.Length() ) break; startIdx= raw.TrimAt( startIdx ); } } // now convert parent.StringConverter.LoadFromString( variable, raw ); // copy the parsed values back to our entry and store the delimiter for( int i= 0; i < variable.Size() ; i++ ) Values.Add( new AString( variable.GetString( i ) ) ); } // otherwise, use base method else base.ToVariable( parent, variable ); }
bool Load( Variable variable, bool searchOnly= false ) { tmpAS._()._( variable.Fullname ).ToUpper(); String env= System.Environment.GetEnvironmentVariable( tmpAS.ToString() ); if ( env == null ) return false; if ( !searchOnly ) StringConverter.LoadFromString( variable, env ); return true; }
// ############################################################################################# // ConfigurationPlugin interface implementation // ############################################################################################# /** **************************************************************************************** * Creates or replaces existing variable in our storage. If #AutoSave is set, the file * is written * * @param variable The variable to retrieve. * @return \c true if the variable was written, \c false if not. The latter might only * happen if the variable given was illegal, e.g. empty name. ******************************************************************************************/ public override bool Store( Variable variable ) { base.Store( variable ); if ( AutoSave ) WriteFile(); return true; }
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 ); } }
/** **************************************************************************************** * Creates or replaces existing variable in our storage. * * @param variable The variable to retrieve. * @return \c true if the variable was written, \c false if not. The latter might only * happen if the variable given was illegal, e.g. empty name. ******************************************************************************************/ public override bool Store( Variable variable ) { Section section= SearchOrCreateSection( variable.Category, null ); if ( variable.Size() > 0 ) { Entry entry= section.GetEntry( variable.Name, true ); entry.FromVariable( this, variable ); return true; } return section.DeleteEntry( variable.Name ); }
/** ******************************************************************************************** * Log_TextLogger_FormatConfig **********************************************************************************************/ void testFormatConfig( String testFormat, String expFmt, String expFmtError = null, String expFmtWarning = null, String expFmtInfo = null, String expFmtVerbose = null ) { Variable var= new Variable(); var.Define(ALox.ConfigCategoryName, "TESTML_FORMAT", ',').Store( testFormat ); Lox lox= new Lox("TEST"); MemoryLogger ml= new MemoryLogger("TESTML"); lox.SetVerbosity( ml, Verbosity.Info ); lox.RemoveLogger( ml ); ALox.Register( lox, ContainerOp.Remove ); UT_EQ( expFmt , ml.MetaInfo.Format ); if( expFmtError != null ) { UT_EQ( expFmtError , ml.MetaInfo.VerbosityError ); } if( expFmtWarning!= null ) { UT_EQ( expFmtWarning, ml.MetaInfo.VerbosityWarning ); } if( expFmtInfo != null ) { UT_EQ( expFmtInfo , ml.MetaInfo.VerbosityInfo ); } if( expFmtVerbose!= null ) { UT_EQ( expFmtVerbose, ml.MetaInfo.VerbosityVerbose ); } }
/** * Virtual method that copies the values of the given \p variable to us. * * @param parent The plug-in we belong to. * @param variable The variable to fill with our values. */ public virtual void FromVariable( InMemoryPlugin parent, Variable variable ) { // copy attributes Delim= variable.Delim; FormatHints= variable.FormatHints; FormatAttrAlignment= variable.FormatAttrAlignment; if ( Comments.IsEmpty() ) // do not overwrite comments Comments._( variable.Comments ); // adjust size of value array int varSize= variable.Size(); int valSize= Values.Count; while (valSize < varSize ) { Values.Add( new AString() ); valSize++; } while (valSize > varSize ) Values.RemoveAt( --valSize ); // copy for ( int i= 0; i< variable.Size(); i++ ) Values[i]._()._( variable.GetString(i) ); }
/** **************************************************************************************** * Constructs a variable using the definition of another variable. The values are not * copied. * * @param variable A variable to copy the definition (which is comprised with fields * #Category, #Name, #Fullname, #Delim, #Comments and #DefaultValue) from. ******************************************************************************************/ public Variable( Variable variable ) { Define( variable ); }
/** ******************************************************************************************** * Creates an AnsiConsoleLogger. * @param name (Optional) The name of the \e Logger, defaults to "ANSI_CONSOLE". **********************************************************************************************/ public AnsiConsoleLogger( String name= null ) : base( Console.Out, true, name, "ANSI_CONSOLE" ) { // evaluate environment variable "ALOX_CONSOLE_HAS_LIGHT_BACKGROUND" Variable variable= new Variable( ALox.CONSOLE_HAS_LIGHT_BACKGROUND ); variable.Load(); if ( variable.Size() > 0 ) IsBackgroundLight= variable.IsTrue(); else { ConsoleColor fgCol= Console.ForegroundColor; IsBackgroundLight= fgCol == ConsoleColor.Black || fgCol == ConsoleColor.DarkBlue || fgCol == ConsoleColor.DarkCyan || fgCol == ConsoleColor.DarkGray || fgCol == ConsoleColor.DarkGreen || fgCol == ConsoleColor.DarkMagenta || fgCol == ConsoleColor.DarkRed || fgCol == ConsoleColor.DarkYellow ; } }
/** **************************************************************************************** * Constructs a variable using the definition of another variable. The values are not * copied. * * @param variable A variable to copy the definition (which is comprised with fields * #Category, #Name, #Fullname, #Delim, #Comments and #DefaultValue) from. * @return \c this to allow concatenated operations. ******************************************************************************************/ public Variable Define ( Variable variable ) { clear(); Category._(variable.Category); Name ._(variable.Name); Fullname._(variable.Fullname); Comments._(variable.Comments); Delim= variable.Delim; return this; }