package main import "core:strings" import "core:fmt" SwitchDefinition :: struct { name: string, fullname: string, shortname: string, usage: string, description: string, no_argument: bool, callback: proc(value: string, data: rawptr) -> (ok: bool), } SwitchSplitError :: enum { None, Empty, MissingDash, MissingStartQuote, MissingEndQuote, } switch_split :: proc(str: string) -> (name, value: string, err: SwitchSplitError) { name = "" value = "" err = .None if len(str) == 0 { err = .Empty return } if str[0] != '-' { err = .MissingDash return } colon_index := strings.index_rune(str, ':') if colon_index == -1 { name = str[1:] return } name = str[1:colon_index] value = str[colon_index + 1:] if value[0] != '"' && value[len(value) - 1] == '"' { err = .MissingStartQuote return } else if value[0] == '"' && value[len(value) - 1] != '"' { err = .MissingEndQuote return } if value[0] == '"' && value[len(value) - 1] == '"' { value = value[1:len(value) - 2] } return } process_switches :: proc(args: []string, switch_definitions: []SwitchDefinition, allocator := context.allocator, data: rawptr) -> bool { ok := true error_state: bool switch_map := make(map[string]SwitchDefinition) for switch_definition in switch_definitions { shortname := switch_definition.shortname shortname_length := len(shortname) if shortname_length > 0 { if shortname in switch_map { ok = false existing_switch_definition := switch_map[shortname] fmt.eprintln("Argument error: Switch for ", switch_definition.name, " (", shortname, ") already existed for '", existing_switch_definition.name, sep = "") } else { switch_map[shortname] = switch_definition } } fullname := switch_definition.fullname fullname_length := len(fullname) if fullname_length > 0 { if fullname in switch_map { ok = false existing_switch_definition := switch_map[fullname] fmt.eprintln("Argument error: Switch for ", switch_definition.name, " (", fullname, ") already existed for '", existing_switch_definition.name, sep = "") } else { switch_map[fullname] = switch_definition } } if shortname_length == 0 && fullname_length == 0 { ok = false fmt.eprintln("Switch definition error: ", switch_definition.name, " had no shortname or fullname", sep = "") } } for arg in args { name, value, err := switch_split(arg) if err != .None { ok = false fmt.eprintln("Argument error: ", err, " (", arg, ")", sep = "") continue } if name not_in switch_map { ok = false fmt.eprintln("Argument error: Non-existent switch", name, sep = "") continue } switch_map[name].callback(value, data) } return ok }