package main import "./compiler" import "./compiler/cimport" import "./compiler/linker" import "./compiler/target" import "core:fmt" import "core:os/os2" Cli_Options :: struct { input_path: string, output_path: string, link_arguments: []linker.Argument, c_options: cimport.Options, target: target.Target, } parse_cli_args :: proc(args: []string, allocator := context.allocator) -> (Cli_Options, bool) { if len(args) < 4 { return {}, false } options := Cli_Options{input_path=args[1], target=target.DEFAULT} link_arguments: [dynamic]linker.Argument link_arguments.allocator = allocator include_paths: [dynamic]string include_paths.allocator = allocator defines: [dynamic]string defines.allocator = allocator success := false defer { if !success { delete(link_arguments) delete(include_paths) delete(defines) } } output_set := false cursor := 2 for cursor < len(args) { option := args[cursor] cursor += 1 if cursor >= len(args) { return {}, false } value := args[cursor] cursor += 1 switch option { case "-o": if output_set { return {}, false } output_set = true options.output_path = value case "--c-link": append(&link_arguments, linker.Argument{kind=.Input, value=value}) case "--c-library-path": append(&link_arguments, linker.Argument{kind=.Library_Path, value=value}) case "--c-library": append(&link_arguments, linker.Argument{kind=.Library, value=value}) case "--c-include-path": append(&include_paths, value) case "--c-define": append(&defines, value) case "--target": selected, ok := target.parse(value) if !ok { return {}, false } options.target = selected case: return {}, false } } if !output_set || len(options.output_path) == 0 { return {}, false } options.link_arguments = link_arguments[:] options.c_options.include_paths = include_paths[:] options.c_options.defines = defines[:] success = true return options, true } print_usage :: proc() { fmt.eprintln( "usage: brolang -o [--target aarch64-macos] [--c-link | --c-library-path | --c-library | --c-include-path | --c-define ]...", ) } main :: proc() { options, valid := parse_cli_args(os2.args) if !valid { print_usage() os2.exit(2) } defer delete(options.link_arguments) defer delete(options.c_options.include_paths) defer delete(options.c_options.defines) status := compiler.compile_package(options.input_path, options.output_path, options.link_arguments, options.target, options.c_options) if status != 0 { os2.exit(status) } }