std: make options a struct instance instead of a namespace

This commit is contained in:
Veikka Tuominen 2024-01-28 00:30:24 +02:00
parent 776cd673f2
commit 220d3264c9
10 changed files with 47 additions and 108 deletions

View file

@ -18,12 +18,12 @@
//! ```
//! const std = @import("std");
//!
//! pub const std_options = struct {
//! pub const std_options = .{
//! // Set the log level to info
//! pub const log_level = .info;
//! .log_level = .info,
//!
//! // Define logFn to override the std implementation
//! pub const logFn = myLogFn;
//! .logFn = myLogFn,
//! };
//!
//! pub fn myLogFn(

View file

@ -195,79 +195,35 @@ 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 {};
/// Stdlib-wide options that can be overridden by the root file.
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;
pub const options: Options = if (@hasDecl(root, "std_options")) root.std_options else .{};
pub const Options = struct {
enable_segfault_handler: bool = 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;
wasiCwd: fn () fs.Dir = fs.defaultWasiCwd,
/// The current log level.
pub const log_level: log.Level = if (@hasDecl(options_override, "log_level"))
options_override.log_level
else
log.default_level;
log_level: log.Level = log.default_level,
pub const log_scope_levels: []const log.ScopeLevel = if (@hasDecl(options_override, "log_scope_levels"))
options_override.log_scope_levels
else
&.{};
log_scope_levels: []const log.ScopeLevel = &.{},
pub const logFn: fn (
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;
) void = log.defaultLog,
pub const fmt_max_depth = if (@hasDecl(options_override, "fmt_max_depth"))
options_override.fmt_max_depth
else
fmt.default_max_depth;
fmt_max_depth: usize = fmt.default_max_depth,
pub const cryptoRandomSeed: fn (buffer: []u8) void = if (@hasDecl(options_override, "cryptoRandomSeed"))
options_override.cryptoRandomSeed
else
@import("crypto/tlcsprng.zig").defaultRandomSeed;
cryptoRandomSeed: fn (buffer: []u8) void = @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;
crypto_always_getrandom: bool = false,
pub const crypto_fork_safety: bool = if (@hasDecl(options_override, "crypto_fork_safety"))
options_override.crypto_fork_safety
else
true;
crypto_fork_safety: bool = true,
/// By default Zig disables SIGPIPE by setting a "no-op" handler for it. Set this option
/// to `true` to prevent that.
@ -280,35 +236,22 @@ pub const options = struct {
/// cases it's unclear why the process was terminated. By capturing SIGPIPE instead, functions that
/// write to broken pipes will return the EPIPE error (error.BrokenPipe) and the program can handle
/// it like any other error.
pub const keep_sigpipe: bool = if (@hasDecl(options_override, "keep_sigpipe"))
options_override.keep_sigpipe
else
false;
keep_sigpipe: bool = false,
/// By default, std.http.Client will support HTTPS connections. Set this option to `true` to
/// disable TLS support.
///
/// This will likely reduce the size of the binary, but it will also make it impossible to
/// make a HTTPS connection.
pub const http_disable_tls = if (@hasDecl(options_override, "http_disable_tls"))
options_override.http_disable_tls
else
false;
http_disable_tls: bool = false,
pub const side_channels_mitigations: crypto.SideChannelsMitigations = if (@hasDecl(options_override, "side_channels_mitigations"))
options_override.side_channels_mitigations
else
crypto.default_side_channels_mitigations;
side_channels_mitigations: crypto.SideChannelsMitigations = crypto.default_side_channels_mitigations,
};
// 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 {

View file

@ -3,9 +3,9 @@ const std = @import("std");
const io = std.io;
const builtin = @import("builtin");
pub const std_options = struct {
pub const io_mode: io.Mode = builtin.test_io_mode;
pub const logFn = log;
pub const std_options = .{
.io_mode = builtin.test_io_mode,
.logFn = log,
};
var log_err_count: usize = 0;

View file

@ -29,16 +29,16 @@ const AstGen = @import("AstGen.zig");
const mingw = @import("mingw.zig");
const Server = std.zig.Server;
pub const std_options = struct {
pub const wasiCwd = wasi_cwd;
pub const logFn = log;
pub const enable_segfault_handler = false;
pub const std_options = .{
.wasiCwd = wasi_cwd,
.logFn = log,
.enable_segfault_handler = false,
pub const log_level: std.log.Level = switch (builtin.mode) {
.log_level = switch (builtin.mode) {
.Debug => .debug,
.ReleaseSafe, .ReleaseFast => .info,
.ReleaseSmall => .err,
};
},
};
// Crash report needs to override the panic handler

View file

@ -440,14 +440,14 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
cases.add("std.log per scope log level override",
\\const std = @import("std");
\\
\\pub const std_options = struct {
\\ pub const log_level: std.log.Level = .debug;
\\pub const std_options = .{
\\ .log_level = .debug,
\\
\\ pub const log_scope_levels = &[_]std.log.ScopeLevel{
\\ .log_scope_levels = &.{
\\ .{ .scope = .a, .level = .warn },
\\ .{ .scope = .c, .level = .err },
\\ };
\\ pub const logFn = log;
\\ },
\\ .logFn = log,
\\};
\\
\\const loga = std.log.scoped(.a);
@ -497,9 +497,9 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
cases.add("std.heap.LoggingAllocator logs to std.log",
\\const std = @import("std");
\\
\\pub const std_options = struct {
\\ pub const log_level: std.log.Level = .debug;
\\ pub const logFn = log;
\\pub const std_options = .{
\\ .log_level = .debug,
\\ .logFn = log,
\\};
\\
\\pub fn main() !void {

View file

@ -1207,8 +1207,8 @@ const WaitGroup = std.Thread.WaitGroup;
const build_options = @import("build_options");
const Package = @import("../../src/Package.zig");
pub const std_options = struct {
pub const log_level: std.log.Level = .err;
pub const std_options = .{
.log_level = .err,
};
var general_purpose_allocator = std.heap.GeneralPurposeAllocator(.{

View file

@ -7,8 +7,8 @@ const Client = http.Client;
const mem = std.mem;
const testing = std.testing;
pub const std_options = struct {
pub const http_disable_tls = true;
pub const std_options = .{
.http_disable_tls = true,
};
const max_header_size = 8192;

View file

@ -1,7 +1,7 @@
const std = @import("std");
pub const std_options = struct {
pub const logFn = log;
pub const std_options = .{
.logFn = log,
};
pub fn log(

View file

@ -1,4 +0,0 @@
pub const std_options = struct {
pub const io_mode = .evented;
};
pub fn main() void {}

View file

@ -1,11 +1,11 @@
const std = @import("std");
const build_options = @import("build_options");
pub const std_options = if (build_options.keep_sigpipe) struct {
pub const keep_sigpipe = true;
} else struct {
// intentionally not setting keep_sigpipe to ensure the default behavior is equivalent to false
};
pub usingnamespace if (build_options.keep_sigpipe) struct {
pub const std_options = .{
.keep_sigpipe = true,
};
} else struct {};
pub fn main() !void {
const pipe = try std.os.pipe();