type command-line option values

* pass argv inputs directly to the config command line
* define each option's value type in the switch table so comma splitting
  is applied only to list typed switches
This commit is contained in:
Nikita Smith committed 2026-08-17 22:55:58 -07:00
1 parent 76e267482f
commit efe2a78019
7 files changed
+390 -452

No files matched your search

+2 -2
View File
@@ -1233,7 +1233,7 @@ lnk_load_objs(TP_Context *tp, TP_Arena *arena, LNK_Config *config, LNK_Inputer *
LNK_DirectiveInfo directive_info = lnk_directive_info_from_raw_directives(scratch.arena, obj, raw_directives);
for EachIndex(i, ArrayCount(directive_info.v)) {
for (LNK_Directive *dir = directive_info.v[i].first; dir != 0; dir = dir->next) {
lnk_apply_cmd_option_to_config(config, dir->id, dir->value_list, obj);
lnk_apply_cmd_option_to_config(config, dir->id, dir->value, obj);
}
}
}
@@ -6738,7 +6738,7 @@ lnk_run_type_server(TP_Context *tp, TP_Arena *arena, LNK_Config *config)
{
LNK_CmdLine default_line = lnk_cmd_line_from_stringf_windows_rules(scratch.arena, "/DEBUG:GHASH /NOD /RAD_WRITE_TEMP_FILES");
for EachNode(cmd, LNK_CmdOption, default_line.first_option) {
lnk_apply_cmd_option_to_config(config, cmd->string, cmd->value_strings, &(LNK_Obj){0});
lnk_apply_cmd_option_to_config(config, cmd->string, cmd->value, &(LNK_Obj){0});
}
}
+12 -51
View File
@@ -15,7 +15,7 @@ lnk_arg_list_parse_windows_rules(Arena *arena, String8 string)
while(ptr < opl) {
U64 size = (U64)(opl - ptr);
UnicodeDecode uni = utf8_decode(ptr, size);
if (uni.codepoint != ' ' && uni.codepoint != '\n' && uni.codepoint != '\r') {
if (uni.codepoint != ' ' && uni.codepoint != '\t' && uni.codepoint != '\n' && uni.codepoint != '\r') {
break;
}
ptr += uni.inc;
@@ -31,7 +31,7 @@ lnk_arg_list_parse_windows_rules(Arena *arena, String8 string)
UnicodeDecode uni;
uni = utf8_decode(ptr, (U64)(opl-ptr));
if (uni.codepoint == '\0' || uni.codepoint == '\n' || uni.codepoint == '\r' || uni.codepoint == ' ') {
if (uni.codepoint == '\0' || uni.codepoint == '\t' || uni.codepoint == '\n' || uni.codepoint == '\r' || uni.codepoint == ' ') {
break;
}
@@ -89,12 +89,12 @@ lnk_cmd_line_push_option_node(LNK_CmdLine *cmd_line, LNK_CmdOption *opt)
}
internal LNK_CmdOption *
lnk_cmd_line_push_option_list(Arena *arena, LNK_CmdLine *cmd_line, String8 string, String8List value_strings)
lnk_cmd_line_push_option_string(Arena *arena, LNK_CmdLine *cmd_line, String8 string, String8 value)
{
// fill out node
LNK_CmdOption *opt = push_array(arena, LNK_CmdOption, 1);
opt->string = string;
opt->value_strings = value_strings;
opt->value = value;
// push node
lnk_cmd_line_push_option_node(cmd_line, opt);
@@ -102,14 +102,6 @@ lnk_cmd_line_push_option_list(Arena *arena, LNK_CmdLine *cmd_line, String8 strin
return opt;
}
internal LNK_CmdOption *
lnk_cmd_line_push_option_string(Arena *arena, LNK_CmdLine *cmd_line, String8 string, String8 value)
{
String8List value_list = str8_split_by_string_chars(arena, value, str8_lit(","), StringSplitFlag_KeepEmpties);
LNK_CmdOption *opt = lnk_cmd_line_push_option_list(arena, cmd_line, string, value_list);
return opt;
}
internal LNK_CmdOption *
lnk_cmd_line_push_option(Arena *arena, LNK_CmdLine *cmd_line, char *string, char *value)
{
@@ -161,15 +153,12 @@ lnk_cmd_line_parse_windows_rules(Arena *arena, String8List arg_list)
// skip ':'
String8 value_string = str8_skip(arg, param_start_pos + 1);
// make value list
String8List value_list_temp = str8_split_by_string_chars(scratch.arena, value_string, str8_lit(","), 0);
String8List value_list = str8_list_copy(arena, &value_list_temp);
// push command
option_name = push_str8_copy(arena, option_name);
lnk_cmd_line_push_option_list(arena, &cmd_line, option_name, value_list);
value_string = push_str8_copy(arena, value_string);
lnk_cmd_line_push_option_string(arena, &cmd_line, option_name, value_string);
} else if (str8_starts_with(arg, str8_lit("@"))) {
lnk_cmd_line_push_option_list(arena, &cmd_line, push_str8_copy(arena, arg), (String8List){0});
lnk_cmd_line_push_option_string(arena, &cmd_line, push_str8_copy(arena, arg), str8_zero());
} else {
str8_list_push(arena, &cmd_line.input_list, push_str8_copy(arena, arg));
}
@@ -204,7 +193,7 @@ lnk_cmd_line_option_from_string(LNK_CmdLine cmd_line, String8 string)
{
LNK_CmdOption *opt;
for (opt = cmd_line.first_option; opt != NULL; opt = opt->next) {
if (str8_match(string, opt->string, StringMatchFlag_CaseInsensitive)) {
if (str8_matchi(string, opt->string)) {
break;
}
}
@@ -230,42 +219,14 @@ lnk_data_from_cmd_line(Arena *arena, LNK_CmdLine cmd_line)
{
String8List result = {0};
for (LNK_CmdOption *opt = cmd_line.first_option; opt != 0; opt = opt->next) {
// separate directives
for EachNode(opt, LNK_CmdOption, cmd_line.first_option) {
// separate commands
if (opt != cmd_line.first_option) {
str8_list_pushf(arena, &result, " ");
}
// push new directive
str8_list_pushf(arena, &result, "/%.*s", str8_varg(opt->string));
// do we have arguments?
if (opt->value_strings.node_count > 0) {
str8_list_pushf(arena, &result, ":");
for (String8Node *value_node = opt->value_strings.first; value_node != 0; value_node = value_node->next) {
// separate arguments
if (value_node != opt->value_strings.first) {
str8_list_pushf(arena, &result, ",");
}
// push argument
B32 has_spaces = str8_find_needle(value_node->string, 0, str8_lit(" "), StringMatchFlag_CaseInsensitive) < value_node->string.size;
if (has_spaces) {
str8_list_pushf(arena, &result, "\"%.*s\"", str8_varg(value_node->string));
} else {
str8_list_pushf(arena, &result, "%.*s", str8_varg(value_node->string));
}
}
}
}
// append inputs
for (String8Node *input_node = cmd_line.input_list.first; input_node != 0; input_node = input_node->next) {
if (input_node != cmd_line.input_list.first) {
str8_list_pushf(arena, &result, " ");
}
str8_list_pushf(arena, &result, "\"%.*s\"", str8_varg(input_node->string));
// push command line option
str8_list_pushf(arena, &result, "/%S%s%S", opt->string, opt->value.size ? ":" : "", opt->value);
}
return result;
+2 -2
View File
@@ -7,7 +7,7 @@ typedef struct LNK_CmdOption
{
struct LNK_CmdOption *next;
String8 string;
String8List value_strings;
String8 value;
} LNK_CmdOption;
typedef struct LNK_CmdLine
@@ -50,7 +50,7 @@ internal String8List lnk_arg_list_parse_windows_rules (Arena *arena,
internal LNK_CmdLine lnk_cmd_line_parse_windows_rules (Arena *arena, String8List arg_list);
internal LNK_CmdLine lnk_cmd_line_from_stringfv_windows_rules(Arena *arena, char *fmt, va_list args);
internal LNK_CmdLine lnk_cmd_line_from_stringf_windows_rules (Arena *arena, char *fmt, ...);
internal LNK_CmdOption * lnk_cmd_line_push_option_list (Arena *arena, LNK_CmdLine *cmd_line, String8 string, String8List value_strings);
internal LNK_CmdOption * lnk_cmd_line_push_option_string (Arena *arena, LNK_CmdLine *cmd_line, String8 string, String8 value);
internal LNK_CmdOption * lnk_cmd_line_push_option (Arena *arena, LNK_CmdLine *cmd_line, char *string, char *value);
internal LNK_CmdOption * lnk_cmd_line_push_option_if_not_present (Arena *arena, LNK_CmdLine *cmd_line, char *string, char *value);
internal String8List lnk_data_from_cmd_line (Arena *arena, LNK_CmdLine cmd_line);
+351 -382
View File
File diff suppressed because it is too large. Load diff
+21 -13
View File
@@ -155,10 +155,18 @@ typedef enum
LNK_CmdSwitch_Count
} LNK_CmdSwitchType;
typedef enum LNK_CmdValueKind
{
LNK_CmdValueKind_Null,
LNK_CmdValueKind_Scalar,
LNK_CmdValueKind_List,
} LNK_CmdValueKind;
typedef struct LNK_CmdSwitch
{
LNK_CmdSwitchType type;
B32 is_legal_directive;
LNK_CmdValueKind value_kind;
char *name;
char *args;
char *desc;
@@ -566,18 +574,18 @@ internal void lnk_error_cmd_switch_invalid_param (LNK_ErrorCode code, struc
// --- Specialized Parsers ------------------------------------------------------
internal B32 lnk_cmd_switch_parse_version (struct LNK_Obj *obj, LNK_CmdSwitchType cmd_switch, String8List value_strings, Version *ver_out);
internal B32 lnk_cmd_switch_parse_tuple (struct LNK_Obj *obj, LNK_CmdSwitchType cmd_switch, String8List value_strings, Rng1U64 *tuple_out);
internal B32 lnk_cmd_switch_parse_u64 (struct LNK_Obj *obj, LNK_CmdSwitchType cmd_switch, String8List value_strings, U64 *value_out, LNK_ParseU64Flags flags);
internal B32 lnk_cmd_switch_parse_u32 (struct LNK_Obj *obj, LNK_CmdSwitchType cmd_switch, String8List value_strings, U32 *value_out, LNK_ParseU64Flags flags);
internal B32 lnk_cmd_switch_parse_flag (struct LNK_Obj *obj, LNK_CmdSwitchType cmd_switch, String8List value_strings, LNK_SwitchState *value_out);
internal void lnk_cmd_switch_set_flag_inv_16(struct LNK_Obj *obj, LNK_CmdSwitchType cmd_switch, String8List value_strings, U16 *flags, U16 bits);
internal void lnk_cmd_switch_set_flag_inv_64(struct LNK_Obj *obj, LNK_CmdSwitchType cmd_switch, String8List value_strings, U64 *flags, U64 bits);
internal void lnk_cmd_switch_set_flag_16 (struct LNK_Obj *obj, LNK_CmdSwitchType cmd_switch, String8List value_strings, U16 *flags, U16 bits);
internal void lnk_cmd_switch_set_flag_32 (struct LNK_Obj *obj, LNK_CmdSwitchType cmd_switch, String8List value_strings, U32 *flags, U32 bits);
internal void lnk_cmd_switch_set_flag_64 (struct LNK_Obj *obj, LNK_CmdSwitchType cmd_switch, String8List value_strings, U64 *flags, U64 bits);
internal B32 lnk_cmd_switch_parse_string (struct LNK_Obj *obj, LNK_CmdSwitchType cmd_switch, String8List value_strings, String8 *string_out);
internal void lnk_cmd_switch_parse_string_copy(Arena *arena, struct LNK_Obj *obj, LNK_CmdSwitchType cmd_switch, String8List value_strings, String8 *string_out);
internal B32 lnk_cmd_switch_parse_version (struct LNK_Obj *obj, LNK_CmdSwitchType cmd_switch, String8 value, Version *ver_out);
internal B32 lnk_cmd_switch_parse_tuple (struct LNK_Obj *obj, LNK_CmdSwitchType cmd_switch, String8List values, Rng1U64 *tuple_out);
internal B32 lnk_cmd_switch_parse_u64 (struct LNK_Obj *obj, LNK_CmdSwitchType cmd_switch, String8 value, U64 *value_out, LNK_ParseU64Flags flags);
internal B32 lnk_cmd_switch_parse_u32 (struct LNK_Obj *obj, LNK_CmdSwitchType cmd_switch, String8 value, U32 *value_out, LNK_ParseU64Flags flags);
internal B32 lnk_cmd_switch_parse_flag (struct LNK_Obj *obj, LNK_CmdSwitchType cmd_switch, String8 value, LNK_SwitchState *value_out);
internal void lnk_cmd_switch_set_flag_inv_16(struct LNK_Obj *obj, LNK_CmdSwitchType cmd_switch, String8 value, U16 *flags, U16 bits);
internal void lnk_cmd_switch_set_flag_inv_64(struct LNK_Obj *obj, LNK_CmdSwitchType cmd_switch, String8 value, U64 *flags, U64 bits);
internal void lnk_cmd_switch_set_flag_16 (struct LNK_Obj *obj, LNK_CmdSwitchType cmd_switch, String8 value, U16 *flags, U16 bits);
internal void lnk_cmd_switch_set_flag_32 (struct LNK_Obj *obj, LNK_CmdSwitchType cmd_switch, String8 value, U32 *flags, U32 bits);
internal void lnk_cmd_switch_set_flag_64 (struct LNK_Obj *obj, LNK_CmdSwitchType cmd_switch, String8 value, U64 *flags, U64 bits);
internal B32 lnk_cmd_switch_parse_string (struct LNK_Obj *obj, LNK_CmdSwitchType cmd_switch, String8 value, String8 *string_out);
internal void lnk_cmd_switch_parse_string_copy(Arena *arena, struct LNK_Obj *obj, LNK_CmdSwitchType cmd_switch, String8 value, String8 *string_out);
internal B32 lnk_parse_alt_name_directive (String8 string, struct LNK_Obj *obj, LNK_AltName *alt_out);
internal B32 lnk_parse_merge_directive (String8 string, struct LNK_Obj *obj, LNK_MergeDirective *parse_out);
@@ -613,7 +621,7 @@ internal void lnk_whole_archive(LNK_Config *config, String8 lib_name);
// --- Config ------------------------------------------------------------------
internal void lnk_apply_cmd_option_to_config(LNK_Config *config, String8 name, String8List value_list, struct LNK_Obj *obj);
internal void lnk_apply_cmd_option_to_config(LNK_Config *config, String8 name, String8 value, struct LNK_Obj *obj);
internal LNK_Config * lnk_config_init(U64 argc, char **argv);
+1 -1
View File
@@ -881,7 +881,7 @@ lnk_parse_msvc_linker_directive(Arena *arena, LNK_Obj *obj, LNK_DirectiveInfo *d
LNK_Directive *directive = push_array_no_zero(arena, LNK_Directive, 1);
directive->next = 0;
directive->id = str8_cstring(cmd_switch->name);
directive->value_list = str8_list_copy(arena, &opt->value_strings);
directive->value = push_str8_copy(arena, opt->value);
LNK_DirectiveList *directive_list = &directive_info->v[cmd_switch->type];
SLLQueuePush(directive_list->first, directive_list->last, directive);
+1 -1
View File
@@ -89,7 +89,7 @@ typedef struct LNK_Directive
{
struct LNK_Directive *next;
String8 id;
String8List value_list;
String8 value;
} LNK_Directive;
typedef struct LNK_DirectiveList