Handle multiple +build package tags with '!' (nots)

This commit is contained in:
gingerBill
2018-05-28 21:25:08 +01:00
parent 6eb505a677
commit ccbb6df749
+40 -22
View File
@@ -4217,6 +4217,22 @@ void parse_setup_file_decls(Parser *p, AstFile *f, String base_dir, Array<AstNod
} }
} }
String build_tag_get_token(String s, String *out) {
s = string_trim_whitespace(s);
isize n = 0;
while (n < s.len) {
Rune rune = 0;
isize width = gb_utf8_decode(&s[n], s.len-n, &rune);
if (rune_is_whitespace(rune)) {
*out = substring(s, n+width, s.len);
return substring(s, 0, n);
}
n += width;
}
out->len = 0;
return s;
}
bool parse_build_tag(Token token_for_pos, String s) { bool parse_build_tag(Token token_for_pos, String s) {
String const prefix = str_lit("+build"); String const prefix = str_lit("+build");
GB_ASSERT(string_starts_with(s, prefix)); GB_ASSERT(string_starts_with(s, prefix));
@@ -4226,49 +4242,51 @@ bool parse_build_tag(Token token_for_pos, String s) {
return true; return true;
} }
auto platforms = array_make<String>(heap_allocator()); bool any_correct = false;
defer (array_free(&platforms));
isize n = 0; do {
while (n < s.len) { String p = build_tag_get_token(s, &s);
Rune rune = 0; if (p.len == 0) break;
isize width = gb_utf8_decode(&s[n], s.len, &rune); bool is_notted = false;
if (rune_is_whitespace(rune)) { if (p[0] == '!') {
String f = substring(s, 0, n); is_notted = true;
array_add(&platforms, f); p = substring(p, 1, p.len);
s = substring(s, n+width, s.len); if (p.len == 0) {
n = 0; error(token_for_pos, "Expected a build platform after '!'");
continue;
} else if (n+width == s.len) {
String f = substring(s, 0, n+width);
array_add(&platforms, f);
break; break;
} }
n += width;
} }
if (p.len > 0) {
bool any_correct = false;
for_array(i, platforms) {
String p = platforms[i];
TargetOsKind os = get_target_os_from_string(p); TargetOsKind os = get_target_os_from_string(p);
TargetArchKind arch = get_target_arch_from_string(p); TargetArchKind arch = get_target_arch_from_string(p);
if (os != TargetOs_Invalid) { if (os != TargetOs_Invalid) {
GB_ASSERT(arch == TargetArch_Invalid); GB_ASSERT(arch == TargetArch_Invalid);
any_correct = true; any_correct = true;
if (os == build_context.target_os) { if (is_notted) {
if (os != build_context.target_os) {
return true;
}
} else if (os == build_context.target_os) {
return true; return true;
} }
} else if (arch != TargetArch_Invalid) { } else if (arch != TargetArch_Invalid) {
any_correct = true; any_correct = true;
if (arch == build_context.target_arch) { if (is_notted) {
if (arch != build_context.target_arch) {
return true;
}
} else if (arch == build_context.target_arch) {
return true; return true;
} }
} }
if (os == TargetOs_Invalid && arch == TargetArch_Invalid) { if (os == TargetOs_Invalid && arch == TargetArch_Invalid) {
error(token_for_pos, "Invalid build tag platform: %.*s", LIT(p)); error(token_for_pos, "Invalid build tag platform: %.*s", LIT(p));
break;
} }
} }
} while (s.len > 0);
if (any_correct) { if (any_correct) {
return false; return false;
} }