Skip to content

Commit c2f7afd

Browse files
authored
builtin: add pub fn arguments() []string {; make os.args use it, remove edge case in cgen (#21852)
1 parent 48ab08c commit c2f7afd

File tree

8 files changed

+49
-32
lines changed

8 files changed

+49
-32
lines changed

vlib/builtin/builtin.c.v

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -711,14 +711,32 @@ fn v_fixed_index(i int, len int) int {
711711

712712
// NOTE: g_main_argc and g_main_argv are filled in right after C's main start.
713713
// They are used internally by V's builtin; for user code, it is much
714-
// more convenient to just use `os.args` instead.
714+
// more convenient to just use `os.args` or call `arguments()` instead.
715715

716716
@[markused]
717717
__global g_main_argc = int(0)
718718

719719
@[markused]
720720
__global g_main_argv = unsafe { nil }
721721

722+
// arguments returns the command line arguments, used for starting the current program as a V array of strings.
723+
// The first string in the array (index 0), is the name of the program, used for invoking the program.
724+
// The second string in the array (index 1), if it exists, is the first argument to the program, etc.
725+
// For example, if you started your program as `myprogram -option`, then arguments() will return ['myprogram', '-option'].
726+
// Note: if you `v run file.v abc def`, then arguments() will return ['file', 'abc', 'def'], or ['file.exe', 'abc', 'def'] (on Windows).
727+
pub fn arguments() []string {
728+
argv := &&u8(g_main_argv)
729+
mut res := []string{cap: g_main_argc}
730+
for i in 0 .. g_main_argc {
731+
$if windows {
732+
res << unsafe { string_from_wide(&u16(argv[i])) }
733+
} $else {
734+
res << unsafe { tos_clone(argv[i]) }
735+
}
736+
}
737+
return res
738+
}
739+
722740
@[if vplayground ?]
723741
fn vplayground_mlimit(n isize) {
724742
if n > 10000 {

vlib/os/os.c.v

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ $if freebsd || openbsd {
99
#include <sys/sysctl.h>
1010
}
1111

12-
pub const args = []string{}
12+
pub const args = arguments()
1313

1414
fn C.readdir(voidptr) &C.dirent
1515

vlib/os/os_nix.c.v

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,8 @@ pub fn loginname() !string {
272272
return error(posix_get_error_msg(C.errno))
273273
}
274274

275+
@[deprecated: 'os.args now uses arguments()']
276+
@[deprecated_after: '2024-07-30']
275277
fn init_os_args(argc int, argv &&u8) []string {
276278
mut args_ := []string{len: argc}
277279
for i in 0 .. argc {

vlib/os/os_windows.c.v

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,8 @@ pub struct C._utimbuf {
103103

104104
fn C._utime(&char, voidptr) int
105105

106+
@[deprecated: 'os.args now uses arguments()']
107+
@[deprecated_after: '2024-07-30']
106108
fn init_os_args_wide(argc int, argv &&u8) []string {
107109
mut args_ := []string{len: argc}
108110
for i in 0 .. argc {

vlib/v/gen/c/cgen.v

Lines changed: 20 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -6116,29 +6116,22 @@ fn (mut g Gen) const_decl_init_later(mod string, name string, expr ast.Expr, typ
61166116
mut styp := g.typ(typ)
61176117
cname := g.c_const_name(name)
61186118
mut init := strings.new_builder(100)
6119-
if cname == '_const_os__args' {
6120-
if g.pref.os == .windows {
6121-
init.writeln('\t_const_os__args = os__init_os_args_wide(___argc, (byteptr*)___argv);')
6122-
} else {
6123-
init.writeln('\t_const_os__args = os__init_os_args(___argc, (byte**)___argv);')
6124-
}
6119+
6120+
if surround_cbr {
6121+
init.writeln('{')
6122+
}
6123+
if unwrap_option {
6124+
init.writeln(g.expr_string_surround('\t${cname} = *(${styp}*)', expr, '.data;'))
6125+
} else if expr is ast.ArrayInit && (expr as ast.ArrayInit).has_index {
6126+
init.writeln(g.expr_string_surround('\tmemcpy(&${cname}, &', expr, ', sizeof(${styp}));'))
6127+
} else if expr is ast.CallExpr
6128+
&& g.table.final_sym(g.unwrap_generic((expr as ast.CallExpr).return_type)).kind == .array_fixed {
6129+
init.writeln(g.expr_string_surround('\tmemcpy(&${cname}, ', expr, ', sizeof(${styp}));'))
61256130
} else {
6126-
if surround_cbr {
6127-
init.writeln('{')
6128-
}
6129-
if unwrap_option {
6130-
init.writeln(g.expr_string_surround('\t${cname} = *(${styp}*)', expr, '.data;'))
6131-
} else if expr is ast.ArrayInit && (expr as ast.ArrayInit).has_index {
6132-
init.writeln(g.expr_string_surround('\tmemcpy(&${cname}, &', expr, ', sizeof(${styp}));'))
6133-
} else if expr is ast.CallExpr
6134-
&& g.table.final_sym(g.unwrap_generic((expr as ast.CallExpr).return_type)).kind == .array_fixed {
6135-
init.writeln(g.expr_string_surround('\tmemcpy(&${cname}, ', expr, ', sizeof(${styp}));'))
6136-
} else {
6137-
init.writeln(g.expr_string_surround('\t${cname} = ', expr, ';'))
6138-
}
6139-
if surround_cbr {
6140-
init.writeln('}')
6141-
}
6131+
init.writeln(g.expr_string_surround('\t${cname} = ', expr, ';'))
6132+
}
6133+
if surround_cbr {
6134+
init.writeln('}')
61426135
}
61436136
mut def := '${styp} ${cname}'
61446137
expr_sym := g.table.sym(typ)
@@ -6288,7 +6281,11 @@ fn (mut g Gen) global_decl(node ast.GlobalDecl) {
62886281
} else {
62896282
// More complex expressions need to be moved to `_vinit()`
62906283
// e.g. `__global ( mygblobal = 'hello ' + world' )`
6291-
init = '\t${field.name} = ${g.expr_string(field.expr)}; // 3global'
6284+
if field.name in ['g_main_argc', 'g_main_argv'] {
6285+
init = '\t// skipping ${field.name}, it was initialised in main'
6286+
} else {
6287+
init = '\t${field.name} = ${g.expr_string(field.expr)}; // 3global'
6288+
}
62926289
}
62936290
} else if !g.pref.translated { // don't zero globals from C code
62946291
default_initializer := g.type_default(field.typ)

vlib/v/markused/markused.v

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,8 +135,6 @@ pub fn mark_used(mut table ast.Table, mut pref_ pref.Preferences, ast_files []&a
135135
'main.vtest_new_metainfo',
136136
'main.vtest_new_filemetainfo',
137137
'os.getwd',
138-
'os.init_os_args',
139-
'os.init_os_args_wide',
140138
'v.embed_file.find_index_entry_by_path',
141139
]
142140
}

vlib/v/slow_tests/profile/profile_test.v

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,10 +67,10 @@ fn test_v_profile_works() {
6767
println(@FN)
6868
sfile := 'vlib/v/slow_tests/profile/profile_test_1.v'
6969
validate_output(@FN, '', sfile, {
70-
'os__init_os_args': 1
71-
'main__main': 1
72-
'println': 1
73-
'strconv__atoi': 1
70+
'arguments': 1
71+
'main__main': 1
72+
'println': 1
73+
'strconv__atoi': 1
7474
})
7575
}
7676

vlib/v/tests/testdata/trace_calls/with_modules.vv.must_match

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
*> trace * C.main*
22
*> trace * _vinit*
3-
*> trace * os os.init_os_args*
3+
*> trace * builtin arguments/0*
44
*> trace * main main.main/0*
55
*> trace * main main.f1/0*
66
*> trace * main main.f2/0*

0 commit comments

Comments
 (0)