mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 13:54:21 +00:00
delete deprecated API
This commit is intended to be reverted before the branch is merged, and then reapplied after 0.14.0 is tagged.
This commit is contained in:
parent
85e8cc8abc
commit
ffdacaac18
2 changed files with 0 additions and 492 deletions
|
|
@ -41,20 +41,6 @@ test {
|
|||
_ = windows;
|
||||
}
|
||||
|
||||
/// Deprecated in favor of accepting a `std.process.Init` argument to main.
|
||||
/// To be removed after 0.14.0 is tagged.
|
||||
/// See https://github.com/ziglang/zig/issues/4524 for more details.
|
||||
pub var environ: [][*:0]u8 = undefined;
|
||||
|
||||
/// Deprecated in favor of accepting a `std.process.Init` argument to main.
|
||||
/// To be removed after 0.14.0 is tagged.
|
||||
/// See https://github.com/ziglang/zig/issues/4524 for more details.
|
||||
pub var argv: [][*:0]u8 = if (builtin.link_libc) undefined else switch (native_os) {
|
||||
.windows => @compileError("argv isn't supported on Windows: use std.process.argsAlloc instead"),
|
||||
.wasi => @compileError("argv isn't supported on WASI: use std.process.argsAlloc instead"),
|
||||
else => undefined,
|
||||
};
|
||||
|
||||
/// Call from Windows-specific code if you already have a WTF-16LE encoded, null terminated string.
|
||||
/// Otherwise use `access` or `accessZ`.
|
||||
pub fn accessW(path: [*:0]const u16) windows.GetFileAttributesError!void {
|
||||
|
|
|
|||
|
|
@ -1137,484 +1137,6 @@ test hasEnvVar {
|
|||
try testing.expect(!has_env);
|
||||
}
|
||||
|
||||
/// Deprecated, to be removed after 0.14.0 is tagged.
|
||||
pub const ArgIteratorPosix = Init.Args.Iterator.Posix;
|
||||
/// Deprecated, to be removed after 0.14.0 is tagged.
|
||||
pub const ArgIteratorWasi = Init.Args.Iterator.Wasi;
|
||||
/// Deprecated, to be removed after 0.14.0 is tagged.
|
||||
pub const ArgIteratorWindows = Init.Args.Iterator.Windows;
|
||||
/// Deprecated, to be removed after 0.14.0 is tagged.
|
||||
pub const ArgIterator = Init.Args.Iterator;
|
||||
|
||||
/// Deprecated, to be removed after 0.14.0 is tagged.
|
||||
pub const ArgIteratorGeneralOptions = struct {
|
||||
comments: bool = false,
|
||||
single_quotes: bool = false,
|
||||
};
|
||||
|
||||
/// Deprecated, to be removed after 0.14.0 is tagged.
|
||||
pub fn ArgIteratorGeneral(comptime options: ArgIteratorGeneralOptions) type {
|
||||
return struct {
|
||||
allocator: Allocator,
|
||||
index: usize = 0,
|
||||
cmd_line: []const u8,
|
||||
|
||||
/// Should the cmd_line field be free'd (using the allocator) on deinit()?
|
||||
free_cmd_line_on_deinit: bool,
|
||||
|
||||
/// buffer MUST be long enough to hold the cmd_line plus a null terminator.
|
||||
/// buffer will we free'd (using the allocator) on deinit()
|
||||
buffer: []u8,
|
||||
start: usize = 0,
|
||||
end: usize = 0,
|
||||
|
||||
pub const Self = @This();
|
||||
|
||||
pub const InitError = error{OutOfMemory};
|
||||
|
||||
/// cmd_line_utf8 MUST remain valid and constant while using this instance
|
||||
pub fn init(allocator: Allocator, cmd_line_utf8: []const u8) InitError!Self {
|
||||
const buffer = try allocator.alloc(u8, cmd_line_utf8.len + 1);
|
||||
errdefer allocator.free(buffer);
|
||||
|
||||
return Self{
|
||||
.allocator = allocator,
|
||||
.cmd_line = cmd_line_utf8,
|
||||
.free_cmd_line_on_deinit = false,
|
||||
.buffer = buffer,
|
||||
};
|
||||
}
|
||||
|
||||
/// cmd_line_utf8 will be free'd (with the allocator) on deinit()
|
||||
pub fn initTakeOwnership(allocator: Allocator, cmd_line_utf8: []const u8) InitError!Self {
|
||||
const buffer = try allocator.alloc(u8, cmd_line_utf8.len + 1);
|
||||
errdefer allocator.free(buffer);
|
||||
|
||||
return Self{
|
||||
.allocator = allocator,
|
||||
.cmd_line = cmd_line_utf8,
|
||||
.free_cmd_line_on_deinit = true,
|
||||
.buffer = buffer,
|
||||
};
|
||||
}
|
||||
|
||||
// Skips over whitespace in the cmd_line.
|
||||
// Returns false if the terminating sentinel is reached, true otherwise.
|
||||
// Also skips over comments (if supported).
|
||||
fn skipWhitespace(self: *Self) bool {
|
||||
while (true) : (self.index += 1) {
|
||||
const character = if (self.index != self.cmd_line.len) self.cmd_line[self.index] else 0;
|
||||
switch (character) {
|
||||
0 => return false,
|
||||
' ', '\t', '\r', '\n' => continue,
|
||||
'#' => {
|
||||
if (options.comments) {
|
||||
while (true) : (self.index += 1) {
|
||||
switch (self.cmd_line[self.index]) {
|
||||
'\n' => break,
|
||||
0 => return false,
|
||||
else => continue,
|
||||
}
|
||||
}
|
||||
continue;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
},
|
||||
else => break,
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
pub fn skip(self: *Self) bool {
|
||||
if (!self.skipWhitespace()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var backslash_count: usize = 0;
|
||||
var in_quote = false;
|
||||
while (true) : (self.index += 1) {
|
||||
const character = if (self.index != self.cmd_line.len) self.cmd_line[self.index] else 0;
|
||||
switch (character) {
|
||||
0 => return true,
|
||||
'"', '\'' => {
|
||||
if (!options.single_quotes and character == '\'') {
|
||||
backslash_count = 0;
|
||||
continue;
|
||||
}
|
||||
const quote_is_real = backslash_count % 2 == 0;
|
||||
if (quote_is_real) {
|
||||
in_quote = !in_quote;
|
||||
}
|
||||
},
|
||||
'\\' => {
|
||||
backslash_count += 1;
|
||||
},
|
||||
' ', '\t', '\r', '\n' => {
|
||||
if (!in_quote) {
|
||||
return true;
|
||||
}
|
||||
backslash_count = 0;
|
||||
},
|
||||
else => {
|
||||
backslash_count = 0;
|
||||
continue;
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a slice of the internal buffer that contains the next argument.
|
||||
/// Returns null when it reaches the end.
|
||||
pub fn next(self: *Self) ?[:0]const u8 {
|
||||
if (!self.skipWhitespace()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var backslash_count: usize = 0;
|
||||
var in_quote = false;
|
||||
while (true) : (self.index += 1) {
|
||||
const character = if (self.index != self.cmd_line.len) self.cmd_line[self.index] else 0;
|
||||
switch (character) {
|
||||
0 => {
|
||||
self.emitBackslashes(backslash_count);
|
||||
self.buffer[self.end] = 0;
|
||||
const token = self.buffer[self.start..self.end :0];
|
||||
self.end += 1;
|
||||
self.start = self.end;
|
||||
return token;
|
||||
},
|
||||
'"', '\'' => {
|
||||
if (!options.single_quotes and character == '\'') {
|
||||
self.emitBackslashes(backslash_count);
|
||||
backslash_count = 0;
|
||||
self.emitCharacter(character);
|
||||
continue;
|
||||
}
|
||||
const quote_is_real = backslash_count % 2 == 0;
|
||||
self.emitBackslashes(backslash_count / 2);
|
||||
backslash_count = 0;
|
||||
|
||||
if (quote_is_real) {
|
||||
in_quote = !in_quote;
|
||||
} else {
|
||||
self.emitCharacter('"');
|
||||
}
|
||||
},
|
||||
'\\' => {
|
||||
backslash_count += 1;
|
||||
},
|
||||
' ', '\t', '\r', '\n' => {
|
||||
self.emitBackslashes(backslash_count);
|
||||
backslash_count = 0;
|
||||
if (in_quote) {
|
||||
self.emitCharacter(character);
|
||||
} else {
|
||||
self.buffer[self.end] = 0;
|
||||
const token = self.buffer[self.start..self.end :0];
|
||||
self.end += 1;
|
||||
self.start = self.end;
|
||||
return token;
|
||||
}
|
||||
},
|
||||
else => {
|
||||
self.emitBackslashes(backslash_count);
|
||||
backslash_count = 0;
|
||||
self.emitCharacter(character);
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn emitBackslashes(self: *Self, emit_count: usize) void {
|
||||
var i: usize = 0;
|
||||
while (i < emit_count) : (i += 1) {
|
||||
self.emitCharacter('\\');
|
||||
}
|
||||
}
|
||||
|
||||
fn emitCharacter(self: *Self, char: u8) void {
|
||||
self.buffer[self.end] = char;
|
||||
self.end += 1;
|
||||
}
|
||||
|
||||
/// Call to free the internal buffer of the iterator.
|
||||
pub fn deinit(self: *Self) void {
|
||||
self.allocator.free(self.buffer);
|
||||
|
||||
if (self.free_cmd_line_on_deinit) {
|
||||
self.allocator.free(self.cmd_line);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// Deprecated in favor of `Init.Args.iterate`.
|
||||
/// To be removed after 0.14.0 is tagged.
|
||||
pub fn args() Init.Args.Iterator {
|
||||
var a: Init.Args = .{ .data = if (Init.Args.Data == void) {} else std.os.argv };
|
||||
return a.iterate();
|
||||
}
|
||||
|
||||
/// Deprecated in favor of `Init.Args.iterate`.
|
||||
/// To be removed after 0.14.0 is tagged.
|
||||
pub fn argsWithAllocator(allocator: Allocator) ArgIterator.InitError!Init.Args.Iterator {
|
||||
var a: Init.Args = .{ .data = if (Init.Args.Data == void) {} else std.os.argv };
|
||||
return a.iterateWithAllocator(allocator);
|
||||
}
|
||||
|
||||
/// Deprecated in favor of `Init.Args.toSlice`.
|
||||
/// To be removed after 0.14.0 is tagged.
|
||||
pub fn argsAlloc(allocator: Allocator) ![][:0]u8 {
|
||||
var a: Init.Args = .{ .data = if (Init.Args.Data == void) {} else std.os.argv };
|
||||
return a.toSlice(allocator);
|
||||
}
|
||||
|
||||
/// Deprecated in favor of `Init.Args.freeSlice`.
|
||||
/// To be removed after 0.14.0 is tagged.
|
||||
pub fn argsFree(allocator: Allocator, args_alloc: []const [:0]u8) void {
|
||||
Init.Args.freeSlice(allocator, args_alloc);
|
||||
}
|
||||
|
||||
test ArgIteratorWindows {
|
||||
const t = testArgIteratorWindows;
|
||||
|
||||
try t(
|
||||
\\"C:\Program Files\zig\zig.exe" run .\src\main.zig -target x86_64-windows-gnu -O ReleaseSafe -- --emoji=🗿 --eval="new Regex(\"Dwayne \\\"The Rock\\\" Johnson\")"
|
||||
, &.{
|
||||
\\C:\Program Files\zig\zig.exe
|
||||
,
|
||||
\\run
|
||||
,
|
||||
\\.\src\main.zig
|
||||
,
|
||||
\\-target
|
||||
,
|
||||
\\x86_64-windows-gnu
|
||||
,
|
||||
\\-O
|
||||
,
|
||||
\\ReleaseSafe
|
||||
,
|
||||
\\--
|
||||
,
|
||||
\\--emoji=🗿
|
||||
,
|
||||
\\--eval=new Regex("Dwayne \"The Rock\" Johnson")
|
||||
,
|
||||
});
|
||||
|
||||
// Empty
|
||||
try t("", &.{});
|
||||
|
||||
// Separators
|
||||
try t("aa bb cc", &.{ "aa", "bb", "cc" });
|
||||
try t("aa\tbb\tcc", &.{ "aa", "bb", "cc" });
|
||||
try t("aa\nbb\ncc", &.{"aa\nbb\ncc"});
|
||||
try t("aa\r\nbb\r\ncc", &.{"aa\r\nbb\r\ncc"});
|
||||
try t("aa\rbb\rcc", &.{"aa\rbb\rcc"});
|
||||
try t("aa\x07bb\x07cc", &.{"aa\x07bb\x07cc"});
|
||||
try t("aa\x7Fbb\x7Fcc", &.{"aa\x7Fbb\x7Fcc"});
|
||||
try t("aa🦎bb🦎cc", &.{"aa🦎bb🦎cc"});
|
||||
|
||||
// Leading/trailing whitespace
|
||||
try t(" ", &.{""});
|
||||
try t(" aa bb ", &.{ "", "aa", "bb" });
|
||||
try t("\t\t", &.{""});
|
||||
try t("\t\taa\t\tbb\t\t", &.{ "", "aa", "bb" });
|
||||
try t("\n\n", &.{"\n\n"});
|
||||
try t("\n\naa\n\nbb\n\n", &.{"\n\naa\n\nbb\n\n"});
|
||||
|
||||
// Executable name with quotes/backslashes
|
||||
try t("\"aa bb\tcc\ndd\"", &.{"aa bb\tcc\ndd"});
|
||||
try t("\"", &.{""});
|
||||
try t("\"\"", &.{""});
|
||||
try t("\"\"\"", &.{""});
|
||||
try t("\"\"\"\"", &.{""});
|
||||
try t("\"\"\"\"\"", &.{""});
|
||||
try t("aa\"bb\"cc\"dd", &.{"aabbccdd"});
|
||||
try t("aa\"bb cc\"dd", &.{"aabb ccdd"});
|
||||
try t("\"aa\\\"bb\"", &.{"aa\\bb"});
|
||||
try t("\"aa\\\\\"", &.{"aa\\\\"});
|
||||
try t("aa\\\"bb", &.{"aa\\bb"});
|
||||
try t("aa\\\\\"bb", &.{"aa\\\\bb"});
|
||||
|
||||
// Arguments with quotes/backslashes
|
||||
try t(". \"aa bb\tcc\ndd\"", &.{ ".", "aa bb\tcc\ndd" });
|
||||
try t(". aa\" \"bb\"\t\"cc\"\n\"dd\"", &.{ ".", "aa bb\tcc\ndd" });
|
||||
try t(". ", &.{"."});
|
||||
try t(". \"", &.{ ".", "" });
|
||||
try t(". \"\"", &.{ ".", "" });
|
||||
try t(". \"\"\"", &.{ ".", "\"" });
|
||||
try t(". \"\"\"\"", &.{ ".", "\"" });
|
||||
try t(". \"\"\"\"\"", &.{ ".", "\"\"" });
|
||||
try t(". \"\"\"\"\"\"", &.{ ".", "\"\"" });
|
||||
try t(". \" \"", &.{ ".", " " });
|
||||
try t(". \" \"\"", &.{ ".", " \"" });
|
||||
try t(". \" \"\"\"", &.{ ".", " \"" });
|
||||
try t(". \" \"\"\"\"", &.{ ".", " \"\"" });
|
||||
try t(". \" \"\"\"\"\"", &.{ ".", " \"\"" });
|
||||
try t(". \" \"\"\"\"\"\"", &.{ ".", " \"\"\"" });
|
||||
try t(". \\\"", &.{ ".", "\"" });
|
||||
try t(". \\\"\"", &.{ ".", "\"" });
|
||||
try t(". \\\"\"\"", &.{ ".", "\"" });
|
||||
try t(". \\\"\"\"\"", &.{ ".", "\"\"" });
|
||||
try t(". \\\"\"\"\"\"", &.{ ".", "\"\"" });
|
||||
try t(". \\\"\"\"\"\"\"", &.{ ".", "\"\"\"" });
|
||||
try t(". \" \\\"", &.{ ".", " \"" });
|
||||
try t(". \" \\\"\"", &.{ ".", " \"" });
|
||||
try t(". \" \\\"\"\"", &.{ ".", " \"\"" });
|
||||
try t(". \" \\\"\"\"\"", &.{ ".", " \"\"" });
|
||||
try t(". \" \\\"\"\"\"\"", &.{ ".", " \"\"\"" });
|
||||
try t(". \" \\\"\"\"\"\"\"", &.{ ".", " \"\"\"" });
|
||||
try t(". aa\\bb\\\\cc\\\\\\dd", &.{ ".", "aa\\bb\\\\cc\\\\\\dd" });
|
||||
try t(". \\\\\\\"aa bb\"", &.{ ".", "\\\"aa", "bb" });
|
||||
try t(". \\\\\\\\\"aa bb\"", &.{ ".", "\\\\aa bb" });
|
||||
|
||||
// From https://learn.microsoft.com/en-us/cpp/cpp/main-function-command-line-args#results-of-parsing-command-lines
|
||||
try t(
|
||||
\\foo.exe "abc" d e
|
||||
, &.{ "foo.exe", "abc", "d", "e" });
|
||||
try t(
|
||||
\\foo.exe a\\b d"e f"g h
|
||||
, &.{ "foo.exe", "a\\\\b", "de fg", "h" });
|
||||
try t(
|
||||
\\foo.exe a\\\"b c d
|
||||
, &.{ "foo.exe", "a\\\"b", "c", "d" });
|
||||
try t(
|
||||
\\foo.exe a\\\\"b c" d e
|
||||
, &.{ "foo.exe", "a\\\\b c", "d", "e" });
|
||||
try t(
|
||||
\\foo.exe a"b"" c d
|
||||
, &.{ "foo.exe", "ab\" c d" });
|
||||
|
||||
// From https://daviddeley.com/autohotkey/parameters/parameters.htm#WINCRULESEX
|
||||
try t("foo.exe CallMeIshmael", &.{ "foo.exe", "CallMeIshmael" });
|
||||
try t("foo.exe \"Call Me Ishmael\"", &.{ "foo.exe", "Call Me Ishmael" });
|
||||
try t("foo.exe Cal\"l Me I\"shmael", &.{ "foo.exe", "Call Me Ishmael" });
|
||||
try t("foo.exe CallMe\\\"Ishmael", &.{ "foo.exe", "CallMe\"Ishmael" });
|
||||
try t("foo.exe \"CallMe\\\"Ishmael\"", &.{ "foo.exe", "CallMe\"Ishmael" });
|
||||
try t("foo.exe \"Call Me Ishmael\\\\\"", &.{ "foo.exe", "Call Me Ishmael\\" });
|
||||
try t("foo.exe \"CallMe\\\\\\\"Ishmael\"", &.{ "foo.exe", "CallMe\\\"Ishmael" });
|
||||
try t("foo.exe a\\\\\\b", &.{ "foo.exe", "a\\\\\\b" });
|
||||
try t("foo.exe \"a\\\\\\b\"", &.{ "foo.exe", "a\\\\\\b" });
|
||||
|
||||
// Surrogate pair encoding of 𐐷 separated by quotes.
|
||||
// Encoded as WTF-16:
|
||||
// "<0xD801>"<0xDC37>
|
||||
// Encoded as WTF-8:
|
||||
// "<0xED><0xA0><0x81>"<0xED><0xB0><0xB7>
|
||||
// During parsing, the quotes drop out and the surrogate pair
|
||||
// should end up encoded as its normal UTF-8 representation.
|
||||
try t("foo.exe \"\xed\xa0\x81\"\xed\xb0\xb7", &.{ "foo.exe", "𐐷" });
|
||||
}
|
||||
|
||||
fn testArgIteratorWindows(cmd_line: []const u8, expected_args: []const []const u8) !void {
|
||||
const cmd_line_w = try unicode.wtf8ToWtf16LeAllocZ(testing.allocator, cmd_line);
|
||||
defer testing.allocator.free(cmd_line_w);
|
||||
|
||||
// next
|
||||
{
|
||||
var it = try ArgIteratorWindows.init(testing.allocator, cmd_line_w);
|
||||
defer it.deinit();
|
||||
|
||||
for (expected_args) |expected| {
|
||||
if (it.next()) |actual| {
|
||||
try testing.expectEqualStrings(expected, actual);
|
||||
} else {
|
||||
return error.TestUnexpectedResult;
|
||||
}
|
||||
}
|
||||
try testing.expect(it.next() == null);
|
||||
}
|
||||
|
||||
// skip
|
||||
{
|
||||
var it = try ArgIteratorWindows.init(testing.allocator, cmd_line_w);
|
||||
defer it.deinit();
|
||||
|
||||
for (0..expected_args.len) |_| {
|
||||
try testing.expect(it.skip());
|
||||
}
|
||||
try testing.expect(!it.skip());
|
||||
}
|
||||
}
|
||||
|
||||
test "general arg parsing" {
|
||||
try testGeneralCmdLine("a b\tc d", &.{ "a", "b", "c", "d" });
|
||||
try testGeneralCmdLine("\"abc\" d e", &.{ "abc", "d", "e" });
|
||||
try testGeneralCmdLine("a\\\\\\b d\"e f\"g h", &.{ "a\\\\\\b", "de fg", "h" });
|
||||
try testGeneralCmdLine("a\\\\\\\"b c d", &.{ "a\\\"b", "c", "d" });
|
||||
try testGeneralCmdLine("a\\\\\\\\\"b c\" d e", &.{ "a\\\\b c", "d", "e" });
|
||||
try testGeneralCmdLine("a b\tc \"d f", &.{ "a", "b", "c", "d f" });
|
||||
try testGeneralCmdLine("j k l\\", &.{ "j", "k", "l\\" });
|
||||
try testGeneralCmdLine("\"\" x y z\\\\", &.{ "", "x", "y", "z\\\\" });
|
||||
|
||||
try testGeneralCmdLine("\".\\..\\zig-cache\\build\" \"bin\\zig.exe\" \".\\..\" \".\\..\\zig-cache\" \"--help\"", &.{
|
||||
".\\..\\zig-cache\\build",
|
||||
"bin\\zig.exe",
|
||||
".\\..",
|
||||
".\\..\\zig-cache",
|
||||
"--help",
|
||||
});
|
||||
|
||||
try testGeneralCmdLine(
|
||||
\\ 'foo' "bar"
|
||||
, &.{ "'foo'", "bar" });
|
||||
}
|
||||
|
||||
fn testGeneralCmdLine(input_cmd_line: []const u8, expected_args: []const []const u8) !void {
|
||||
var it = try ArgIteratorGeneral(.{}).init(std.testing.allocator, input_cmd_line);
|
||||
defer it.deinit();
|
||||
for (expected_args) |expected_arg| {
|
||||
const arg = it.next().?;
|
||||
try testing.expectEqualStrings(expected_arg, arg);
|
||||
}
|
||||
try testing.expect(it.next() == null);
|
||||
}
|
||||
|
||||
test "response file arg parsing" {
|
||||
try testResponseFileCmdLine(
|
||||
\\a b
|
||||
\\c d\
|
||||
, &.{ "a", "b", "c", "d\\" });
|
||||
try testResponseFileCmdLine("a b c d\\", &.{ "a", "b", "c", "d\\" });
|
||||
|
||||
try testResponseFileCmdLine(
|
||||
\\j
|
||||
\\ k l # this is a comment \\ \\\ \\\\ "none" "\\" "\\\"
|
||||
\\ "m" #another comment
|
||||
\\
|
||||
, &.{ "j", "k", "l", "m" });
|
||||
|
||||
try testResponseFileCmdLine(
|
||||
\\ "" q ""
|
||||
\\ "r s # t" "u\" v" #another comment
|
||||
\\
|
||||
, &.{ "", "q", "", "r s # t", "u\" v" });
|
||||
|
||||
try testResponseFileCmdLine(
|
||||
\\ -l"advapi32" a# b#c d#
|
||||
\\e\\\
|
||||
, &.{ "-ladvapi32", "a#", "b#c", "d#", "e\\\\\\" });
|
||||
|
||||
try testResponseFileCmdLine(
|
||||
\\ 'foo' "bar"
|
||||
, &.{ "foo", "bar" });
|
||||
}
|
||||
|
||||
fn testResponseFileCmdLine(input_cmd_line: []const u8, expected_args: []const []const u8) !void {
|
||||
var it = try ArgIteratorGeneral(.{ .comments = true, .single_quotes = true })
|
||||
.init(std.testing.allocator, input_cmd_line);
|
||||
defer it.deinit();
|
||||
for (expected_args) |expected_arg| {
|
||||
const arg = it.next().?;
|
||||
try testing.expectEqualStrings(expected_arg, arg);
|
||||
}
|
||||
try testing.expect(it.next() == null);
|
||||
}
|
||||
|
||||
pub const UserInfo = struct {
|
||||
uid: posix.uid_t,
|
||||
gid: posix.gid_t,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue