Zig 0.17.0-dev (Split by item)

This is an example of documentation generated by ZigDoc, an alternative to Zig's built-in Auto Doc feature. See also examples in other modes/formats. The project being documented here (as the example) is the Zig library itself.

main

objdump.main
pub fn main(init: std.process.Init) !void

File

lib/compiler/objdump.zig:49

Code

pub fn main(init: std.process.Init) !void {
    const io = init.io;
    const args = try init.minimal.args.toSlice(init.arena.allocator());
    const arena = init.arena.allocator();

    var i: usize = 1;

    var opt_exports: ?bool = null;
    var opt_exports_sort: ?bool = null;
    var opt_file_headers: ?bool = null;
    var opt_imports: ?bool = null;
    var opt_input_path: ?[]const u8 = null;
    var opt_linker_member: ?std.coff.ArchiveMemberHeader.Kind = null;
    var opt_member_headers: ?bool = null;
    var any_elements = false;
    var elements: ?@FieldType(Options, "elements") = null;
    var redact: @FieldType(Options, "redact") = .initFill(false);
    var opt_relocs: ?bool = null;
    var opt_section_headers: ?bool = null;
    var opt_strings: ?bool = null;
    var opt_symbols: ?bool = null;
    var opt_tls: ?bool = null;
    var section_filters: std.ArrayList([]const u8) = .empty;
    var symbol_filters: std.ArrayList([]const u8) = .empty;
    var member_filters: std.ArrayList([]const u8) = .empty;
    while (i < args.len) : (i += 1) {
        const arg = args[i];
        if (mem.startsWith(u8, arg, "-")) {
            if (mem.eql(u8, arg, "-h") or mem.eql(u8, arg, "--help")) {
                return Io.File.stdout().writeStreamingAll(io, usage);
            } else if (mem.eql(u8, arg, "--all-headers")) {
                opt_file_headers = true;
                opt_linker_member = .second_linker;
                opt_member_headers = true;
                opt_section_headers = true;
                opt_symbols = true;
                opt_relocs = true;
            } else if (mem.startsWith(u8, arg, "--exports")) {
                opt_exports = true;
                opt_linker_member = .second_linker;
                if (mem.eql(u8, arg["--exports".len..], "=sort"))
                    opt_exports_sort = true;
            } else if (mem.eql(u8, arg, "--file-headers")) {
                opt_file_headers = true;
            } else if (mem.eql(u8, arg, "--imports")) {
                opt_imports = true;
            } else if (mem.startsWith(u8, arg, "--linker-member")) {
                if (mem.eql(u8, arg["--linker-member".len..], "=1"))
                    opt_linker_member = .first_linker
                else if (mem.eql(u8, arg["--linker-member".len..], "=longnames"))
                    opt_linker_member = .longnames
                else
                    opt_linker_member = .second_linker;
            } else if (mem.eql(u8, arg, "--member-headers")) {
                opt_member_headers = true;
            } else if (mem.startsWith(u8, arg, "--elements=")) {
                any_elements = true;
                var split = std.mem.splitScalar(u8, arg["--elements=".len..], ',');
                while (split.next()) |element| {
                    const kind, const add = if (element.len > 0 and element[0] == '-')
                        .{ element[1..], false }
                    else
                        .{ element, true };

                    if (elements == null) elements = .initFill(false);
                    if (std.meta.stringToEnum(Element, kind)) |format_kind| {
                        elements.?.set(format_kind, add);
                    } else if (std.mem.eql(u8, kind, "all")) {
                        elements.? = .initFill(add);
                    } else {
                        fatal("unrecognized element: '{s}'", .{kind});
                    }
                }
            } else if (mem.startsWith(u8, arg, "--only-member=")) {
                (try member_filters.addOne(arena)).* = try arena.dupe(u8, arg["--only-member=".len..]);
            } else if (mem.startsWith(u8, arg, "--only-section=")) {
                (try section_filters.addOne(arena)).* = try arena.dupe(u8, arg["--only-section=".len..]);
            } else if (mem.startsWith(u8, arg, "--only-symbol=")) {
                (try symbol_filters.addOne(arena)).* = try arena.dupe(u8, arg["--only-symbol=".len..]);
            } else if (mem.startsWith(u8, arg, "--redact=")) {
                const kind = arg["--redact=".len..];
                if (std.meta.stringToEnum(FieldKind, kind)) |field_kind| {
                    redact.set(field_kind, true);
                } else if (std.mem.eql(u8, kind, "all")) {
                    redact = .initFill(true);
                } else {
                    fatal("unrecognized redaction kind: {s}", .{kind});
                }
            } else if (mem.eql(u8, arg, "--relocs")) {
                opt_relocs = true;
            } else if (mem.eql(u8, arg, "--section-headers")) {
                opt_section_headers = true;
            } else if (mem.eql(u8, arg, "-s") or mem.eql(u8, arg, "--snapshot")) {
                elements = .initFill(false);
                redact = .initFill(true);
            } else if (mem.eql(u8, arg, "--strings")) {
                opt_strings = true;
            } else if (mem.eql(u8, arg, "--symbols")) {
                opt_symbols = true;
            } else if (mem.eql(u8, arg, "--tls")) {
                opt_tls = true;
            } else {
                fatal("unrecognized argument: {s}", .{arg});
            }
        } else if (opt_input_path == null) {
            opt_input_path = arg;
        } else {
            fatal("unexpected positional: {s}", .{arg});
        }
    }

    const opts: Options = .{
        .input_path = opt_input_path orelse fatal("missing input file path positional argument", .{}),
        .exports = opt_exports orelse false,
        .exports_sort = opt_exports_sort orelse false,
        .file_headers = opt_file_headers orelse false,
        .imports = opt_imports orelse false,
        .linker_member = opt_linker_member,
        .member_filters = member_filters.items,
        .member_headers = opt_member_headers orelse false,
        .elements = elements orelse .initFill(true),
        .redact = redact,
        .relocs = opt_relocs orelse false,
        .section_filters = section_filters.items,
        .section_headers = opt_section_headers orelse false,
        .strings = opt_strings orelse false,
        .symbol_filters = symbol_filters.items,
        .symbols = opt_symbols orelse false,
        .tls = opt_tls orelse false,
    };

    var file = std.Io.Dir.cwd().openFile(io, opts.input_path, .{}) catch |err|
        fatal("failed to open {s}: {t}", .{ opts.input_path, err });
    defer file.close(io);

    var buffer: [4096]u8 = undefined;
    var file_reader = file.reader(io, &buffer);
    var stdout_writer = std.Io.File.stdout().writerStreaming(io, &stdout_buffer);

    const ctx: DumpContext = .{
        .gpa = init.gpa,
        .opts = &opts,
        .fr = &file_reader,
        .w = &stdout_writer.interface,
    };

    dump(&ctx) catch |err| switch (err) {
        error.ReadFailed => return file_reader.err.?,
        error.WriteFailed => return stdout_writer.err.?,
        error.UnknownFile => fatal("unrecognized file: {s}", .{opts.input_path}),
        error.ParseFailure => {},
        else => |e| return e,
    };
    try stdout_writer.flush();
}