upgrade enum discriminants

This commit is contained in:
2026-07-17 20:32:12 +02:00
parent 866e28adb8
commit cedc63b28b
19 changed files with 3168 additions and 96 deletions
+119 -11
View File
@@ -98,7 +98,7 @@ print_usage :: proc() {
"usage: brolang <package-directory> -o <executable> [--root <project-root>] [--target aarch64-macos] [--c-link <path> | --c-library-path <dir> | --c-library <name> | --c-include-path <dir> | --c-define <name[=value]>]...",
)
fmt.eprintln(
" brolang translate-c|--translate-c <header.h> [--target aarch64-macos] [--c-include-path <dir> | --c-define <name[=value]>]...",
" brolang translate-c|--translate-c <header.h>... [--output-dir <dir>] [--target aarch64-macos] [--c-include-path <dir> | --c-define <name[=value]>]...",
)
fmt.eprintln(
" brolang build [root] (reads root/build.bro; writes root/build/name)",
@@ -429,11 +429,14 @@ run_translate_c :: proc(args: []string) -> int {
print_usage()
return 2
}
header := args[2]
selected := target.DEFAULT
headers: [dynamic]string
include_paths: [dynamic]string
owned_include_paths: [dynamic]string
defines: [dynamic]string
output_dir := ""
output_dir_set := false
defer delete(headers)
defer delete(include_paths)
defer {
for path in owned_include_paths {
@@ -442,10 +445,14 @@ run_translate_c :: proc(args: []string) -> int {
delete(owned_include_paths)
}
defer delete(defines)
cursor := 3
cursor := 2
for cursor < len(args) {
option := args[cursor]
cursor += 1
if !strings.has_prefix(option, "--") {
append(&headers, option)
continue
}
if cursor >= len(args) {
fmt.eprintfln("missing value for %s", option)
return 2
@@ -457,6 +464,13 @@ run_translate_c :: proc(args: []string) -> int {
append(&include_paths, value)
case "--c-define":
append(&defines, value)
case "--output-dir":
if output_dir_set || len(value) == 0 {
fmt.eprintln("--output-dir may be provided once with a non-empty value")
return 2
}
output_dir = value
output_dir_set = true
case "--target":
parsed, ok := target.parse(value)
if !ok {
@@ -469,18 +483,112 @@ run_translate_c :: proc(args: []string) -> int {
return 2
}
}
if len(headers) == 0 {
print_usage()
return 2
}
if len(headers) > 1 && !output_dir_set {
fmt.eprintln("multiple headers require --output-dir")
return 2
}
names := make([]string, len(headers))
defer {
for name in names {
delete(name)
}
delete(names)
}
if output_dir_set {
seen_names: map[string]bool
defer delete(seen_names)
for header, index in headers {
base := filepath.base(header)
extension := filepath.ext(base)
stem := base[:len(base)-len(extension)]
if len(stem) == 0 {
fmt.eprintfln("cannot derive an output name from header '%s'", header)
return 2
}
name := fmt.aprintf("%s.bro", stem)
if seen_names[name] {
fmt.eprintfln("duplicate generated output name '%s'", name)
delete(name)
return 2
}
seen_names[name] = true
names[index] = name
}
}
_ = append_zig_libc_include_paths(&include_paths, &owned_include_paths, selected)
import_header, _ := resolve_translate_c_header(header, include_paths[:])
defer delete(import_header)
c_options := cimport.Options{include_paths=include_paths[:], defines=defines[:]}
result := cimport.import_header(c_options, import_header, selected)
defer cimport.destroy_result(&result)
if !result.available {
message := result.error_message if len(result.error_message) > 0 else "failed to import header"
fmt.eprintln(message)
resolved_headers: [dynamic]string
results: [dynamic]cimport.Result
defer {
for header in resolved_headers {
delete(header)
}
delete(resolved_headers)
for &result in results {
cimport.destroy_result(&result)
}
delete(results)
}
for header in headers {
resolved, _ := resolve_translate_c_header(header, include_paths[:])
append(&resolved_headers, resolved)
result := cimport.import_header(c_options, resolved, selected)
append(&results, result)
if !result.available {
message := result.error_message if len(result.error_message) > 0 else "failed to import header"
fmt.eprintln(message)
return 1
}
}
if !output_dir_set {
fmt.print(translatec.emit(&results[0], headers[0]))
return 0
}
inputs := make([]translatec.Package_Input, len(headers))
defer delete(inputs)
for header, index in headers {
inputs[index] = translatec.Package_Input{
result=&results[index],
header=header,
name=names[index],
}
}
outputs, generation_error := translatec.emit_package(inputs[:])
defer translatec.destroy_package_outputs(outputs)
defer delete(generation_error)
if len(generation_error) > 0 {
fmt.eprintln(generation_error)
return 1
}
fmt.print(translatec.emit(&result, header))
if !ensure_directory(output_dir) {
return 1
}
paths := make([]string, len(outputs))
defer {
for path in paths {
delete(path)
}
delete(paths)
}
for output, index in outputs {
path, join_error := filepath.join({output_dir, output.name})
if join_error != nil {
fmt.eprintfln("failed to form output path for '%s'", output.name)
return 1
}
paths[index] = path
}
for output, index in outputs {
if !os.write_entire_file(paths[index], transmute([]byte)output.source) {
fmt.eprintfln("failed to write generated bindings '%s'", paths[index])
return 1
}
}
return 0
}