// Copyright Epic Games, Inc. All Rights Reserved. using System; using System.Text.RegularExpressions; using EpicGames.Core; using Microsoft.Extensions.Logging; #nullable enable namespace AutomationUtils.Matchers { /// /// Matches shader compile errors and annotates with the source file path and revision /// class ShaderEventMatcher : ILogEventMatcher { const string Prefix = @"^\s*LogShaderCompilers: (?Error|Warning): "; const string FilePattern = @"(?" + // optional drive letter @"(?:[a-zA-Z]:)?" + // any non-colon character @"[^:(\s]+" + // any filename character (not whitespace or slash) @"[^:(\s\\/]" + @")"; const string LinePattern = @"(?\d+)(?::(?\d+))?"; static readonly Regex s_pattern = new Regex(Prefix); static readonly Regex s_patternWithFile = new Regex($"{Prefix}{FilePattern}(?:\\({LinePattern}\\))?:"); static readonly Regex s_content = new Regex(@"^(?:\s+|Validation failed)"); /// public LogEventMatch? Match(ILogCursor input) { Match? match; if (input.TryMatch(s_pattern, out match)) { LogLevel level = GetLogLevelFromSeverity(match); LogEventBuilder builder = new LogEventBuilder(input); builder.Annotate(match.Groups["severity"], LogEventMarkup.Severity); Match? fileMatch; if (input.TryMatch(s_patternWithFile, out fileMatch)) { builder.AnnotateSourceFile(fileMatch.Groups["file"], ""); builder.TryAnnotate(fileMatch.Groups["line"], LogEventMarkup.LineNumber); builder.TryAnnotate(fileMatch.Groups["column"], LogEventMarkup.ColumnNumber); } while (builder.Next.IsMatch(s_content)) { builder.MoveNext(); } return builder.ToMatch(LogEventPriority.AboveNormal, level, KnownLogEvents.Engine_ShaderCompiler); } return null; } static LogLevel GetLogLevelFromSeverity(Match match) { string severity = match.Groups["severity"].Value; if (severity.Equals("Warning", StringComparison.Ordinal)) { return LogLevel.Warning; } else { return LogLevel.Error; } } } }