-
Notifications
You must be signed in to change notification settings - Fork 139
Expand file tree
/
Copy pathroot.zig
More file actions
128 lines (116 loc) · 5.31 KB
/
Copy pathroot.zig
File metadata and controls
128 lines (116 loc) · 5.31 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
const std = @import("std");
const types = @import("../types.zig");
const common = @import("common.zig");
const app = @import("app.zig");
const alias = @import("alias.zig");
const clean = @import("clean.zig");
const config = @import("config.zig");
const export_auth = @import("export.zig");
const import_auth = @import("import.zig");
const list = @import("list.zig");
const login = @import("login.zig");
const remove = @import("remove.zig");
const reset = @import("reset.zig");
const switch_account = @import("switch.zig");
pub fn parseArgs(allocator: std.mem.Allocator, args: []const [:0]const u8) !types.ParseResult {
if (args.len < 2) return .{ .command = .{ .help = .top_level } };
const cmd = std.mem.sliceTo(args[1], 0);
if (common.isHelpFlag(cmd)) {
if (args.len > 2) {
return common.usageErrorResult(allocator, .top_level, "unexpected argument after `{s}`: `{s}`.", .{
cmd,
std.mem.sliceTo(args[2], 0),
});
}
return .{ .command = .{ .help = .top_level } };
}
if (std.mem.eql(u8, cmd, "help")) return parseHelpArgs(allocator, args[2..]);
if (std.mem.eql(u8, cmd, "--version") or std.mem.eql(u8, cmd, "-V")) {
if (args.len > 2) {
return common.usageErrorResult(allocator, .top_level, "unexpected argument after `{s}`: `{s}`.", .{
cmd,
std.mem.sliceTo(args[2], 0),
});
}
return .{ .command = .{ .version = {} } };
}
if (std.mem.eql(u8, cmd, "-")) {
if (args.len > 2) {
return common.usageErrorResult(allocator, .top_level, "unexpected argument after `-`: `{s}`.", .{
std.mem.sliceTo(args[2], 0),
});
}
return .{ .command = .{ .switch_account = .{ .target = .previous } } };
}
if (std.mem.eql(u8, cmd, "list")) return list.parse(allocator, args[2..]);
if (std.mem.eql(u8, cmd, "login")) return login.parse(allocator, args[2..]);
if (std.mem.eql(u8, cmd, "import")) return import_auth.parse(allocator, args[2..]);
if (std.mem.eql(u8, cmd, "export")) return export_auth.parse(allocator, args[2..]);
if (std.mem.eql(u8, cmd, "switch")) return switch_account.parse(allocator, args[2..]);
if (std.mem.eql(u8, cmd, "remove")) return remove.parse(allocator, args[2..]);
if (std.mem.eql(u8, cmd, "alias")) return alias.parse(allocator, args[2..]);
if (std.mem.eql(u8, cmd, "reset")) return reset.parse(allocator, args[2..]);
if (std.mem.eql(u8, cmd, "clean")) return clean.parse(allocator, args[2..]);
if (std.mem.eql(u8, cmd, "config")) return config.parse(allocator, args[2..]);
if (std.mem.eql(u8, cmd, "app")) return app.parse(allocator, args[2..]);
return common.usageErrorResult(allocator, .top_level, "unknown command `{s}`.", .{cmd});
}
pub fn freeParseResult(allocator: std.mem.Allocator, result: *types.ParseResult) void {
switch (result.*) {
.command => |*cmd| freeCommand(allocator, cmd),
.usage_error => |usage_err| allocator.free(usage_err.message),
}
result.* = undefined;
}
fn freeCommand(allocator: std.mem.Allocator, cmd: *types.Command) void {
switch (cmd.*) {
.import_auth => |opts| common.freeImportOptions(allocator, opts.auth_path, opts.alias),
.export_auth => |opts| {
if (opts.dest_path) |path| allocator.free(path);
},
.switch_account => |opts| switch (opts.target) {
.query => |query| allocator.free(query),
else => {},
},
.remove_account => |opts| {
common.freeOwnedStringList(allocator, opts.selectors);
allocator.free(opts.selectors);
},
.alias => |opts| switch (opts) {
.set => |set_opts| {
allocator.free(set_opts.selector);
allocator.free(set_opts.alias);
},
.clear => |clear_opts| allocator.free(clear_opts.selector),
},
.reset => |opts| allocator.free(opts.selector),
else => {},
}
cmd.* = undefined;
}
fn parseHelpArgs(allocator: std.mem.Allocator, rest: []const [:0]const u8) !types.ParseResult {
if (rest.len == 0) return .{ .command = .{ .help = .top_level } };
if (rest.len > 1) {
return common.usageErrorResult(allocator, .top_level, "unexpected argument after `help`: `{s}`.", .{
std.mem.sliceTo(rest[1], 0),
});
}
const topic_name = std.mem.sliceTo(rest[0], 0);
const topic = helpTopicForName(topic_name) orelse
return common.usageErrorResult(allocator, .top_level, "unknown help topic `{s}`.", .{topic_name});
return .{ .command = .{ .help = topic } };
}
fn helpTopicForName(name: []const u8) ?types.HelpTopic {
if (std.mem.eql(u8, name, "list")) return .list;
if (std.mem.eql(u8, name, "login")) return .login;
if (std.mem.eql(u8, name, "import")) return .import_auth;
if (std.mem.eql(u8, name, "export")) return .export_auth;
if (std.mem.eql(u8, name, "switch")) return .switch_account;
if (std.mem.eql(u8, name, "remove")) return .remove_account;
if (std.mem.eql(u8, name, "alias")) return .alias;
if (std.mem.eql(u8, name, "reset")) return .reset;
if (std.mem.eql(u8, name, "clean")) return .clean;
if (std.mem.eql(u8, name, "config")) return .config;
if (std.mem.eql(u8, name, "app")) return .app;
return null;
}