summaryrefslogtreecommitdiff
path: root/src/cmd.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd.zig')
-rw-r--r--src/cmd.zig250
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 => {},
+ }
+ }
+};