authorgravatar for hello@nektro.netMeghan Denny <hello@nektro.net> 2021-09-11 01:31:19 -07:00
committergravatar for hello@nektro.netMeghan Denny <hello@nektro.net> 2021-09-11 01:31:19 -07:00
loge33f6377f0718880908f9712ba47d83c2c9abfb9
treef6f47e4e7fbc032900d7e6c2d0c81ff6717189c0
parentf0f44765c5594bf7cda36da6c95d6976ec6f5d1f

initial code implementation


6 files changed, 117 insertions(+), 0 deletions(-)

.gitignore created+3
...@@ -0,0 +1,3 @@
1zig-*
2.zigmod
3deps.zig
build.zig created+27
...@@ -0,0 +1,27 @@
1const std = @import("std");
2
3pub fn build(b: *std.build.Builder) void {
4 // Standard target options allows the person running `zig build` to choose
5 // what target to build for. Here we do not override the defaults, which
6 // means any target is allowed, and the default is native. Other options
7 // for restricting supported target set are available.
8 const target = b.standardTargetOptions(.{});
9
10 // Standard release options allow the person running `zig build` to select
11 // between Debug, ReleaseSafe, ReleaseFast, and ReleaseSmall.
12 const mode = b.standardReleaseOptions();
13
14 const exe = b.addExecutable("zig-flag", "src/main.zig");
15 exe.setTarget(target);
16 exe.setBuildMode(mode);
17 exe.install();
18
19 const run_cmd = exe.run();
20 run_cmd.step.dependOn(b.getInstallStep());
21 if (b.args) |args| {
22 run_cmd.addArgs(args);
23 }
24
25 const run_step = b.step("run", "Run the app");
26 run_step.dependOn(&run_cmd.step);
27}
src/lib.zig created+73
...@@ -0,0 +1,73 @@
1const std = @import("std");
2const string = []const u8;
3const List = std.ArrayList(string);
4const extras = @import("extras");
5
6var singles: std.StringArrayHashMap(string) = undefined;
7var multis: std.StringArrayHashMap(List) = undefined;
8
9pub fn init(alloc: *std.mem.Allocator) void {
10 singles = std.StringArrayHashMap(string).init(alloc);
11 multis = std.StringArrayHashMap(List).init(alloc);
12}
13
14pub fn addSingle(name: string) !void {
15 try singles.putNoClobber(name, "");
16}
17
18pub fn addMulti(name: string) !void {
19 try multis.putNoClobber(name, List.init(multis.allocator));
20}
21
22pub const FlagDashKind = enum {
23 single,
24 double,
25
26 pub fn hypen(self: FlagDashKind) string {
27 return switch (self) {
28 .single => "-",
29 .double => "--",
30 };
31 }
32};
33
34pub fn parse(k: FlagDashKind) !std.process.ArgIterator {
35 const dash = k.hypen();
36 var argiter = std.process.args();
37 defer argiter.deinit();
38 var argi: usize = 0;
39 blk: while (argiter.next(singles.allocator)) |item| : (argi += 1) {
40 if (argi == 0) continue;
41 const data = try item;
42 const name = extras.trimPrefix(data, dash);
43 if (data.len == name.len) return error.BadFlag;
44
45 for (singles.keys()) |jtem| {
46 if (std.mem.eql(u8, name, jtem)) {
47 const value = try argiter.next(singles.allocator).?;
48 try singles.put(name, value);
49 continue :blk;
50 }
51 }
52 for (multis.keys()) |jtem| {
53 if (std.mem.eql(u8, name, jtem)) {
54 const value = try argiter.next(multis.allocator).?;
55 try multis.get(name).?.append(value);
56 continue :blk;
57 }
58 }
59 std.log.err("Unrecognized argument: {s}{s}", .{ dash, name });
60 std.os.exit(1);
61 }
62 return argiter;
63}
64
65pub fn getSingle(name: string) ?string {
66 const x = singles.get(name).?;
67 return if (x.len > 0) x else null;
68}
69
70pub fn getMulti(name: string) ?[]const string {
71 const x = multis.get(name).?.toOwnedSlice();
72 return if (x.len > 0) x else null;
73}
src/main.zig created+5
...@@ -0,0 +1,5 @@
1const std = @import("std");
2
3pub fn main() anyerror!void {
4 std.log.info("All your codebase are belong to us.", .{});
5}
zig.mod created+7
...@@ -0,0 +1,7 @@
1id: pm68dn67ppvlmnp1taw31k1t9exei2oqvfx2l9nuxgmeeo32
2name: flag
3main: src/lib.zig
4license: MIT
5description: Config management for Zig.
6dependencies:
7 - src: git https://github.com/nektro/zig-extras
zigmod.lock created+2
...@@ -0,0 +1,2 @@
12
2git https://github.com/nektro/zig-extras commit-0657e287853475843c27660242e9bbb117374c6b