diff options
Diffstat (limited to 'src/cmd.zig')
-rw-r--r-- | src/cmd.zig | 250 |
1 files changed, 250 insertions, 0 deletions
diff --git a/src/cmd.zig b/src/cmd.zig new file mode 100644 index 0000000..665b2bf --- /dev/null +++ b/src/cmd.zig @@ -0,0 +1,250 @@ +const std = @import("std"); +const Allocator = std.mem.Allocator; +const ArrayList = std.ArrayList; + +const syntax = @import("syntax.zig"); +const FileSpec = syntax.FileSpec; +const Redirect = syntax.Redirect; + +const Copy = @import("cmd/copy.zig").Copy; + +pub const BuiltinCommand = union(enum) { + // File-oriented + Copy: Copy, + Deltree: struct { + path: []const u8, + }, + Dir: struct { + path: []const u8, + }, + Fc, + Find, + Mkdir: struct { + path: []const u8, + }, + Move, + Remove: struct { + path: []const u8, + }, + Rename: struct { + from: FileSpec, + to: FileSpec, + }, + Replace, + Rmdir: struct { + path: []const u8, + }, + Sort, + Tree: struct { + path: []const u8, + }, + Type: struct { + file: FileSpec, + }, + Xcopy: struct { + from: FileSpec, + to: FileSpec, + recursive: bool, + }, + + // Shell-oriented + Append, + Chdir: struct { + path: []const u8, + }, + EchoOff, + EchoOn, + EchoPlain, + EchoText: struct { + message: []const u8, + }, + Exit, + PathGet, + PathSet: struct { + value: []const u8, + }, + PromptGet, + PromptSet: struct { + message: []const u8, + }, + Set: struct { + name: []const u8, + value: []const u8, + }, + Setver, + Ver, + + // Utilities + Date, + Time, + + // Screen-oriented + Cls, + More, + + // Dummies + Verify, + Fastopen, + Smartdrv, + Sizer, + + // For later + Assign, + Attrib, + Chkdsk, + Doskey, + Dosshell, + Edit, + Fasthelp, + Help, + Join, + Mem, + Power, + Subst, + Truename, + + // For much later, if ever + Break, + Chcp, + Ctty, + Defrag, + Diskcopy, + Emm386, + Fdisk, + Format, + Interlnk, + Keyb, + Label, + Mode, + Msav, + Msbackup, + Mscdex, + Msd, + Print_: void, // 'print' is reserved in Zig + Qbasic, + Restore, + Scandisk, + Share, + Sys, + Undelete, + Unformat, + Vol, + Vsafe, + + // Scripting + Call, + Choice, + Echo, + For, + Goto, + If, + Pause, + Prompt, + Rem: struct { + message: []const u8, + }, + Shift, +}; + +pub const Command = union(enum) { + Pipe: struct { + left: *Command, + right: *Command, + }, + Redirect: struct { + command: *Command, + redirects: ArrayList(Redirect), + }, + External: struct { + program: []const u8, + args: ArrayList([]const u8), + }, + Builtin: BuiltinCommand, + Empty, + + pub fn deinit(self: *Command, allocator: Allocator) void { + switch (self.*) { + .Pipe => |*pipe| { + pipe.left.deinit(allocator); + pipe.right.deinit(allocator); + allocator.destroy(pipe.left); + allocator.destroy(pipe.right); + }, + .Redirect => |*redirect| { + redirect.command.deinit(allocator); + allocator.destroy(redirect.command); + for (redirect.redirects.items) |redir| { + switch (redir.target) { + .Path => |path| allocator.free(path), + else => {}, + } + } + redirect.redirects.deinit(); + }, + .External => |*external| { + allocator.free(external.program); + for (external.args.items) |arg| { + allocator.free(arg); + } + external.args.deinit(); + }, + .Builtin => |builtin| { + switch (builtin) { + .Dir => |dir| allocator.free(dir.path), + .Chdir => |chdir| allocator.free(chdir.path), + .EchoText => |echo| allocator.free(echo.message), + .Type => |type_cmd| { + switch (type_cmd.file) { + .Path => |path| allocator.free(path), + else => {}, + } + }, + .Copy => |copy| { + switch (copy.from) { + .Path => |path| allocator.free(path), + else => {}, + } + switch (copy.to) { + .Path => |path| allocator.free(path), + else => {}, + } + }, + .Remove => |remove| allocator.free(remove.path), + .Mkdir => |mkdir| allocator.free(mkdir.path), + .Deltree => |deltree| allocator.free(deltree.path), + .Tree => |tree| allocator.free(tree.path), + .Rmdir => |rmdir| allocator.free(rmdir.path), + .PathSet => |pathset| allocator.free(pathset.value), + .PromptSet => |promptset| allocator.free(promptset.message), + .Set => |set| { + allocator.free(set.name); + allocator.free(set.value); + }, + .Rem => |rem| allocator.free(rem.message), + .Rename => |rename| { + switch (rename.from) { + .Path => |path| allocator.free(path), + else => {}, + } + switch (rename.to) { + .Path => |path| allocator.free(path), + else => {}, + } + }, + .Xcopy => |xcopy| { + switch (xcopy.from) { + .Path => |path| allocator.free(path), + else => {}, + } + switch (xcopy.to) { + .Path => |path| allocator.free(path), + else => {}, + } + }, + else => {}, + } + }, + else => {}, + } + } +}; |