v2 / vlib / v / ast / cflags.v
81 lines · 77 sloc · 2.07 KB · 00b9f0d76cc0e621c7dc3343cd3e9b047531191a
Raw
1// Copyright (c) 2019-2024 Alexander Medvednikov. All rights reserved.
2// Use of this source code is governed by an MIT license
3// that can be found in the LICENSE file.
4module ast
5
6import v.cflag
7
8// check if cflag is in table
9pub fn (t &Table) has_cflag(flag cflag.CFlag) bool {
10 for cf in t.cflags {
11 if cf.os == flag.os && cf.name == flag.name && cf.value == flag.value {
12 return true
13 }
14 }
15 return false
16}
17
18// parse the flags to (ast.cflags) []CFlag
19// Note: clean up big time (joe-c)
20pub fn (mut t Table) parse_cflag(cflg string, mod string, ctimedefines []string) ! {
21 allowed_flags := ['framework', 'library', 'Wa', 'Wl', 'Wp', 'I', 'l', 'L', 'D']
22 flag_orig := cflg.trim_space()
23 mut flag := flag_orig
24 if flag == '' {
25 return error('flag is empty')
26 }
27 if flag.contains('`') {
28 return error('bad #flag `${flag_orig}`: shell command substitution with backticks is not supported; use #pkgconfig or explicit flags instead')
29 }
30 mut fos := ''
31 mut allowed_os_overrides := []string{}
32 allowed_os_overrides << valid_comptime_not_user_defined
33 allowed_os_overrides << ctimedefines
34 for os_override in allowed_os_overrides {
35 if !flag.starts_with(os_override) {
36 continue
37 }
38 pos := flag.index(' ') or { return error('none') }
39 fos = flag[..pos].trim_space()
40 flag = flag[pos..].trim_space()
41 }
42 for {
43 mut name := ''
44 mut value := ''
45 if flag[0] == `-` {
46 for f in allowed_flags {
47 i := 1 + f.len
48 if i <= flag.len && f == flag[1..i] {
49 name = flag[..i].trim_space()
50 flag = flag[i..].trim_space()
51 break
52 }
53 }
54 }
55 // -I/usr/local/a b c/include -m64 -I/usr/include
56 index := flag.index_(' -')
57 if index > -1 {
58 value = flag[..index].trim_space()
59 flag = flag[index..].trim_space()
60 } else {
61 value = flag
62 }
63
64 if name in ['-I', '-l', '-L'] && value == '' {
65 hint := if name == '-l' { 'library name' } else { 'path' }
66 return error('bad #flag `${flag_orig}`: missing ${hint} after `${name}`')
67 }
68 cf := cflag.CFlag{
69 mod: mod
70 os: fos
71 name: name
72 value: value
73 }
74 if !t.has_cflag(cf) {
75 t.cflags << cf
76 }
77 if index == -1 {
78 break
79 }
80 }
81}
82