static IEnumerable <NodeRegex> GetNodeRegexps(Syntax.Node n, NodeRegexContext ctx) { switch (n.Type) { case Syntax.NodeType.Text: return (EnumOne(new NodeRegex(ctx.GetRegexFromStringLiteral(n.Data), "fixed string '" + n.Data + "'", NodeRegexFlags.IsStringLiteral, n.NodeStart, n.NodeEnd) { StringLiteral = n.Data }) .Select(ctx.ApplyContextLimitationsToOutputRegex)); case Syntax.NodeType.Layout: return(n.Children.SelectMany(c => GetNodeRegexps(c, ctx))); case Syntax.NodeType.Renderer: return(GetRendererNodeRegexps(n, ctx)); default: return(Enumerable.Empty <NodeRegex>()); } }
private static NodeRegex GetDateNodeRegex(Syntax.Node dateRenderer, NodeRegexContext ctx) { var format = GetParamValue(dateRenderer, "format").FirstOrDefault(); if (string.IsNullOrEmpty(format)) { format = "G"; } var dateCulture = GetRendererCulture(dateRenderer); var parserFormat = DateTimeFormatParsing.ParseDateTimeFormat(format, dateCulture, new FormatParsing_RegexBuilderHook() { ctx = ctx }); NodeRegexFlags reFlags = NodeRegexFlags.None; var fillDateMask = DateTimeFormatParsing.DateTimeFormatFlag.ContainsYear | DateTimeFormatParsing.DateTimeFormatFlag.ContainsMonth | DateTimeFormatParsing.DateTimeFormatFlag.ContainsDay; if ((parserFormat.Flags & fillDateMask) == fillDateMask) { reFlags |= NodeRegexFlags.RepresentsDate; } var fillTimeMask = DateTimeFormatParsing.DateTimeFormatFlag.ContainsHour; if ((parserFormat.Flags & fillTimeMask) == fillTimeMask) { reFlags |= NodeRegexFlags.RepresentsTime; } if ((reFlags & NodeRegexFlags.RepresentsDateOrTime) == 0) { reFlags |= NodeRegexFlags.IsIgnorable; } return(new NodeRegex(parserFormat.Regex, dateRenderer.Description, reFlags, dateRenderer.NodeStart, dateRenderer.NodeEnd) { DateTimeFormat = format, DateTimeCulture = dateCulture.Name }); }
static IEnumerable <NodeRegex> GetInnerLayoutRegexps(Syntax.Node renderer, NodeRegexContext ctx, string innerLayoutParamName = "inner") { return(GetInnerLayout(renderer, innerLayoutParamName).SelectMany(inner => GetNodeRegexps(inner, ctx))); }
private static IEnumerable <NodeRegex> GetPaddingRegexps(Syntax.Node renderer, NodeRegexContext ctx) { int padding; int.TryParse(GetNormalizedParamValue(renderer, "padding").DefaultIfEmpty("0").First(), out padding); var padChar = GetParamValue(renderer, "padCharacter").DefaultIfEmpty("").First().DefaultIfEmpty(' ').First(); var fixedLength = GetNormalizedParamValue(renderer, "fixedLength").DefaultIfEmpty("false").First() == "true"; if (padding == 0) { return(GetInnerLayoutRegexps(renderer, ctx).Select(ctx.ApplyContextLimitationsToOutputRegex)); } if (fixedLength) { return(GetInnerLayoutRegexps( renderer, ctx.PushWrapper(new RegexModifyingWrapper(WrapperType.NotHandleable, renderer, "padding with fixedLength=True")) )); } var paddingRe = new NodeRegex( string.Format("{0}{{0,{1}}}", ctx.GetRegexFromStringLiteral(new string(padChar, 1)), Math.Abs(padding) ), renderer.Description, NodeRegexFlags.None, renderer.NodeStart, renderer.NodeEnd ); if (padding > 0) { return (EnumOne(paddingRe) .Concat(GetInnerLayoutRegexps(renderer, ctx)) .Select(ctx.ApplyContextLimitationsToOutputRegex)); } else { return (GetInnerLayoutRegexps(renderer, ctx) .Concat(EnumOne(paddingRe)) .Select(ctx.ApplyContextLimitationsToOutputRegex)); } }
static IEnumerable <NodeRegex> GetRendererNodeRegexps(Syntax.Node renderer, NodeRegexContext ctx) { NodeRegexContext subCtx; switch (renderer.Data) { case "longdate": return (EnumOne(new NodeRegex(@"\d{4}\-\d{2}\-\d{2}\ \d{2}\:\d{2}\:\d{2}\.\d{4}", renderer.Description, NodeRegexFlags.RepresentsDate | NodeRegexFlags.RepresentsTime, renderer.NodeStart, renderer.NodeEnd) { DateTimeFormat = "yyyy-MM-dd HH:mm:ss.ffff" }) .Select(ctx.ApplyContextLimitationsToOutputRegex)); case "shortdate": return (EnumOne(new NodeRegex(@"\d{4}\-\d{2}\-\d{2}", renderer.Description, NodeRegexFlags.RepresentsDate, renderer.NodeStart, renderer.NodeEnd) { DateTimeFormat = "yyyy-MM-dd" }) .Select(ctx.ApplyContextLimitationsToOutputRegex)); case "time": return (EnumOne(new NodeRegex(@"\d{2}\:\d{2}\:\d{2}\.\d{4}", renderer.Description, NodeRegexFlags.RepresentsTime, renderer.NodeStart, renderer.NodeEnd) { DateTimeFormat = "HH:mm:ss.ffff" }) .Select(ctx.ApplyContextLimitationsToOutputRegex)); case "date": return (EnumOne(GetDateNodeRegex(renderer, ctx)) .Select(ctx.ApplyContextLimitationsToOutputRegex)); case "ticks": return (EnumOne(new NodeRegex(@"\d+", renderer.Description, NodeRegexFlags.RepresentsDate | NodeRegexFlags.RepresentsTime, renderer.NodeStart, renderer.NodeEnd) { DateTimeFormat = TicksFakeDateTimeFormat }) .Select(ctx.ApplyContextLimitationsToOutputRegex)); case "literal": return (GetParamValue(renderer, "text") .Select(text => new NodeRegex(ctx.GetRegexFromStringLiteral(text), "literal '" + text + "'", NodeRegexFlags.IsStringLiteral, renderer.NodeStart, renderer.NodeEnd) { StringLiteral = text }) .Select(ctx.ApplyContextLimitationsToOutputRegex)); case "uppercase": return(GetInnerLayoutRegexps( renderer, IsRendererEnabled(renderer) ? ctx.PushWrapper(new RegexModifyingWrapper(WrapperType.UpperCase, renderer)) : ctx )); case "lowercase": return(GetInnerLayoutRegexps( renderer, IsRendererEnabled(renderer) ? ctx.PushWrapper(new RegexModifyingWrapper(WrapperType.LowerCase, renderer)) : ctx )); case "pad": return(GetPaddingRegexps(renderer, ctx)); case "cached": return(GetInnerLayoutRegexps(renderer, ctx)); case "filesystem-normalize": case "json-encode": case "xml-encode": case "replace": case "rot13": case "url-encode": case "replace-newlines": case "wrapline": case "trim-whitespace": return(GetInnerLayoutRegexps( renderer, IsRendererEnabled(renderer) ? ctx.PushWrapper(new RegexModifyingWrapper(WrapperType.NotHandleable, renderer)) : ctx )); case "onexception": case "when": subCtx = ctx.IncreaseRegexLevel().PushWrapper( new RegexModifyingWrapper(WrapperType.Conditional, renderer)); return (EnumOne(new NodeRegex(@"(", "begin of " + renderer.Description, NodeRegexFlags.IsAuxiliaryRegexPart, null, null)) .Concat(GetInnerLayoutRegexps(renderer, subCtx)) .Concat(EnumOne(new NodeRegex(@")?", "end of " + renderer.Description, NodeRegexFlags.IsAuxiliaryRegexPart, null, null))) .Select(subCtx.ApplyContextLimitationsToOutputRegex)); case "whenempty": subCtx = ctx.IncreaseRegexLevel().PushWrapper( new RegexModifyingWrapper(WrapperType.Conditional, renderer)); return (EnumOne(new NodeRegex(@"((", "begin of ${whenEmpty}", NodeRegexFlags.IsAuxiliaryRegexPart, null, null)) .Concat(GetInnerLayoutRegexps(renderer, subCtx, "inner")) .Concat(EnumOne(new NodeRegex(@")|(", "OR between alternative layouts of ${whenEmpty}", NodeRegexFlags.IsAuxiliaryRegexPart, null, null))) .Concat(GetInnerLayoutRegexps(renderer, subCtx, "whenempty")) .Concat(EnumOne(new NodeRegex(@"))", "end of ${whenEmpty}", NodeRegexFlags.IsAuxiliaryRegexPart, null, null))) .Select(subCtx.ApplyContextLimitationsToOutputRegex)); case "level": return (EnumOne(new NodeRegex( string.Format("({0}|{1}|{2}|{3}|{4}|{5})", ctx.GetRegexFromStringLiteral("Trace"), ctx.GetRegexFromStringLiteral("Debug"), ctx.GetRegexFromStringLiteral("Info"), ctx.GetRegexFromStringLiteral("Warn"), ctx.GetRegexFromStringLiteral("Error"), ctx.GetRegexFromStringLiteral("Fatal")), renderer.Description, NodeRegexFlags.RepresentsSeverity, renderer.NodeStart, renderer.NodeEnd)) .Select(ctx.ApplyContextLimitationsToOutputRegex)); case "threadid": return (EnumOne(new NodeRegex(@"\d+", renderer.Description, NodeRegexFlags.RepresentsThread, renderer.NodeStart, renderer.NodeEnd)) .Select(ctx.ApplyContextLimitationsToOutputRegex)); case "threadname": return (EnumOne(new NodeRegex(NotSpecificRegexp, renderer.Description, NodeRegexFlags.RepresentsThread | NodeRegexFlags.IsNotSpecific, renderer.NodeStart, renderer.NodeEnd)) .Select(ctx.ApplyContextLimitationsToOutputRegex)); case "counter": case "gc": case "processid": return (EnumOne(new NodeRegex( renderer.Data == "gc" ? @"\d*" : @"\d+", // mono renders empty strings for gc props renderer.Description, NodeRegexFlags.None, renderer.NodeStart, renderer.NodeEnd)) .Select(ctx.ApplyContextLimitationsToOutputRegex)); case "guid": return (EnumOne(new NodeRegex(GetGuidRegex(renderer), renderer.Description, NodeRegexFlags.None, renderer.NodeStart, renderer.NodeEnd)) .Select(ctx.ApplyContextLimitationsToOutputRegex)); case "logger": return (EnumOne(new NodeRegex(NotSpecificRegexp, renderer.Description, NodeRegexFlags.IsNotSpecific, renderer.NodeStart, renderer.NodeEnd)) .Select(ctx.ApplyContextLimitationsToOutputRegex)); case "newline": return (EnumOne(new NodeRegex(@"((\r\n)|\r|\n)", renderer.Description, NodeRegexFlags.None, renderer.NodeStart, renderer.NodeEnd)) .Select(ctx.ApplyContextLimitationsToOutputRegex)); case "processtime": return (EnumOne(new NodeRegex(@"\d{2}\:\d{2}\:\d{2}\.\d{1,4}", renderer.Description, NodeRegexFlags.None, renderer.NodeStart, renderer.NodeEnd)) .Select(ctx.ApplyContextLimitationsToOutputRegex)); case "processinfo": return (EnumOne(new NodeRegex(GetProcessInfoRegex(renderer), renderer.Description, NodeRegexFlags.None, renderer.NodeStart, renderer.NodeEnd)) .Select(ctx.ApplyContextLimitationsToOutputRegex)); case "processname": return (EnumOne(new NodeRegex(NotSpecificRegexp, renderer.Description, NodeRegexFlags.IsNotSpecific, renderer.NodeStart, renderer.NodeEnd)) .Select(ctx.ApplyContextLimitationsToOutputRegex)); case "qpc": return (EnumOne(new NodeRegex(GetGpcRegex(renderer), renderer.Description, NodeRegexFlags.None, renderer.NodeStart, renderer.NodeEnd)) .Select(ctx.ApplyContextLimitationsToOutputRegex)); case "windows-identity": return (GetWindowsIdentityRegexps(renderer) .Select(ctx.ApplyContextLimitationsToOutputRegex)); case "asp-application": case "aspnet-application": case "aspnet-request": case "aspnet-request-cookie": case "aspnet-request-host": case "aspnet-request-method": case "aspnet-request-querystring": case "aspnet-request-referrer": case "aspnet-request-useragent": case "aspnet-request-url": case "aspnet-session": case "aspnet-sessionid": case "aspnet-user-authtype": case "aspnet-user-identity": case "aspnet-user-isauthenticated": case "iis-site-name": case "asp-request": case "asp-session": case "basedir": case "callsite": case "document-uri": case "environment": case "event-context": case "event-properties": case "exception": case "file-contents": case "gdc": case "identity": case "install-context": case "log4jxmlevent": case "machinename": case "mdc": case "mdlc": case "message": case "ndc": case "ndlc": case "nlogdir": case "performancecounter": case "registry": case "sl-appinfo": case "specialfolder": case "stacktrace": case "tempdir": case "all-event-properties": case "assembly-version": case "var": case "appsetting": case "aspnet-mvc-action": case "aspnet-mvc-controller": case "aspnet-item": case "aspnet-traceidentifier": return (EnumOne(new NodeRegex(NotSpecificRegexp, renderer.Description, NodeRegexFlags.IsNotSpecific, renderer.NodeStart, renderer.NodeEnd)) .Select(ctx.ApplyContextLimitationsToOutputRegex)); case "activityid": return (EnumOne(new NodeRegex(GetGuidRegex('D'), renderer.Description, NodeRegexFlags.None, renderer.NodeStart, renderer.NodeEnd)) .Select(ctx.ApplyContextLimitationsToOutputRegex)); case "appdomain": return (EnumOne(GetAppDomainNode(renderer)) .Select(ctx.ApplyContextLimitationsToOutputRegex)); case "callsite-linenumber": return (EnumOne(new NodeRegex(@"\d+", renderer.Description, NodeRegexFlags.None, renderer.NodeStart, renderer.NodeEnd)) .Select(ctx.ApplyContextLimitationsToOutputRegex)); default: return (EnumOne(new NodeRegex(NotSpecificRegexp, renderer.Description, NodeRegexFlags.IsUnknownRenderer | NodeRegexFlags.IsNotSpecific, renderer.NodeStart, renderer.NodeEnd)) .Select(ctx.ApplyContextLimitationsToOutputRegex)); } }