예제 #1
0
        /// <summary>
        /// <para>Renders given <paramref name="event"/>'s message using its <see cref="LogEvent.MessageTemplate"/> and <see cref="LogEvent.Properties"/>.</para>
        /// <para>Performs substitution of property placeholders present in message template.</para>
        /// <para>Uses template syntax defined for <see cref="OutputTemplate"/> (with one key difference outlined below).</para>
        /// <para>Unlike to <see cref="LogEventFormatter"/>, there are no special predefined properties during message formatting. Only event properties are used.</para>
        /// <para>Example message template: <c>'Hello, {User}! You have {UnreadCount:D5} messages to read.'</c></para>
        /// </summary>
        public static void Format(
            [NotNull] LogEvent @event,
            [NotNull] TextWriter writer,
            [CanBeNull] IFormatProvider formatProvider = null)
        {
            if (@event == null)
            {
                throw new ArgumentNullException(nameof(@event));
            }
            if (writer == null)
            {
                throw new ArgumentNullException(nameof(writer));
            }

            if (@event.MessageTemplate == null)
            {
                return;
            }

            if (!TemplateTokenizer.CanContainNamedTokens(@event.MessageTemplate))
            {
                if (@event.MessageTemplate.Length > 0)
                {
                    writer.Write(@event.MessageTemplate);
                }
            }
            else
            {
                FormatInternal(@event, writer, formatProvider);
            }
        }
예제 #2
0
        public override EnumeratorTemplateElement Deserialize(TemplateTokenizer tokenizer, AbstractTemplateElement root)
        {
            var result = new EnumeratorTemplateElement(root);

            tokenizer.AdvanceUntilChar(' ');
            tokenizer.AdvanceWhileChar(' ');

            switch (tokenizer.CurrentChar)
            {
            case '{':
                result.EnumerationCondition = new VariableConditionPart {
                    VariableName = tokenizer.AdvanceUntilChar('>').InfoBetween("{", "}")
                };
                tokenizer.Advance();
                break;

            case '[':
                result.EnumerationCondition = ConditionDeserializer.Deserialize(tokenizer.AdvanceUntilChar(']').InfoAfter("[", int.MaxValue), new Dictionary <string, AbstractConditionPart>());
                tokenizer.AdvanceUntilChar('>');
                tokenizer.Advance();
                break;
            }
            result.Elements = FindElements(result, tokenizer, "/FOREACH").ToArray();
            tokenizer.AdvanceUntilChar('>');
            return(result);
        }
예제 #3
0
        /// <inheritdoc cref="Format(LogEvent,TextWriter,IFormatProvider)"/>
        public static string Format(
            [NotNull] LogEvent @event,
            [CanBeNull] IFormatProvider formatProvider = null)
        {
            if (@event == null)
            {
                throw new ArgumentNullException(nameof(@event));
            }

            if (@event.MessageTemplate == null)
            {
                return(string.Empty);
            }

            if (!TemplateTokenizer.CanContainNamedTokens(@event.MessageTemplate))
            {
                return(@event.MessageTemplate);
            }

            var builder = StringBuilderCache.Acquire(@event.MessageTemplate.Length * 2);
            var writer  = new StringWriter(builder);

            FormatInternal(@event, writer, formatProvider);

            StringBuilderCache.Release(builder);

            return(builder.ToString());
        }
