| 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. |
| 4 | module ast |
| 5 | |
| 6 | import v.cflag |
| 7 | |
| 8 | // check if cflag is in table |
| 9 | pub 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) |
| 20 | pub 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 | |