Move cmd to c
This commit is contained in:
@@ -1,38 +1,49 @@
|
|||||||
|
|
||||||
CmdParser MakeCmdParser(MA_Arena *arena, int argc, char **argv) {
|
CmdParser MakeCmdParser(MA_Arena *arena, int argc, char **argv) {
|
||||||
CmdParser result = {argc, argv};
|
CmdParser result = {argc, argv, arena};
|
||||||
result.decls = {arena};
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddBool(CmdParser *p, bool *value, const char *name, const char *help) {
|
void AddBool(CmdParser *p, bool *result, const char *name, const char *help) {
|
||||||
p->decls.add({CmdDeclKind_Bool, S8_MakeFromChar((char *)name), S8_MakeFromChar((char *)help), value});
|
CmdDecl *decl = MA_PushStruct(p->arena, CmdDecl);
|
||||||
|
decl->kind = CmdDeclKind_Bool;
|
||||||
|
decl->name = S8_MakeFromChar((char *)name);
|
||||||
|
decl->help = S8_MakeFromChar((char *)help);
|
||||||
|
decl->bool_result = result;
|
||||||
|
SLL_QUEUE_ADD(p->fdecl, p->ldecl, decl);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddList(CmdParser *p, Array<S8_String> *list, const char *name, const char *help) {
|
void AddList(CmdParser *p, S8_List *result, const char *name, const char *help) {
|
||||||
p->decls.add({CmdDeclKind_List, S8_MakeFromChar((char *)name), S8_MakeFromChar((char *)help), 0, list});
|
CmdDecl *decl = MA_PushStruct(p->arena, CmdDecl);
|
||||||
|
decl->kind = CmdDeclKind_List;
|
||||||
|
decl->name = S8_MakeFromChar((char *)name);
|
||||||
|
decl->help = S8_MakeFromChar((char *)help);
|
||||||
|
decl->list_result = result;
|
||||||
|
SLL_QUEUE_ADD(p->fdecl, p->ldecl, decl);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddEnum(CmdParser *p, int *result, const char *name, const char *help, const char **enum_options, int enum_option_count) {
|
void AddEnum(CmdParser *p, int *result, const char *name, const char *help, const char **enum_options, int enum_option_count) {
|
||||||
CmdDecl *decl = p->decls.alloc();
|
CmdDecl *decl = MA_PushStruct(p->arena, CmdDecl);
|
||||||
decl->kind = CmdDeclKind_Enum;
|
decl->kind = CmdDeclKind_Enum;
|
||||||
decl->name = S8_MakeFromChar((char *)name);
|
decl->name = S8_MakeFromChar((char *)name);
|
||||||
decl->help = S8_MakeFromChar((char *)help);
|
decl->help = S8_MakeFromChar((char *)help);
|
||||||
decl->enum_result = result;
|
decl->enum_result = result;
|
||||||
decl->enum_options = enum_options;
|
decl->enum_options = enum_options;
|
||||||
decl->enum_option_count = enum_option_count;;
|
decl->enum_option_count = enum_option_count;
|
||||||
|
SLL_QUEUE_ADD(p->fdecl, p->ldecl, decl);
|
||||||
}
|
}
|
||||||
|
|
||||||
CmdDecl *FindDecl(CmdParser *p, S8_String name) {
|
CmdDecl *FindDecl(CmdParser *p, S8_String name) {
|
||||||
For (p->decls) {
|
for (CmdDecl *it = p->fdecl; it; it = it->next) {
|
||||||
if (it.name == name) {
|
if (S8_AreEqual(it->name, name, true)) {
|
||||||
return ⁢
|
return it;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
S8_String StrEnumValues(MA_Arena *arena, CmdDecl *decl) {
|
S8_String StrEnumValues(MA_Arena *arena, CmdDecl *decl) {
|
||||||
S8_List list = {};
|
S8_List list = {0};
|
||||||
S8_AddF(arena, &list, "[");
|
S8_AddF(arena, &list, "[");
|
||||||
for (int i = 0; i < decl->enum_option_count; i += 1) {
|
for (int i = 0; i < decl->enum_option_count; i += 1) {
|
||||||
S8_AddF(arena, &list, "%s", decl->enum_options[i]);
|
S8_AddF(arena, &list, "%s", decl->enum_options[i]);
|
||||||
@@ -43,20 +54,18 @@ S8_String StrEnumValues(MA_Arena *arena, CmdDecl *decl) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void PrintCmdUsage(CmdParser *p) {
|
void PrintCmdUsage(CmdParser *p) {
|
||||||
MA_Scratch scratch;
|
|
||||||
|
|
||||||
IO_Printf("\nhere are the supported commands:\n");
|
IO_Printf("\nhere are the supported commands:\n");
|
||||||
For(p->decls) {
|
for (CmdDecl *it = p->fdecl; it; it = it->next) {
|
||||||
if (it.kind == CmdDeclKind_List) {
|
if (it->kind == CmdDeclKind_List) {
|
||||||
S8_String example = S8_Format(scratch, "-%.*s a b c", S8_Expand(it.name));
|
S8_String example = S8_Format(p->arena, "-%.*s a b c", S8_Expand(it->name));
|
||||||
IO_Printf("%-30.*s %.*s\n", S8_Expand(example), S8_Expand(it.help));
|
IO_Printf("%-30.*s %.*s\n", S8_Expand(example), S8_Expand(it->help));
|
||||||
} else if (it.kind == CmdDeclKind_Bool) {
|
} else if (it->kind == CmdDeclKind_Bool) {
|
||||||
S8_String example = S8_Format(scratch, "-%.*s", S8_Expand(it.name));
|
S8_String example = S8_Format(p->arena, "-%.*s", S8_Expand(it->name));
|
||||||
IO_Printf("%-30.*s %.*s\n", S8_Expand(example), S8_Expand(it.help));
|
IO_Printf("%-30.*s %.*s\n", S8_Expand(example), S8_Expand(it->help));
|
||||||
} else if (it.kind == CmdDeclKind_Enum) {
|
} else if (it->kind == CmdDeclKind_Enum) {
|
||||||
S8_String enum_vals = StrEnumValues(scratch, &it);
|
S8_String enum_vals = StrEnumValues(p->arena, it);
|
||||||
S8_String example = S8_Format(scratch, "-%.*s %.*s", S8_Expand(it.name), S8_Expand(enum_vals));
|
S8_String example = S8_Format(p->arena, "-%.*s %.*s", S8_Expand(it->name), S8_Expand(enum_vals));
|
||||||
IO_Printf("%-30.*s %.*s\n", S8_Expand(example), S8_Expand(it.help));
|
IO_Printf("%-30.*s %.*s\n", S8_Expand(example), S8_Expand(it->help));
|
||||||
} else IO_Todo();
|
} else IO_Todo();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -67,11 +76,11 @@ bool InvalidCmdArg(CmdParser *p, S8_String arg) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ParseCmd(CmdParser *p) {
|
bool ParseCmd(MA_Arena *arg_arena, CmdParser *p) {
|
||||||
for (int i = 1; i < p->argc; i += 1) {
|
for (int i = 1; i < p->argc; i += 1) {
|
||||||
S8_String arg = S8_MakeFromChar(p->argv[i]);
|
S8_String arg = S8_MakeFromChar(p->argv[i]);
|
||||||
|
|
||||||
if (arg == "--help" || arg == "-h" || arg == "-help") {
|
if (S8_AreEqual(arg, S8_Lit("--help"), true) || S8_AreEqual(arg, S8_Lit("-h"), true) || S8_AreEqual(arg, S8_Lit("-help"), true)) {
|
||||||
PrintCmdUsage(p);
|
PrintCmdUsage(p);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -94,7 +103,7 @@ bool ParseCmd(CmdParser *p) {
|
|||||||
bool found_option = false;
|
bool found_option = false;
|
||||||
for (int i = 0; i < decl->enum_option_count; i += 1) {
|
for (int i = 0; i < decl->enum_option_count; i += 1) {
|
||||||
S8_String option = S8_MakeFromChar((char *)decl->enum_options[i]);
|
S8_String option = S8_MakeFromChar((char *)decl->enum_options[i]);
|
||||||
if (option == option_from_cmd) {
|
if (S8_AreEqual(option, option_from_cmd, true)) {
|
||||||
*decl->enum_result = i;
|
*decl->enum_result = i;
|
||||||
found_option = true;
|
found_option = true;
|
||||||
break;
|
break;
|
||||||
@@ -102,8 +111,7 @@ bool ParseCmd(CmdParser *p) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!found_option) {
|
if (!found_option) {
|
||||||
MA_Scratch scratch;
|
IO_Printf("expected one of the enum values: %.*s", S8_Expand(StrEnumValues(p->arena, decl)));
|
||||||
IO_Printf("expected one of the enum values: %.*s", S8_Expand(StrEnumValues(scratch, decl)));
|
|
||||||
IO_Printf(" got instead: %.*s\n", S8_Expand(option_from_cmd));
|
IO_Printf(" got instead: %.*s\n", S8_Expand(option_from_cmd));
|
||||||
PrintCmdUsage(p);
|
PrintCmdUsage(p);
|
||||||
return false;
|
return false;
|
||||||
@@ -121,7 +129,7 @@ bool ParseCmd(CmdParser *p) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
decl->list_result->add(arg);
|
S8_AddNode(arg_arena, decl->list_result, arg);
|
||||||
}
|
}
|
||||||
} else IO_Todo();
|
} else IO_Todo();
|
||||||
|
|
||||||
@@ -149,25 +157,24 @@ void TestCmdParser() {
|
|||||||
};
|
};
|
||||||
int argc = MA_Lengthof(argv);
|
int argc = MA_Lengthof(argv);
|
||||||
|
|
||||||
MA_Scratch scratch;
|
MA_Checkpoint scratch = MA_GetScratch();
|
||||||
bool build_scratch = false;
|
bool build_scratch = false;
|
||||||
Array<S8_String> test_list = {scratch};
|
S8_List test_list = {0};
|
||||||
Array<S8_String> test_things = {scratch};
|
S8_List test_things = {0};
|
||||||
int build_profile = 0;
|
int build_profile = 0;
|
||||||
const char *build_profiles[] = {"debug", "release"};
|
const char *build_profiles[] = {"debug", "release"};
|
||||||
int build_profiles_count = MA_Lengthof(build_profiles);
|
int build_profiles_count = MA_Lengthof(build_profiles);
|
||||||
|
|
||||||
CmdParser p = MakeCmdParser(scratch, argc, argv);
|
CmdParser p = MakeCmdParser(scratch.arena, argc, argv);
|
||||||
AddBool(&p, &build_scratch, "build_scratch", "builds a sandbox where I experiment with things");
|
AddBool(&p, &build_scratch, "build_scratch", "builds a sandbox where I experiment with things");
|
||||||
AddList(&p, &test_list, "tests", "list of specific tests to run");
|
AddList(&p, &test_list, "tests", "list of specific tests to run");
|
||||||
AddList(&p, &test_things, "things", "list of things");
|
AddList(&p, &test_things, "things", "list of things");
|
||||||
AddEnum(&p, &build_profile, "build", "choose build profile", build_profiles, build_profiles_count);
|
AddEnum(&p, &build_profile, "build", "choose build profile", build_profiles, build_profiles_count);
|
||||||
bool success = ParseCmd(&p);
|
bool success = ParseCmd(scratch.arena, &p);
|
||||||
IO_Assertf(success, "failed to parse cmd");
|
IO_Assertf(success, "failed to parse cmd");
|
||||||
IO_Assert(build_scratch);
|
IO_Assert(build_scratch);
|
||||||
IO_Assert(test_list.len == 3);
|
IO_Assert(test_list.node_count == 3);
|
||||||
IO_Assert(test_list[2] == "c");
|
IO_Assert(test_things.node_count == 2);
|
||||||
IO_Assert(test_list[0] == "a");
|
|
||||||
IO_Assert(test_things.len == 2);
|
|
||||||
IO_Assert(build_profile == 1);
|
IO_Assert(build_profile == 1);
|
||||||
|
MA_ReleaseScratch(scratch);
|
||||||
}
|
}
|
||||||
16
core/cmd.h
16
core/cmd.h
@@ -1,25 +1,31 @@
|
|||||||
enum CmdDeclKind {
|
|
||||||
|
typedef enum {
|
||||||
CmdDeclKind_Bool,
|
CmdDeclKind_Bool,
|
||||||
CmdDeclKind_List,
|
CmdDeclKind_List,
|
||||||
CmdDeclKind_Enum,
|
CmdDeclKind_Enum,
|
||||||
};
|
} CmdDeclKind;
|
||||||
|
|
||||||
|
typedef struct CmdDecl CmdDecl;
|
||||||
struct CmdDecl {
|
struct CmdDecl {
|
||||||
|
CmdDecl *next;
|
||||||
CmdDeclKind kind;
|
CmdDeclKind kind;
|
||||||
S8_String name;
|
S8_String name;
|
||||||
S8_String help;
|
S8_String help;
|
||||||
|
|
||||||
bool *bool_result;
|
bool *bool_result;
|
||||||
Array<S8_String> *list_result;
|
S8_List *list_result;
|
||||||
|
|
||||||
int *enum_result;
|
int *enum_result;
|
||||||
const char **enum_options;
|
const char **enum_options;
|
||||||
int enum_option_count;
|
int enum_option_count;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef struct CmdParser CmdParser;
|
||||||
struct CmdParser {
|
struct CmdParser {
|
||||||
int argc;
|
int argc;
|
||||||
char **argv;
|
char **argv;
|
||||||
Array<CmdDecl> decls;
|
MA_Arena *arena;
|
||||||
|
|
||||||
|
CmdDecl *fdecl;
|
||||||
|
CmdDecl *ldecl;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -19,9 +19,7 @@
|
|||||||
#include "../standalone_libraries/load_library.c"
|
#include "../standalone_libraries/load_library.c"
|
||||||
#include "filesystem.c"
|
#include "filesystem.c"
|
||||||
|
|
||||||
#if LANG_CPP
|
#include "cmd.c"
|
||||||
#include "cmd.cpp"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
- I think it's okay to say that strings being null terminated should be mostly treated as NOT terminated but leave some
|
- I think it's okay to say that strings being null terminated should be mostly treated as NOT terminated but leave some
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
#include "../standalone_libraries/multimedia.h"
|
#include "../standalone_libraries/multimedia.h"
|
||||||
#include "../standalone_libraries/load_library.h"
|
#include "../standalone_libraries/load_library.h"
|
||||||
#include "filesystem.h"
|
#include "filesystem.h"
|
||||||
|
#include "cmd.h"
|
||||||
|
|
||||||
#if LANG_CPP
|
#if LANG_CPP
|
||||||
#include "../standalone_libraries/defer.hpp"
|
#include "../standalone_libraries/defer.hpp"
|
||||||
@@ -30,7 +31,6 @@
|
|||||||
#define ARRAY_SET_DEFAULT_ALLOCATOR \
|
#define ARRAY_SET_DEFAULT_ALLOCATOR \
|
||||||
if (!allocator.p) allocator = M_GetSystemAllocator();
|
if (!allocator.p) allocator = M_GetSystemAllocator();
|
||||||
#include "../standalone_libraries/array.hpp"
|
#include "../standalone_libraries/array.hpp"
|
||||||
#include "cmd.h"
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
Reference in New Issue
Block a user