mirror of
https://github.com/ziglang/zig.git
synced 2024-11-23 04:40:19 +00:00
std: collect all options under one namespace
This commit is contained in:
parent
fe2bd9dda8
commit
f83834993e
@ -5,7 +5,6 @@
|
||||
|
||||
const std = @import("std");
|
||||
const builtin = @import("builtin");
|
||||
const root = @import("root");
|
||||
const mem = std.mem;
|
||||
const os = std.os;
|
||||
|
||||
@ -67,8 +66,8 @@ fn tlsCsprngFill(_: *anyopaque, buffer: []u8) void {
|
||||
// Allow applications to decide they would prefer to have every call to
|
||||
// std.crypto.random always make an OS syscall, rather than rely on an
|
||||
// application implementation of a CSPRNG.
|
||||
if (comptime std.meta.globalOption("crypto_always_getrandom", bool) orelse false) {
|
||||
return fillWithOsEntropy(buffer);
|
||||
if (std.options.crypto_always_getrandom) {
|
||||
return defaultRandomSeed(buffer);
|
||||
}
|
||||
|
||||
if (wipe_mem.len == 0) {
|
||||
@ -86,7 +85,7 @@ fn tlsCsprngFill(_: *anyopaque, buffer: []u8) void {
|
||||
) catch {
|
||||
// Could not allocate memory for the local state, fall back to
|
||||
// the OS syscall.
|
||||
return fillWithOsEntropy(buffer);
|
||||
return std.options.cryptoRandomSeed(buffer);
|
||||
};
|
||||
// The memory is already zero-initialized.
|
||||
} else {
|
||||
@ -128,14 +127,14 @@ fn tlsCsprngFill(_: *anyopaque, buffer: []u8) void {
|
||||
// Since we failed to set up fork safety, we fall back to always
|
||||
// calling getrandom every time.
|
||||
ctx.init_state = .failed;
|
||||
return fillWithOsEntropy(buffer);
|
||||
return std.options.cryptoRandomSeed(buffer);
|
||||
},
|
||||
.initialized => {
|
||||
return fillWithCsprng(buffer);
|
||||
},
|
||||
.failed => {
|
||||
if (want_fork_safety) {
|
||||
return fillWithOsEntropy(buffer);
|
||||
return std.options.cryptoRandomSeed(buffer);
|
||||
} else {
|
||||
unreachable;
|
||||
}
|
||||
@ -165,7 +164,7 @@ fn fillWithCsprng(buffer: []u8) void {
|
||||
mem.set(u8, ctx.gimli.toSlice()[0..std.crypto.core.Gimli.RATE], 0);
|
||||
}
|
||||
|
||||
fn fillWithOsEntropy(buffer: []u8) void {
|
||||
pub fn defaultRandomSeed(buffer: []u8) void {
|
||||
os.getrandom(buffer) catch @panic("getrandom() failed to provide entropy");
|
||||
}
|
||||
|
||||
@ -174,12 +173,8 @@ fn initAndFill(buffer: []u8) void {
|
||||
// Because we panic on getrandom() failing, we provide the opportunity
|
||||
// to override the default seed function. This also makes
|
||||
// `std.crypto.random` available on freestanding targets, provided that
|
||||
// the `cryptoRandomSeed` function is provided.
|
||||
if (@hasDecl(root, "cryptoRandomSeed")) {
|
||||
root.cryptoRandomSeed(&seed);
|
||||
} else {
|
||||
fillWithOsEntropy(&seed);
|
||||
}
|
||||
// the `std.options.cryptoRandomSeed` function is provided.
|
||||
std.options.cryptoRandomSeed(&seed);
|
||||
|
||||
const ctx = @ptrCast(*Context, wipe_mem.ptr);
|
||||
ctx.gimli = std.crypto.core.Gimli.init(seed);
|
||||
|
@ -1861,10 +1861,9 @@ pub const have_segfault_handling_support = switch (native_os) {
|
||||
.freebsd, .openbsd => @hasDecl(os.system, "ucontext_t"),
|
||||
else => false,
|
||||
};
|
||||
pub const enable_segfault_handler: bool = if (@hasDecl(root, "enable_segfault_handler"))
|
||||
root.enable_segfault_handler
|
||||
else
|
||||
runtime_safety and have_segfault_handling_support;
|
||||
|
||||
const enable_segfault_handler = std.options.enable_segfault_handler;
|
||||
pub const default_enable_segfault_handler = runtime_safety and have_segfault_handling_support;
|
||||
|
||||
pub fn maybeEnableSegfaultHandler() void {
|
||||
if (enable_segfault_handler) {
|
||||
|
@ -17,7 +17,7 @@ pub fn Batch(
|
||||
comptime async_behavior: enum {
|
||||
/// Observe the value of `std.io.is_async` to decide whether `add`
|
||||
/// and `wait` will be async functions. Asserts that the jobs do not suspend when
|
||||
/// `std.io.mode == .blocking`. This is a generally safe assumption, and the
|
||||
/// `std.options.io_mode == .blocking`. This is a generally safe assumption, and the
|
||||
/// usual recommended option for this parameter.
|
||||
auto_async,
|
||||
|
||||
|
@ -1,6 +1,5 @@
|
||||
const std = @import("../std.zig");
|
||||
const builtin = @import("builtin");
|
||||
const root = @import("root");
|
||||
const assert = std.debug.assert;
|
||||
const testing = std.testing;
|
||||
const mem = std.mem;
|
||||
@ -104,25 +103,29 @@ pub const Loop = struct {
|
||||
};
|
||||
};
|
||||
|
||||
const LoopOrVoid = switch (std.io.mode) {
|
||||
.blocking => void,
|
||||
.evented => Loop,
|
||||
pub const Instance = switch (std.options.io_mode) {
|
||||
.blocking => @TypeOf(null),
|
||||
.evented => ?*Loop,
|
||||
};
|
||||
pub const instance = std.options.event_loop;
|
||||
|
||||
var global_instance_state: LoopOrVoid = undefined;
|
||||
const default_instance: ?*LoopOrVoid = switch (std.io.mode) {
|
||||
var global_instance_state: Loop = undefined;
|
||||
pub const default_instance = switch (std.options.io_mode) {
|
||||
.blocking => null,
|
||||
.evented => &global_instance_state,
|
||||
};
|
||||
pub const instance: ?*LoopOrVoid = if (@hasDecl(root, "event_loop")) root.event_loop else default_instance;
|
||||
|
||||
pub const Mode = enum {
|
||||
single_threaded,
|
||||
multi_threaded,
|
||||
};
|
||||
pub const default_mode = .multi_threaded;
|
||||
|
||||
/// TODO copy elision / named return values so that the threads referencing *Loop
|
||||
/// have the correct pointer value.
|
||||
/// https://github.com/ziglang/zig/issues/2761 and https://github.com/ziglang/zig/issues/2765
|
||||
pub fn init(self: *Loop) !void {
|
||||
if (builtin.single_threaded or
|
||||
(@hasDecl(root, "event_loop_mode") and root.event_loop_mode == .single_threaded))
|
||||
{
|
||||
if (builtin.single_threaded or std.options.event_loop_mode == .single_threaded) {
|
||||
return self.initSingleThreaded();
|
||||
} else {
|
||||
return self.initMultiThreaded();
|
||||
|
@ -2661,17 +2661,17 @@ pub fn cwd() Dir {
|
||||
if (builtin.os.tag == .windows) {
|
||||
return Dir{ .fd = os.windows.peb().ProcessParameters.CurrentDirectory.Handle };
|
||||
} else if (builtin.os.tag == .wasi) {
|
||||
if (@hasDecl(root, "wasi_cwd")) {
|
||||
return root.wasi_cwd();
|
||||
} else {
|
||||
// Expect the first preopen to be current working directory.
|
||||
return .{ .fd = 3 };
|
||||
}
|
||||
return std.options.wasiCwd();
|
||||
} else {
|
||||
return Dir{ .fd = os.AT.FDCWD };
|
||||
}
|
||||
}
|
||||
|
||||
pub fn defaultWasiCwd() Dir {
|
||||
// Expect the first preopen to be current working directory.
|
||||
return .{ .fd = 3 };
|
||||
}
|
||||
|
||||
/// Opens a directory at the given path. The directory is a system resource that remains
|
||||
/// open until `close` is called on the result.
|
||||
/// See `openDirAbsoluteZ` for a function that accepts a null-terminated path.
|
||||
|
@ -21,7 +21,7 @@ pub const File = struct {
|
||||
/// blocking.
|
||||
capable_io_mode: io.ModeOverride = io.default_mode,
|
||||
|
||||
/// Furthermore, even when `std.io.mode` is async, it is still sometimes desirable
|
||||
/// Furthermore, even when `std.options.io_mode` is async, it is still sometimes desirable
|
||||
/// to perform blocking I/O, although not by default. For example, when printing a
|
||||
/// stack trace to stderr. This field tracks both by acting as an overriding I/O mode.
|
||||
/// When not building in async I/O mode, the type only has the `.blocking` tag, making
|
||||
|
@ -19,14 +19,7 @@ pub const Mode = enum {
|
||||
evented,
|
||||
};
|
||||
|
||||
/// The application's chosen I/O mode. This defaults to `Mode.blocking` but can be overridden
|
||||
/// by `root.event_loop`.
|
||||
pub const mode: Mode = if (@hasDecl(root, "io_mode"))
|
||||
root.io_mode
|
||||
else if (@hasDecl(root, "event_loop"))
|
||||
Mode.evented
|
||||
else
|
||||
Mode.blocking;
|
||||
const mode = std.options.io_mode;
|
||||
pub const is_async = mode != .blocking;
|
||||
|
||||
/// This is an enum value to use for I/O mode at runtime, since it takes up zero bytes at runtime,
|
||||
|
@ -1,6 +1,6 @@
|
||||
//! std.log is a standardized interface for logging which allows for the logging
|
||||
//! of programs and libraries using this interface to be formatted and filtered
|
||||
//! by the implementer of the root.log function.
|
||||
//! by the implementer of the `std.options.logFn` function.
|
||||
//!
|
||||
//! Each log message has an associated scope enum, which can be used to give
|
||||
//! context to the logging. The logging functions in std.log implicitly use a
|
||||
@ -13,16 +13,20 @@
|
||||
//! `const log = std.log.scoped(.libfoo);` to use .libfoo as the scope of its
|
||||
//! log messages.
|
||||
//!
|
||||
//! An example root.log might look something like this:
|
||||
//! An example `logFn` might look something like this:
|
||||
//!
|
||||
//! ```
|
||||
//! const std = @import("std");
|
||||
//!
|
||||
//! // Set the log level to info
|
||||
//! pub const log_level: std.log.Level = .info;
|
||||
//! pub const std_options = struct {
|
||||
//! // Set the log level to info
|
||||
//! pub const log_level = .info;
|
||||
//!
|
||||
//! // Define root.log to override the std implementation
|
||||
//! pub fn log(
|
||||
//! // Define logFn to override the std implementation
|
||||
//! pub const logFn = myLogFn;
|
||||
//! };
|
||||
//!
|
||||
//! pub fn myLogFn(
|
||||
//! comptime level: std.log.Level,
|
||||
//! comptime scope: @TypeOf(.EnumLiteral),
|
||||
//! comptime format: []const u8,
|
||||
@ -70,7 +74,6 @@
|
||||
|
||||
const std = @import("std.zig");
|
||||
const builtin = @import("builtin");
|
||||
const root = @import("root");
|
||||
|
||||
pub const Level = enum {
|
||||
/// Error: something has gone wrong. This might be recoverable or might
|
||||
@ -102,22 +105,14 @@ pub const default_level: Level = switch (builtin.mode) {
|
||||
.ReleaseFast, .ReleaseSmall => .err,
|
||||
};
|
||||
|
||||
/// The current log level. This is set to root.log_level if present, otherwise
|
||||
/// log.default_level.
|
||||
pub const level: Level = if (@hasDecl(root, "log_level"))
|
||||
root.log_level
|
||||
else
|
||||
default_level;
|
||||
const level = std.options.log_level;
|
||||
|
||||
pub const ScopeLevel = struct {
|
||||
scope: @Type(.EnumLiteral),
|
||||
level: Level,
|
||||
};
|
||||
|
||||
const scope_levels = if (@hasDecl(root, "scope_levels"))
|
||||
root.scope_levels
|
||||
else
|
||||
[0]ScopeLevel{};
|
||||
const scope_levels = std.options.log_scope_levels;
|
||||
|
||||
fn log(
|
||||
comptime message_level: Level,
|
||||
@ -127,13 +122,7 @@ fn log(
|
||||
) void {
|
||||
if (comptime !logEnabled(message_level, scope)) return;
|
||||
|
||||
if (@hasDecl(root, "log")) {
|
||||
if (@typeInfo(@TypeOf(root.log)) != .Fn)
|
||||
@compileError("Expected root.log to be a function");
|
||||
root.log(message_level, scope, format, args);
|
||||
} else {
|
||||
defaultLog(message_level, scope, format, args);
|
||||
}
|
||||
std.options.logFn(message_level, scope, format, args);
|
||||
}
|
||||
|
||||
/// Determine if a specific log message level and scope combination are enabled for logging.
|
||||
@ -149,8 +138,8 @@ pub fn defaultLogEnabled(comptime message_level: Level) bool {
|
||||
return comptime logEnabled(message_level, default_log_scope);
|
||||
}
|
||||
|
||||
/// The default implementation for root.log. root.log may forward log messages
|
||||
/// to this function.
|
||||
/// The default implementation for the log function, custom log functions may
|
||||
/// forward log messages to this function.
|
||||
pub fn defaultLog(
|
||||
comptime message_level: Level,
|
||||
comptime scope: @Type(.EnumLiteral),
|
||||
|
@ -527,7 +527,7 @@ const bad_main_ret = "expected return type of main to be 'void', '!void', 'noret
|
||||
// and we want fewer call frames in stack traces.
|
||||
inline fn initEventLoopAndCallMain() u8 {
|
||||
if (std.event.Loop.instance) |loop| {
|
||||
if (!@hasDecl(root, "event_loop")) {
|
||||
if (loop == std.event.Loop.default_instance) {
|
||||
loop.init() catch |err| {
|
||||
std.log.err("{s}", .{@errorName(err)});
|
||||
if (@errorReturnTrace()) |trace| {
|
||||
@ -556,7 +556,7 @@ inline fn initEventLoopAndCallMain() u8 {
|
||||
// because it is working around stage1 compiler bugs.
|
||||
inline fn initEventLoopAndCallWinMain() std.os.windows.INT {
|
||||
if (std.event.Loop.instance) |loop| {
|
||||
if (!@hasDecl(root, "event_loop")) {
|
||||
if (loop == std.event.Loop.default_instance) {
|
||||
loop.init() catch |err| {
|
||||
std.log.err("{s}", .{@errorName(err)});
|
||||
if (@errorReturnTrace()) |trace| {
|
||||
|
@ -94,10 +94,79 @@ pub const wasm = @import("wasm.zig");
|
||||
pub const zig = @import("zig.zig");
|
||||
pub const start = @import("start.zig");
|
||||
|
||||
const root = @import("root");
|
||||
const options_override = if (@hasDecl(root, "std_options")) root.std_options else struct {};
|
||||
|
||||
pub const options = struct {
|
||||
pub const enable_segfault_handler: bool = if (@hasDecl(options_override, "enable_segfault_handler"))
|
||||
options_override.enable_segfault_handler
|
||||
else
|
||||
debug.default_enable_segfault_handler;
|
||||
|
||||
/// Function used to implement std.fs.cwd for wasi.
|
||||
pub const wasiCwd: fn () fs.Dir = if (@hasDecl(options_override, "wasiCwd"))
|
||||
options_override.wasiCwd
|
||||
else
|
||||
fs.defaultWasiCwd;
|
||||
|
||||
/// The application's chosen I/O mode.
|
||||
pub const io_mode: io.Mode = if (@hasDecl(options_override, "io_mode"))
|
||||
options_override.io_mode
|
||||
else if (@hasDecl(options_override, "event_loop"))
|
||||
.evented
|
||||
else
|
||||
.blocking;
|
||||
|
||||
pub const event_loop: event.Loop.Instance = if (@hasDecl(options_override, "event_loop"))
|
||||
options_override.event_loop
|
||||
else
|
||||
event.Loop.default_instance;
|
||||
|
||||
pub const event_loop_mode: event.Loop.Mode = if (@hasDecl(options_override, "event_loop_mode"))
|
||||
options_override.event_loop_mode
|
||||
else
|
||||
event.Loop.default_mode;
|
||||
|
||||
/// The current log level.
|
||||
pub const log_level: log.Level = if (@hasDecl(options_override, "log_level"))
|
||||
options_override.log_level
|
||||
else
|
||||
log.default_level;
|
||||
|
||||
pub const log_scope_levels: []const log.ScopeLevel = if (@hasDecl(options_override, "log_scope_levels"))
|
||||
options_override.log_scope_levels
|
||||
else
|
||||
&.{};
|
||||
|
||||
pub const logFn: fn (
|
||||
comptime message_level: log.Level,
|
||||
comptime scope: @TypeOf(.enum_literal),
|
||||
comptime format: []const u8,
|
||||
args: anytype,
|
||||
) void = if (@hasDecl(options_override, "logFn"))
|
||||
options_override.logFn
|
||||
else
|
||||
log.defaultLog;
|
||||
|
||||
pub const cryptoRandomSeed: fn (buffer: []u8) void = if (@hasDecl(options_override, "cryptoRandomSeed"))
|
||||
options_override.cryptoRandomSeed
|
||||
else
|
||||
@import("crypto/tlcsprng.zig").defaultRandomSeed;
|
||||
|
||||
pub const crypto_always_getrandom: bool = if (@hasDecl(options_override, "crypto_always_getrandom"))
|
||||
options_override.crypto_always_getrandom
|
||||
else
|
||||
false;
|
||||
};
|
||||
|
||||
// This forces the start.zig file to be imported, and the comptime logic inside that
|
||||
// file decides whether to export any appropriate start symbols, and call main.
|
||||
comptime {
|
||||
_ = start;
|
||||
|
||||
for (@typeInfo(options_override).Struct.decls) |decl| {
|
||||
if (!@hasDecl(options, decl.name)) @compileError("no option named " ++ decl.name);
|
||||
}
|
||||
}
|
||||
|
||||
test {
|
||||
|
@ -2,7 +2,10 @@ const std = @import("std");
|
||||
const io = std.io;
|
||||
const builtin = @import("builtin");
|
||||
|
||||
pub const io_mode: io.Mode = builtin.test_io_mode;
|
||||
pub const std_options = struct {
|
||||
pub const io_mode: io.Mode = builtin.test_io_mode;
|
||||
pub const logFn = log;
|
||||
};
|
||||
|
||||
var log_err_count: usize = 0;
|
||||
|
||||
@ -45,7 +48,7 @@ pub fn main() void {
|
||||
if (!have_tty) {
|
||||
std.debug.print("{d}/{d} {s}... ", .{ i + 1, test_fn_list.len, test_fn.name });
|
||||
}
|
||||
const result = if (test_fn.async_frame_size) |size| switch (io_mode) {
|
||||
const result = if (test_fn.async_frame_size) |size| switch (std.options.io_mode) {
|
||||
.evented => blk: {
|
||||
if (async_frame_buffer.len < size) {
|
||||
std.heap.page_allocator.free(async_frame_buffer);
|
||||
|
@ -13,12 +13,10 @@ const Decl = Module.Decl;
|
||||
|
||||
pub const is_enabled = builtin.mode == .Debug;
|
||||
|
||||
/// To use these crash report diagnostics, publish these symbols in your main file.
|
||||
/// To use these crash report diagnostics, publish this panic in your main file
|
||||
/// and add `pub const enable_segfault_handler = false;` to your `std_options`.
|
||||
/// You will also need to call initialize() on startup, preferably as the very first operation in your program.
|
||||
pub const root_decls = struct {
|
||||
pub const panic = if (is_enabled) compilerPanic else std.builtin.default_panic;
|
||||
pub const enable_segfault_handler = false;
|
||||
};
|
||||
pub const panic = if (is_enabled) compilerPanic else std.builtin.default_panic;
|
||||
|
||||
/// Install signal handlers to identify crashes and report diagnostics.
|
||||
pub fn initialize() void {
|
||||
|
26
src/main.zig
26
src/main.zig
@ -25,11 +25,23 @@ const target_util = @import("target.zig");
|
||||
const ThreadPool = @import("ThreadPool.zig");
|
||||
const crash_report = @import("crash_report.zig");
|
||||
|
||||
// Crash report needs to override the panic handler and other root decls
|
||||
pub usingnamespace crash_report.root_decls;
|
||||
pub const std_options = struct {
|
||||
pub const wasiCwd = wasi_cwd;
|
||||
pub const logFn = log;
|
||||
pub const enable_segfault_handler = false;
|
||||
|
||||
pub const log_level: std.log.Level = switch (builtin.mode) {
|
||||
.Debug => .debug,
|
||||
.ReleaseSafe, .ReleaseFast => .info,
|
||||
.ReleaseSmall => .err,
|
||||
};
|
||||
};
|
||||
|
||||
// Crash report needs to override the panic handler
|
||||
pub const panic = crash_report.panic;
|
||||
|
||||
var wasi_preopens: fs.wasi.Preopens = undefined;
|
||||
pub inline fn wasi_cwd() fs.Dir {
|
||||
pub fn wasi_cwd() fs.Dir {
|
||||
// Expect the first preopen to be current working directory.
|
||||
const cwd_fd: std.os.fd_t = 3;
|
||||
assert(mem.eql(u8, wasi_preopens.names[cwd_fd], "."));
|
||||
@ -111,12 +123,6 @@ const debug_usage = normal_usage ++
|
||||
|
||||
const usage = if (debug_extensions_enabled) debug_usage else normal_usage;
|
||||
|
||||
pub const log_level: std.log.Level = switch (builtin.mode) {
|
||||
.Debug => .debug,
|
||||
.ReleaseSafe, .ReleaseFast => .info,
|
||||
.ReleaseSmall => .err,
|
||||
};
|
||||
|
||||
var log_scopes: std.ArrayListUnmanaged([]const u8) = .{};
|
||||
|
||||
pub fn log(
|
||||
@ -128,7 +134,7 @@ pub fn log(
|
||||
// Hide debug messages unless:
|
||||
// * logging enabled with `-Dlog`.
|
||||
// * the --debug-log arg for the scope has been provided
|
||||
if (@enumToInt(level) > @enumToInt(std.log.level) or
|
||||
if (@enumToInt(level) > @enumToInt(std.options.log_level) or
|
||||
@enumToInt(level) > @enumToInt(std.log.Level.info))
|
||||
{
|
||||
if (!build_options.enable_logging) return;
|
||||
|
@ -509,8 +509,8 @@ test "ptrCast comptime known slice to C pointer" {
|
||||
test "ptrToInt on a generic function" {
|
||||
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64 and builtin.os.tag != .linux) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64 and builtin.os.tag != .linux) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
|
||||
const S = struct {
|
||||
fn generic(i: anytype) @TypeOf(i) {
|
||||
|
@ -440,11 +440,14 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
|
||||
cases.add("std.log per scope log level override",
|
||||
\\const std = @import("std");
|
||||
\\
|
||||
\\pub const log_level: std.log.Level = .debug;
|
||||
\\
|
||||
\\pub const scope_levels = [_]std.log.ScopeLevel{
|
||||
\\ .{ .scope = .a, .level = .warn },
|
||||
\\ .{ .scope = .c, .level = .err },
|
||||
\\pub const std_options = struct {
|
||||
\\ pub const log_level: std.log.Level = .debug;
|
||||
\\
|
||||
\\ pub const log_scope_levels = &[_]std.log.ScopeLevel{
|
||||
\\ .{ .scope = .a, .level = .warn },
|
||||
\\ .{ .scope = .c, .level = .err },
|
||||
\\ };
|
||||
\\ pub const logFn = log;
|
||||
\\};
|
||||
\\
|
||||
\\const loga = std.log.scoped(.a);
|
||||
@ -494,7 +497,10 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
|
||||
cases.add("std.heap.LoggingAllocator logs to std.log",
|
||||
\\const std = @import("std");
|
||||
\\
|
||||
\\pub const log_level: std.log.Level = .debug;
|
||||
\\pub const std_options = struct {
|
||||
\\ pub const log_level: std.log.Level = .debug;
|
||||
\\ pub const logFn = log;
|
||||
\\};
|
||||
\\
|
||||
\\pub fn main() !void {
|
||||
\\ var allocator_buf: [10]u8 = undefined;
|
||||
|
@ -1,5 +1,9 @@
|
||||
const std = @import("std");
|
||||
|
||||
pub const std_options = struct {
|
||||
pub const logFn = log;
|
||||
};
|
||||
|
||||
pub fn log(
|
||||
comptime message_level: std.log.Level,
|
||||
comptime scope: @Type(.EnumLiteral),
|
||||
|
@ -1,2 +1,4 @@
|
||||
pub const io_mode = .evented;
|
||||
pub const std_options = struct {
|
||||
pub const io_mode = .evented;
|
||||
};
|
||||
pub fn main() void {}
|
||||
|
Loading…
Reference in New Issue
Block a user