/** **************************************************************************************** * Converts variable value data. Replaces certain characters by escape sequences. * @param os The output stream to write to. * @param value The value to write * @param temp A temporary AString needed internally. * @return The difference of length written and given value length. ******************************************************************************************/ protected int addEscapeSequences(TextWriter os, Substring value, AString temp) { int sizeDiff = 0; temp.Clear(); if (char.IsWhiteSpace(value.CharAtStart()) || char.IsWhiteSpace(value.CharAtEnd())) { temp._('\"')._(value)._('\"'); sizeDiff = 2; } else { temp._(value); } for (int i = 0; i < EscapeSequences.Count;) { String replacement = EscapeSequences[i++]; String needle = EscapeSequences[i++]; sizeDiff += temp.SearchAndReplace(needle, replacement, 0) * (replacement.Length - needle.Length); } os.Write(temp.Buffer(), 0, temp.Length()); return(sizeDiff); }
/** **************************************************************************************** * Helper method used when reading file. * @param subs A sub-string. * @return true if provided substring starts with comment character. ******************************************************************************************/ protected bool startsWithCommentSymbol(Substring subs) { int i = commentChars.IndexOf(subs.CharAtStart()); return((i >= 0 && i < 2) || (i == 2 && subs.CharAt(1) == '/')); }
/** **************************************************************************************** * Converts variable value data provided in the token and appends it to the target * variable. * Respects (and removes) quotation marks. * Replaces certain characters by escape sequences. * @param value The input string. * @param target The AString that gets the converted result appended. ******************************************************************************************/ protected void removeEscapeSequences(Substring value, AString target) { // remove quotation markes if (value.CharAtStart() == '\"' && value.CharAtEnd() == '\"') { value.Start++; value.End--; } int regionStart = target.Length(); value.CopyTo(target, true); for (int i = 0; i < EscapeSequences.Count;) { String needle = EscapeSequences[i++]; String replacement = EscapeSequences[i++]; target.SearchAndReplace(needle, replacement, regionStart); } }
// ############################################################################################# // logText // ############################################################################################# /** ******************************************************************************************** * * The implementation of the abstract method of parent class TextLogger. Logs messages to the * application console and/or the VStudio output window. * * @param domain The <em>Log Domain</em>. * @param verbosity The verbosity. This has been checked to be active already on this * stage and is provided to be able to be logged out only. * @param msg The log message * @param scope Information about the scope of the <em>Log Statement</em>.. * @param lineNumber The line number of a multi-line message, starting with 0. For * single line messages this is -1. **********************************************************************************************/ override protected void logText(Domain domain, Verbosity verbosity, AString msg, ScopeInfo scope, int lineNumber) { // loop over message, print the parts between the escape sequences Tokenizer msgParts = new Tokenizer(msg, '\x001B'); Substring actual = msgParts.Actual; Substring rest = msgParts.Rest; int column = 0; for (;;) { msgParts.Next(Whitespaces.Keep); // check if this is an ANSI sequence already if (rest.CharAtStart() == '[') { // read the 'm' int idx = rest.IndexOf('m'); if (idx < 0) // unknown ANSI Code { ALIB.WARNING("Unknown ANSI ESC Code "); textWriter.Write(actual.Buf, actual.Start, actual.Length()); continue; } column += actual.Length(); actual.End = rest.Start + idx; rest.Start += idx + 1; textWriter.Write(actual.Buf, actual.Start, actual.Length()); continue; } else { if (actual.IsNotEmpty()) { textWriter.Write(actual.Buf, actual.Start, actual.Length()); column += actual.Length(); } } // end of loop? if (!msgParts.HasNext()) { break; } // found an ESC sequence char c = rest.Consume(); // Colors bool isForeGround = true; if (c == 'C' || c == 'c') { isForeGround = c == 'c'; c = rest.Consume(); int colNo = c - '0'; ALIB.ASSERT_WARNING(colNo >= 0 && colNo <= 9, "Unknown ESC-c code"); // add bg colNo += isForeGround ? 0 : 10; // add light colNo += (isForeGround ? !IsBackgroundLight : IsBackgroundLight) ? 20 : 0; textWriter.Write(ansiCols[colNo]); } // Styles else if (c == 's') { // bold/italics style not supported in Windows console // reset all if (rest.Consume() == 'a') { textWriter.Write(ANSI_RESET); } } // auto tab / end of meta else if (c == 't' || c == 'A') { bool endOfMeta = c == 'A'; c = rest.Consume(); int extraSpace = c >= '0' && c <= '9' ? (int)(c - '0') : (int)(c - 'A') + 10; int tabStop = AutoSizes.Next(column, extraSpace); Util.WriteSpaces(textWriter, tabStop - column); column = tabStop; if (endOfMeta) { String msgPrefix; switch (verbosity) { case lox.Verbosity.Verbose: msgPrefix = MsgPrefixVerbose; break; case lox.Verbosity.Info: msgPrefix = MsgPrefixInfo; break; case lox.Verbosity.Warning: msgPrefix = MsgPrefixWarning; break; case lox.Verbosity.Error: msgPrefix = MsgPrefixError; break; default: msgPrefix = ""; break; } textWriter.Write(msgPrefix); } } // Link (we just colorize links here) else if (c == 'l') { textWriter.Write(rest.Consume() == 'S' ? (IsBackgroundLight ? ANSI_LIGHT_BLUE : ANSI_LIGHT_BLUE) : ANSI_STD_COL); } else { ALIB.WARNING("Unknown ESC code"); } } // write loop textWriter.WriteLine(MsgSuffix); }
public void FrontEnd() { // empty substring { Substring subs = new Substring(); UT_EQ('\0', subs.CharAtStart( )); UT_EQ('\0', subs.CharAt(0)); UT_EQ('\0', subs.CharAt(1)); UT_EQ('\0', subs.CharAt(-1)); UT_EQ('\0', subs.CharAt(2)); UT_EQ('\0', subs.CharAt(-2)); UT_EQ('\0', subs.CharAtEnd( )); UT_EQ('\0', subs.CharAtEnd(0)); UT_EQ('\0', subs.CharAtEnd(1)); UT_EQ('\0', subs.CharAtEnd(-1)); UT_EQ('\0', subs.CharAtEnd(2)); UT_EQ('\0', subs.CharAtEnd(-2)); } // empty substring { Substring subs = new Substring("aaaaaaaaaaaa"); subs.Start = 5; subs.End = 4; UT_EQ('\0', subs.CharAtStart( )); UT_EQ('\0', subs.CharAt(0)); UT_EQ('\0', subs.CharAt(1)); UT_EQ('\0', subs.CharAt(-1)); UT_EQ('\0', subs.CharAt(2)); UT_EQ('\0', subs.CharAt(-2)); UT_EQ('\0', subs.CharAtEnd( )); UT_EQ('\0', subs.CharAtEnd(0)); UT_EQ('\0', subs.CharAtEnd(1)); UT_EQ('\0', subs.CharAtEnd(-1)); UT_EQ('\0', subs.CharAtEnd(2)); UT_EQ('\0', subs.CharAtEnd(-2)); } // substring of length 1 { Substring subs = new Substring("aaaaaaaaaaaa"); subs.Start = subs.End = 5; UT_EQ('a', subs.CharAtStart( )); UT_EQ('a', subs.CharAt(0)); UT_EQ('\0', subs.CharAt(1)); UT_EQ('\0', subs.CharAt(-1)); UT_EQ('\0', subs.CharAt(2)); UT_EQ('\0', subs.CharAt(-2)); UT_EQ('a', subs.CharAtEnd( )); UT_EQ('a', subs.CharAtEnd(0)); UT_EQ('\0', subs.CharAtEnd(1)); UT_EQ('\0', subs.CharAtEnd(-1)); UT_EQ('\0', subs.CharAtEnd(2)); UT_EQ('\0', subs.CharAtEnd(-2)); } // substring of length 2 { Substring subs = new Substring("aaaaabbbbbb"); subs.End = subs.IndexOf('b'); subs.Start = subs.End - 1; UT_EQ('a', subs.CharAtStart( )); UT_EQ('a', subs.CharAt(0)); UT_EQ('b', subs.CharAt(1)); UT_EQ('\0', subs.CharAt(-1)); UT_EQ('\0', subs.CharAt(2)); UT_EQ('\0', subs.CharAt(-2)); UT_EQ('b', subs.CharAtEnd( )); UT_EQ('b', subs.CharAtEnd(0)); UT_EQ('a', subs.CharAtEnd(1)); UT_EQ('\0', subs.CharAtEnd(-1)); UT_EQ('\0', subs.CharAtEnd(2)); UT_EQ('\0', subs.CharAtEnd(-2)); } }
// ############################################################################################# // Protected interface // ############################################################################################# /** **************************************************************************************** * Gets a node. If not existent and parameter \p create is \c true, the node is created. * @param key The key to the stored value. * @param create Flag if a non-existent entry should be created. * @param separators A list of characters recognized as separators. * @return Returns the ourselves or a child node representing the key string. ******************************************************************************************/ protected PathMap <StoreT> get(Substring key, bool create, AString separators) { int idx = 0; int pLen = Path.Length(); if (pLen > 0) { int cmpLen = pLen < key.Length() ? pLen : key.Length(); char[] kBuf = key.Buf; char[] pBuf = Path.Buffer(); while (idx < cmpLen && kBuf[key.Start + idx] == pBuf[idx]) { idx++; } key.Consume(idx); } // all of 'our' path characters matched if (idx == pLen) { // identical to the searched string? if (key.IsEmpty()) { return(this); } // return matching child foreach (PathMap <StoreT> child in Childs) { if (key.CharAtStart() == child.Path.CharAtStart()) { PathMap <StoreT> search = child.get(key, create, separators); if (search != null) { return(search); } } } // no child found if (create) { PathMap <StoreT> newChild = null; newChild = new PathMap <StoreT>(this); newChild.Path._(key); Childs.Add(newChild); return(newChild); } } // nothing matched else if (idx == 0) { return(null); } // just a part of us matched else if (create) { // create new child receiving our old path (rest), our value and childs PathMap <StoreT> child1 = new PathMap <StoreT>(this); child1.Path._(Path, idx); List <PathMap <StoreT> > tempList = child1.Childs; foreach (PathMap <StoreT> child in Childs) { child.Parent = child1; } child1.Childs = Childs; Childs = tempList; child1.Value = Value; Childs.Clear(); Childs.Add(child1); // cut my path and clear my value Path.SetLength_NC(idx); Value = default(StoreT); // create second child if remaining path is not empty if (key.IsNotEmpty()) { PathMap <StoreT> child2 = new PathMap <StoreT>(this); child2.Path._(key); Childs.Add(child2); return(child2); } return(this); } // return us, or if this is not a real node, our parent if (Parent == null || idx == 0 || separators.IndexOf(Path.CharAt_NC(idx - 1)) >= 0) { return(this); } else { return(Parent); } }