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)); } }