//! Kernel debug output and logging functions. const std = @import("std"); fn dummy_write(_: u8) void {} /// The main method of kernel logging. pub const log = struct { /// Level to emit log records at. pub const Level = enum { /// Debug. debug, /// Info. info, /// Warning. warn, /// Error/Fatal. err, }; var write_fn: *const fn (u8) void = dummy_write; const writer: std.io.GenericWriter(u0, error{}, write_wrapper_fn) = .{ .context = 0 }; fn write_wrapper_fn(context: u0, data: []const u8) error{}!usize { _ = context; for (data) |byte| { write_fn(byte); } return data.len; } /// Replaces the function to print debug bytes with a new one. pub fn set_write_fn(f: *const fn (u8) void) void { write_fn = f; } /// Emit an `info`-level log record. pub inline fn info(comptime format: []const u8, args: anytype) void { writeln(.info, format, args); } /// Emit a `debug`-level log record. pub inline fn debug(comptime format: []const u8, args: anytype) void { writeln(.debug, format, args); } /// Emit a `warn`-level log record. pub inline fn warn(comptime format: []const u8, args: anytype) void { writeln(.warn, format, args); } /// Emit a `err`-level log record. pub inline fn err(comptime format: []const u8, args: anytype) void { writeln(.err, format, args); } /// Write raw byte data into the debugging output. pub fn write_raw(data: []const u8) void { _ = write_wrapper_fn(0, data) catch return; } /// Write a formatted string (without logging prefix/suffix/newline) into the debugging output. pub fn write(comptime format: []const u8, args: anytype) void { writer.print(format, args) catch return; } /// Write a formatted log record into the debugging output. pub fn writeln(comptime level: Level, comptime format: []const u8, args: anytype) void { const prefix = comptime log_prefix(level); const suffix = comptime log_suffix(level); writer.print(prefix ++ format ++ suffix ++ "\r\n", args) catch return; } /// Helper function to emit a `Not yet implemented` message and panic. pub fn todo(comptime msg: []const u8, args: anytype) noreturn { err("Not yet implemented: " ++ msg, args); @panic("Not yet implemented"); } /// Helper function to emit a `PANIC` message and panic. pub fn panic(comptime msg: []const u8, args: anytype) noreturn { err("PANIC: " ++ msg, args); @panic("Explicit kernel panic"); } fn log_prefix(comptime level: Level) []const u8 { switch (level) { .debug => return "", .info => return "\x1B[1;36m", .warn => return "\x1B[1;33m", .err => return "\x1B[1;31m", } } fn log_suffix(comptime level: Level) []const u8 { if (level == .debug) { return ""; } else { return "\x1B[0m"; } } };