Skip to content

Commit 719c3b3

Browse files
committed
v.cflag: support #flag $when_first_existing(libABC.a, /some/path/libABC.a, ...), without panicing (unlike #flag $first_existing(...))
1 parent 5a74958 commit 719c3b3

File tree

2 files changed

+37
-18
lines changed

2 files changed

+37
-18
lines changed

vlib/v/cflag/cflags.v

Lines changed: 35 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -22,28 +22,46 @@ pub fn (c &CFlag) str() string {
2222
}
2323

2424
const fexisting_literal = r'$first_existing'
25+
const wexisting_literal = r'$when_first_existing'
26+
27+
fn find_first_existing_path(remainder string, literal string) (bool, string, int, []string) {
28+
sparams := remainder[literal.len + 1..].all_before(')')
29+
delta_i := sparams.len + literal.len + 1
30+
svalues := sparams.replace(',', '\n').split_into_lines().map(it.trim('\t \'"'))
31+
for spath in svalues {
32+
if os.exists(spath) {
33+
return true, spath, delta_i, []string{}
34+
}
35+
}
36+
return false, '', delta_i, svalues
37+
}
2538

2639
// expand the flag value
27-
pub fn (cf &CFlag) eval() string {
40+
pub fn (cf &CFlag) eval() ?string {
2841
mut value_builder := strings.new_builder(10 * cf.value.len)
2942
cflag_eval_outer_loop: for i := 0; i < cf.value.len; i++ {
3043
x := cf.value[i]
3144
if x == `$` {
3245
remainder := cf.value[i..]
3346
if remainder.starts_with(fexisting_literal) {
34-
sparams := remainder[fexisting_literal.len + 1..].all_before(')')
35-
i += sparams.len + fexisting_literal.len + 1
36-
svalues := sparams.replace(',', '\n').split_into_lines().map(it.trim('\t \'"'))
37-
// mut found_spath := ''
38-
for spath in svalues {
39-
if os.exists(spath) {
40-
// found_spath = spath
41-
value_builder.write_string(spath)
42-
continue cflag_eval_outer_loop
43-
}
47+
found, spath, delta_i, svalues := find_first_existing_path(remainder,
48+
fexisting_literal)
49+
if found {
50+
value_builder.write_string(spath)
51+
i += delta_i
52+
continue
4453
}
4554
panic('>> error: none of the paths ${svalues} exist')
46-
continue
55+
}
56+
if remainder.starts_with(wexisting_literal) {
57+
found, spath, delta_i, svalues := find_first_existing_path(remainder,
58+
wexisting_literal)
59+
if found {
60+
value_builder.write_string(spath)
61+
i += delta_i
62+
continue
63+
}
64+
return none
4765
}
4866
}
4967
value_builder.write_string(x.ascii_str())
@@ -52,12 +70,12 @@ pub fn (cf &CFlag) eval() string {
5270
}
5371

5472
// format flag
55-
pub fn (cf &CFlag) format() string {
73+
pub fn (cf &CFlag) format() ?string {
5674
mut value := ''
5775
if cf.cached != '' {
5876
value = cf.cached
5977
} else {
60-
value = cf.eval()
78+
value = cf.eval()?
6179
}
6280
if cf.name in ['-l', '-Wa', '-Wl', '-Wp'] && value != '' {
6381
return '${cf.name}${value}'.trim_space()
@@ -97,7 +115,7 @@ pub fn (cflags []CFlag) c_options_without_object_files() []string {
97115
if flag.value.ends_with('.o') || flag.value.ends_with('.obj') {
98116
continue
99117
}
100-
args << flag.format()
118+
args << flag.format() or { continue }
101119
}
102120
return args
103121
}
@@ -108,10 +126,10 @@ pub fn (cflags []CFlag) c_options_only_object_files() []string {
108126
// TODO figure out a better way to copy cross compiling flags to the linker
109127
if flag.value.ends_with('.o') || flag.value.ends_with('.obj')
110128
|| (flag.name == '-l' && flag.value == 'pq') {
111-
args << flag.format()
129+
args << flag.format() or { continue }
112130
}
113131
}
114-
return args
132+
return args.filter(it != '')
115133
}
116134

117135
pub fn (cflags []CFlag) defines_others_libs() ([]string, []string, []string) {

vlib/v/parser/comptime.v

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,14 +112,15 @@ fn (mut p Parser) hash() ast.HashStmt {
112112
}
113113
}
114114

115+
const error_msg = 'only `\$tmpl()`, `\$env()`, `\$embed_file()`, `\$pkgconfig()`, `\$vweb.html()`, `\$compile_error()`, `\$compile_warn()`, `\$d()` and `\$res()` comptime functions are supported right now'
116+
115117
fn (mut p Parser) comptime_call() ast.ComptimeCall {
116118
err_node := ast.ComptimeCall{
117119
scope: unsafe { nil }
118120
}
119121
start_pos := p.tok.pos()
120122
p.check(.dollar)
121123
mut is_veb := false
122-
error_msg := 'only `\$tmpl()`, `\$env()`, `\$embed_file()`, `\$pkgconfig()`, `\$vweb.html()`, `\$compile_error()`, `\$compile_warn()`, `\$d()` and `\$res()` comptime functions are supported right now'
123124
if p.peek_tok.kind == .dot {
124125
name := p.check_name() // skip `vweb.html()` TODO
125126
if name != 'vweb' && name != 'veb' {

0 commit comments

Comments
 (0)