pluto/src/kernel/log.zig
DrDeano 2c91e6f9d0
Remove the old and in with the new
Added the new testing to the OS files

Some spelling
INOUT => IN/OUT
Added some doc comments to log

Added the new runtime to the build + added the None test mode

Moved some stuff around
None test mode is the default to run/build the OS normally with no runtime tests.

Add the new runtime testing to the CI


Updated README and CI


Increased timeout


Print the log message


Spelling


Move runtime to test folder


Add new RT to tty


Add a log to use the unmapped memory to cause page fault in release


Ensure the integer overflow happens even in release builds
2020-06-23 12:43:52 +01:00

135 lines
4.4 KiB
Zig

const build_options = @import("build_options");
const std = @import("std");
const Serial = @import("serial.zig").Serial;
const fmt = std.fmt;
/// The errors that can occur when logging
const LoggingError = error{};
/// The OutStream for the format function
const OutStream = std.io.OutStream(void, LoggingError, logCallback);
/// The different levels of logging that can be outputted.
pub const Level = enum {
INFO,
DEBUG,
WARNING,
ERROR,
};
var serial: Serial = undefined;
///
/// The call back function for the std library format function.
///
/// Arguments:
/// context: void - The context of the printing. There isn't a need for a context for this
/// so is void.
/// str: []const u8 - The string to print to the serial terminal.
///
/// Return: usize
/// The number of bytes written. This will always be the length of the string to print.
///
/// Error: LoggingError
/// {} - No error as LoggingError is empty.
///
fn logCallback(context: void, str: []const u8) LoggingError!usize {
serial.writeBytes(str);
return str.len;
}
///
/// Write a message to the log output stream with a certain logging level.
///
/// Arguments:
/// IN comptime level: Level - The logging level to use. Determines the message prefix and
/// whether it is filtered.
/// IN comptime format: []const u8 - The message format. Uses the standard format specification
/// options.
/// IN args: var - A struct of the parameters for the format string.
///
pub fn log(comptime level: Level, comptime format: []const u8, args: var) void {
fmt.format(OutStream{ .context = {} }, "[" ++ @tagName(level) ++ "] " ++ format, args) catch unreachable;
}
///
/// Write a message to the log output stream with the INFO level.
///
/// Arguments:
/// IN comptime format: []const u8 - The message format. Uses the standard format specification
/// options.
/// IN args: var - A struct of the parameters for the format string.
///
pub fn logInfo(comptime format: []const u8, args: var) void {
log(Level.INFO, format, args);
}
///
/// Write a message to the log output stream with the DEBUG level.
///
/// Arguments:
/// IN comptime format: []const u8 - The message format. Uses the standard format specification
/// options.
/// IN args: var - A struct of the parameters for the format string.
///
pub fn logDebug(comptime format: []const u8, args: var) void {
log(Level.DEBUG, format, args);
}
///
/// Write a message to the log output stream with the WARNING level.
///
/// Arguments:
/// IN comptime format: []const u8 - The message format. Uses the standard format specification
/// options.
/// IN args: var - A struct of the parameters for the format string.
///
pub fn logWarning(comptime format: []const u8, args: var) void {
log(Level.WARNING, format, args);
}
///
/// Write a message to the log output stream with the ERROR level.
///
/// Arguments:
/// IN comptime format: []const u8 - The message format. Uses the standard format specification
/// options.
/// IN args: var - A struct of the parameters for the format string.
///
pub fn logError(comptime format: []const u8, args: var) void {
log(Level.ERROR, format, args);
}
///
/// Initialise the logging stream using the given Serial instance.
///
/// Arguments:
/// IN ser: Serial - The serial instance to use when logging
///
pub fn init(ser: Serial) void {
serial = ser;
switch (build_options.test_mode) {
.Initialisation => runtimeTests(),
else => {},
}
}
///
/// The logging runtime tests that will test all logging levels.
///
pub fn runtimeTests() void {
inline for (@typeInfo(Level).Enum.fields) |field| {
const level = @field(Level, field.name);
log(level, "Test " ++ field.name ++ " level\n", .{});
log(level, "Test " ++ field.name ++ " level with args {}, {}\n", .{ "a", @as(u32, 1) });
const logFn = switch (level) {
.INFO => logInfo,
.DEBUG => logDebug,
.WARNING => logWarning,
.ERROR => logError,
};
logFn("Test " ++ field.name ++ " function\n", .{});
logFn("Test " ++ field.name ++ " function with args {}, {}\n", .{ "a", @as(u32, 1) });
}
}