power_play/src/base/base_cmdline.c

99 lines
2.6 KiB
C

////////////////////////////////////////////////////////////
//~ Bootstrap
void BootstrapCmdline(void)
{
TempArena scratch = BeginScratchNoConflict();
{
StringList raw = GetRawCommandline();
u64 tmp_args_count = 0;
u64 tmp_positionals_count = 0;
CommandlineArg *tmp_args = PushStructs(scratch.arena, CommandlineArg, raw.count);
String *tmp_positionals = PushStructs(scratch.arena, String, raw.count);
{
String name = Zi;
for (StringListNode *n = raw.first; n; n = n->next)
{
String s = n->s;
if (StringBeginsWith(s, Lit("--")))
{
if (name.len > 0)
{
CommandlineArg *arg = &tmp_args[tmp_args_count++];
arg->name = name;
arg->exists = 1;
}
name = TrimLeft(s, Lit("--"));
}
else
{
if (name.len > 0)
{
CommandlineArg *arg = &tmp_args[tmp_args_count++];
arg->name = name;
arg->value = s;
arg->exists = 1;
name = Zstr;
}
else
{
tmp_positionals[tmp_positionals_count++] = s;
}
}
}
if (name.len > 0)
{
CommandlineArg *arg = &tmp_args[tmp_args_count++];
arg->name = name;
arg->exists = 1;
}
}
Arena *perm = PermArena();
Base.cmdline.positional_args_count = tmp_positionals_count;
Base.cmdline.positional_args = PushStructsNoZero(perm, String, tmp_positionals_count);
CopyStructs(Base.cmdline.positional_args, tmp_positionals, tmp_positionals_count);
for (u64 i = 0; i < tmp_args_count; ++i)
{
CommandlineArg arg = tmp_args[i];
CommandlineArgNode *n = PushStruct(perm, CommandlineArgNode);
u64 hash = HashString(arg.name);
u64 bin_idx = hash % countof(Base.cmdline.arg_bins);
n->arg = arg;
n->hash = hash;
n->next = Base.cmdline.arg_bins[bin_idx];
Base.cmdline.arg_bins[bin_idx] = n;
}
}
EndScratch(scratch);
}
////////////////////////////////////////////////////////////
//~ Command line
String StringFromCommandlineIdx(i32 idx)
{
String result = Zi;
if (idx < Base.cmdline.positional_args_count)
{
result = Base.cmdline.positional_args[idx];
}
return result;
}
CommandlineArg CommandlineArgFromName(String name)
{
CommandlineArg result = Zi;
u64 hash = HashString(name);
for (CommandlineArgNode *n = Base.cmdline.arg_bins[hash % countof(Base.cmdline.arg_bins)]; n; n = n->next)
{
if (n->hash == hash && MatchString(n->arg.name, name))
{
result = n->arg;
break;
}
}
return result;
}