summaryrefslogtreecommitdiff
path: root/src/parser.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/parser.zig')
-rw-r--r--src/parser.zig63
1 files changed, 59 insertions, 4 deletions
diff --git a/src/parser.zig b/src/parser.zig
index b07f31c..7bbfdab 100644
--- a/src/parser.zig
+++ b/src/parser.zig
@@ -270,7 +270,19 @@ const Parser = struct {
const cmd_upper = try std.ascii.allocUpperString(self.allocator, command_name);
defer self.allocator.free(cmd_upper);
- if (std.mem.eql(u8, cmd_upper, "ECHO")) {
+ // Check for /? help flag first
+ if (hasHelpFlag(args.items)) {
+ const cmd_copy = try self.allocator.dupe(u8, cmd_upper);
+ return Command{ .Builtin = BuiltinCommand{ .Help = .{ .command = cmd_copy } } };
+ }
+
+ if (std.mem.eql(u8, cmd_upper, "HELP")) {
+ const help_command = if (args.items.len > 0)
+ try self.allocator.dupe(u8, args.items[0])
+ else
+ null;
+ return Command{ .Builtin = BuiltinCommand{ .Help = .{ .command = help_command } } };
+ } else if (std.mem.eql(u8, cmd_upper, "ECHO")) {
if (args.items.len == 0) {
return Command{ .Builtin = BuiltinCommand.EchoPlain };
} else {
@@ -295,11 +307,30 @@ const Parser = struct {
} else if (std.mem.eql(u8, cmd_upper, "VERIFY")) {
return Command{ .Builtin = BuiltinCommand.Verify };
} else if (std.mem.eql(u8, cmd_upper, "DIR")) {
- const path = if (args.items.len == 0)
+ const separated = try self.separateFlagsFromArgs(args.items);
+ defer separated.flags.deinit();
+ defer separated.positional.deinit();
+
+ const path = if (separated.positional.items.len == 0)
try self.allocator.dupe(u8, ".")
else
- try self.allocator.dupe(u8, args.items[0]);
- return Command{ .Builtin = BuiltinCommand{ .Dir = .{ .path = path } } };
+ try self.allocator.dupe(u8, separated.positional.items[0]);
+
+ var wide_format = false;
+ var bare_format = false;
+ var subdirs = false;
+
+ for (separated.flags.items) |flag| {
+ if (std.mem.eql(u8, flag, "/w") or std.mem.eql(u8, flag, "/W")) {
+ wide_format = true;
+ } else if (std.mem.eql(u8, flag, "/b") or std.mem.eql(u8, flag, "/B")) {
+ bare_format = true;
+ } else if (std.mem.eql(u8, flag, "/s") or std.mem.eql(u8, flag, "/S")) {
+ subdirs = true;
+ }
+ }
+
+ return Command{ .Builtin = BuiltinCommand{ .Dir = .{ .path = path, .wide_format = wide_format, .bare_format = bare_format, .subdirs = subdirs } } };
} else if (std.mem.eql(u8, cmd_upper, "VER")) {
return Command{ .Builtin = BuiltinCommand.Ver };
} else if (std.mem.eql(u8, cmd_upper, "DATE")) {
@@ -378,6 +409,30 @@ const Parser = struct {
return Command{ .External = .{ .program = program_copy, .args = args_copy } };
}
}
+
+ fn hasHelpFlag(args: []const []const u8) bool {
+ for (args) |arg| {
+ if (std.mem.eql(u8, arg, "/?") or std.mem.eql(u8, arg, "/h") or std.mem.eql(u8, arg, "/help")) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ fn separateFlagsFromArgs(self: *Parser, args: []const []const u8) !struct { flags: ArrayList([]const u8), positional: ArrayList([]const u8) } {
+ var flags = ArrayList([]const u8).init(self.allocator);
+ var positional = ArrayList([]const u8).init(self.allocator);
+
+ for (args) |arg| {
+ if (arg.len > 0 and arg[0] == '/') {
+ try flags.append(arg);
+ } else {
+ try positional.append(arg);
+ }
+ }
+
+ return .{ .flags = flags, .positional = positional };
+ }
};
fn parseFilespec(allocator: Allocator, path_str: []const u8) !FileSpec {