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() ); }
// ############################################################################################# // 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() ); } } } } }
/** **************************************************************************************** * 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++; } }
// ############################################################################################# // 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; }
/** **************************************************************************************** * Invokes grand-parent's method and in addition, de-registers with * \ref cs::aworx::lib::ALIB::StdOutputStreamsLock "ALIB.StdOutputStreamsLock" * @param acquirer The acquirer to remove. * @return The new number of \e acquirers set. ******************************************************************************************/ public override int RemoveAcquirer( ThreadLock acquirer ) { // d-register with ALIB lockers (if not done yet) if ( usesStdStreams ) { ALIB.Lock.Acquire(); int stdStreamLockRegistrationCounter= --this.stdStreamLockRegistrationCounter; ALIB.Lock.Release(); if ( stdStreamLockRegistrationCounter == 0 ) ALIB.StdOutputStreamsLock.RemoveAcquirer( this ); } Variable variable= new Variable(); // export autosizes to configuration variable.Define( ALox.AUTO_SIZES, GetName() ); AutoSizes.Export( variable.AddString() ); variable.Store(); // export "max elapsed time" to configuration variable.Define( ALox.MAX_ELAPSED_TIME, GetName() ); AString destVal= variable.Load() != 0 ? variable.GetString() : variable.AddString(); destVal._()._( MetaInfo.MaxElapsedTime.InSeconds() ); variable.Store(); // call parents' implementation return base.RemoveAcquirer( acquirer ); }
// ############################################################################################# // Reimplementing interface of grand-parent class SmartLock // ############################################################################################# /** **************************************************************************************** * Invokes grand-parent's method and in addition, if field #usesStdStreams is set, * registers with * \ref cs::aworx::lib::ALIB::StdOutputStreamsLock "ALIB.StdOutputStreamsLock", respectively * * @param newAcquirer The acquirer to add. * @return The new number of \e acquirers set. ******************************************************************************************/ public override int AddAcquirer( ThreadLock newAcquirer ) { // register with ALIB lockers (if not done yet) if ( usesStdStreams ) { ALIB.Lock.Acquire(); int stdStreamLockRegistrationCounter= this.stdStreamLockRegistrationCounter++; ALIB.Lock.Release(); if ( stdStreamLockRegistrationCounter == 0 ) ALIB.StdOutputStreamsLock.AddAcquirer( this ); } Variable variable= new Variable(); // import autosizes from configuration (last session) if ( variable.Define( ALox.AUTO_SIZES, GetName()).Load() != 0 ) AutoSizes.Import( variable.GetString() ); // import "max elapsed time" from configuration (last session) if ( variable.Define( ALox.MAX_ELAPSED_TIME, GetName()).Load() != 0 ) { long maxInSecs= variable.GetInteger(); Substring attrValue= new Substring(); if ( variable.GetAttribute( "limit", attrValue ) ) { long maxMax; attrValue.ConsumeLong( out maxMax ); if ( maxInSecs > maxMax ) maxInSecs= maxMax; } MetaInfo.MaxElapsedTime.FromSeconds( maxInSecs ); } // Variable <name>_FORMAT / <typeName>_FORMAT: ALIB.ASSERT_WARNING( ALox.FORMAT.DefaultValue == null, "Default value of variable FORMAT should be kept null" ); if( 0 == variable.Define( ALox.FORMAT, GetName() ).Load() && 0 == variable.Define( ALox.FORMAT, GetTypeName() ).Load() ) { // no variable created, yet. Let's create a 'personal' one on our name variable.Define( ALox.FORMAT, GetName() ); variable.AddString( MetaInfo.Format ); variable.AddString( MetaInfo.VerbosityError ); variable.AddString( MetaInfo.VerbosityWarning ); variable.AddString( MetaInfo.VerbosityInfo ); variable.AddString( MetaInfo.VerbosityVerbose ); variable.Store(); } else { MetaInfo.Format ._()._( variable.GetString(0) ); if( variable.Size() >= 2 ) MetaInfo.VerbosityError = variable.GetString(1).ToString(); if( variable.Size() >= 3 ) MetaInfo.VerbosityWarning= variable.GetString(2).ToString(); if( variable.Size() >= 4 ) MetaInfo.VerbosityInfo = variable.GetString(3).ToString(); if( variable.Size() >= 5 ) MetaInfo.VerbosityVerbose= variable.GetString(4).ToString(); } // Variable <name>_FORMAT_DATE_TIME / <typeName>_FORMAT_DATE_TIME: ALIB.ASSERT_WARNING( ALox.FORMAT_DATE_TIME.DefaultValue == null, "Default value of variable FORMAT_DATE_TIME should be kept null" ); if( 0 == variable.Define( ALox.FORMAT_DATE_TIME, GetName() ).Load() && 0 == variable.Define( ALox.FORMAT_DATE_TIME, GetTypeName() ).Load() ) { // no variable created, yet. Let's create a 'personal' one on our name variable.Define( ALox.FORMAT_DATE_TIME, GetName() ); variable.AddString( MetaInfo.DateFormat ); variable.AddString( MetaInfo.TimeOfDayFormat ); variable.AddString( MetaInfo.TimeElapsedDays ); variable.Store(); } else { MetaInfo.DateFormat = variable.GetString(0).ToString(); if( variable.Size() >= 2 ) MetaInfo.TimeOfDayFormat = variable.GetString(1).ToString(); if( variable.Size() >= 3 ) MetaInfo.TimeElapsedDays = variable.GetString(2).ToString(); } // Variable <name>FORMAT_TIME_DIFF / <typeName>FORMAT_TIME_DIFF: ALIB.ASSERT_WARNING( ALox.FORMAT_TIME_DIFF.DefaultValue == null, "Default value of variable FORMAT_TIME_DIFF should be kept null" ); if( 0 == variable.Define( ALox.FORMAT_TIME_DIFF, GetName() ).Load() && 0 == variable.Define( ALox.FORMAT_TIME_DIFF, GetTypeName() ).Load() ) { // no variable created, yet. Let's create a 'personal' one on our name variable.Define( ALox.FORMAT_TIME_DIFF, GetName() ); variable.AddInteger ( MetaInfo.TimeDiffMinimum); variable.AddString( MetaInfo.TimeDiffNone ); variable.AddString( MetaInfo.TimeDiffNanos ); variable.AddString( MetaInfo.TimeDiffMicros ); variable.AddString( MetaInfo.TimeDiffMillis ); variable.AddString( MetaInfo.TimeDiffSecs ); variable.AddString( MetaInfo.TimeDiffMins ); variable.AddString( MetaInfo.TimeDiffHours ); variable.AddString( MetaInfo.TimeDiffDays ); variable.Store(); } else { MetaInfo.TimeDiffMinimum= variable.GetInteger (0); if( variable.Size() >= 2 ) MetaInfo.TimeDiffNone = variable.GetString(1).ToString(); if( variable.Size() >= 3 ) MetaInfo.TimeDiffNanos = variable.GetString(2).ToString(); if( variable.Size() >= 4 ) MetaInfo.TimeDiffMicros = variable.GetString(3).ToString(); if( variable.Size() >= 5 ) MetaInfo.TimeDiffMillis = variable.GetString(4).ToString(); if( variable.Size() >= 6 ) MetaInfo.TimeDiffSecs = variable.GetString(5).ToString(); if( variable.Size() >= 7 ) MetaInfo.TimeDiffMins = variable.GetString(6).ToString(); if( variable.Size() >= 8 ) MetaInfo.TimeDiffHours = variable.GetString(7).ToString(); if( variable.Size() >= 9 ) MetaInfo.TimeDiffDays = variable.GetString(8).ToString(); } // Variable <name>FORMAT_MULTILINE / <typeName>FORMAT_MULTILINE: ALIB.ASSERT_WARNING( ALox.FORMAT_MULTILINE.DefaultValue == null, "Default value of variable FORMAT_MULTILINE should be kept null" ); if( 0 == variable.Define( ALox.FORMAT_MULTILINE, GetName() ).Load() && 0 == variable.Define( ALox.FORMAT_MULTILINE, GetTypeName() ).Load() ) { // no variable created, yet. Let's create a 'personal' one on our name variable.Define( ALox.FORMAT_MULTILINE, GetName() ); variable.AddInteger( MultiLineMsgMode ); variable.AddString ( FmtMultiLineMsgHeadline ); variable.AddString ( FmtMultiLinePrefix ); variable.AddString ( FmtMultiLineSuffix ); variable.Store(); } else { MultiLineMsgMode= (int) variable.GetInteger(0) ; if( variable.Size() >= 2 ) FmtMultiLineMsgHeadline= variable.GetString(1).ToString(); if( variable.Size() >= 3 ) FmtMultiLinePrefix = variable.GetString(2).ToString(); if( variable.Size() >= 4 ) FmtMultiLineSuffix = variable.GetString(3).ToString(); if( variable.Size() >= 5 ) { if (variable.GetString(4).Equals( "nulled" , Case.Ignore ) ) MultiLineDelimiter= null; else MultiLineDelimiter= variable.GetString(4).ToString(); } if( variable.Size() >= 6 ) MultiLineDelimiterRepl = variable.GetString(5).ToString(); } // call parents' implementation return base.AddAcquirer( newAcquirer ); }
public void IniFileTest() { // write sample config file //UT_PRINT(""); UT_PRINT( "### Configuration with IniFile ###" ); String iniFileContents= "##########################################################################" +"\n" +"## unit test config file" +"\n" +"##########################################################################" +"\n" +"// this is also a comment" +"\n" +"; and this is as well" +"\n" +"" +"\n" +"HOME= overwritten_by_environment" +"\n" +"HOMEPATH= overwritten_by_environment" +"\n" +"" +"\n" +"concat= start =5, \\" +"\n" +" end =32, \\" +"\n" +" \\#no comment, \\" +"\n" +" \\;nocomment, \\" +"\n" +" ;a comment, \\" +"\n" +" getsLonger, \\" +"\n" +" getsLongerxxx, \\" +"\n" +" getsshorter, \\" +"\n" +" getsLongerxxxxx, \\" +"\n" +" getsLongerxxxxxxxxx, \\" +"\n" +" getsshorterxx, \\" +"\n" +" last" +"\n" +"" +"\n" +"" +"\n" +"CUBA=a country" +"\n" +"# The size " +"\n" +" SIZE= 25 " +"\n" +"" +"\n" +"# doble comment line" +"\n" +"# double, i meant" +"\n" +"2Comments= much talk" +"\n" +"" +"\n" +"# A great section" +"\n" +"[Great Section] " +"\n" +"SectionVar=5" +"\n" +"Double=12.3" +"\n" +"Tricky= backslash\\\\" +"\n" +"# A 2nd section" +"\n" +"[2nd Section] " +"\n" +"SectionVar=6" +"\n" +"" +"\n" +"" +"\n" +"[Great Section] " +"\n" +"SECTION_CONTINUED = yEs" +"\n" +"" +"\n" +"" +"\n" +"[ESC] " +"\n" +"Blanks= \" x \"" +"\n" +"Blanks2= \" x \" \\" +"\n" +" \" y \" " +"\n" +"Tabs=\t\t\\tx\\t" +"\n" +"nrslash= \"\\n\\r//\\\\\"" +"\n" ; String fileName= Environment.CurrentDirectory + "/unittest_testiniFile.cfg"; // write sample config file { StreamWriter file= new StreamWriter( fileName ); file.Write( iniFileContents ); file.Close(); } IniFile iniFile= new IniFile( fileName ); UT_TRUE( (IniFile.Status.OK == iniFile.LastStatus) ); // check some values Variable var= new Variable(); iniFile.Load( var.Define( "", "CUBA") ); UT_EQ( "a country", var.GetString() ); iniFile.Load( var.Define( "", "cUbA") ); UT_EQ( "a country", var.GetString() ); iniFile.Load( var.Define( "", "SIZE") ); UT_EQ( "25", var.GetString() ); iniFile.Load( var.Define( "", "concat", ',') ); UT_EQ( 11 , var.Size()); UT_EQ( "start =5" , var.GetString(0) ); UT_EQ( "end =32" , var.GetString(1) ); UT_EQ( "#no comment" , var.GetString(2) ); UT_EQ( ";nocomment" , var.GetString(3) ); iniFile.Load( var.Define( "ESC", "Blanks" ) ); UT_EQ( " x " , var.GetString() ); iniFile.Load( var.Define( "ESC", "Blanks2" ) ); UT_EQ( " x y " , var.GetString() ); iniFile.Load( var.Define( "ESC", "Tabs" ) ); UT_EQ( "\tx\t" , var.GetString() ); iniFile.Load( var.Define( "ESC", "nrslash" ) ); UT_EQ( "\n\r//\\" , var.GetString() ); iniFile.Load( var.Define( "Great Section", "SectionVar" ) ); UT_EQ( "5" , var.GetString() ); iniFile.Load( var.Define( "2nd Section", "SectionVar" ) ); UT_EQ( "6" , var.GetString() ); iniFile.Load( var.Define( "Great Section", "SECTION_CONTINUED") ); UT_EQ( "yEs", var.GetString() ); iniFile.Load( var.Define( "Great Section", "Tricky" ) ); UT_EQ( "backslash\\", var.GetString() ); // add it to ALIB config ALox.Init(); ALIB.Config.InsertPlugin( iniFile, Configuration.PrioIniFile ); ALIB.Config.Load( var.Define( "", "CUBA" ) ); UT_EQ( "a country" , var.GetString() ); ALIB.Config.Load( var.Define( "", "cUbA" ) ); UT_EQ( "a country" , var.GetString() ); ALIB.Config.Load( var.Define( "", "SIZE" ) ); UT_EQ( "25" , var.GetString() ); ALIB.Config.Load( var.Define( "", "concat" ) ); UT_EQ( 11 , var.Size()); UT_EQ( "start =5" , var.GetString(0) ); UT_EQ( "end =32" , var.GetString(1) ); ALIB.Config.Load( var.Define( "Great Section", "SectionVar" ) ); UT_EQ( "5" , var.GetString() ); ALIB.Config.Load( var.Define( "2nd Section", "SectionVar" ) ); UT_EQ( "6" , var.GetString() ); ALIB.Config.Load( var.Define( "Great Section", "SECTION_CONTINUED" ) ); UT_EQ( "yEs" , var.GetString() ); ALIB.Config.Load( var.Define( "Great Section", "Tricky" ) ); UT_EQ( "backslash\\", var.GetString() ); ALIB.Config.Load( var.Define( "Great Section", "SECTION_CONTINUED" ) ); UT_TRUE( var.IsTrue() ); // check if environment variable "home" overwrites INI file AString vIniFile= new AString(); iniFile.Load( var.Define( "", "hOme" ) ); UT_EQ( "overwritten_by_environment", var.GetString() ); int prio= ALIB.Config.Load( var.Define("", "hOme" )); if (prio != Configuration.PrioEnvironment ) // Windows platform? { prio= ALIB.Config.Load( var.Define("", "hOmePAth") ); iniFile.Load( var.Define( "", "hOmePAth") ); UT_EQ( "overwritten_by_environment", var.GetString() ); } UT_EQ( Configuration.PrioEnvironment, prio ); UT_TRUE( var.GetString().Length() > 0 ); UT_TRUE( !vIniFile.Equals( var.GetString()) ); // change a value and write a new one var.Define( "New Section", "newvar"); var.Priority= Configuration.PrioIniFile; UT_EQ( Configuration.PrioIniFile, ALIB.Config.Store( var, "new" ) ); ALIB.Config.Load ( var.Define("New Section", "newvar") ); UT_EQ( "new", var.GetString() ); var.Define( "", "newvar"); var.Priority= Configuration.PrioIniFile; UT_EQ( Configuration.PrioIniFile, ALIB.Config.Store( var, "aworx") ); ALIB.Config.Load ( var.Define("", "newvar") ); UT_EQ( "aworx", var.GetString() ); var.Define( "", "newvarList", ','); var.AddString("val1=5"); var.AddString("val2=10"); var.AddString("val3=hello"); var.Priority= Configuration.PrioIniFile; UT_EQ( Configuration.PrioIniFile, ALIB.Config.Store(var) ); ALIB.Config.Load ( var.Define( "", "newvarList") ); var.Define( "", "commented", ',', "2lines" ); var.Priority= Configuration.PrioIniFile; UT_EQ( Configuration.PrioIniFile, ALIB.Config.Store( var, "this is c-line 1 \nand this line 2" ) ); // write the file iniFile.FileName._(".writeback.txt"); iniFile.WriteFile(); // load the written file into another config IniFile readBack= new IniFile( iniFile.FileName.ToString() ); Variable varBack= new Variable(); // compare all UT_TRUE( (IniFile.Status.OK == readBack.LastStatus) ); { AString msg= new AString(); Substring orig= new Substring(); Substring back= new Substring(); foreach ( IniFile.Section section in iniFile.Sections ) { foreach ( IniFile.Entry entry in section.Entries ) { msg.Clear()._( "Reading variable " ).Field()._( section.Name )._( '/' )._( entry.Name ); UT_PRINT( msg ); char delim= '\0'; if( entry.Name.Equals("concat") || entry.Name.Equals("newvarList") ) delim= ','; iniFile .Load( var .Define( section.Name, entry.Name, delim) ); readBack.Load( varBack.Define( section.Name, entry.Name, delim) ); UT_EQ( var.Size(), varBack.Size() ); for ( int i= 0; i< var.Size(); i++ ) { int idx= var.GetString(i).IndexOf('='); if( idx < 0 ) { UT_EQ( var.GetString(i), varBack.GetString(i) ); } else { int idxBack= varBack.GetString(i).IndexOf('='); orig.Set( var .GetString(i), 0, idx ); back.Set( varBack.GetString(i), 0, idxBack ); UT_EQ( orig.Trim().ToString(), back.Trim().ToString() ); orig.Set( var .GetString(i), idx +1 ); back.Set( varBack.GetString(i), idxBack +1 ); UT_EQ( orig.Trim().ToString(), back.Trim().ToString() ); } } } } } readBack.Load ( var.Define( "New Section", "newvar" ) ); UT_EQ( "new" , var.GetString() ); readBack.Load ( var.Define( "", "newvar" ) ); UT_EQ( "aworx", var.GetString() ); ALIB.Config.RemovePlugin( iniFile ); ALIB.Config.InsertPlugin( readBack, Configuration.PrioIniFile ); ALIB.Config.Load ( var.Define( "New Section", "newvar") ); UT_EQ( "new" , var.GetString() ); ALIB.Config.Load ( var.Define( "", "newvar") ); UT_EQ( "aworx" , var.GetString() ); ALIB.Config.RemovePlugin( readBack ); }
/** **************************************************************************************** * Reads the verbosity for the given logger and domain from the ALib configuration system. * This internal method is used in two occasions: * - when a new logger is added: recursively for all existing domains (\p configStr is * given) * - when a new domain is created on the fly(\p configStr is not given) * * @param logger The logger to set the verbosity for. * @param dom The domain to set the verbosity for. * @param variable The (already read) variable to set verbosities from. ******************************************************************************************/ protected void getVerbosityFromConfig( Logger logger, Domain dom, Variable variable ) { // get logger number. It may happen that the logger is not existent in this domain tree. int loggerNo= dom.GetLoggerNo( logger ) ; if ( loggerNo < 0 ) return; Tokenizer verbosityTknzr= new Tokenizer(); Substring domainStr= new Substring(); AString domainStrBuf= new AString(); for( int varNo= 0; varNo< variable.Size(); varNo++ ) { verbosityTknzr.Set( variable.GetString( varNo ), '=' ); domainStr.Set( verbosityTknzr.Next() ); if ( domainStr.StartsWith( "INTERNAL_DOMAINS", DomainSensitivity ) ) { domainStrBuf._()._( domainStr.Buf, domainStr.Start + 16, domainStr.Length() -16 ); while ( domainStrBuf.CharAtStart() == '/' ) domainStrBuf.DeleteStart( 1 ); domainStrBuf.InsertAt( ALox.InternalDomains, 0 ); domainStr.Set( domainStrBuf ); } Substring verbosityStr= verbosityTknzr.Next(); if ( verbosityStr.IsEmpty() ) continue; int searchMode= 0; if ( domainStr.Consume ( '*' ) ) searchMode+= 2; if ( domainStr.ConsumeFromEnd( '*' ) ) searchMode+= 1; if( ( searchMode == 0 && dom.FullPath.Equals ( domainStr, DomainSensitivity ) ) || ( searchMode == 1 && dom.FullPath.StartsWith ( domainStr, DomainSensitivity ) ) || ( searchMode == 2 && dom.FullPath.EndsWith ( domainStr, DomainSensitivity ) ) || ( searchMode == 3 && dom.FullPath.IndexOf ( domainStr, 0, DomainSensitivity ) >=0 ) ) { Verbosity verbosity= ALox.ReadVerbosity( verbosityStr); dom.SetVerbosity( loggerNo, verbosity, variable.Priority ); // log info on this intMsg._()._NC( "Logger \"" )._NC( logger.GetName() ) ._NC( "\":" ).Tab(11 + maxLoggerNameLength) ._( '\'' )._NC( dom.FullPath ) ._( '\'' ).InsertChars(' ', maxDomainPathLength - dom.FullPath.Length() + 1 ) ._("= Verbosity." ); ALox.ToString( verbosity, dom.GetPriority(loggerNo), intMsg ).TrimEnd() ._('.'); logInternal( Verbosity.Info, "LGR", intMsg ); } } }
public void ConfigReplacementVariables() { UT_INIT(); String[] args= { "COMMANDLINE", "--REPL_CMDLINE=ReplCommandLine", "--NOCATCMDLINE=NoCatCommandLine", }; Configuration cfg= new Configuration(); cfg.SetCommandLineArgs( args ); Variable var= new Variable(); // replacements from command line plugin var.Define( "TEST", "VARIABLE" ); cfg.ProtectedValues.Store( var, "no replacment" ); cfg.Load( var ); UT_EQ( "no replacment" ,var.GetString() ); cfg.ProtectedValues.Store( var, "$UKN" ); cfg.Load( var ); UT_EQ( "" ,var.GetString() ); cfg.ProtectedValues.Store( var, "-$UKN * $UKN2-" ); cfg.Load( var ); UT_EQ( "- * -" ,var.GetString() ); cfg.ProtectedValues.Store( var, "$NOCATCMDLINE" ); cfg.Load( var ); UT_EQ( "NoCatCommandLine" ,var.GetString() ); cfg.ProtectedValues.Store( var, "$$NOCATCMDLINE$" ); cfg.Load( var ); UT_EQ( "$NoCatCommandLine$" ,var.GetString() ); cfg.ProtectedValues.Store( var, "$REPL_CMDLINE" ); cfg.Load( var ); UT_EQ( "ReplCommandLine" ,var.GetString() ); cfg.ProtectedValues.Store( var, "$REPL_ CMDLINE" ); cfg.Load( var ); UT_EQ( " CMDLINE" ,var.GetString() ); cfg.ProtectedValues.Store( var, "$repL_CmdLine" ); cfg.Load( var ); UT_EQ( "ReplCommandLine" ,var.GetString() ); cfg.ProtectedValues.Store( var, "$repL_CmdLine$repL_CmdLine" ); cfg.Load( var ); UT_EQ( "ReplCommandLineReplCommandLine" ,var.GetString() ); cfg.ProtectedValues.Store( var, "$repL_CmdLine $repL_CmdLine" ); cfg.Load( var ); UT_EQ( "ReplCommandLine ReplCommandLine" ,var.GetString() ); // replacements without category name cfg.ProtectedValues.Store( var.Define( "" , "NOCAT" ), "NoCat" ); cfg.ProtectedValues.Store( var.Define( "" , "NO_CAT" ), "No_cat" ); cfg.ProtectedValues.Store( var.Define( "TEST", "VARIABLE"), "$nocat" ); cfg.Load( var ); UT_EQ( "NoCat" ,var.GetString() ); cfg.ProtectedValues.Store( var.Define( "TEST", "VARIABLE"), "$_nocat" ); cfg.Load( var ); UT_EQ( "NoCat" ,var.GetString() ); // need to add an underscore, if no category but name contains underscore! cfg.ProtectedValues.Store( var.Define( "TEST", "VARIABLE"), "$no_cat" ); cfg.Load( var ); UT_EQ( "" ,var.GetString() ); cfg.ProtectedValues.Store( var.Define( "TEST", "VARIABLE"), "$_no_cat" ); cfg.Load( var ); UT_EQ( "No_cat" ,var.GetString() ); // nested variables cfg.ProtectedValues.Store( var.Define( "Rep", "Var1" ), "$Rep_Var2" ); cfg.ProtectedValues.Store( var.Define( "Rep", "Var2" ), "nested" ); cfg.ProtectedValues.Store( var.Define( "TEST", "VARIABLE"), "$rep_var2" ); cfg.Load( var ); UT_EQ( "nested" ,var.GetString() ); cfg.ProtectedValues.Store( var.Define( "TEST", "VARIABLE"), "$rep_var1" ); cfg.Load( var ); UT_EQ( "nested" ,var.GetString() ); // illegal recursion UT_PRINT( "One warning should follow" ); cfg.ProtectedValues.Store( var.Define( "Rep", "Var1" ), "$Rep_Var2" ); cfg.ProtectedValues.Store( var.Define( "Rep", "Var2" ), "$Rep_Var1" ); cfg.ProtectedValues.Store( var.Define( "TEST", "VARIABLE"), "$rep_var1" ); cfg.Load( var ); // custom variable definitions cfg.ProtectedValues.Store( var.Define( "Rep", "CUST" ), "cf" ); cfg.ProtectedValues.Store( var.Define( "TEST", "VARIABLE"), ">>$REP_CUST<<" ); cfg.Load( var ); UT_EQ( ">>cf<<" ,var.GetString() ); cfg.SubstitutionVariableStart._()._( "${" ); cfg.SubstitutionVariableEnd ._()._( "}" ); cfg.ProtectedValues.Store( var.Define( "TEST", "VARIABLE"), ">>${REP_CUST}<<" ); cfg.Load( var ); UT_EQ( ">>cf<<" ,var.GetString() ); cfg.SubstitutionVariableStart._()._( "€€€-"); cfg.SubstitutionVariableEnd ._()._( "--" ); cfg.ProtectedValues.Store( var.Define( "TEST", "VARIABLE"), ">>€€€-REP_CUST--<<" ); cfg.Load( var ); UT_EQ( ">>cf<<" ,var.GetString() ); cfg.ProtectedValues.Store( var.Define( "TEST", "VARIABLE"), ">>€€€-REP_CUST--" ); cfg.Load( var ); UT_EQ( ">>cf" ,var.GetString() ); cfg.ProtectedValues.Store( var.Define( "TEST", "VARIABLE"), "€€€-REP_CUST--" ); cfg.Load( var ); UT_EQ( "cf" ,var.GetString() ); cfg.ProtectedValues.Store( var.Define( "TEST", "VARIABLE"), "€€€-REP_CUST--€€€-REP_CUST--" ); cfg.Load( var ); UT_EQ( "cfcf" ,var.GetString() ); cfg.ProtectedValues.Store( var.Define( "TEST", "VARIABLE"), "€€-REP_CUST--" ); cfg.Load( var ); UT_EQ( "€€-REP_CUST--" ,var.GetString() ); UT_PRINT( "One warning should follow" ); cfg.ProtectedValues.Store( var.Define( "TEST", "VARIABLE"), "€€€-REP_CUST-" ); cfg.Load( var ); UT_EQ( "€€€-REP_CUST-" ,var.GetString() ); cfg.SubstitutionVariableStart._()._( "$" ); cfg.SubstitutionVariableEnd._(); // multi line replacements cfg.DefaultValues.Store( var.Define("ML", "REPL1", ';'), "repl1-v1;repl1-v2" ); cfg.DefaultValues.Store( var.Define("ML", "REPL2", ';'), "repl2-v1;repl2-v2" ); cfg.DefaultValues.Store( var.Define("ML", "VAR" , ';'), "$ML_REPL1;$ML_REPL2" ); var.Define("ML", "VAR", ';' ); cfg.Load( var ); UT_EQ( 4, var.Size() ); UT_EQ( "repl1-v1", var.GetString(0) ); UT_EQ( "repl1-v2", var.GetString(1) ); UT_EQ( "repl2-v1", var.GetString(2) ); UT_EQ( "repl2-v2", var.GetString(3) ); }
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 ); }
public void Log_WriteVerbosities() { UT_INIT(); Log.AddDebugLogger(); MemoryLogger memLogger= new MemoryLogger("MYLGGR"); Log.SetVerbosity( Log.DebugLogger, Verbosity.Verbose, ALox.InternalDomains ); Variable var= new Variable( ALox.ConfigCategoryName, Log.LOX.GetName() + "_MYLGGR_VERBOSITY", ';' ); Variable varBack= new Variable(); // test writing into other variable with variable name error UT_PRINT( "An error message should follow (wrong variable format): " ); var.Store( "writeback MY_" ); Log.SetVerbosity( memLogger, Verbosity.Verbose ); Log.RemoveLogger( memLogger ); // test writing into other variable var.Store( "writeback MY_VAR" ); Log.SetVerbosity( memLogger, Verbosity.Verbose ); Log.RemoveLogger( memLogger ); varBack.Define( "MY", "VAR" ).Load(); UT_PRINT( "Variable written: " + varBack.GetString().ToString() ); UT_TRUE( varBack.GetString().Length() > 0 ); // test writing into other variable without cat var.Store( "writeback ANON" ); Log.SetVerbosity( memLogger, Verbosity.Verbose ); Log.RemoveLogger( memLogger ); varBack.Define( "", "ANON" ).Load(); UT_PRINT( "Variable written: " + varBack.GetString().ToString() ); UT_TRUE( varBack.GetString().Length() > 0 ); // test writing into other variable without cat and with underscores in name var.Store( "writeback _2ND_ANON" ); Log.SetVerbosity( memLogger, Verbosity.Verbose ); Log.RemoveLogger( memLogger ); varBack.Define( "", "2ND_ANON" ).Load(); UT_PRINT( "Variable written: " + varBack.GetString().ToString() ); UT_TRUE( varBack.GetString().Length() > 0 ); // test writing into other the variable itself var.Store( "writeback" ); Log.SetVerbosity( memLogger, Verbosity.Verbose ); Log.RemoveLogger( memLogger ); ALIB.Config.Load( var); UT_PRINT( "Variable written: " + var.GetString().ToString() ); UT_TRUE( var.GetString().Length() > 0 ); Log.RemoveDebugLogger(); }
/** **************************************************************************************** * Implements functionality for configuration variable \c LOXNAME_DUMP_STATE_ON_EXIT. * Is called when a logger is removed. ******************************************************************************************/ protected void dumpStateOnLoggerRemoval() { if( !loggerAddedSinceLastDebugState ) return; loggerAddedSinceLastDebugState= false; Variable variable= new Variable( ALox.DUMP_STATE_ON_EXIT, GetName() ); variable.Load(); String domain= null; Verbosity verbosity= Verbosity.Info; Substring tok= new Substring(); int flags= 0; for( int tokNo= 0; tokNo< variable.Size(); tokNo++ ) { tok.Set( variable.GetString( tokNo ) ); if( tok.IsEmpty() ) continue; // state flags if( tok.Equals( "NONE" , Case.Ignore ) ) { flags= 0; break; } else if( tok.Equals( "Basic" , Case.Ignore ) ) flags|= (int) Lox.StateInfo.Basic ; else if( tok.Equals( "Version" , Case.Ignore ) ) flags|= (int) Lox.StateInfo.Version ; else if( tok.Equals( "Loggers" , Case.Ignore ) ) flags|= (int) Lox.StateInfo.Loggers ; else if( tok.Equals( "Domains" , Case.Ignore ) ) flags|= (int) Lox.StateInfo.Domains ; else if( tok.Equals( "InternalDomains" , Case.Ignore ) ) flags|= (int) Lox.StateInfo.InternalDomains ; else if( tok.Equals( "ScopeDomains" , Case.Ignore ) ) flags|= (int) Lox.StateInfo.ScopeDomains ; else if( tok.Equals( "DSR" , Case.Ignore ) ) flags|= (int) Lox.StateInfo.DSR ; else if( tok.Equals( "PrefixLogables" , Case.Ignore ) ) flags|= (int) Lox.StateInfo.PrefixLogables ; else if( tok.Equals( "Once" , Case.Ignore ) ) flags|= (int) Lox.StateInfo.Once ; else if( tok.Equals( "LogData" , Case.Ignore ) ) flags|= (int) Lox.StateInfo.LogData ; else if( tok.Equals( "ThreadMappings" , Case.Ignore ) ) flags|= (int) Lox.StateInfo.ThreadMappings ; else if( tok.Equals( "SPTR" , Case.Ignore ) ) flags|= (int) Lox.StateInfo.SPTR ; else if( tok.Equals( "All" , Case.Ignore ) ) flags|= (int) Lox.StateInfo.All ; // domain and verbosity else if( tok.Consume( "domain", Case.Ignore, Whitespaces.Trim ) ) { if( tok.Consume( '=', Case.Sensitive, Whitespaces.Trim ) ) domain= tok.Trim().ToString(); } else if( tok.Consume( "verbosity", Case.Ignore, Whitespaces.Trim ) ) { if( tok.Consume( '=', Case.Sensitive, Whitespaces.Trim ) ) verbosity= ALox.ReadVerbosity( tok.Trim() ); } // unknown argument else { logInternal( Verbosity.Error, "VAR", intMsg._() ._( "Unknown argument '" )._(tok) ._( "' in variable " )._(variable.Fullname)._( " = \"")._(variable.GetString())._('\"') ); } } if ( flags != 0 ) { State( domain, verbosity, "Auto dump state on exit requested: ", (Lox.StateInfo) flags ); } }
/** **************************************************************************************** * 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 ); }
/** ************************************************************************************ * This method creates an adequate/default console logger. 'Adequate' here means that * this function tries to detect what might be the best choice for the environment * that the ALox based process is running in. * This method is due to changes with the evolution of future ALox versions and * should be considered as a convenience method to shorten the bootstrap code needed * to use ALox. * * The current C# implementation takes the following approach: * * - check if configuration variable * [ALOX_CONSOLE_TYPE](../group__GrpALoxConfigVars.html) is set. This variable's * setting takes priority and if set, the according logger is created. * - check whether a console window is attached to the current process. * If not, then a plain text logger is chosen (class * \ref cs::aworx::lox::loggers::ConsoleLogger "ConsoleLogger"). * - Otherwise, on Unix like OS, class * \ref cs::aworx::lox::loggers::AnsiConsoleLogger "AnsiConsoleLogger" is chosen, * while on windows systems class * \ref cs::aworx::lox::loggers::ColorConsoleLogger "ColorConsoleLogger" * takes preference. * * For further information check out the source code. * * @param name (Optional) The name of the \e Logger. * Defaults to null, which implies standard logger names defined * in the \e Logger sub-classes. * @return The \b TextLogger chosen. **************************************************************************************/ public static TextLogger CreateConsoleLogger( String name= null ) { #if ALOX_DBG_LOG || ALOX_REL_LOG //--- first: check environment "ALOX_DBG_CONSOLE_TYPE". They have precedence --- Variable variable= new Variable(ALox.CONSOLE_TYPE); variable.Load(); AString val= variable.GetString().Trim(); if ( val.IsEmpty() || val.Equals( "DEFAULT", Case.Ignore ) || val.Equals( "PLAIN", Case.Ignore ) ) return new ConsoleLogger ( name ); if( val.Equals( "ANSI", Case.Ignore ) ) return new AnsiConsoleLogger ( name ); if( val.Equals( "WINDOWS", Case.Ignore ) ) return new ColorConsoleLogger( name ); ALIB.WARNING( "Unrecognized value in config variable \"" + variable.Fullname + "\"= " + variable.GetString() ); //--- second: check debug environment // .... this is not implemented in C#, yet ... // not detected: in windows, we choose ColorConsoleLogger, in Unix ANSI if( ALIB.SysInfo_HasConsoleWindow ) return ALIB.SysInfo_IsWindowsOS() ? (TextLogger) new ColorConsoleLogger( name ) : (TextLogger) new AnsiConsoleLogger ( name ); // default return new ConsoleLogger( name ); #else return null; #endif }
/** **************************************************************************************** * Reads a prefix string from the ALib configuration system. * This internal method is used when a new domain is created, * * @param dom The domain to set the verbosity for. ******************************************************************************************/ protected void getDomainPrefixFromConfig( Domain dom ) { Variable variable= new Variable( ALox.PREFIXES, GetName() ); if( 0 == variable.Load() ) return; Tokenizer prefixTok= new Tokenizer(); Tokenizer prefixTokInner= new Tokenizer(); Substring domainStr= new Substring(); AString domainStrBuf= new AString(); Substring prefixStr= new Substring(); for( int varNo= 0; varNo< variable.Size(); varNo++ ) { prefixTok.Set( variable.GetString( varNo ), '=' ); domainStr.Set( prefixTok.Next() ); if ( domainStr.StartsWith( "INTERNAL_DOMAINS", DomainSensitivity ) ) { domainStrBuf._()._( domainStr.Buf, domainStr.Start + 16, domainStr.Length() -16 ); while ( domainStrBuf.CharAtStart() == '/' ) domainStrBuf.DeleteStart( 1 ); domainStrBuf.InsertAt( ALox.InternalDomains, 0 ); domainStr.Set( domainStrBuf ); } prefixTokInner.Set( prefixTok.Next(), ',' ); prefixStr.Set( prefixTokInner.Next() ); if ( prefixStr.IsEmpty() ) continue; if ( prefixStr.Consume( '\"' ) ) prefixStr.ConsumeFromEnd( '\"' ); Inclusion otherPLs= Inclusion.Include; prefixTokInner.Next(); if ( prefixTokInner.Actual.IsNotEmpty() ) otherPLs= ALIB.ReadInclusion( prefixTokInner.Actual ); int searchMode= 0; if ( domainStr.Consume ( '*' ) ) searchMode+= 2; if ( domainStr.ConsumeFromEnd( '*' ) ) searchMode+= 1; if( ( searchMode == 0 && dom.FullPath.Equals ( domainStr, DomainSensitivity ) ) || ( searchMode == 1 && dom.FullPath.StartsWith ( domainStr, DomainSensitivity ) ) || ( searchMode == 2 && dom.FullPath.EndsWith ( domainStr, DomainSensitivity ) ) || ( searchMode == 3 && dom.FullPath.IndexOf ( domainStr, 0, DomainSensitivity ) >=0 ) ) { dom.PrefixLogables.Add( new Domain.PL( new AString( prefixStr ), otherPLs ) ); // log info on this intMsg._()._NC( "String \"" )._NC( prefixStr )._NC ( "\" added as prefix logable for domain \'" ) ._NC( dom.FullPath ) ._NC( "\'. (Retrieved from variable" ) ._NC( variable.Fullname )._( ".)" ); logInternal( Verbosity.Info, "PFX", intMsg ); } } }
/** * 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 ); }
/** * 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) ); }
// ############################################################################################# // Constructors // ############################################################################################# /** **************************************************************************************** * Constructs a new, empty Lox with the given \p name. * The name is immutable and all \b %Lox objects registered with ALox must be unique. * The name \c "Log" is reserved for the internal default singleton used for debug-logging. * In addition, name \c "GLOBAL" is not allowed. * * If parameter \p register is \c true (the default), static method * \ref cs::aworx::lox::ALox::Register "ALox.Register" is invoked and the object will be * retrievable with static method * \ref cs::aworx::lox::ALox::Get "ALox.Get". In some situations, such 'registration' * may not be wanted. * @param name The name of the Lox. Will be converted to upper case. * @param doRegister If \c true, this object is registered with static class * \ref cs::aworx::lox::ALox "ALox". * Optional and defaults to \c true. ******************************************************************************************/ public Lox( String name, bool doRegister = true ) : base() { // set recursion warning of log buffer lock to 1. Warnings are logged if recursively // acquired more than once #if ALOX_DBG_LOG || ALOX_REL_LOG logBufLock.RecursionWarningThreshold= 1; scopeInfo= new ScopeInfo( name, threadDictionary ); scopeDomains= new ScopeStore<AString >( scopeInfo, false ); scopePrefixes= new ScopeStore<Object >( scopeInfo, false ); scopeLogData= new ScopeStore<Dictionary<AString, LogData>>( scopeInfo, true ); scopeLogOnce= new ScopeStore<Dictionary<AString, int[]> >( scopeInfo, true ); // create domain trees domains = new Domain( null, new AString( "") ); internalDomains = new Domain( null, new AString( ALox.InternalDomains, 0, ALox.InternalDomains.Length - 1) ); // create internal sub-domains bool wasCreated= false; String[] internalDomainList= {"LGR", "DMN", "PFX", "THR", "LGD", "VAR" }; foreach ( String it in internalDomainList ) { resDomainInternal._()._NC( it ); internalDomains.Find( resDomainInternal, Case.Sensitive, 1, ref wasCreated ); } maxDomainPathLength= ALox.InternalDomains.Length + 3; // register with ALox if ( doRegister ) ALox.Register( this, ContainerOp.Insert ); // read domain substitution rules from configuration Variable variable= new Variable( ALox.DOMAIN_SUBSTITUTION, GetName() ); if ( variable.Load() != 0 ) { for( int ruleNo= 0; ruleNo< variable.Size(); ruleNo++ ) { AString rule= variable.GetString( ruleNo ); int idx= rule.IndexOf( "->" ); if ( idx > 0 ) { String domainPath= rule.ToString( 0, idx ).Trim(); String replacement= rule.ToString( idx + 2 ).Trim(); SetDomainSubstitutionRule( domainPath, replacement ); } else { // using alib warning here as we can't do internal logging in the constructor ALIB.WARNING( "Syntax error in variable \"" + variable.Fullname + "\"." ); } } } #endif }