Skip to content

Commit 7895bf0

Browse files
committed
Modules: refactor module option handling for static allocation
Moves module option structs out of global config and removes dynamic allocation, using static buffers and size assertions for safer, simpler management. Refactors module initialization and destruction to work with isolated option structs, eliminating the need for the previous modules container and related code. Unifies module option header usage and updates detection logic to leverage statically-sized option buffers, improving encapsulation and maintainability. Simplifies module function signatures and reduces coupling between modules and config. Enhances future extensibility and reliability by enforcing max size constraints and removing unnecessary indirections.
1 parent 5590828 commit 7895bf0

289 files changed

Lines changed: 1448 additions & 1671 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CMakeLists.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -474,7 +474,6 @@ set(LIBFASTFETCH_SRC
474474
src/modules/wmtheme/wmtheme.c
475475
src/modules/zpool/zpool.c
476476
src/options/display.c
477-
src/options/modules.c
478477
src/options/logo.c
479478
src/options/general.c
480479
src/util/edidHelper.c

presets/neofetch.jsonc

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,12 @@
33
"display": {
44
"size": {
55
"maxPrefix": "MB",
6-
"ndigits": 0
6+
"ndigits": 0,
7+
"spaceBeforeUnit": "never"
8+
},
9+
"freq": {
10+
"ndigits": 3,
11+
"spaceBeforeUnit": "never"
712
}
813
},
914
"modules": [
@@ -39,11 +44,12 @@
3944
"cpu",
4045
{
4146
"type": "gpu",
42-
"key": "GPU"
47+
"key": "GPU",
48+
"format": "{name}"
4349
},
4450
{
4551
"type": "memory",
46-
"format": "{} / {}"
52+
"format": "{used} / {total}"
4753
},
4854
"break",
4955
"colors"

src/common/commandoption.c

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212

1313
void ffPrepareCommandOption(FFdata* data)
1414
{
15-
FFOptionsModules* const options = &instance.config.modules;
1615
//If we don't have a custom structure, use the default one
1716
if(data->structure.length == 0)
1817
ffStrbufAppendS(&data->structure, FASTFETCH_DATATEXT_STRUCTURE); // Cannot use `ffStrbufSetStatic` here because we will modify the string
@@ -21,22 +20,38 @@ void ffPrepareCommandOption(FFdata* data)
2120
ffPrepareCPUUsage();
2221

2322
if(ffStrbufContainIgnCaseS(&data->structure, FF_DISKIO_MODULE_NAME))
24-
ffPrepareDiskIO(&options->diskIo);
23+
{
24+
__attribute__((__cleanup__(ffDestroyDiskIOOptions))) FFDiskIOOptions options;
25+
ffInitDiskIOOptions(&options);
26+
ffPrepareDiskIO(&options);
27+
}
2528

2629
if(ffStrbufContainIgnCaseS(&data->structure, FF_NETIO_MODULE_NAME))
27-
ffPrepareNetIO(&options->netIo);
30+
{
31+
__attribute__((__cleanup__(ffDestroyNetIOOptions))) FFNetIOOptions options;
32+
ffInitNetIOOptions(&options);
33+
ffPrepareNetIO(&options);
34+
}
2835

2936
if(instance.config.general.multithreading)
3037
{
3138
if(ffStrbufContainIgnCaseS(&data->structure, FF_PUBLICIP_MODULE_NAME))
32-
ffPreparePublicIp(&options->publicIP);
39+
{
40+
__attribute__((__cleanup__(ffDestroyPublicIpOptions))) FFPublicIPOptions options;
41+
ffInitPublicIpOptions(&options);
42+
ffPreparePublicIp(&options);
43+
}
3344

3445
if(ffStrbufContainIgnCaseS(&data->structure, FF_WEATHER_MODULE_NAME))
35-
ffPrepareWeather(&options->weather);
46+
{
47+
__attribute__((__cleanup__(ffDestroyWeatherOptions))) FFWeatherOptions options;
48+
ffInitWeatherOptions(&options);
49+
ffPrepareWeather(&options);
50+
}
3651
}
3752
}
3853

39-
static void genJsonConfig(FFModuleBaseInfo* baseInfo, yyjson_mut_doc* doc)
54+
static void genJsonConfig(FFModuleBaseInfo* baseInfo, void* options, yyjson_mut_doc* doc)
4055
{
4156
yyjson_mut_val* modules = yyjson_mut_obj_get(doc->root, "modules");
4257
if (!modules)
@@ -48,27 +63,27 @@ static void genJsonConfig(FFModuleBaseInfo* baseInfo, yyjson_mut_doc* doc)
4863
yyjson_mut_obj_add_strbuf(doc, module, "type", &type);
4964

5065
if (baseInfo->generateJsonConfig)
51-
baseInfo->generateJsonConfig(baseInfo, doc, module);
66+
baseInfo->generateJsonConfig(options, doc, module);
5267

5368
if (yyjson_mut_obj_size(module) > 1)
5469
yyjson_mut_arr_add_val(modules, module);
5570
else
5671
yyjson_mut_arr_add_strbuf(doc, modules, &type);
5772
}
5873

59-
static void genJsonResult(FFModuleBaseInfo* baseInfo, yyjson_mut_doc* doc)
74+
static void genJsonResult(FFModuleBaseInfo* baseInfo, void* options, yyjson_mut_doc* doc)
6075
{
6176
yyjson_mut_val* module = yyjson_mut_arr_add_obj(doc, doc->root);
6277
yyjson_mut_obj_add_str(doc, module, "type", baseInfo->name);
6378
if (baseInfo->generateJsonResult)
64-
baseInfo->generateJsonResult(baseInfo, doc, module);
79+
baseInfo->generateJsonResult(options, doc, module);
6580
else
6681
yyjson_mut_obj_add_str(doc, module, "error", "Unsupported for JSON format");
6782
}
6883

6984
static void parseStructureCommand(
7085
const char* line,
71-
void (*fn)(FFModuleBaseInfo *baseInfo, yyjson_mut_doc* jsonDoc),
86+
void (*fn)(FFModuleBaseInfo* baseInfo, void* options, yyjson_mut_doc* jsonDoc),
7287
yyjson_mut_doc* jsonDoc
7388
)
7489
{
@@ -79,10 +94,13 @@ static void parseStructureCommand(
7994
FFModuleBaseInfo* baseInfo = *modules;
8095
if (ffStrEqualsIgnCase(line, baseInfo->name))
8196
{
97+
uint8_t optionBuf[FF_OPTION_MAX_SIZE];
98+
baseInfo->initOptions(optionBuf);
8299
if (__builtin_expect(jsonDoc != NULL, false))
83-
fn(baseInfo, jsonDoc);
100+
fn(baseInfo, optionBuf, jsonDoc);
84101
else
85-
baseInfo->printModule(baseInfo);
102+
baseInfo->printModule(optionBuf);
103+
baseInfo->destroyOptions(optionBuf);
86104
return;
87105
}
88106
}

src/common/init.c

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -42,14 +42,13 @@ static void defaultConfig(void)
4242
{
4343
ffOptionsInitLogo(&instance.config.logo);
4444
ffOptionsInitGeneral(&instance.config.general);
45-
ffOptionsInitModules(&instance.config.modules);
4645
ffOptionsInitDisplay(&instance.config.display);
4746
}
4847

4948
void ffInitInstance(void)
5049
{
5150
#ifdef WIN32
52-
//https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/setlocale-wsetlocale?source=recommendations&view=msvc-170#utf-8-support
51+
// https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/setlocale-wsetlocale?source=recommendat>
5352
setlocale(LC_ALL, ".UTF8");
5453
#else
5554
// Never use `setlocale(LC_ALL, "")`
@@ -96,11 +95,6 @@ static void chldSignalHandler(FF_MAYBE_UNUSED int signal)
9695

9796
void ffStart(void)
9897
{
99-
#ifdef FF_START_DETECTION_THREADS
100-
if(instance.config.general.multithreading)
101-
startDetectionThreads();
102-
#endif
103-
10498
ffDisableLinewrap = instance.config.display.disableLinewrap && !instance.config.display.pipe && !instance.state.resultDoc;
10599
ffHideCursor = instance.config.display.hideCursor && !instance.config.display.pipe && !instance.state.resultDoc;
106100

@@ -150,7 +144,6 @@ static void destroyConfig(void)
150144
{
151145
ffOptionsDestroyLogo(&instance.config.logo);
152146
ffOptionsDestroyGeneral(&instance.config.general);
153-
ffOptionsDestroyModules(&instance.config.modules);
154147
ffOptionsDestroyDisplay(&instance.config.display);
155148
}
156149

src/common/jsonconfig.c

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -99,12 +99,12 @@ const char* ffJsonConfigParseEnum(yyjson_val* val, int* result, FFKeyValuePair p
9999
return "Invalid enum value type; must be a string or integer";
100100
}
101101

102-
static inline void genJsonResult(FFModuleBaseInfo* baseInfo, yyjson_mut_doc* doc)
102+
static inline void genJsonResult(FFModuleBaseInfo* baseInfo, void* options, yyjson_mut_doc* doc)
103103
{
104104
yyjson_mut_val* module = yyjson_mut_arr_add_obj(doc, doc->root);
105105
yyjson_mut_obj_add_str(doc, module, "type", baseInfo->name);
106106
if (baseInfo->generateJsonResult)
107-
baseInfo->generateJsonResult(baseInfo, doc, module);
107+
baseInfo->generateJsonResult(options, doc, module);
108108
else
109109
yyjson_mut_obj_add_str(doc, module, "error", "Unsupported for JSON format");
110110
}
@@ -118,11 +118,14 @@ static bool parseModuleJsonObject(const char* type, yyjson_val* jsonVal, yyjson_
118118
FFModuleBaseInfo* baseInfo = *modules;
119119
if (ffStrEqualsIgnCase(type, baseInfo->name))
120120
{
121-
if (jsonVal) baseInfo->parseJsonObject(baseInfo, jsonVal);
121+
uint8_t optionBuf[FF_OPTION_MAX_SIZE];
122+
baseInfo->initOptions(optionBuf);
123+
if (jsonVal) baseInfo->parseJsonObject(optionBuf, jsonVal);
122124
if (__builtin_expect(jsonDoc != NULL, false))
123-
genJsonResult(baseInfo, jsonDoc);
125+
genJsonResult(baseInfo, optionBuf, jsonDoc);
124126
else
125-
baseInfo->printModule(baseInfo);
127+
baseInfo->printModule(optionBuf);
128+
baseInfo->destroyOptions(optionBuf);
126129
return true;
127130
}
128131
}
@@ -131,7 +134,6 @@ static bool parseModuleJsonObject(const char* type, yyjson_val* jsonVal, yyjson_
131134

132135
static void prepareModuleJsonObject(const char* type, yyjson_val* module)
133136
{
134-
FFconfig* cfg = &instance.config;
135137
switch (type[0])
136138
{
137139
case 'b': case 'B': {
@@ -142,32 +144,40 @@ static void prepareModuleJsonObject(const char* type, yyjson_val* module)
142144
case 'd': case 'D': {
143145
if (ffStrEqualsIgnCase(type, FF_DISKIO_MODULE_NAME))
144146
{
145-
if (module) cfg->modules.diskIo.moduleInfo.parseJsonObject(&cfg->modules.diskIo, module);
146-
ffPrepareDiskIO(&cfg->modules.diskIo);
147+
__attribute__((__cleanup__(ffDestroyDiskIOOptions))) FFDiskIOOptions options;
148+
ffInitDiskIOOptions(&options);
149+
if (module) ffDiskIOModuleInfo.parseJsonObject(&options, module);
150+
ffPrepareDiskIO(&options);
147151
}
148152
break;
149153
}
150154
case 'n': case 'N': {
151155
if (ffStrEqualsIgnCase(type, FF_NETIO_MODULE_NAME))
152156
{
153-
if (module) cfg->modules.netIo.moduleInfo.parseJsonObject(&cfg->modules.netIo, module);
154-
ffPrepareNetIO(&cfg->modules.netIo);
157+
__attribute__((__cleanup__(ffDestroyNetIOOptions))) FFNetIOOptions options;
158+
ffInitNetIOOptions(&options);
159+
if (module) ffNetIOModuleInfo.parseJsonObject(&options, module);
160+
ffPrepareNetIO(&options);
155161
}
156162
break;
157163
}
158164
case 'p': case 'P': {
159165
if (ffStrEqualsIgnCase(type, FF_PUBLICIP_MODULE_NAME))
160166
{
161-
if (module) cfg->modules.publicIP.moduleInfo.parseJsonObject(&cfg->modules.publicIP, module);
162-
ffPreparePublicIp(&cfg->modules.publicIP);
167+
__attribute__((__cleanup__(ffDestroyPublicIpOptions))) FFPublicIPOptions options;
168+
ffInitPublicIpOptions(&options);
169+
if (module) ffPublicIPModuleInfo.parseJsonObject(&options, module);
170+
ffPreparePublicIp(&options);
163171
}
164172
break;
165173
}
166174
case 'w': case 'W': {
167175
if (ffStrEqualsIgnCase(type, FF_WEATHER_MODULE_NAME))
168176
{
169-
if (module) cfg->modules.weather.moduleInfo.parseJsonObject(&cfg->modules.weather, module);
170-
ffPrepareWeather(&cfg->modules.weather);
177+
__attribute__((__cleanup__(ffDestroyWeatherOptions))) FFWeatherOptions options;
178+
ffInitWeatherOptions(&options);
179+
if (module) ffPublicIPModuleInfo.parseJsonObject(&options, module);
180+
ffPrepareWeather(&options);
171181
}
172182
break;
173183
}

0 commit comments

Comments
 (0)