diff options
Diffstat (limited to 'src/parser.zig')
-rw-r--r-- | src/parser.zig | 63 |
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 { |