summaryrefslogtreecommitdiffstats
path: root/src/common/option.h
diff options
context:
space:
mode:
authorsumuel <samuel@yakubos.org>2026-08-17 20:44:55 +0000
committersumuel <samuel@yakubos.org>2026-08-17 20:44:55 +0000
commit76424950e373d3b04ac3dd13019151bfba3e8423 (patch)
tree4c3cfdbda039e592b9186be3e28f8d7cfd439e8a /src/common/option.h
Add the files
Diffstat (limited to 'src/common/option.h')
-rw-r--r--src/common/option.h96
1 files changed, 96 insertions, 0 deletions
diff --git a/src/common/option.h b/src/common/option.h
new file mode 100644
index 0000000..ce0a0ab
--- /dev/null
+++ b/src/common/option.h
@@ -0,0 +1,96 @@
+#pragma once
+
+#include "common/FFstrbuf.h"
+
+struct yyjson_val;
+struct yyjson_mut_doc;
+struct yyjson_mut_val;
+
+typedef struct FFModuleFormatArg {
+ const char* desc;
+ const char* name;
+} FFModuleFormatArg;
+
+typedef struct FFModuleFormatArgList {
+ FFModuleFormatArg* args;
+ uint32_t count;
+} FFModuleFormatArgList;
+
+#define FF_FORMAT_ARG_LIST(list) { .args = list, .count = sizeof(list) / sizeof(FFModuleFormatArg) }
+
+// Must be the first field of FFModuleOptions
+typedef struct FFModuleBaseInfo {
+ const char* name;
+ const char* description;
+ // A dirty polymorphic implementation in C.
+ // This is UB, because `void*` is not compatible with `FF*Options*`.
+ // However we can't do it better unless we move to C++, so that `option` becomes a `this` pointer
+ // https://stackoverflow.com/questions/559581/casting-a-function-pointer-to-another-type
+
+ void (*initOptions)(void* options);
+ void (*destroyOptions)(void* options);
+ void (*parseJsonObject)(void* options, struct yyjson_val* module);
+ bool (*printModule)(void* options); // true on success
+ bool (*generateJsonResult)(void* options, struct yyjson_mut_doc* doc, struct yyjson_mut_val* module); // true on success
+ void (*generateJsonConfig)(void* options, struct yyjson_mut_doc* doc, struct yyjson_mut_val* obj);
+ FFModuleFormatArgList formatArgs;
+} FFModuleBaseInfo;
+
+typedef enum FF_A_PACKED FFModuleKeyType {
+ FF_MODULE_KEY_TYPE_NONE = 0,
+ FF_MODULE_KEY_TYPE_STRING = 1 << 0,
+ FF_MODULE_KEY_TYPE_ICON = 1 << 1,
+ FF_MODULE_KEY_TYPE_SPACE_SHIFT = 4,
+ FF_MODULE_KEY_TYPE_BOTH_0 = FF_MODULE_KEY_TYPE_STRING | FF_MODULE_KEY_TYPE_ICON,
+ FF_MODULE_KEY_TYPE_BOTH_1 = FF_MODULE_KEY_TYPE_BOTH_0 | (1 << FF_MODULE_KEY_TYPE_SPACE_SHIFT),
+ FF_MODULE_KEY_TYPE_BOTH = FF_MODULE_KEY_TYPE_BOTH_1, // alias
+ FF_MODULE_KEY_TYPE_BOTH_2 = FF_MODULE_KEY_TYPE_BOTH_0 | (2 << FF_MODULE_KEY_TYPE_SPACE_SHIFT),
+ FF_MODULE_KEY_TYPE_BOTH_3 = FF_MODULE_KEY_TYPE_BOTH_0 | (3 << FF_MODULE_KEY_TYPE_SPACE_SHIFT),
+ FF_MODULE_KEY_TYPE_BOTH_4 = FF_MODULE_KEY_TYPE_BOTH_0 | (4 << FF_MODULE_KEY_TYPE_SPACE_SHIFT),
+ FF_MODULE_KEY_TYPE_FORCE_UNSIGNED = UINT8_MAX,
+} FFModuleKeyType;
+
+typedef struct FFModuleArgs {
+ FFstrbuf key;
+ FFstrbuf keyColor;
+ FFstrbuf keyIcon;
+ FFstrbuf outputFormat;
+ FFstrbuf outputColor;
+ uint32_t keyWidth;
+} FFModuleArgs;
+
+typedef struct FFKeyValuePair {
+ const char* key;
+ int value;
+} FFKeyValuePair;
+
+const char* ffOptionTestPrefix(const char* argumentKey, const char* moduleName);
+void ffOptionParseString(const char* argumentKey, const char* value, FFstrbuf* buffer);
+FF_A_NODISCARD uint32_t ffOptionParseUInt32(const char* argumentKey, const char* value);
+FF_A_NODISCARD int32_t ffOptionParseInt32(const char* argumentKey, const char* value);
+FF_A_NODISCARD int ffOptionParseEnum(const char* argumentKey, const char* requestedKey, FFKeyValuePair pairs[]);
+FF_A_NODISCARD bool ffOptionParseBoolean(const char* str);
+void ffOptionParseColorNoClear(const char* value, FFstrbuf* buffer);
+static inline void ffOptionParseColor(const char* value, FFstrbuf* buffer) {
+ ffStrbufClear(buffer);
+ ffOptionParseColorNoClear(value, buffer);
+}
+
+static inline void ffOptionInitModuleArg(FFModuleArgs* args, const char* icon) {
+ ffStrbufInit(&args->key);
+ ffStrbufInit(&args->keyColor);
+ ffStrbufInitStatic(&args->keyIcon, icon);
+ ffStrbufInit(&args->outputFormat);
+ ffStrbufInit(&args->outputColor);
+ args->keyWidth = 0;
+}
+
+static inline void ffOptionDestroyModuleArg(FFModuleArgs* args) {
+ ffStrbufDestroy(&args->key);
+ ffStrbufDestroy(&args->keyColor);
+ ffStrbufDestroy(&args->keyIcon);
+ ffStrbufDestroy(&args->outputFormat);
+ ffStrbufDestroy(&args->outputColor);
+}
+
+enum { FF_OPTION_MAX_SIZE = 1 << 8 }; // Maximum size of a single option value, used for static allocation