feat: preprocess native argv into sentinel slices
This commit is contained in:
+57
-47
@@ -3534,10 +3534,28 @@ main func() int ! Error { return try value() }
|
||||
source=`process :: import "@std/process"
|
||||
Error :: enum { failed }
|
||||
fail func() void ! Error { return .failed }
|
||||
main func(_ process.Init) void ! Error { try fail() }
|
||||
main func(init process.Init) void ! Error {
|
||||
if init.args.values.len != 3 { return }
|
||||
if init.args.values[1].len != 0 or init.args.values[2].len != 9 { return }
|
||||
if init.args.values[2][0] != 't' or init.args.values[2][8] != 's' { return }
|
||||
try fail()
|
||||
}
|
||||
`,
|
||||
exit_code=1,
|
||||
},
|
||||
{
|
||||
name="process-success",
|
||||
source=`process :: import "@std/process"
|
||||
Error :: enum { failed }
|
||||
main func(init process.Init) i32 ! Error {
|
||||
if init.args.values.len != 3 { return .failed }
|
||||
if init.args.values[1].len != 0 or init.args.values[2].len != 9 { return .failed }
|
||||
if init.args.values[2][0] != 't' or init.args.values[2][8] != 's' { return .failed }
|
||||
return 7
|
||||
}
|
||||
`,
|
||||
exit_code=7,
|
||||
},
|
||||
{
|
||||
name="inferred-main-try",
|
||||
source=`Error :: enum { failed }
|
||||
@@ -3578,7 +3596,12 @@ main func() void! { try dispatch(2) }
|
||||
source=`process :: import "@std/process"
|
||||
Error :: enum { failed }
|
||||
fail func() void ! Error { return .failed }
|
||||
main func(_ process.Init) void! { try fail() }
|
||||
main func(init process.Init) void! {
|
||||
if init.args.values.len != 3 { return }
|
||||
if init.args.values[1].len != 0 or init.args.values[2].len != 9 { return }
|
||||
if init.args.values[2][0] != 't' or init.args.values[2][8] != 's' { return }
|
||||
try fail()
|
||||
}
|
||||
`,
|
||||
exit_code=1,
|
||||
},
|
||||
@@ -3603,7 +3626,7 @@ main func(_ process.Init) void! { try fail() }
|
||||
)
|
||||
testing.expect_value(t, status, 0)
|
||||
state, stdout, stderr, _ := os2.process_exec(
|
||||
os2.Process_Desc{command=[]string{output}},
|
||||
os2.Process_Desc{command=[]string{output, "", "two words"}},
|
||||
context.allocator,
|
||||
)
|
||||
defer delete(stdout)
|
||||
@@ -3941,7 +3964,7 @@ milestone_37_validates_process_init_and_hidden_system_provider :: proc(t: ^testi
|
||||
system func() Io { return Io {value = 0} }
|
||||
`,
|
||||
process_source=`io :: import "@std/io"
|
||||
Args :: struct { values [][*;0]u8 }
|
||||
Args :: struct { values [][;0]u8 }
|
||||
Init :: struct { io io.Io, args Args }
|
||||
`,
|
||||
},
|
||||
@@ -3950,7 +3973,7 @@ Init :: struct { io io.Io, args Args }
|
||||
@hide system func() Io { return Io {value = 0} }
|
||||
`,
|
||||
process_source=`io :: import "@std/io"
|
||||
Args :: struct { values [][*;0]u8 }
|
||||
Args :: struct { values [][;0]u8 }
|
||||
Init :: struct { io io.Io, args Args, extra i32 }
|
||||
`,
|
||||
},
|
||||
@@ -3959,7 +3982,7 @@ Init :: struct { io io.Io, args Args, extra i32 }
|
||||
@hide system func() Io { return Io {value = 0} }
|
||||
`,
|
||||
process_source=`io :: import "@std/io"
|
||||
Args :: struct { values [][*;0]u8 }
|
||||
Args :: struct { values [][;0]u8 }
|
||||
Init :: struct { io io.Io }
|
||||
`,
|
||||
},
|
||||
@@ -3968,7 +3991,7 @@ Init :: struct { io io.Io }
|
||||
@hide system func() Io { return Io {value = 0} }
|
||||
`,
|
||||
process_source=`io :: import "@std/io"
|
||||
Args :: struct { values [][*]u8 }
|
||||
Args :: struct { values [][]u8 }
|
||||
Init :: struct { io io.Io, args Args }
|
||||
`,
|
||||
},
|
||||
@@ -3977,7 +4000,7 @@ Init :: struct { io io.Io, args Args }
|
||||
@hide system func() Io { return Io {value = 0} }
|
||||
`,
|
||||
process_source=`io :: import "@std/io"
|
||||
Args :: struct { values [][*;0]u8, extra i32 }
|
||||
Args :: struct { values [][;0]u8, extra i32 }
|
||||
Init :: struct { io io.Io, args Args }
|
||||
`,
|
||||
},
|
||||
@@ -3986,7 +4009,7 @@ Init :: struct { io io.Io, args Args }
|
||||
@hide system func() Io { return Io {value = 0} }
|
||||
`,
|
||||
process_source=`io :: import "@std/io"
|
||||
Args :: struct { values [][*;0]u8 }
|
||||
Args :: struct { values [][;0]u8 }
|
||||
Init :: struct { io io.Io, args i32 }
|
||||
`,
|
||||
},
|
||||
@@ -4030,7 +4053,7 @@ main func(init process.Init) void { _ = init }
|
||||
}
|
||||
|
||||
@(test)
|
||||
process_init_supplies_native_arguments_and_helpers_borrow_explicit_storage :: proc(t: ^testing.T) {
|
||||
process_init_supplies_native_argument_slices :: proc(t: ^testing.T) {
|
||||
directory := "/tmp/brolang-test-process-args"
|
||||
main_path := "/tmp/brolang-test-process-args/main.bro"
|
||||
output := "/tmp/brolang-test-process-args/app"
|
||||
@@ -4038,43 +4061,23 @@ process_init_supplies_native_arguments_and_helpers_borrow_explicit_storage :: pr
|
||||
io :: import "@std/io"
|
||||
mem :: import "@std/mem"
|
||||
|
||||
supplied_args_work func() bool {
|
||||
text [3;0]mut u8 := ['r', 'u', 'n']
|
||||
pointers [1][*;0]u8 :: [(&text).ptr]
|
||||
args :: process.Args { values = pointers[..] }
|
||||
if process.argument_count(args) != 1 { return false }
|
||||
if process.argument(args, 0) |value| {
|
||||
text[0] = 'f'
|
||||
if !mem.eql(value, "fun") { return false }
|
||||
} else { return false }
|
||||
if process.argument(args, 1) |_| { return false }
|
||||
empty :: process.Args { values = pointers[0..0] }
|
||||
if process.argument_count(empty) != 0 { return false }
|
||||
if process.argument(empty, 0) |_| { return false }
|
||||
return true
|
||||
}
|
||||
|
||||
main func(init process.Init) i32 {
|
||||
count :: process.argument_count(init.args)
|
||||
if count != 1 and count != 4 { return 1 }
|
||||
if process.argument(init.args, 0) |executable| {
|
||||
if !mem.eql(executable, "/tmp/brolang-test-process-args/app") { return 2 }
|
||||
} else { return 3 }
|
||||
if process.argument(init.args, count) |_| { return 4 }
|
||||
if process.argument(init.args, maxval!(usize)) |_| { return 5 }
|
||||
count :: init.args.values.len
|
||||
if count != 1 and count != 4 and count != 16385 { return 1 }
|
||||
if !mem.eql(init.args.values[0], "/tmp/brolang-test-process-args/app") { return 2 }
|
||||
if count == 4 {
|
||||
if process.argument(init.args, 1) |operation| {
|
||||
if !mem.eql(operation, "run") { return 6 }
|
||||
} else { return 7 }
|
||||
if process.argument(init.args, 2) |empty| {
|
||||
if empty.len != 0 { return 8 }
|
||||
} else { return 9 }
|
||||
if process.argument(init.args, 3) |spaced| {
|
||||
if !mem.eql(spaced, "two words") { return 10 }
|
||||
} else { return 11 }
|
||||
if !mem.eql(init.args.values[1], "run") { return 3 }
|
||||
if init.args.values[2].len != 0 { return 4 }
|
||||
if !mem.eql(init.args.values[3], "two words") { return 5 }
|
||||
}
|
||||
if !supplied_args_work() { return 12 }
|
||||
io.write_all(io.stdout(init.io), "args-ok\n") catch |_| { return 13 }
|
||||
if count == 16385 {
|
||||
index := usize(1)
|
||||
while index < count {
|
||||
if init.args.values[index].len != 0 { return 6 }
|
||||
index += 1
|
||||
}
|
||||
}
|
||||
io.write_all(io.stdout(init.io), "args-ok\n") catch |_| { return 7 }
|
||||
return 0
|
||||
}
|
||||
`
|
||||
@@ -4085,9 +4088,16 @@ main func(init process.Init) i32 {
|
||||
testing.expect_value(t, compiler_core.compile_package(
|
||||
directory, output, nil, target.DEFAULT, cimport.Options{}, ".",
|
||||
), 0)
|
||||
large_command := make([]string, 16385)
|
||||
defer delete(large_command)
|
||||
large_command[0] = output
|
||||
for index in 1..<len(large_command) {
|
||||
large_command[index] = ""
|
||||
}
|
||||
commands := [][]string{
|
||||
{output},
|
||||
{output, "run", "", "two words"},
|
||||
large_command,
|
||||
}
|
||||
for command in commands {
|
||||
state, stdout, stderr, error := os2.process_exec(
|
||||
@@ -4126,16 +4136,16 @@ process_init_startup_respects_reordered_fields :: proc(t: ^testing.T) {
|
||||
@hide system func() Io { return Io {value = 37} }
|
||||
`
|
||||
process_source := `io :: import "@std/io"
|
||||
Args :: struct { values [][*;0]u8 }
|
||||
Args :: struct { values [][;0]u8 }
|
||||
Init :: struct { args Args, io io.Io }
|
||||
`
|
||||
main_source := `process :: import "@std/process"
|
||||
main func(init process.Init) i32 {
|
||||
if init.io.value != 37 or init.args.values.len != 3 { return 1 }
|
||||
empty :: init.args.values[1]
|
||||
if empty[0] != 0 { return 2 }
|
||||
if empty.len != 0 { return 2 }
|
||||
spaced :: init.args.values[2]
|
||||
if spaced[0] != 'a' or spaced[1] != ' ' or spaced[2] != 'b' or spaced[3] != 0 { return 3 }
|
||||
if spaced.len != 3 or spaced[0] != 'a' or spaced[1] != ' ' or spaced[2] != 'b' { return 3 }
|
||||
return 0
|
||||
}
|
||||
`
|
||||
|
||||
Reference in New Issue
Block a user