102 lines
3.0 KiB
Zig
102 lines
3.0 KiB
Zig
//! 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";
|
|
}
|
|
}
|
|
};
|