예제 #4
0
        private void TokenizerTest(string text, bool unclosed, params TemplateTokenResult[] expected)
        {
            var tokenizer = new TemplateTokenizer(new StringReader(text));
            var tokens    = tokenizer.GetTokens().ToArray();

            bool passed = false;

            try {
                Assert.AreEqual(expected.Length, tokens.Length);
                Assert.AreEqual(0, tokens[0].Start);
                Assert.AreEqual(text.Length - 1, tokens[tokens.Length - 1].End);

                for (int i = 0; i < expected.Length; i++)
                {
                    var expectedToken = expected[i].Token;

                    Assert.AreEqual(expectedToken.Kind, tokens[i].Kind);
                    Assert.AreEqual(expectedToken.Start, tokens[i].Start);
                    Assert.AreEqual(expectedToken.End, tokens[i].End);
                    switch (expectedToken.Kind)
                    {
                    case TemplateTokenKind.Block:
                    case TemplateTokenKind.Comment:
                    case TemplateTokenKind.Variable:
                        Assert.AreEqual('{', text[expectedToken.Start]);
                        if (!unclosed)
                        {
                            Assert.AreEqual('}', text[expectedToken.End]);
                        }
                        break;
                    }
                    if (expected[i].Start != null)
                    {
                        Assert.AreEqual(expected[i].Start, text[expectedToken.Start]);
                    }
                    if (expected[i].End != null)
                    {
                        Assert.AreEqual(expected[i].End, text[expectedToken.End]);
                    }
                }
                passed = true;
            } finally {
                if (!passed)
                {
                    List <string> res = new List <string>();
                    for (int i = 0; i < tokens.Length; i++)
                    {
                        res.Add(
                            String.Format("new TemplateToken(TemplateTokenKind.{0}, {1}, {2})",
                                          tokens[i].Kind,
                                          tokens[i].Start,
                                          tokens[i].End
                                          )
                            );
                    }
                    Console.WriteLine(String.Join(",\r\n", res));
                }
            }
        }
예제 #5
0
        public override XmTemplateElement Deserialize(TemplateTokenizer tokenizer, AbstractTemplateElement root)
        {
            var result = new XmTemplateElement {
                TemplateSource = tokenizer.CurrentTemplate
            };

            result.Elements = FindElements(result, tokenizer).ToArray();
            return(result);
        }
        public override EvaluateTemplateElement Deserialize(TemplateTokenizer tokenizer, AbstractTemplateElement root)
        {
            var result = new EvaluateTemplateElement(root)
            {
                Expression = ConditionDeserializer.Deserialize(tokenizer.AdvanceUntilChar(']').InfoAfter("[", int.MaxValue), new Dictionary <string, AbstractConditionPart>())
            };

            tokenizer.AdvanceUntilChar('>');
            return(result);
        }
        public override StaticTemplateElement Deserialize(TemplateTokenizer tokenizer, AbstractTemplateElement root)
        {
            var result = new StaticTemplateElement(root)
            {
                Content = "<:BR:>"
            };

            tokenizer.AdvanceUntilChar('>');
            return(result);
        }
        public void Should_Parse_Optional_Value(string template, string name)
        {
            // Given, When
            var result = TemplateTokenizer.Tokenize(template);

            // Then
            result.Count.ShouldBe(1);
            result[0].TokenKind.ShouldBe(TemplateToken.Kind.OptionalValue);
            result[0].Value.ShouldBe(name);
        }
예제 #9
0
        protected void TokenizerAssertEquals(String TemplateString, params String[] Tokens)
        {
            var StringTokens = TemplateTokenizer.Tokenize(new TokenizerStringReader(TemplateString)).Select(Token => Token.Text).ToArray();

            foreach (var StringToken in StringTokens)
            {
                Console.WriteLine(StringToken);
            }
            CollectionAssert.AreEqual(StringTokens, Tokens);
        }
        public void Should_Parse_Short_Option()
        {
            // Given, When
            var result = TemplateTokenizer.Tokenize("-f");

            // Then
            result.Count.ShouldBe(1);
            result[0].TokenKind.ShouldBe(TemplateToken.Kind.ShortName);
            result[0].Value.ShouldBe("f");
        }
        public void Parse_EmptyString_ReturnsEndToken()
        {
            var parser = new TemplateTokenizer(string.Empty);
            var tokens = parser.ToArray();

            CollectionAssert.AreEqual(
                tokens, new[]
            {
                new TemplateToken(TemplateTokenType.End, 0, 1, string.Empty)
            });
        }
        public void Should_Throw_If_Value_Is_Unterminated(string template)
        {
            // Given, When
            var result = Record.Exception(() => TemplateTokenizer.Tokenize(template));

            // Then
            result.ShouldBeOfType <TemplateException>().And(e =>
            {
                e.Message.ShouldBe("Encountered unterminated value name 'FOO'.");
                e.Template.ShouldBe(template);
            });
        }
        public override DefineTemplateElement Deserialize(TemplateTokenizer tokenizer, AbstractTemplateElement root)
        {
            var result = new DefineTemplateElement(root);

            tokenizer.AdvanceUntilChar(' ');
            var stuff = tokenizer.AdvanceUntilChar('>').Trim();

            result.Variable = (VariableConditionPart)ConditionDeserializer.Deserialize(stuff, new Dictionary <string, AbstractConditionPart>());
            result.IsArray  = Command == TemplateCommandEnum.DefineArray;
            tokenizer.Advance();
            result.Elements = FindElements(result, tokenizer, "/DEFINE").ToArray();
            tokenizer.AdvanceUntilChar('>');
            return(result);
        }
