diff --git a/lib/std/log.zig b/lib/std/log.zig index a20648626e..1b3095e0ee 100644 --- a/lib/std/log.zig +++ b/lib/std/log.zig @@ -100,6 +100,23 @@ pub const Level = enum { info, /// Debug: messages only useful for debugging. debug, + + /// Returns a string literal of the given level in full text form. + pub fn asText(comptime self: Level) switch (self) { + .emerg => @TypeOf("emergency"), + .crit => @TypeOf("critical"), + .err => @TypeOf("error"), + .warn => @TypeOf("warning"), + else => @TypeOf(@tagName(self)), + } { + return switch (self) { + .emerg => "emergency", + .crit => "critical", + .err => "error", + .warn => "warning", + else => @tagName(self), + }; + } }; /// The default log level is based on build mode. @@ -145,30 +162,34 @@ fn log( if (@typeInfo(@TypeOf(root.log)) != .Fn) @compileError("Expected root.log to be a function"); root.log(message_level, scope, format, args); - } else if (std.Target.current.os.tag == .freestanding) { - // On freestanding one must provide a log function; we do not have - // any I/O configured. - return; } else { - const level_txt = switch (message_level) { - .emerg => "emergency", - .alert => "alert", - .crit => "critical", - .err => "error", - .warn => "warning", - .notice => "notice", - .info => "info", - .debug => "debug", - }; - const prefix2 = if (scope == .default) ": " else "(" ++ @tagName(scope) ++ "): "; - const stderr = std.io.getStdErr().writer(); - const held = std.debug.getStderrMutex().acquire(); - defer held.release(); - nosuspend stderr.print(level_txt ++ prefix2 ++ format ++ "\n", args) catch return; + defaultLog(message_level, scope, format, args); } } } +/// The default implementation for root.log. root.log may forward log messages +/// to this function. +pub fn defaultLog( + comptime message_level: Level, + comptime scope: @Type(.EnumLiteral), + comptime format: []const u8, + args: anytype, +) void { + if (std.Target.current.os.tag == .freestanding) { + // On freestanding one must provide a log function; we do not have + // any I/O configured. + return; + } + + const level_txt = comptime message_level.asText(); + const prefix2 = if (scope == .default) ": " else "(" ++ @tagName(scope) ++ "): "; + const stderr = std.io.getStdErr().writer(); + const held = std.debug.getStderrMutex().acquire(); + defer held.release(); + nosuspend stderr.print(level_txt ++ prefix2 ++ format ++ "\n", args) catch return; +} + /// Returns a scoped logging namespace that logs all messages using the scope /// provided here. pub fn scoped(comptime scope: @Type(.EnumLiteral)) type { diff --git a/test/compare_output.zig b/test/compare_output.zig index 742e43e6c7..c3da3cc4a5 100644 --- a/test/compare_output.zig +++ b/test/compare_output.zig @@ -585,16 +585,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void { \\ comptime format: []const u8, \\ args: anytype, \\) void { - \\ const level_txt = switch (level) { - \\ .emerg => "emergency", - \\ .alert => "alert", - \\ .crit => "critical", - \\ .err => "error", - \\ .warn => "warning", - \\ .notice => "notice", - \\ .info => "info", - \\ .debug => "debug", - \\ }; + \\ const level_txt = comptime level.asText(); \\ const prefix2 = if (scope == .default) ": " else "(" ++ @tagName(scope) ++ "): "; \\ const stdout = std.io.getStdOut().writer(); \\ nosuspend stdout.print(level_txt ++ prefix2 ++ format ++ "\n", args) catch return; @@ -638,16 +629,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void { \\ comptime format: []const u8, \\ args: anytype, \\) void { - \\ const level_txt = switch (level) { - \\ .emerg => "emergency", - \\ .alert => "alert", - \\ .crit => "critical", - \\ .err => "error", - \\ .warn => "warning", - \\ .notice => "notice", - \\ .info => "info", - \\ .debug => "debug", - \\ }; + \\ const level_txt = comptime level.asText(); \\ const prefix2 = if (scope == .default) ": " else "(" ++ @tagName(scope) ++ "): "; \\ const stdout = std.io.getStdOut().writer(); \\ nosuspend stdout.print(level_txt ++ prefix2 ++ format ++ "\n", args) catch return;