|
| 1 | +# test = 'pass' |
| 2 | + |
| 3 | +# Validate and normalize gcc flags. They can be either a string `-Wextra` or |
| 4 | +# a structured value `{flag = "W", arg = "extra"}`. Arguments are not checked. |
| 5 | +let |
| 6 | + GccFlag = |
| 7 | + let supported_flags = ["W", "c", "S", "e", "o"] in |
| 8 | + let is_valid_flag |
| 9 | + | doc "check if a string of length > 0 is a valid flag" |
| 10 | + = fun string => |
| 11 | + std.array.elem (std.string.substring 0 1 string) supported_flags |
| 12 | + in |
| 13 | + |
| 14 | + std.contract.custom (fun label => |
| 15 | + match { |
| 16 | + value if std.is_string value && is_valid_flag value => 'Ok value, |
| 17 | + { flag, arg } if std.array.elem flag supported_flags => |
| 18 | + # We normalize a record representation to a string |
| 19 | + 'Ok "%{flag}%{arg}", |
| 20 | + value if std.is_string value => |
| 21 | + 'Error { message = "unknown flag %{value}" }, |
| 22 | + { flag, arg = _ } => |
| 23 | + 'Error { message = "unknown flag %{flag}" }, |
| 24 | + { .. } => |
| 25 | + 'Error { |
| 26 | + message = "bad record structure: missing field `flag` or `arg`", |
| 27 | + }, |
| 28 | + _ => 'Error { message = "expected record or string" }, |
| 29 | + } |
| 30 | + ), |
| 31 | + Path = |
| 32 | + let pattern = m%"^(.+)/([^/]+)$"% in |
| 33 | + std.contract.from_validator (fun value => |
| 34 | + if std.is_string value then |
| 35 | + if std.string.is_match pattern value then |
| 36 | + 'Ok |
| 37 | + else |
| 38 | + 'Error { message = "invalid path" } |
| 39 | + else |
| 40 | + 'Error { message = "not a string" } |
| 41 | + ), |
| 42 | + SharedObjectFile = |
| 43 | + std.contract.from_validator (fun value => |
| 44 | + if std.is_string value then |
| 45 | + if std.string.is_match m%"\.so$"% value then |
| 46 | + 'Ok |
| 47 | + else |
| 48 | + 'Error { message = "not an .so file" } |
| 49 | + else |
| 50 | + 'Error { message = "not a string" } |
| 51 | + ), |
| 52 | + OptLevel = |
| 53 | + std.contract.from_predicate (match { |
| 54 | + 0 or 1 or 2 => true, |
| 55 | + _ => false, |
| 56 | + } |
| 57 | + ), |
| 58 | +in |
| 59 | + |
| 60 | +let GccConf = { |
| 61 | + path_libc |
| 62 | + | doc "Path to libc." |
| 63 | + | Path |
| 64 | + | SharedObjectFile |
| 65 | + | default |
| 66 | + = "/lib/x86_64-linux-gnu/libc.so", |
| 67 | + |
| 68 | + flags |
| 69 | + | doc m%" |
| 70 | + Additional flags to pass to GCC. Either provide a string without the |
| 71 | + leading `-`, or a structured value `{flag : String, arg: String}`. |
| 72 | + "% |
| 73 | + | Array GccFlag |
| 74 | + | default |
| 75 | + = [], |
| 76 | + |
| 77 | + optimization_level |
| 78 | + | doc m%" |
| 79 | + Optimization level. Possible values: |
| 80 | +
|
| 81 | + - *0*: unoptimized |
| 82 | + - *1*: normal |
| 83 | + - *2*: use optimizations |
| 84 | + "% |
| 85 | + | OptLevel |
| 86 | + | default |
| 87 | + = 1, |
| 88 | +} |
| 89 | +in |
| 90 | + |
| 91 | +{ |
| 92 | + flags = ["Wextra", { flag = "o", arg = "stuff.o" }], |
| 93 | + optimization_level = 2, |
| 94 | +} | GccConf |
| 95 | + |
0 commit comments