예제 #14
0
        public void GetArtifacts(ITextProvider text, ArtifactCollection artifactCollection)
        {
            var reader    = new TextProviderReader(text);
            var tokenizer = new TemplateTokenizer(reader);

            foreach (var token in tokenizer.GetTokens())
            {
                if (token.Kind != TemplateTokenKind.Text)
                {
                    var range    = TextRange.FromBounds(token.Start, token.End + 1);
                    var artifact = TemplateArtifact.Create(token.Kind, range, token.IsClosed);
                    artifactCollection.Add(artifact);
                }
            }
        }
        public void Should_Parse_Multiple_Options()
        {
            // Given, When
            var result = TemplateTokenizer.Tokenize("-f|--foo|--bar|-b");

            // Then
            result.Count.ShouldBe(4);
            result[0].TokenKind.ShouldBe(TemplateToken.Kind.ShortName);
            result[0].Value.ShouldBe("f");
            result[1].TokenKind.ShouldBe(TemplateToken.Kind.LongName);
            result[1].Value.ShouldBe("foo");
            result[2].TokenKind.ShouldBe(TemplateToken.Kind.LongName);
            result[2].Value.ShouldBe("bar");
            result[3].TokenKind.ShouldBe(TemplateToken.Kind.ShortName);
            result[3].Value.ShouldBe("b");
        }
        public static void Format(
            [NotNull] LogEvent @event,
            [NotNull] TextWriter writer,
            [CanBeNull] object value,
            [CanBeNull] string format = null,
            [CanBeNull] IFormatProvider formatProvider = null)
        {
            if (@event == null)
            {
                throw new ArgumentNullException(nameof(@event));
            }
            if (writer == null)
            {
                throw new ArgumentNullException(nameof(writer));
            }

            if (value is OperationContextValue contextValue)
            {
                value = contextValue.ToString();
            }

            if (value is not string template || !TemplateTokenizer.CanContainNamedTokens(template))
            {
                PropertyValueFormatter.Format(writer, value, format, formatProvider);
                return;
            }

            var tokens = TemplatesCache.ObtainTokens(template);

            PaddingFormatHelper.TryParseFormat(format, out var insertLeadingSpace, out var insertTrailingSpace);

            if (insertLeadingSpace)
            {
                writer.WriteSpace();
            }

            foreach (var token in tokens)
            {
                token.Render(@event, writer, formatProvider);
            }

            if (insertTrailingSpace)
            {
                writer.WriteSpace();
            }
        }
        public void Parse_StringLiteral_ReturnsCorrectTokens()
        {
            var parser = new TemplateTokenizer("Test123");
            var tokens = parser.ToArray();

            CollectionAssert.AreEqual(
                tokens,
                new[]
            {
                new TemplateToken(TemplateTokenType.Character, 0, 1, "T"),
                new TemplateToken(TemplateTokenType.Character, 1, 1, "e"),
                new TemplateToken(TemplateTokenType.Character, 2, 1, "s"),
                new TemplateToken(TemplateTokenType.Character, 3, 1, "t"),
                new TemplateToken(TemplateTokenType.Character, 4, 1, "1"),
                new TemplateToken(TemplateTokenType.Character, 5, 1, "2"),
                new TemplateToken(TemplateTokenType.Character, 6, 1, "3"),
                new TemplateToken(TemplateTokenType.End, 7, 1, string.Empty)
            });
        }
        public void Parse_LineNumbers_AreCorrect()
        {
            var parser = new TemplateTokenizer("1\n2\r3\n\r4\r\n5");
            var tokens = parser.ToArray();

            CollectionAssert.AreEqual(
                tokens,
                new[]
            {
                new TemplateToken(TemplateTokenType.Character, 0, 1, "1"),
                new TemplateToken(TemplateTokenType.LineBreak, 1, 1, "\n"),
                new TemplateToken(TemplateTokenType.Character, 2, 2, "2"),
                new TemplateToken(TemplateTokenType.LineBreak, 3, 2, "\r"),
                new TemplateToken(TemplateTokenType.Character, 4, 3, "3"),
                new TemplateToken(TemplateTokenType.LineBreak, 5, 3, "\n\r"),
                new TemplateToken(TemplateTokenType.Character, 7, 4, "4"),
                new TemplateToken(TemplateTokenType.LineBreak, 8, 4, "\r\n"),
                new TemplateToken(TemplateTokenType.Character, 10, 5, "5"),
                new TemplateToken(TemplateTokenType.End, 11, 5, string.Empty)
            });
        }
