Skip to content

Commit

Permalink
v.cflag: support `#flag $when_first_existing(libABC.a, /some/path/lib…
Browse files Browse the repository at this point in the history
…ABC.a, ...)`, without panicing (unlike `#flag $first_existing(...)`)
  • Loading branch information
spytheman committed Feb 21, 2025
1 parent 5a74958 commit 719c3b3
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 18 deletions.
52 changes: 35 additions & 17 deletions vlib/v/cflag/cflags.v
Original file line number Diff line number Diff line change
Expand Up @@ -22,28 +22,46 @@ pub fn (c &CFlag) str() string {
}

const fexisting_literal = r'$first_existing'
const wexisting_literal = r'$when_first_existing'

fn find_first_existing_path(remainder string, literal string) (bool, string, int, []string) {
sparams := remainder[literal.len + 1..].all_before(')')
delta_i := sparams.len + literal.len + 1
svalues := sparams.replace(',', '\n').split_into_lines().map(it.trim('\t \'"'))
for spath in svalues {
if os.exists(spath) {
return true, spath, delta_i, []string{}
}
}
return false, '', delta_i, svalues
}

// expand the flag value
pub fn (cf &CFlag) eval() string {
pub fn (cf &CFlag) eval() ?string {
mut value_builder := strings.new_builder(10 * cf.value.len)
cflag_eval_outer_loop: for i := 0; i < cf.value.len; i++ {
x := cf.value[i]
if x == `$` {
remainder := cf.value[i..]
if remainder.starts_with(fexisting_literal) {
sparams := remainder[fexisting_literal.len + 1..].all_before(')')
i += sparams.len + fexisting_literal.len + 1
svalues := sparams.replace(',', '\n').split_into_lines().map(it.trim('\t \'"'))
// mut found_spath := ''
for spath in svalues {
if os.exists(spath) {
// found_spath = spath
value_builder.write_string(spath)
continue cflag_eval_outer_loop
}
found, spath, delta_i, svalues := find_first_existing_path(remainder,
fexisting_literal)
if found {
value_builder.write_string(spath)
i += delta_i
continue
}
panic('>> error: none of the paths ${svalues} exist')
continue
}
if remainder.starts_with(wexisting_literal) {
found, spath, delta_i, svalues := find_first_existing_path(remainder,

Check warning on line 57 in vlib/v/cflag/cflags.v

View workflow job for this annotation

GitHub Actions / build-vc

unused variable: `svalues`

Check warning on line 57 in vlib/v/cflag/cflags.v

View workflow job for this annotation

GitHub Actions / cross-linux

unused variable: `svalues`

Check warning on line 57 in vlib/v/cflag/cflags.v

View workflow job for this annotation

GitHub Actions / bootstrap-v (ubuntu-latest)

unused variable: `svalues`

Check warning on line 57 in vlib/v/cflag/cflags.v

View workflow job for this annotation

GitHub Actions / gcc-linux

unused variable: `svalues`

Check warning on line 57 in vlib/v/cflag/cflags.v

View workflow job for this annotation

GitHub Actions / gcc-linux

unused variable: `svalues`

Check warning on line 57 in vlib/v/cflag/cflags.v

View workflow job for this annotation

GitHub Actions / websocket_tests

unused variable: `svalues`

Check warning on line 57 in vlib/v/cflag/cflags.v

View workflow job for this annotation

GitHub Actions / clang-linux

unused variable: `svalues`

Check warning on line 57 in vlib/v/cflag/cflags.v

View workflow job for this annotation

GitHub Actions / clang-linux

unused variable: `svalues`

Check warning on line 57 in vlib/v/cflag/cflags.v

View workflow job for this annotation

GitHub Actions / tcc-linux

unused variable: `svalues`

Check warning on line 57 in vlib/v/cflag/cflags.v

View workflow job for this annotation

GitHub Actions / tcc-linux

unused variable: `svalues`

Check warning on line 57 in vlib/v/cflag/cflags.v

View workflow job for this annotation

GitHub Actions / tcc-linux

unused variable: `svalues`

Check warning on line 57 in vlib/v/cflag/cflags.v

View workflow job for this annotation

GitHub Actions / tcc-linux

unused variable: `svalues`

Check warning on line 57 in vlib/v/cflag/cflags.v

View workflow job for this annotation

GitHub Actions / tcc-linux

unused variable: `svalues`

Check warning on line 57 in vlib/v/cflag/cflags.v

View workflow job for this annotation

GitHub Actions / tcc-linux

unused variable: `svalues`

Check warning on line 57 in vlib/v/cflag/cflags.v

View workflow job for this annotation

GitHub Actions / tcc-linux

unused variable: `svalues`

Check warning on line 57 in vlib/v/cflag/cflags.v

View workflow job for this annotation

GitHub Actions / Run a FreeBSD 14.2 x86 VM

unused variable: `svalues`

Check warning on line 57 in vlib/v/cflag/cflags.v

View workflow job for this annotation

GitHub Actions / Run a FreeBSD 14.2 x86 VM

unused variable: `svalues`
wexisting_literal)
if found {
value_builder.write_string(spath)
i += delta_i
continue
}
return none
}
}
value_builder.write_string(x.ascii_str())
Expand All @@ -52,12 +70,12 @@ pub fn (cf &CFlag) eval() string {
}

// format flag
pub fn (cf &CFlag) format() string {
pub fn (cf &CFlag) format() ?string {
mut value := ''
if cf.cached != '' {
value = cf.cached
} else {
value = cf.eval()
value = cf.eval()?
}
if cf.name in ['-l', '-Wa', '-Wl', '-Wp'] && value != '' {
return '${cf.name}${value}'.trim_space()
Expand Down Expand Up @@ -97,7 +115,7 @@ pub fn (cflags []CFlag) c_options_without_object_files() []string {
if flag.value.ends_with('.o') || flag.value.ends_with('.obj') {
continue
}
args << flag.format()
args << flag.format() or { continue }
}
return args
}
Expand All @@ -108,10 +126,10 @@ pub fn (cflags []CFlag) c_options_only_object_files() []string {
// TODO figure out a better way to copy cross compiling flags to the linker
if flag.value.ends_with('.o') || flag.value.ends_with('.obj')
|| (flag.name == '-l' && flag.value == 'pq') {
args << flag.format()
args << flag.format() or { continue }
}
}
return args
return args.filter(it != '')
}

pub fn (cflags []CFlag) defines_others_libs() ([]string, []string, []string) {
Expand Down
3 changes: 2 additions & 1 deletion vlib/v/parser/comptime.v
Original file line number Diff line number Diff line change
Expand Up @@ -112,14 +112,15 @@ fn (mut p Parser) hash() ast.HashStmt {
}
}

const error_msg = 'only `\$tmpl()`, `\$env()`, `\$embed_file()`, `\$pkgconfig()`, `\$vweb.html()`, `\$compile_error()`, `\$compile_warn()`, `\$d()` and `\$res()` comptime functions are supported right now'

fn (mut p Parser) comptime_call() ast.ComptimeCall {
err_node := ast.ComptimeCall{
scope: unsafe { nil }
}
start_pos := p.tok.pos()
p.check(.dollar)
mut is_veb := false
error_msg := 'only `\$tmpl()`, `\$env()`, `\$embed_file()`, `\$pkgconfig()`, `\$vweb.html()`, `\$compile_error()`, `\$compile_warn()`, `\$d()` and `\$res()` comptime functions are supported right now'
if p.peek_tok.kind == .dot {
name := p.check_name() // skip `vweb.html()` TODO
if name != 'vweb' && name != 'veb' {
Expand Down

0 comments on commit 719c3b3

Please sign in to comment.