summaryrefslogtreecommitdiff
path: root/src/main.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.zig')
-rw-r--r--src/main.zig149
1 files changed, 149 insertions, 0 deletions
diff --git a/src/main.zig b/src/main.zig
new file mode 100644
index 0000000..e987bb0
--- /dev/null
+++ b/src/main.zig
@@ -0,0 +1,149 @@
+const std = @import("std");
+const argsWithAllocator = std.process.argsWithAllocator;
+const eql = std.mem.eql;
+const expect = std.testing.expect;
+const parseInt = std.fmt.parseInt;
+const print = std.debug.print;
+const GeneralPurposeAllocator = std.heap.GeneralPurposeAllocator;
+
+/// There are 4 args: help, version, copyright, and quiet
+/// ArgType also contains longarg, which is how zeven checks if the arg
+/// will be --
+const ArgType = enum {
+ help,
+ version,
+ copyright,
+ quiet,
+ longarg,
+ badarg,
+};
+
+const VERSION = "1.0.0";
+const LICENSE = "MIT";
+
+test "@rem(-2, 2) == 0" {
+ try expect(@rem(-2, 2) == 0);
+}
+
+test "parseInt(i32, \"-2\", 10) == -2" {
+ var test_int = try parseInt(i32, "-2", 10);
+
+ try expect(test_int == -2);
+}
+
+test "parseInt(i32, \"\", 10) != 0" {
+ var test_int = try parseInt(i32, "-2", 10);
+ try expect(test_int != 0);
+}
+
+pub fn main() anyerror!u8 {
+ // This is an iterator for the provided args
+ var gpa = GeneralPurposeAllocator(.{}){};
+ const allocator = gpa.allocator();
+ defer _ = gpa.deinit();
+ var arg_it = try argsWithAllocator(allocator);
+ defer arg_it.deinit();
+ var f_arg: ?ArgType = null;
+ var f_int: i32 = undefined;
+ // This is whether or not to print the results
+ var quiet: bool = false;
+ // This is to check if a value has been provided
+ var value: bool = false;
+ // This skips the name of the binary
+ _ = arg_it.next();
+ while (arg_it.next()) |arg| {
+ f_arg = null;
+ if (arg[0] == '-') { // It's an arg!
+ f_arg = switch (arg[1]) {
+ 'h' => ArgType.help,
+ 'v' => ArgType.version,
+ 'c' => ArgType.copyright,
+ 'q' => ArgType.quiet,
+ '-' => ArgType.longarg,
+ '0'...'9' => null,
+ else => ArgType.badarg,
+ };
+ }
+ if (f_arg) |usearg| {
+ var realarg = usearg;
+ if (usearg == ArgType.longarg) {
+ if (eql(u8, arg, "--help")) {
+ realarg = ArgType.help;
+ } else if (eql(u8, arg, "--copyright")) {
+ realarg = ArgType.copyright;
+ } else if (eql(u8, arg, "--version")) {
+ realarg = ArgType.version;
+ } else if (eql(u8, arg, "--quiet")) {
+ realarg = ArgType.quiet;
+ } else {
+ realarg = ArgType.badarg;
+ }
+ }
+ _ = switch (realarg) {
+ ArgType.quiet => {
+ quiet = true;
+ continue;
+ },
+ ArgType.help => {
+ return print_arg(0);
+ },
+ ArgType.copyright => {
+ return print_arg(1);
+ },
+ ArgType.version => {
+ return print_arg(2);
+ },
+ else => {
+ return print_arg(255);
+ },
+ };
+ } else { // Not an arg!
+ value = true;
+ f_int = parseInt(i32, arg, 10) catch |err| return err;
+ }
+ }
+ if (value) {
+ if (@rem(f_int, 2) == 0) {
+ if (!quiet) {
+ print("even\n", .{});
+ }
+ return 0;
+ } else {
+ if (!quiet) {
+ print("odd\n", .{});
+ }
+ return 1;
+ }
+ } else {
+ print("No value was provided!\n", .{});
+ }
+ return 1;
+}
+
+pub fn print_arg(err: u8) !u8 {
+ return switch (err) {
+ 0 => {
+ print("zeven: a simple binary to check if a number ", .{});
+ print("is even or odd\n", .{});
+ print("\tzeven [-cvh]\n", .{});
+ print("\tzeven [--help]\n", .{});
+ print("\tzeven [--copyright]\n", .{});
+ print("\tzeven [--version]\n", .{});
+ print("\tzeven [-q] [--quiet] X\n", .{});
+ return 0;
+ },
+ 1 => {
+ print("zeven is Free software under the {s} license.\n", .{LICENSE});
+ print("zeven copyright (c) Zachary Smith 2024\n", .{});
+ return 0;
+ },
+ 2 => {
+ print("zeven version {s}\n", .{VERSION});
+ return 0;
+ },
+ else => {
+ print("Error!\n", .{});
+ return 1;
+ },
+ };
+}