예제 #19
0
        public override RangeTemplateElement Deserialize(TemplateTokenizer tokenizer, AbstractTemplateElement root)
        {
            var result = new RangeTemplateElement(root);

            tokenizer.AdvanceUntilChar(' ');
            tokenizer.AdvanceWhileChar(' ');

            if (tokenizer.CurrentChar == '[')
            {
                var condition = ConditionDeserializer.Deserialize(tokenizer.AdvanceUntilChar(']').InfoAfter("[", int.MaxValue), new Dictionary <string, AbstractConditionPart>());
                var opCond    = condition as OperationConditionPart;
                if (!(opCond?.LeftSide is VariableConditionPart) || opCond.Operator != ConditionPartOperatorEnum.Range || !(opCond.RightSide is OperationConditionPart))
                {
                    throw new ArgumentException("Invalid FOR condition");
                }

                result.Variable = (VariableConditionPart)opCond.LeftSide;
                var cond = (OperationConditionPart)opCond.RightSide;

                if (cond.Operator != ConditionPartOperatorEnum.To && cond.Operator != ConditionPartOperatorEnum.Until)
                {
                    throw new ArgumentException("Invalid FOR condition");
                }

                result.InludeMaximum = cond.Operator == ConditionPartOperatorEnum.To;
                result.Minimum       = cond.LeftSide;
                result.Maximum       = cond.RightSide;

                tokenizer.AdvanceUntilChar('>');
                tokenizer.Advance();
            }
            else
            {
                throw new ArgumentException("FOR must have a condition in []");
            }

            result.Elements = FindElements(result, tokenizer, "/FOR").ToArray();
            tokenizer.AdvanceUntilChar('>');
            return(result);
        }
        public override ConditionalTemplateElement Deserialize(TemplateTokenizer tokenizer, AbstractTemplateElement root)
        {
            var result = new ConditionalTemplateElement(root)
            {
                Condition = ConditionDeserializer.Deserialize(tokenizer.AdvanceUntilChar(']').InfoAfter("[", int.MaxValue), new Dictionary <string, AbstractConditionPart>())
            };

            tokenizer.AdvanceUntilChar('>');
            tokenizer.Advance();
            result.ConditionTrueElements = FindElements(result, tokenizer, "/IF", ":ELSE:").ToArray();
            var command = tokenizer.AdvanceUntilChar('>').ToUpper();

            if (command != ":ELSE:")
            {
                return(result);
            }

            tokenizer.Advance();
            result.ConditionFalseElements = FindElements(result, tokenizer, "/IF", ":ELSE:").ToArray();
            tokenizer.AdvanceUntilChar('>');
            return(result);
        }
        private static void Test(string template, params ITemplateToken[] expectedTokens)
        {
            var actualTokens = TemplateTokenizer.Tokenize(template, new PropertyTokensFactory()).ToArray();

            actualTokens.Should().HaveCount(expectedTokens.Length);

            foreach (var(actual, expected) in actualTokens.Zip(expectedTokens, (actual, expected) => (actual, expected)))
            {
                if (expected is TextToken expectedText)
                {
                    actual.Should().BeOfType <TextToken>().Which.ToString().Should().Be(expectedText.ToString());
                }
                else if (expected is PropertyToken expectedProperty)
                {
                    actual.Should().BeOfType <PropertyToken>().And.BeEquivalentTo(expectedProperty);
                }
                else
                {
                    throw new InvalidOperationException("Expected tokens can only be TextTokens or PropertyTokens.");
                }
            }
        }
