// Copyright Epic Games, Inc. All Rights Reserved. using System; using System.Text.RegularExpressions; using EpicGames.Core; using Microsoft.Extensions.Logging; namespace UnrealBuildTool.Matchers { /// /// Matcher for generic Microsoft errors (see https://docs.microsoft.com/en-us/cpp/build/formatting-the-output-of-a-custom-build-step-or-build-event?view=msvc-160) /// class MicrosoftEventMatcher : ILogEventMatcher { static readonly Regex s_warningCodePattern = new Regex( @"(?(?:error|warning)) " + @"(?[a-zA-Z]+[0-9]+)\s*:"); static readonly Regex s_fileOrToolPattern = new Regex(@"^\s*(.*[^\s])\s*:"); static readonly Regex s_fileLinePattern = new Regex(@"^\s*(?.*)\((?\d+)(?:, (?\d+))?\)\s*:$"); public LogEventMatch? Match(ILogCursor cursor) { // filename(line# [, column#]) | toolname} : [ any text ] {error | warning} code+number:localizable string [ any text ] Match? match; if (cursor.TryMatch(s_warningCodePattern, out match)) { string prefix = cursor.CurrentLine!.Substring(0, match.Index); Match fileOrToolMatch = s_fileOrToolPattern.Match(prefix); if (fileOrToolMatch.Success) { LogEventBuilder builder = new LogEventBuilder(cursor); Match fileMatch = s_fileLinePattern.Match(fileOrToolMatch.Value); if (fileMatch.Success) { builder.AnnotateSourceFile(fileMatch.Groups["file"], null); builder.Annotate(fileMatch.Groups["line"], LogEventMarkup.LineNumber); builder.TryAnnotate(fileMatch.Groups["column"]); } else { builder.Annotate("tool", fileOrToolMatch.Groups[1], LogEventMarkup.ToolName); } Group severity = match.Groups["severity"]; builder.Annotate(severity); builder.Annotate(match.Groups["code"]); return builder.ToMatch(LogEventPriority.Normal, severity.Value.Equals("error", StringComparison.OrdinalIgnoreCase) ? LogLevel.Error : LogLevel.Warning, KnownLogEvents.Microsoft); } } return null; } } }