mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-06-27 22:11:47 -07:00
pass over base layer command line parsing. do not assume debugger-style 'treat all after first non-option input as passthrough options'. most things do not want that - the debugger can still get it by doing a quick secondary parse
This commit is contained in:
@@ -2,18 +2,7 @@
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
////////////////////////////////
|
||||
//~ NOTE(rjf): Command Line Option Parsing
|
||||
|
||||
internal U64
|
||||
cmd_line_hash_from_string(String8 string)
|
||||
{
|
||||
U64 result = 5381;
|
||||
for(U64 i = 0; i < string.size; i += 1)
|
||||
{
|
||||
result = ((result << 5) + result) + string.str[i];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
//~ rjf: Command Line Parsing Functions
|
||||
|
||||
internal CmdLineOpt **
|
||||
cmd_line_slot_from_string(CmdLine *cmd_line, String8 string)
|
||||
@@ -21,7 +10,7 @@ cmd_line_slot_from_string(CmdLine *cmd_line, String8 string)
|
||||
CmdLineOpt **slot = 0;
|
||||
if(cmd_line->option_table_size != 0)
|
||||
{
|
||||
U64 hash = cmd_line_hash_from_string(string);
|
||||
U64 hash = u64_hash_from_str8(string);
|
||||
U64 bucket = hash % cmd_line->option_table_size;
|
||||
slot = &cmd_line->option_table[bucket];
|
||||
}
|
||||
@@ -64,7 +53,7 @@ cmd_line_insert_opt(Arena *arena, CmdLine *cmd_line, String8 string, String8List
|
||||
{
|
||||
var = push_array(arena, CmdLineOpt, 1);
|
||||
var->hash_next = *slot;
|
||||
var->hash = cmd_line_hash_from_string(string);
|
||||
var->hash = u64_hash_from_str8(string);
|
||||
var->string = push_str8_copy(arena, string);
|
||||
var->value_strings = values;
|
||||
StringJoin join = {0};
|
||||
@@ -83,28 +72,25 @@ cmd_line_from_string_list(Arena *arena, String8List command_line)
|
||||
{
|
||||
CmdLine parsed = {0};
|
||||
parsed.exe_name = command_line.first->string;
|
||||
parsed.option_table_size = 64;
|
||||
parsed.option_table = push_array(arena, CmdLineOpt *, parsed.option_table_size);
|
||||
|
||||
// NOTE(rjf): Set up config option table.
|
||||
{
|
||||
parsed.option_table_size = 4096;
|
||||
parsed.option_table = push_array(arena, CmdLineOpt *, parsed.option_table_size);
|
||||
}
|
||||
|
||||
// NOTE(rjf): Parse command line.
|
||||
//- rjf: parse options / inputs
|
||||
B32 after_passthrough_option = 0;
|
||||
B32 first_passthrough = 1;
|
||||
for(String8Node *node = command_line.first->next, *next = 0; node != 0; node = next)
|
||||
{
|
||||
next = node->next;
|
||||
String8 option_name = node->string;
|
||||
|
||||
// NOTE(rjf): Look at --, -, or / (only on Windows) at the start of an
|
||||
// argument to determine if it's a flag option. All arguments after a
|
||||
//- rjf: look at --, -, or / (only on Windows) at the start of an
|
||||
// argument to determine if it's a flag option. all arguments after a
|
||||
// single "--" (with no trailing string on the command line will be
|
||||
// considered as input files.
|
||||
B32 is_option = 1;
|
||||
if(after_passthrough_option == 0)
|
||||
// considered as passthrough input strings.
|
||||
B32 is_option = 0;
|
||||
String8 option_name = node->string;
|
||||
if(!after_passthrough_option)
|
||||
{
|
||||
is_option = 1;
|
||||
if(str8_match(node->string, str8_lit("--"), 0))
|
||||
{
|
||||
after_passthrough_option = 1;
|
||||
@@ -128,69 +114,61 @@ cmd_line_from_string_list(Arena *arena, String8List command_line)
|
||||
is_option = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
is_option = 0;
|
||||
}
|
||||
|
||||
// NOTE(rjf): This string is an option.
|
||||
//- rjf: string is an option
|
||||
if(is_option)
|
||||
{
|
||||
B32 has_arguments = 0;
|
||||
U64 arg_signifier_position1 = str8_find_needle(option_name, 0, str8_lit(":"), 0);
|
||||
U64 arg_signifier_position2 = str8_find_needle(option_name, 0, str8_lit("="), 0);
|
||||
U64 arg_signifier_position = Min(arg_signifier_position1, arg_signifier_position2);
|
||||
String8 arg_portion_this_string = str8_skip(option_name, arg_signifier_position+1);
|
||||
if(arg_signifier_position < option_name.size)
|
||||
// rjf: unpack option prefix
|
||||
B32 has_values = 0;
|
||||
U64 value_signifier_position1 = str8_find_needle(option_name, 0, str8_lit(":"), 0);
|
||||
U64 value_signifier_position2 = str8_find_needle(option_name, 0, str8_lit("="), 0);
|
||||
U64 value_signifier_position = Min(value_signifier_position1, value_signifier_position2);
|
||||
String8 value_portion_this_string = str8_skip(option_name, value_signifier_position+1);
|
||||
if(value_signifier_position < option_name.size)
|
||||
{
|
||||
has_arguments = 1;
|
||||
has_values = 1;
|
||||
}
|
||||
option_name = str8_prefix(option_name, arg_signifier_position);
|
||||
option_name = str8_prefix(option_name, value_signifier_position);
|
||||
|
||||
String8List arguments = {0};
|
||||
|
||||
// NOTE(rjf): Parse arguments.
|
||||
if(has_arguments)
|
||||
// rjf: parse option's values
|
||||
String8List values = {0};
|
||||
if(has_values)
|
||||
{
|
||||
for(String8Node *n = node; n; n = n->next)
|
||||
{
|
||||
next = n->next;
|
||||
|
||||
String8 string = n->string;
|
||||
if(n == node)
|
||||
{
|
||||
string = arg_portion_this_string;
|
||||
string = value_portion_this_string;
|
||||
}
|
||||
|
||||
U8 splits[] = { ',' };
|
||||
String8List args_in_this_string = str8_split(arena, string, splits, ArrayCount(splits), 0);
|
||||
for(String8Node *sub_arg = args_in_this_string.first; sub_arg; sub_arg = sub_arg->next)
|
||||
String8List values_in_this_string = str8_split(arena, string, splits, ArrayCount(splits), 0);
|
||||
for(String8Node *sub_val = values_in_this_string.first; sub_val; sub_val = sub_val->next)
|
||||
{
|
||||
str8_list_push(arena, &arguments, sub_arg->string);
|
||||
str8_list_push(arena, &values, sub_val->string);
|
||||
}
|
||||
if(!str8_match(str8_postfix(n->string, 1), str8_lit(","), 0) &&
|
||||
(n != node || arg_portion_this_string.size != 0))
|
||||
(n != node || value_portion_this_string.size != 0))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE(rjf): Register config variable.
|
||||
cmd_line_insert_opt(arena, &parsed, option_name, arguments);
|
||||
// rjf: store
|
||||
cmd_line_insert_opt(arena, &parsed, option_name, values);
|
||||
}
|
||||
|
||||
// NOTE(rjf): Default path, treat as a passthrough config option to be
|
||||
// handled by tool-specific code.
|
||||
//- rjf: default path - treat as a passthrough input
|
||||
else if(!str8_match(node->string, str8_lit("--"), 0) || !first_passthrough)
|
||||
{
|
||||
str8_list_push(arena, &parsed.inputs, node->string);
|
||||
after_passthrough_option = 1;
|
||||
first_passthrough = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// rjf: fill argc/argv
|
||||
//- rjf: fill argc/argv
|
||||
parsed.argc = command_line.node_count;
|
||||
parsed.argv = push_array(arena, char *, parsed.argc);
|
||||
{
|
||||
@@ -239,12 +217,12 @@ internal B32
|
||||
cmd_line_has_flag(CmdLine *cmd_line, String8 name)
|
||||
{
|
||||
CmdLineOpt *var = cmd_line_opt_from_string(cmd_line, name);
|
||||
return(var != 0);
|
||||
return (var != 0);
|
||||
}
|
||||
|
||||
internal B32
|
||||
cmd_line_has_argument(CmdLine *cmd_line, String8 name)
|
||||
{
|
||||
CmdLineOpt *var = cmd_line_opt_from_string(cmd_line, name);
|
||||
return(var != 0 && var->value_strings.node_count > 0);
|
||||
return (var != 0 && var->value_strings.node_count > 0);
|
||||
}
|
||||
|
||||
@@ -39,9 +39,8 @@ struct CmdLine
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ NOTE(rjf): Command Line Option Parsing
|
||||
//~ rjf: Command Line Parsing Functions
|
||||
|
||||
internal U64 cmd_line_hash_from_string(String8 string);
|
||||
internal CmdLineOpt** cmd_line_slot_from_string(CmdLine *cmd_line, String8 string);
|
||||
internal CmdLineOpt* cmd_line_opt_from_slot(CmdLineOpt **slot, String8 string);
|
||||
internal void cmd_line_push_opt(CmdLineOptList *list, CmdLineOpt *var);
|
||||
|
||||
@@ -2484,3 +2484,26 @@ str8_deserial_read_block(String8 string, U64 off, U64 size, String8 *block_out)
|
||||
*block_out = str8_substr(string, range);
|
||||
return block_out->size;
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Basic String Hashes
|
||||
|
||||
#if !defined(XXH_IMPLEMENTATION)
|
||||
# define XXH_IMPLEMENTATION
|
||||
# define XXH_STATIC_LINKING_ONLY
|
||||
# include "third_party/xxHash/xxhash.h"
|
||||
#endif
|
||||
|
||||
internal U64
|
||||
u64_hash_from_seed_str8(U64 seed, String8 string)
|
||||
{
|
||||
U64 result = XXH3_64bits_withSeed(string.str, string.size, seed);
|
||||
return result;
|
||||
}
|
||||
|
||||
internal U64
|
||||
u64_hash_from_str8(String8 string)
|
||||
{
|
||||
U64 result = u64_hash_from_seed_str8(5381, string);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -433,4 +433,10 @@ internal U64 str8_deserial_read_block(String8 string, U64 off, U64 size, Stri
|
||||
#define str8_deserial_read_array(string, off, ptr, count) str8_deserial_read((string), (off), (ptr), sizeof(*(ptr))*(count), sizeof(*(ptr)))
|
||||
#define str8_deserial_read_struct(string, off, ptr) str8_deserial_read_array(string, off, ptr, 1)
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Basic String Hashes
|
||||
|
||||
internal U64 u64_hash_from_seed_str8(U64 seed, String8 string);
|
||||
internal U64 u64_hash_from_str8(String8 string);
|
||||
|
||||
#endif // BASE_STRINGS_H
|
||||
|
||||
@@ -811,6 +811,7 @@ rb_entry_point(CmdLine *cmdline)
|
||||
String8List dump = {0};
|
||||
for(RB_FileNode *n = input_files.first; n != 0; n = n->next)
|
||||
{
|
||||
RB_File *f = n->v;
|
||||
// TODO(rjf)
|
||||
}
|
||||
|
||||
|
||||
+27
-11
@@ -499,20 +499,36 @@ entry_point(CmdLine *cmd_line)
|
||||
|
||||
//- rjf: setup initial target from command line args
|
||||
{
|
||||
String8List args = cmd_line->inputs;
|
||||
if(args.node_count > 0 && args.first->string.size != 0)
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
String8List target_args = {0};
|
||||
{
|
||||
B32 after_first_non_flag = 0;
|
||||
for(U64 idx = 1; idx < cmd_line->argc; idx += 1)
|
||||
{
|
||||
String8 arg = str8_cstring(cmd_line->argv[idx]);
|
||||
if(!str8_match(str8_prefix(arg, 1), str8_lit("-"), 0) &&
|
||||
!str8_match(str8_prefix(arg, 1), str8_lit("--"), 0) &&
|
||||
!str8_match(str8_prefix(arg, 1), str8_lit("/"), 0))
|
||||
{
|
||||
after_first_non_flag = 1;
|
||||
}
|
||||
if(after_first_non_flag)
|
||||
{
|
||||
str8_list_push(scratch.arena, &target_args, arg);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(target_args.node_count > 0 && target_args.first->string.size != 0)
|
||||
{
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
|
||||
//- rjf: unpack command line inputs
|
||||
String8 executable_name_string = {0};
|
||||
String8 arguments_string = {0};
|
||||
String8 working_directory_string = {0};
|
||||
{
|
||||
// rjf: unpack full executable path
|
||||
if(args.first->string.size != 0)
|
||||
if(target_args.first->string.size != 0)
|
||||
{
|
||||
String8 exe_name = args.first->string;
|
||||
String8 exe_name = target_args.first->string;
|
||||
PathStyle style = path_style_from_str8(exe_name);
|
||||
if(style == PathStyle_Relative)
|
||||
{
|
||||
@@ -524,9 +540,9 @@ entry_point(CmdLine *cmd_line)
|
||||
}
|
||||
|
||||
// rjf: unpack working directory
|
||||
if(args.first->string.size != 0)
|
||||
if(target_args.first->string.size != 0)
|
||||
{
|
||||
String8 path_part_of_arg = str8_chop_last_slash(args.first->string);
|
||||
String8 path_part_of_arg = str8_chop_last_slash(target_args.first->string);
|
||||
if(path_part_of_arg.size != 0)
|
||||
{
|
||||
String8 path = push_str8f(scratch.arena, "%S/", path_part_of_arg);
|
||||
@@ -536,7 +552,7 @@ entry_point(CmdLine *cmd_line)
|
||||
|
||||
// rjf: unpack arguments
|
||||
String8List passthrough_args_list = {0};
|
||||
for(String8Node *n = args.first->next; n != 0; n = n->next)
|
||||
for(String8Node *n = target_args.first->next; n != 0; n = n->next)
|
||||
{
|
||||
str8_list_push(scratch.arena, &passthrough_args_list, n->string);
|
||||
}
|
||||
@@ -553,9 +569,9 @@ entry_point(CmdLine *cmd_line)
|
||||
rd_cfg_new(exe, executable_name_string);
|
||||
rd_cfg_new(args, arguments_string);
|
||||
rd_cfg_new(wdir, working_directory_string);
|
||||
|
||||
scratch_end(scratch);
|
||||
rd_cmd(RD_CmdKind_SelectTarget, .cfg = target->id);
|
||||
}
|
||||
scratch_end(scratch);
|
||||
}
|
||||
|
||||
//- rjf: set up shared resources for ipc to this instance; launch IPC signaler thread
|
||||
|
||||
+1
-8
@@ -15,13 +15,6 @@ thread_static UI_State *ui_state = 0;
|
||||
# include "third_party/xxHash/xxhash.h"
|
||||
#endif
|
||||
|
||||
internal U64
|
||||
ui_hash_from_string(U64 seed, String8 string)
|
||||
{
|
||||
U64 result = XXH3_64bits_withSeed(string.str, string.size, seed);
|
||||
return result;
|
||||
}
|
||||
|
||||
internal String8
|
||||
ui_hash_part_from_key_string(String8 string)
|
||||
{
|
||||
@@ -68,7 +61,7 @@ ui_key_from_string(UI_Key seed_key, String8 string)
|
||||
if(string.size != 0)
|
||||
{
|
||||
String8 hash_part = ui_hash_part_from_key_string(string);
|
||||
result.u64[0] = ui_hash_from_string(seed_key.u64[0], hash_part);
|
||||
result.u64[0] = u64_hash_from_seed_str8(seed_key.u64[0], hash_part);
|
||||
}
|
||||
ProfEnd();
|
||||
return result;
|
||||
|
||||
@@ -752,7 +752,6 @@ struct UI_State
|
||||
////////////////////////////////
|
||||
//~ rjf: Basic Type Functions
|
||||
|
||||
internal U64 ui_hash_from_string(U64 seed, String8 string);
|
||||
internal String8 ui_hash_part_from_key_string(String8 string);
|
||||
internal String8 ui_display_part_from_key_string(String8 string);
|
||||
internal UI_Key ui_key_zero(void);
|
||||
|
||||
Reference in New Issue
Block a user