예제 #22
0
    public static ArgumentResult ParseArgumentTemplate(string template)
    {
        var valueName = default(string);
        var required  = false;

        foreach (var token in TemplateTokenizer.Tokenize(template))
        {
            if (token.TokenKind == TemplateToken.Kind.ShortName ||
                token.TokenKind == TemplateToken.Kind.LongName)
            {
                throw CommandTemplateException.ArgumentCannotContainOptions(template, token);
            }

            if (token.TokenKind == TemplateToken.Kind.OptionalValue ||
                token.TokenKind == TemplateToken.Kind.RequiredValue)
            {
                if (!string.IsNullOrWhiteSpace(valueName))
                {
                    throw CommandTemplateException.MultipleValuesAreNotSupported(template, token);
                }

                if (string.IsNullOrWhiteSpace(token.Value))
                {
                    throw CommandTemplateException.ValuesMustHaveName(template, token);
                }

                valueName = token.Value;
                required  = token.TokenKind == TemplateToken.Kind.RequiredValue;
            }
        }

        if (valueName == null)
        {
            throw CommandTemplateException.ArgumentsMustHaveValueName(template);
        }

        return(new ArgumentResult(valueName, required));
    }
예제 #23
0
 public static OutputTemplate Parse(string input) =>
 new OutputTemplate(TemplateTokenizer.Tokenize(input, new AllNamedTokensFactory()).ToArray());
예제 #24
0
    public static OptionResult ParseOptionTemplate(string template)
    {
        var result = new OptionResult();

        foreach (var token in TemplateTokenizer.Tokenize(template))
        {
            if (token.TokenKind == TemplateToken.Kind.LongName || token.TokenKind == TemplateToken.Kind.ShortName)
            {
                if (string.IsNullOrWhiteSpace(token.Value))
                {
                    throw CommandTemplateException.OptionsMustHaveName(template, token);
                }

                if (char.IsDigit(token.Value[0]))
                {
                    throw CommandTemplateException.OptionNamesCannotStartWithDigit(template, token);
                }

                foreach (var character in token.Value)
                {
                    if (!char.IsLetterOrDigit(character) && character != '-' && character != '_')
                    {
                        throw CommandTemplateException.InvalidCharacterInOptionName(template, token, character);
                    }
                }
            }

            if (token.TokenKind == TemplateToken.Kind.LongName)
            {
                if (token.Value.Length == 1)
                {
                    throw CommandTemplateException.LongOptionMustHaveMoreThanOneCharacter(template, token);
                }

                result.LongNames.Add(token.Value);
            }

            if (token.TokenKind == TemplateToken.Kind.ShortName)
            {
                if (token.Value.Length > 1)
                {
                    throw CommandTemplateException.ShortOptionMustOnlyBeOneCharacter(template, token);
                }

                result.ShortNames.Add(token.Value);
            }

            if (token.TokenKind == TemplateToken.Kind.RequiredValue ||
                token.TokenKind == TemplateToken.Kind.OptionalValue)
            {
                if (!string.IsNullOrWhiteSpace(result.Value))
                {
                    throw CommandTemplateException.MultipleOptionValuesAreNotSupported(template, token);
                }

                foreach (var character in token.Value)
                {
                    if (!char.IsLetterOrDigit(character) &&
                        character != '=' && character != '-' && character != '_')
                    {
                        throw CommandTemplateException.InvalidCharacterInValueName(template, token, character);
                    }
                }

                result.Value           = token.Value.ToUpperInvariant();
                result.ValueIsOptional = token.TokenKind == TemplateToken.Kind.OptionalValue;
            }
        }

        if (result.LongNames.Count == 0 &&
            result.ShortNames.Count == 0)
        {
            throw CommandTemplateException.MissingLongAndShortName(template, null);
        }

        return(result);
    }
 public abstract T Deserialize(TemplateTokenizer tokenizer, AbstractTemplateElement root);
 public override AbstractTemplateElement DeserializeElement(TemplateTokenizer tokenizer, AbstractTemplateElement root)
 {
     return(Deserialize(tokenizer, root));
 }
예제 #27
0
 public TemplateCodeGen(String TemplateString, TemplateFactory TemplateFactory = null)
 {
     this.TemplateFactory = TemplateFactory;
     this.Tokens          = new TokenReader(TemplateTokenizer.Tokenize(new TokenizerStringReader(TemplateString)));
 }