diff --git a/src/common/commandoption.c b/src/common/commandoption.c index 4d5df49e3..21ecf9582 100644 --- a/src/common/commandoption.c +++ b/src/common/commandoption.c @@ -9,62 +9,6 @@ #include #include -static inline yyjson_mut_val* genJsonConfig(FFModuleBaseInfo* baseInfo) -{ - yyjson_mut_doc* doc = instance.state.migrateConfigDoc; - if (__builtin_expect(!doc, true)) return NULL; - - yyjson_mut_val* modules = yyjson_mut_obj_get(doc->root, "modules"); - if (!modules) - modules = yyjson_mut_obj_add_arr(doc, doc->root, "modules"); - - yyjson_mut_val* module = yyjson_mut_obj(doc); - FF_STRBUF_AUTO_DESTROY type = ffStrbufCreateS(baseInfo->name); - ffStrbufLowerCase(&type); - yyjson_mut_obj_add_strbuf(doc, module, "type", &type); - - if (baseInfo->generateJsonConfig) - baseInfo->generateJsonConfig(baseInfo, doc, module); - - if (yyjson_mut_obj_size(module) > 1) - yyjson_mut_arr_add_val(modules, module); - else - yyjson_mut_arr_add_strbuf(doc, modules, &type); - - return module; -} - -static inline yyjson_mut_val* genJsonResult(FFModuleBaseInfo* baseInfo) -{ - yyjson_mut_doc* doc = instance.state.resultDoc; - if (__builtin_expect(!doc, true)) return NULL; - - yyjson_mut_val* module = yyjson_mut_arr_add_obj(doc, doc->root); - yyjson_mut_obj_add_str(doc, module, "type", baseInfo->name); - if (baseInfo->generateJsonResult) - baseInfo->generateJsonResult(baseInfo, doc, module); - else - yyjson_mut_obj_add_str(doc, module, "error", "Unsupported for JSON format"); - return module; -} - -bool ffParseModuleCommand(const char* type) -{ - if(!isalpha(type[0])) return false; - - for (FFModuleBaseInfo** modules = ffModuleInfos[toupper(type[0]) - 'A']; *modules; ++modules) - { - FFModuleBaseInfo* baseInfo = *modules; - if (ffStrEqualsIgnCase(type, baseInfo->name)) - { - if (!genJsonConfig(baseInfo) && !genJsonResult(baseInfo)) - baseInfo->printModule(baseInfo); - return true; - } - } - return false; -} - bool ffParseModuleOptions(const char* key, const char* value) { if (!ffStrStartsWith(key, "--") || !isalpha(key[2])) return false; @@ -103,7 +47,42 @@ void ffPrepareCommandOption(FFdata* data) } } -static void parseStructureCommand(const char* line, FFlist* customValues) +static void genJsonConfig(FFModuleBaseInfo* baseInfo, yyjson_mut_doc* doc) +{ + yyjson_mut_val* modules = yyjson_mut_obj_get(doc->root, "modules"); + if (!modules) + modules = yyjson_mut_obj_add_arr(doc, doc->root, "modules"); + + yyjson_mut_val* module = yyjson_mut_obj(doc); + FF_STRBUF_AUTO_DESTROY type = ffStrbufCreateS(baseInfo->name); + ffStrbufLowerCase(&type); + yyjson_mut_obj_add_strbuf(doc, module, "type", &type); + + if (baseInfo->generateJsonConfig) + baseInfo->generateJsonConfig(baseInfo, doc, module); + + if (yyjson_mut_obj_size(module) > 1) + yyjson_mut_arr_add_val(modules, module); + else + yyjson_mut_arr_add_strbuf(doc, modules, &type); +} + +static void genJsonResult(FFModuleBaseInfo* baseInfo, yyjson_mut_doc* doc) +{ + yyjson_mut_val* module = yyjson_mut_arr_add_obj(doc, doc->root); + yyjson_mut_obj_add_str(doc, module, "type", baseInfo->name); + if (baseInfo->generateJsonResult) + baseInfo->generateJsonResult(baseInfo, doc, module); + else + yyjson_mut_obj_add_str(doc, module, "error", "Unsupported for JSON format"); +} + +static void parseStructureCommand( + const char* line, + FFlist* customValues, + void (*fn)(FFModuleBaseInfo *baseInfo, yyjson_mut_doc* jsonDoc), + yyjson_mut_doc* jsonDoc +) { // handle `--set` and `--set-keyless` FF_LIST_FOR_EACH(FFCustomValue, customValue, *customValues) @@ -115,19 +94,35 @@ static void parseStructureCommand(const char* line, FFlist* customValues) if (customValue->printKey) ffStrbufAppend(&options.moduleArgs.key, &customValue->key); ffStrbufAppend(&options.moduleArgs.outputFormat, &customValue->value); - if (!genJsonConfig((FFModuleBaseInfo*) &options)) ffPrintCustom(&options); + if (__builtin_expect(jsonDoc != NULL, false)) + fn((FFModuleBaseInfo*) &options, jsonDoc); + else + ffPrintCustom(&options); return; } } - if(!ffParseModuleCommand(line)) - ffPrintErrorString(line, 0, NULL, FF_PRINT_TYPE_NO_CUSTOM_KEY, ""); + if(isalpha(line[0])) + { + for (FFModuleBaseInfo** modules = ffModuleInfos[toupper(line[0]) - 'A']; *modules; ++modules) + { + FFModuleBaseInfo* baseInfo = *modules; + if (ffStrEqualsIgnCase(line, baseInfo->name)) + { + if (__builtin_expect(jsonDoc != NULL, false)) + fn(baseInfo, jsonDoc); + else + baseInfo->printModule(baseInfo); + return; + } + } + } + + ffPrintErrorString(line, 0, NULL, FF_PRINT_TYPE_NO_CUSTOM_KEY, ""); } -void ffPrintCommandOption(FFdata* data) +void ffPrintCommandOption(FFdata* data, yyjson_mut_doc* jsonDoc) { - yyjson_mut_doc* resultDoc = instance.state.resultDoc; - //Parse the structure and call the modules uint32_t startIndex = 0; while (startIndex < data->structure.length) @@ -139,16 +134,16 @@ void ffPrintCommandOption(FFdata* data) if(instance.config.display.stat) ms = ffTimeGetTick(); - parseStructureCommand(data->structure.chars + startIndex, &data->customValues); + parseStructureCommand(data->structure.chars + startIndex, &data->customValues, genJsonResult, jsonDoc); if(instance.config.display.stat) { ms = ffTimeGetTick() - ms; - if (resultDoc) + if (jsonDoc) { - yyjson_mut_val* moduleJson = yyjson_mut_arr_get_last(resultDoc->root); - yyjson_mut_obj_add_uint(resultDoc, moduleJson, "stat", ms); + yyjson_mut_val* moduleJson = yyjson_mut_arr_get_last(jsonDoc->root); + yyjson_mut_obj_add_uint(jsonDoc, moduleJson, "stat", ms); } else { @@ -162,19 +157,28 @@ void ffPrintCommandOption(FFdata* data) } #if defined(_WIN32) - if (!resultDoc && !instance.config.display.noBuffer) fflush(stdout); + if (!jsonDoc && !instance.config.display.noBuffer) fflush(stdout); #endif startIndex = colonIndex + 1; } } -void ffMigrateCommandOptionToJsonc(FFdata* data) +void ffMigrateCommandOptionToJsonc(FFdata* data, yyjson_mut_doc* jsonDoc) { //If we don't have a custom structure, use the default one if(data->structure.length == 0) ffStrbufAppendS(&data->structure, FASTFETCH_DATATEXT_STRUCTURE); - instance.config.display.stat = false; - ffPrintCommandOption(data); - yyjson_mut_write_fp(stdout, instance.state.migrateConfigDoc, YYJSON_WRITE_INF_AND_NAN_AS_NULL | YYJSON_WRITE_PRETTY_TWO_SPACES, NULL, NULL); + + //Parse the structure and call the modules + uint32_t startIndex = 0; + while (startIndex < data->structure.length) + { + uint32_t colonIndex = ffStrbufNextIndexC(&data->structure, startIndex, ':'); + data->structure.chars[colonIndex] = '\0'; + + parseStructureCommand(data->structure.chars + startIndex, &data->customValues, genJsonConfig, jsonDoc); + + startIndex = colonIndex + 1; + } } diff --git a/src/common/commandoption.h b/src/common/commandoption.h index 1c9ed9721..c20d0f81f 100644 --- a/src/common/commandoption.h +++ b/src/common/commandoption.h @@ -20,10 +20,9 @@ typedef struct FFdata bool loadUserConfig; } FFdata; -bool ffParseModuleCommand(const char* type); bool ffParseModuleOptions(const char* key, const char* value); void ffPrepareCommandOption(FFdata* data); -void ffPrintCommandOption(FFdata* data); -void ffMigrateCommandOptionToJsonc(FFdata* data); +void ffPrintCommandOption(FFdata* data, yyjson_mut_doc* jsonDoc); +void ffMigrateCommandOptionToJsonc(FFdata* data, yyjson_mut_doc* jsonDoc); #endif diff --git a/src/common/jsonconfig.c b/src/common/jsonconfig.c index 1b32ed8b4..f0d20da25 100644 --- a/src/common/jsonconfig.c +++ b/src/common/jsonconfig.c @@ -82,21 +82,17 @@ const char* ffJsonConfigParseEnum(yyjson_val* val, int* result, FFKeyValuePair p return "Invalid enum value type; must be a string or integer"; } -static inline yyjson_mut_val* genJsonResult(FFModuleBaseInfo* baseInfo) +static inline void genJsonResult(FFModuleBaseInfo* baseInfo, yyjson_mut_doc* doc) { - yyjson_mut_doc* doc = instance.state.resultDoc; - if (__builtin_expect(!doc, true)) return NULL; - yyjson_mut_val* module = yyjson_mut_arr_add_obj(doc, doc->root); yyjson_mut_obj_add_str(doc, module, "type", baseInfo->name); if (baseInfo->generateJsonResult) baseInfo->generateJsonResult(baseInfo, doc, module); else yyjson_mut_obj_add_str(doc, module, "error", "Unsupported for JSON format"); - return module; } -static bool parseModuleJsonObject(const char* type, yyjson_val* jsonVal) +static bool parseModuleJsonObject(const char* type, yyjson_val* jsonVal, yyjson_mut_doc* jsonDoc) { if(!isalpha(type[0])) return false; @@ -106,7 +102,9 @@ static bool parseModuleJsonObject(const char* type, yyjson_val* jsonVal) if (ffStrEqualsIgnCase(type, baseInfo->name)) { if (jsonVal) baseInfo->parseJsonObject(baseInfo, jsonVal); - if (!genJsonResult(baseInfo)) + if (__builtin_expect(jsonDoc != NULL, false)) + genJsonResult(baseInfo, jsonDoc); + else baseInfo->printModule(baseInfo); return true; } @@ -159,7 +157,7 @@ static void prepareModuleJsonObject(const char* type, yyjson_val* module) } } -static const char* printJsonConfig(bool prepare) +static const char* printJsonConfig(bool prepare, yyjson_mut_doc* jsonDoc) { yyjson_val* const root = yyjson_doc_get_root(instance.state.configDoc); assert(root); @@ -171,8 +169,6 @@ static const char* printJsonConfig(bool prepare) if (!modules) return NULL; if (!yyjson_is_arr(modules)) return "Property 'modules' must be an array of strings or objects"; - yyjson_mut_doc* resultDoc = instance.state.resultDoc; - yyjson_val* item; size_t idx, max; yyjson_arr_foreach(modules, idx, max, item) @@ -197,16 +193,16 @@ static const char* printJsonConfig(bool prepare) if(prepare) prepareModuleJsonObject(type, module); - else if(!parseModuleJsonObject(type, module)) + else if(!parseModuleJsonObject(type, module, jsonDoc)) return "Unknown module type"; if(!prepare && instance.config.display.stat) { ms = ffTimeGetTick() - ms; - if (resultDoc) + if (jsonDoc) { - yyjson_mut_val* moduleJson = yyjson_mut_arr_get_last(resultDoc->root); - yyjson_mut_obj_add_uint(resultDoc, moduleJson, "stat", ms); + yyjson_mut_val* moduleJson = yyjson_mut_arr_get_last(jsonDoc->root); + yyjson_mut_obj_add_uint(jsonDoc, moduleJson, "stat", ms); } else { @@ -220,16 +216,25 @@ static const char* printJsonConfig(bool prepare) } #if defined(_WIN32) - if (!instance.config.display.noBuffer && !resultDoc) fflush(stdout); + if (!instance.config.display.noBuffer && !jsonDoc) fflush(stdout); #endif } return NULL; } -void ffPrintJsonConfig(bool prepare) +void ffPrintJsonConfig(bool prepare, yyjson_mut_doc* jsonDoc) { - const char* error = printJsonConfig(prepare); + const char* error = printJsonConfig(prepare, jsonDoc); if (error) - ffPrintErrorString("JsonConfig", 0, NULL, FF_PRINT_TYPE_NO_CUSTOM_KEY, "%s", error); + { + if (jsonDoc) + { + yyjson_mut_val* obj = yyjson_mut_obj(jsonDoc); + yyjson_mut_obj_add_str(jsonDoc, obj, "error", error); + yyjson_mut_doc_set_root(jsonDoc, obj); + } + else + ffPrintErrorString("JsonConfig", 0, NULL, FF_PRINT_TYPE_NO_CUSTOM_KEY, "%s", error); + } } diff --git a/src/common/jsonconfig.h b/src/common/jsonconfig.h index 08f522c5c..917beadf2 100644 --- a/src/common/jsonconfig.h +++ b/src/common/jsonconfig.h @@ -4,7 +4,7 @@ bool ffJsonConfigParseModuleArgs(const char* key, yyjson_val* val, FFModuleArgs* moduleArgs); const char* ffJsonConfigParseEnum(yyjson_val* val, int* result, FFKeyValuePair pairs[]); -void ffPrintJsonConfig(bool prepare); +void ffPrintJsonConfig(bool prepare, yyjson_mut_doc* jsonDoc); void ffJsonConfigGenerateModuleArgsConfig(yyjson_mut_doc* doc, yyjson_mut_val* module, FFModuleArgs* defaultModuleArgs, FFModuleArgs* moduleArgs); yyjson_api_inline bool yyjson_mut_obj_add_strbuf(yyjson_mut_doc *doc, diff --git a/src/fastfetch.c b/src/fastfetch.c index bf617e4e7..ef7ad5590 100644 --- a/src/fastfetch.c +++ b/src/fastfetch.c @@ -628,7 +628,7 @@ static void run(FFdata* data) const bool useJsonConfig = data->structure.length == 0 && instance.state.configDoc; if (useJsonConfig) - ffPrintJsonConfig(true /* prepare */); + ffPrintJsonConfig(true /* prepare */, instance.state.resultDoc); else ffPrepareCommandOption(data); @@ -639,9 +639,9 @@ static void run(FFdata* data) #endif if (useJsonConfig) - ffPrintJsonConfig(false); + ffPrintJsonConfig(false, instance.state.resultDoc); else - ffPrintCommandOption(data); + ffPrintCommandOption(data, instance.state.resultDoc); if (instance.state.resultDoc) yyjson_mut_write_fp(stdout, instance.state.resultDoc, YYJSON_WRITE_INF_AND_NAN_AS_NULL | YYJSON_WRITE_PRETTY_TWO_SPACES, NULL, NULL); @@ -655,7 +655,8 @@ static void migrateConfig(FFdata* data) ffOptionsGenerateDisplayJsonConfig(&instance.config.display, instance.state.migrateConfigDoc); ffOptionsGenerateGeneralJsonConfig(&instance.config.general, instance.state.migrateConfigDoc); ffOptionsGenerateLibraryJsonConfig(&instance.config.library, instance.state.migrateConfigDoc); - ffMigrateCommandOptionToJsonc(data); + ffMigrateCommandOptionToJsonc(data, instance.state.migrateConfigDoc); + yyjson_mut_write_fp(stdout, instance.state.migrateConfigDoc, YYJSON_WRITE_INF_AND_NAN_AS_NULL | YYJSON_WRITE_PRETTY_TWO_SPACES, NULL, NULL); } int main(int argc, const char** argv)