Parse build_project_name as [][]string

This commit is contained in:
Damian Tarnawski
2024-08-29 22:08:01 +02:00
parent a10f988020
commit f93779d425
2 changed files with 62 additions and 47 deletions
+30 -16
View File
@@ -18,7 +18,7 @@ Build_Kind :: struct {
} }
File_Tags :: struct { File_Tags :: struct {
build_project_name: []string, build_project_name: [][]string,
build: []Build_Kind, build: []Build_Kind,
private: Private_Flag, private: Private_Flag,
ignore: bool, ignore: bool,
@@ -48,7 +48,9 @@ get_build_arch_from_string :: proc(str: string) -> runtime.Odin_Arch_Type {
} }
@require_results @require_results
parse_file_tags :: proc(file: ast.File) -> (tags: File_Tags) { parse_file_tags :: proc(file: ast.File, allocator := context.allocator) -> (tags: File_Tags) {
context.allocator = allocator
if file.docs == nil { if file.docs == nil {
return return
} }
@@ -87,7 +89,10 @@ parse_file_tags :: proc(file: ast.File) -> (tags: File_Tags) {
build_kinds: [dynamic]Build_Kind build_kinds: [dynamic]Build_Kind
defer shrink(&build_kinds) defer shrink(&build_kinds)
build_project_names: [dynamic]string build_project_name_strings: [dynamic]string
defer shrink(&build_project_name_strings)
build_project_names: [dynamic][]string
defer shrink(&build_project_names) defer shrink(&build_project_names)
for comment in file.docs.list { for comment in file.docs.list {
@@ -116,23 +121,32 @@ parse_file_tags :: proc(file: ast.File) -> (tags: File_Tags) {
tags.private = .Package tags.private = .Package
} }
case "build-project-name": case "build-project-name":
values_loop: for { groups_loop: for {
skip_whitespace(text, &i) index_start := len(build_project_name_strings)
name_start := i defer append(&build_project_names, build_project_name_strings[index_start:])
switch next_char(text, &i) { for {
case 0, '\n': skip_whitespace(text, &i)
i -= 1 name_start := i
break values_loop
case '!': switch next_char(text, &i) {
// include ! in the name case 0, '\n':
case: i -= 1
i -= 1 break groups_loop
case ',':
continue groups_loop
case '!':
// include ! in the name
case:
i -= 1
}
scan_value(text, &i)
append(&build_project_name_strings, text[name_start:i])
} }
scan_value(text, &i) append(&build_project_names, build_project_name_strings[index_start:])
append(&build_project_names, text[name_start:i])
} }
case "build": case "build":
kinds_loop: for { kinds_loop: for {
+32 -31
View File
@@ -3,6 +3,7 @@ package test_core_odin_parser
import "base:runtime" import "base:runtime"
import "core:testing" import "core:testing"
import "core:slice" import "core:slice"
import "core:log"
import "core:odin/ast" import "core:odin/ast"
import "core:odin/parser" import "core:odin/parser"
@@ -60,12 +61,12 @@ package main
}, },
}, {// [4] }, {// [4]
src = ` src = `
//+build-project-name foo !bar //+build-project-name foo !bar, baz
//+build js wasm32, js wasm64p32 //+build js wasm32, js wasm64p32
package main package main
`, `,
tags = { tags = {
build_project_name = {"foo", "!bar"}, build_project_name = {{"foo", "!bar"}, {"baz"}},
build = { build = {
{ {
os = {.JS}, os = {.JS},
@@ -79,11 +80,9 @@ package main
}, },
} }
expect :: proc(t: ^testing.T, ok: bool, name: string, i: int, expected, actual: $T, loc := #caller_location) { error_expected :: proc(name: string, i: int, expected, actual: $T, loc := #caller_location) {
testing.expectf(t, ok, log.errorf("[%d] expected %s:\n\e[0;32m%#v\e[0m, actual:\n\e[0;31m%#v\e[0m",
"[%d] expected %s:\n\e[0;32m%#v\e[0m, actual:\n\e[0;31m%#v\e[0m", i, name, expected, actual, location=loc)
i, name, expected, actual, loc=loc
)
} }
for test_case, i in test_cases { for test_case, i in test_cases {
@@ -100,34 +99,36 @@ package main
tags := parser.parse_file_tags(file) tags := parser.parse_file_tags(file)
expect(t,
slice.equal(test_case.tags.build_project_name, tags.build_project_name),
"build_project_name", i, test_case.tags.build_project_name, tags.build_project_name,
)
expect(t, build_project_name_the_same: bool
slice.equal(test_case.tags.build, tags.build), check: if len(test_case.tags.build_project_name) == len(tags.build_project_name) {
"build", i, test_case.tags.build, tags.build, for tag, i in test_case.tags.build_project_name {
) slice.equal(tag, tags.build_project_name[i]) or_break check
}
build_project_name_the_same = true
}
if !build_project_name_the_same {
error_expected("build_project_name", i, test_case.tags.build_project_name, tags.build_project_name)
}
expect(t, if !slice.equal(test_case.tags.build, tags.build) {
test_case.tags.private == tags.private, error_expected("build", i, test_case.tags.build, tags.build,)
"private", i, test_case.tags.private, tags.private, }
)
expect(t, if test_case.tags.private != tags.private {
test_case.tags.ignore == tags.ignore, error_expected("private", i, test_case.tags.private, tags.private)
"ignore", i, test_case.tags.ignore, tags.ignore, }
)
expect(t, if test_case.tags.ignore != tags.ignore {
test_case.tags.lazy == tags.lazy, error_expected("ignore", i, test_case.tags.ignore, tags.ignore)
"lazy", i, test_case.tags.lazy, tags.lazy, }
)
expect(t, if test_case.tags.lazy != tags.lazy {
test_case.tags.no_instrumentation == tags.no_instrumentation, error_expected("lazy", i, test_case.tags.lazy, tags.lazy)
"no_instrumentation", i, test_case.tags.no_instrumentation, tags.no_instrumentation, }
)
if test_case.tags.no_instrumentation != tags.no_instrumentation {
error_expected("no_instrumentation", i, test_case.tags.no_instrumentation, tags.no_instrumentation)
}
} }
} }