···4141 .target = target,
4242 });
43434444- mod.addImport("network", b.dependency("network", .{}).module("network"));
4545- mod.addImport("gatorcat", b.dependency("gatorcat", .{}).module("gatorcat"));
4646-4744 // Here we define an executable. An executable needs to have a root module
4845 // which needs to expose a `main` function. While we could add a main function
4946 // to the module defined above, it's sometimes preferable to split business
5050- // business logic and the CLI into two separate modules.
4747+ // logic and the CLI into two separate modules.
5148 //
5249 // If your goal is to create a Zig library for others to use, consider if
5350 // it might benefit from also exposing a CLI tool. A parser library for a
···8279 // can be extremely useful in case of collisions (which can happen
8380 // importing modules from different packages).
8481 .{ .name = "zaprus", .module = mod },
8585- .{ .name = "clap", .module = b.dependency("clap", .{}).module("clap") },
8682 },
8783 }),
8884 });
···9288 // step). By default the install prefix is `zig-out/` but can be overridden
9389 // by passing `--prefix` or `-p`.
9490 b.installArtifact(exe);
9595- b.installArtifact(b.addLibrary(.{
9696- .linkage = .static,
9797- .name = "zaprus",
9898- .root_module = mod,
9999- }));
1009110192 // This creates a top level step. Top level steps have a name and can be
10293 // invoked by name when running `zig build` (e.g. `zig build run`).
+2-15
build.zig.zon
···28282929 // Tracks the earliest Zig version that the package considers to be a
3030 // supported use case.
3131- .minimum_zig_version = "0.14.0",
3131+ .minimum_zig_version = "0.16.0",
32323333 // This field is optional.
3434 // Each dependency must either provide a `url` and `hash`, or a `path`.
3535 // `zig build --fetch` can be used to fetch all dependencies of a package, recursively.
3636 // Once all dependencies are fetched, `zig build` no longer requires
3737 // internet connectivity.
3838- .dependencies = .{
3939- .network = .{
4040- .url = "git+https://github.com/ikskuh/zig-network#7947237eec317d9458897f82089f343a05450c2b",
4141- .hash = "network-0.1.0-Pm-Agl8xAQBmkwohveGOfTk4zQnuqDs0Ptfbms4KP5Ce",
4242- },
4343- .clap = .{
4444- .url = "git+https://github.com/Hejsil/zig-clap#9cfa61596cd44ef7be35f8d2e108d2025e09868e",
4545- .hash = "clap-0.10.0-oBajB_TnAQB0l5UdW9WYhhJDEswbedvwFOzzZwGknYeR",
4646- },
4747- .gatorcat = .{
4848- .url = "git+https://github.com/jeffective/gatorcat#db73d0f7780331d82e785e85773d1afaf154c2e6",
4949- .hash = "gatorcat-0.3.11-WcrpTQn0BwArrCFVHy9FPBIPDJQqPrFdJlhiyH7Ng5x4",
5050- },
5151- },
3838+ .dependencies = .{},
5239 .paths = .{
5340 "build.zig",
5441 "build.zig.zon",
+101-65
src/main.zig
···11const is_debug = builtin.mode == .Debug;
2233-/// This creates a debug allocator that can only be referenced in debug mode.
44-/// You should check for is_debug around every reference to dba.
55-var dba: DebugAllocator =
66- if (is_debug)
77- DebugAllocator.init
88- else
99- @compileError("Should not use debug allocator in release mode");
33+const help =
44+ \\-h, --help Display this help and exit.
55+ \\-r, --relay <str> A relay message to send.
66+ \\-d, --dest <str> An IPv4 or <= 4 ASCII byte string.
77+ \\-c, --connect <str> A connection message to send.
88+ \\
99+;
10101111-pub fn main() !void {
1212- defer if (is_debug) {
1313- _ = dba.deinit();
1414- };
1515-1616- const gpa = if (is_debug) dba.allocator() else std.heap.smp_allocator;
1111+const Option = enum { help, relay, dest, connect };
1212+const to_option: StaticStringMap(Option) = .initComptime(.{
1313+ .{ "-h", .help },
1414+ .{ "--help", .help },
1515+ .{ "-r", .relay },
1616+ .{ "--relay", .relay },
1717+ .{ "-d", .dest },
1818+ .{ "--dest", .dest },
1919+ .{ "-c", .connect },
2020+ .{ "--connect", .connect },
2121+});
17222323+pub fn main(init: std.process.Init) !void {
1824 // CLI parsing adapted from the example here
1919- // https://github.com/Hejsil/zig-clap/blob/e47028deaefc2fb396d3d9e9f7bd776ae0b2a43a/README.md#examples
2525+ // https://codeberg.org/ziglang/zig/pulls/30644
20262121- // First we specify what parameters our program can take.
2222- // We can use `parseParamsComptime` to parse a string into an array of `Param(Help)`.
2323- const params = comptime clap.parseParamsComptime(
2424- \\-h, --help Display this help and exit.
2525- \\-r, --relay <str> A relay message to send.
2626- \\-d, --dest <str> An IPv4 or <= 4 ASCII byte string.
2727- \\-c, --connect <str> A connection message to send.
2828- \\
2929- );
2727+ const args = try init.minimal.args.toSlice(init.arena.allocator());
30283131- // Initialize our diagnostics, which can be used for reporting useful errors.
3232- // This is optional. You can also pass `.{}` to `clap.parse` if you don't
3333- // care about the extra information `Diagnostics` provides.
3434- var diag = clap.Diagnostic{};
3535- var res = clap.parse(clap.Help, ¶ms, clap.parsers.default, .{
3636- .diagnostic = &diag,
3737- .allocator = gpa,
3838- }) catch |err| {
3939- // Report useful error and exit.
4040- try diag.reportToFile(.stderr(), err);
4141- return err;
4242- };
4343- defer res.deinit();
4444-4545- if (res.args.help != 0) {
4646- return clap.helpToFile(.stderr(), clap.Help, ¶ms, .{});
2929+ if (args.len == 1) {
3030+ std.debug.print("{s}", .{help});
3131+ return;
4732 }
48334949- var sock_buffer: [1500]u8 = undefined;
5050- var raw_socket_writer: RawSocketWriter = try .init("enp7s0", &sock_buffer); // /proc/net/dev
5151- var net_buffer: [1500]u8 = undefined;
5252- var net_writer: NetWriter = try .init(&raw_socket_writer.interface, &net_buffer);
5353- var client = try SaprusClient.init(&net_writer.interface);
5454- defer client.deinit();
3434+ var flags: struct {
3535+ relay: ?[]const u8 = null,
3636+ dest: ?[]const u8 = null,
3737+ connect: ?[]const u8 = null,
3838+ } = .{};
55395656- if (res.args.relay) |r| {
5757- const dest = parseDest(res.args.dest);
5858- try client.sendRelay(
5959- if (r.len > 0) r else "Hello darkness my old friend",
6060- dest,
6161- );
6262- return;
6363- } else if (res.args.connect) |c| {
6464- if (false) {
6565- _ = client.connect(if (c.len > 0) c else "Hello darkness my old friend") catch |err| switch (err) {
6666- error.WouldBlock => null,
6767- else => return err,
6868- };
6969- return;
4040+ {
4141+ var i: usize = 1;
4242+ while (i < args.len) : (i += 1) {
4343+ if (to_option.get(args[i])) |opt| {
4444+ switch (opt) {
4545+ .help => {
4646+ std.debug.print("{s}\n", .{help});
4747+ return;
4848+ },
4949+ .relay => {
5050+ i += 1;
5151+ if (i < args.len) {
5252+ flags.relay = args[i];
5353+ } else {
5454+ std.debug.print("-r/--relay requires a string\n", .{});
5555+ return;
5656+ }
5757+ },
5858+ .dest => {
5959+ i += 1;
6060+ if (i < args.len) {
6161+ flags.dest = args[i];
6262+ } else {
6363+ std.debug.print("-d/--dest requires a string\n", .{});
6464+ return;
6565+ }
6666+ },
6767+ .connect => {
6868+ i += 1;
6969+ if (i < args.len) {
7070+ flags.connect = args[i];
7171+ } else {
7272+ std.debug.print("-c/--connect requires a string\n", .{});
7373+ return;
7474+ }
7575+ },
7676+ }
7777+ } else {
7878+ std.debug.print("Unknown argument: {s}\n", .{args[i]});
7979+ }
7080 }
7171- @panic("Not implemented");
7281 }
73827474- return clap.helpToFile(.stderr(), clap.Help, ¶ms, .{});
8383+ std.debug.print("relay: {s}\n", .{flags.relay orelse "<null>"});
8484+ std.debug.print("dest: {s}\n", .{flags.dest orelse "<null>"});
8585+ std.debug.print("connect: {s}\n", .{flags.connect orelse "<null>"});
8686+8787+ // var sock_buffer: [1500]u8 = undefined;
8888+ // var raw_socket_writer: RawSocketWriter = try .init("enp7s0", &sock_buffer); // /proc/net/dev
8989+ // var net_buffer: [1500]u8 = undefined;
9090+ // var net_writer: NetWriter = try .init(&raw_socket_writer.interface, &net_buffer);
9191+ // var client = try SaprusClient.init(&net_writer.interface);
9292+ // defer client.deinit();
9393+9494+ // if (res.args.relay) |r| {
9595+ // const dest = parseDest(res.args.dest);
9696+ // try client.sendRelay(
9797+ // if (r.len > 0) r else "Hello darkness my old friend",
9898+ // dest,
9999+ // );
100100+ // return;
101101+ // } else if (res.args.connect) |c| {
102102+ // if (false) {
103103+ // _ = client.connect(if (c.len > 0) c else "Hello darkness my old friend") catch |err| switch (err) {
104104+ // error.WouldBlock => null,
105105+ // else => return err,
106106+ // };
107107+ // return;
108108+ // }
109109+ // @panic("Not implemented");
110110+ // }
111111+112112+ // return clap.helpToFile(.stderr(), clap.Help, ¶ms, .{});
75113}
7611477115fn parseDest(in: ?[]const u8) [4]u8 {
···9012891129const builtin = @import("builtin");
92130const std = @import("std");
9393-const DebugAllocator = std.heap.DebugAllocator(.{});
94131const ArrayList = std.ArrayList;
132132+const StaticStringMap = std.StaticStringMap;
9513396134const zaprus = @import("zaprus");
97135const SaprusClient = zaprus.Client;
98136const SaprusMessage = zaprus.Message;
99137const RawSocketWriter = zaprus.RawSocketWriter;
100100-const NetWriter = zaprus.NetWriter;
101101-102102-const clap = @import("clap");
138138+// const NetWriter = zaprus.NetWriter;