diff --git a/CMakeLists.txt b/CMakeLists.txt index 1e1d251ba..b20f57467 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -331,6 +331,7 @@ set(LIBFASTFETCH_SRC src/modules/chassis/chassis.c src/modules/colors/colors.c src/modules/cpu/cpu.c + src/modules/cpucache/cpucache.c src/modules/cpuusage/cpuusage.c src/modules/cursor/cursor.c src/modules/custom/custom.c @@ -411,6 +412,7 @@ if(LINUX) src/detection/brightness/brightness_linux.c src/detection/chassis/chassis_linux.c src/detection/cpu/cpu_linux.c + src/detection/cpucache/cpucache_linux.c src/detection/cpuusage/cpuusage_linux.c src/detection/cursor/cursor_linux.c src/detection/bluetooth/bluetooth_linux.c @@ -481,6 +483,7 @@ elseif(ANDROID) src/detection/brightness/brightness_nosupport.c src/detection/chassis/chassis_nosupport.c src/detection/cpu/cpu_linux.c + src/detection/cpucache/cpucache_linux.c src/detection/cursor/cursor_nosupport.c src/detection/cpuusage/cpuusage_linux.c src/detection/disk/disk_linux.c @@ -541,6 +544,7 @@ elseif(BSD) src/detection/brightness/brightness_bsd.c src/detection/chassis/chassis_bsd.c src/detection/cpu/cpu_bsd.c + src/detection/cpucache/cpucache_bsd.c src/detection/cpuusage/cpuusage_bsd.c src/detection/cursor/cursor_linux.c src/detection/disk/disk_bsd.c @@ -611,6 +615,7 @@ elseif(APPLE) src/detection/brightness/brightness_apple.c src/detection/chassis/chassis_nosupport.c src/detection/cpu/cpu_apple.c + src/detection/cpucache/cpucache_apple.c src/detection/cpuusage/cpuusage_apple.c src/detection/cursor/cursor_apple.m src/detection/disk/disk_bsd.c @@ -672,6 +677,7 @@ elseif(WIN32) src/detection/brightness/brightness_windows.cpp src/detection/chassis/chassis_windows.c src/detection/cpu/cpu_windows.c + src/detection/cpucache/cpucache_windows.c src/detection/cpuusage/cpuusage_windows.c src/detection/cursor/cursor_windows.c src/detection/disk/disk_windows.c diff --git a/src/common/modules.c b/src/common/modules.c index 9205cc0b5..9580ccb06 100644 --- a/src/common/modules.c +++ b/src/common/modules.c @@ -21,6 +21,7 @@ static FFModuleBaseInfo* C[] = { (void*) &instance.config.modules.command, (void*) &instance.config.modules.colors, (void*) &instance.config.modules.cpu, + (void*) &instance.config.modules.cpuCache, (void*) &instance.config.modules.cpuUsage, (void*) &instance.config.modules.cursor, (void*) &instance.config.modules.custom, diff --git a/src/detection/cpu/cpu.h b/src/detection/cpu/cpu.h index 7c8c4facd..fc9b7e080 100644 --- a/src/detection/cpu/cpu.h +++ b/src/detection/cpu/cpu.h @@ -10,21 +10,6 @@ typedef struct FFCPUCore uint32_t count; } FFCPUCore; -typedef enum FFCPUCacheType -{ - FF_CPU_CACHE_TYPE_UNIFIED = 0, - FF_CPU_CACHE_TYPE_INSTRUCTION = 1, - FF_CPU_CACHE_TYPE_DATA = 2, - FF_CPU_CACHE_TYPE_TRACE = 3, -} FFCPUCacheType; - -typedef struct FFCPUCache -{ - uint32_t size; - uint32_t num; - FFCPUCacheType type; -} FFCPUCache; - typedef struct FFCPUResult { FFstrbuf name; @@ -40,7 +25,6 @@ typedef struct FFCPUResult double frequencyBiosLimit; // GHz FFCPUCore coreTypes[16]; // number of P cores, E cores, etc. - FFlist caches[3]; // L1, L2, L3 double temperature; } FFCPUResult; diff --git a/src/detection/cpu/cpu_windows.c b/src/detection/cpu/cpu_windows.c index c0a82252e..1e6ca5ff6 100644 --- a/src/detection/cpu/cpu_windows.c +++ b/src/detection/cpu/cpu_windows.c @@ -136,42 +136,6 @@ static const char* detectNCores(FFCPUResult* cpu) cpu->coresLogical += ptr->Group.GroupInfo[index].MaximumProcessorCount; } } - else if(ptr->Relationship == RelationCache) - { - if (__builtin_expect(ptr->Cache.Level <= 3, true)) - { - FFCPUCacheType cacheType = 0; - switch (ptr->Cache.Type) - { - case CacheUnified: cacheType = FF_CPU_CACHE_TYPE_UNIFIED; break; - case CacheInstruction: cacheType = FF_CPU_CACHE_TYPE_INSTRUCTION; break; - case CacheData: cacheType = FF_CPU_CACHE_TYPE_DATA; break; - case CacheTrace: cacheType = FF_CPU_CACHE_TYPE_TRACE; break; - default: __builtin_unreachable(); break; - } - - FFlist* cacheLevel = &cpu->caches[ptr->Cache.Level - 1]; - FFCPUCache* found = NULL; - FF_LIST_FOR_EACH(FFCPUCache, item, *cacheLevel) - { - if (item->type == cacheType && item->size == ptr->Cache.CacheSize) - { - found = item; - break; - } - } - if (found) - found->num++; - else - { - *(FFCPUCache*) ffListAdd(cacheLevel) = (FFCPUCache) { - .size = ptr->Cache.CacheSize, - .num = 1, - .type = cacheType, - }; - } - } - } } return NULL; diff --git a/src/detection/cpucache/cpucache.h b/src/detection/cpucache/cpucache.h new file mode 100644 index 000000000..567c6e21f --- /dev/null +++ b/src/detection/cpucache/cpucache.h @@ -0,0 +1,44 @@ +#pragma once + +#include "fastfetch.h" + +typedef enum FFCPUCacheType +{ + FF_CPU_CACHE_TYPE_UNIFIED = 0, + FF_CPU_CACHE_TYPE_INSTRUCTION = 1, + FF_CPU_CACHE_TYPE_DATA = 2, + FF_CPU_CACHE_TYPE_TRACE = 3, +} FFCPUCacheType; + +typedef struct FFCPUCache +{ + uint32_t size; + uint32_t num; + FFCPUCacheType type; +} FFCPUCache; + +typedef struct FFCPUCacheResult +{ + FFlist caches[4]; // L1, L2, L3, L4(?) +} FFCPUCacheResult; + +const char* ffDetectCPUCache(FFCPUCacheResult* result); + +static inline void ffCPUCacheAddItem(FFCPUCacheResult* result, uint32_t level, uint32_t size, FFCPUCacheType type) +{ + FFlist* cacheLevel = &result->caches[level - 1]; + + FF_LIST_FOR_EACH(FFCPUCache, item, *cacheLevel) + { + if (item->type == type && item->size == size) + { + item->num++; + return; + } + } + *(FFCPUCache*) ffListAdd(cacheLevel) = (FFCPUCache) { + .size = size, + .num = 1, + .type = type, + }; +} diff --git a/src/detection/cpucache/cpucache_linux.c b/src/detection/cpucache/cpucache_linux.c new file mode 100644 index 000000000..e7869bb98 --- /dev/null +++ b/src/detection/cpucache/cpucache_linux.c @@ -0,0 +1,98 @@ +#include "cpucache.h" +#include "common/io/io.h" +#include "util/stringUtils.h" + +static const char* parseCpuCacheIndex(FFstrbuf* path, FFCPUCacheResult* result, FFstrbuf* buffer, FFstrbuf* added) +{ + uint32_t baseLen = path->length; + ffStrbufAppendS(path, "/level"); + if (!ffReadFileBuffer(path->chars, buffer)) + return "ffReadFileBuffer(\"/sys/devices/system/cpu/cpuX/cache/indexX/level\") == NULL"; + + uint32_t level = (uint32_t) ffStrbufToUInt(buffer, 0); + if (level < 1 || level > 4) return "level < 1 || level > 4"; + + ffStrbufSubstrBefore(path, baseLen); + ffStrbufAppendS(path, "/size"); + if (!ffReadFileBuffer(path->chars, buffer)) + return "ffReadFileBuffer(\"/sys/devices/system/cpu/cpuX/cache/indexX/size\") == NULL"; + + uint32_t sizeKb = (uint32_t) ffStrbufToUInt(buffer, 0); + if (sizeKb == 0) return "size == 0"; + + ffStrbufSubstrBefore(path, baseLen); + ffStrbufAppendS(path, "/type"); + if (!ffReadFileBuffer(path->chars, buffer)) + return "ffReadFileBuffer(\"/sys/devices/system/cpu/cpuX/cache/indexX/type\") == NULL"; + ffStrbufTrimRightSpace(buffer); + + FFCPUCacheType cacheType = 0; + switch (buffer->chars[0]) + { + case 'I': cacheType = FF_CPU_CACHE_TYPE_INSTRUCTION; break; + case 'D': cacheType = FF_CPU_CACHE_TYPE_DATA; break; + case 'U': cacheType = FF_CPU_CACHE_TYPE_UNIFIED; break; + case 'T': cacheType = FF_CPU_CACHE_TYPE_TRACE; break; + default: return "unknown cache type"; + } + + ffStrbufSubstrBefore(path, baseLen); + ffStrbufAppendS(path, "/shared_cpu_list"); + if (!ffReadFileBuffer(path->chars, buffer)) + return "ffReadFileBuffer(\"/sys/devices/system/cpu/cpuX/cache/indexX/shared_cpu_list\") == NULL"; + ffStrbufTrimRightSpace(buffer); + + // deduplicate shared caches + ffStrbufAppendF(buffer, "_%u_%u_%u\n", level, sizeKb, cacheType); + if (ffStrbufContain(added, buffer)) return "cache already added"; + ffStrbufAppend(added, buffer); + ffCPUCacheAddItem(result, level, sizeKb * 1024, cacheType); + return NULL; +} + +static const char* parseCpuCache(FFstrbuf* path, FFCPUCacheResult* result, FFstrbuf* buffer, FFstrbuf* added) +{ + ffStrbufAppendS(path, "/cache/"); + uint32_t baseLen = path->length; + FF_AUTO_CLOSE_DIR DIR* pathCacheDir = opendir(path->chars); + if (!pathCacheDir) + return "opendir(\"/sys/devices/system/cpu/cpuX/cache/\") == NULL"; + + struct dirent* pathCacheEntry; + while ((pathCacheEntry = readdir(pathCacheDir)) != NULL) + { + if (!ffStrStartsWith(pathCacheEntry->d_name, "index") + || !ffCharIsDigit(pathCacheEntry->d_name[strlen("index")])) continue; + + ffStrbufAppendS(path, pathCacheEntry->d_name); + parseCpuCacheIndex(path, result, buffer, added); + ffStrbufSubstrBefore(path, baseLen); + } + + return NULL; +} + +const char* ffDetectCPUCache(FFCPUCacheResult* result) +{ + // https://www.kernel.org/doc/Documentation/ABI/testing/sysfs-devices-system-cpu + FF_STRBUF_AUTO_DESTROY path = ffStrbufCreateS("/sys/devices/system/cpu/"); + uint32_t baseLen = path.length; + FF_AUTO_CLOSE_DIR DIR* pathCpuDir = opendir(path.chars); + if (!pathCpuDir) + return "opendir(\"/sys/devices/system/cpu/\") == NULL"; + + FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate(); + FF_STRBUF_AUTO_DESTROY added = ffStrbufCreate(); + + struct dirent* pathCpuEntry; + while ((pathCpuEntry = readdir(pathCpuDir)) != NULL) + { + if (!ffStrStartsWith(pathCpuEntry->d_name, "cpu") || + !ffCharIsDigit(pathCpuEntry->d_name[strlen("cpu")])) continue; + + ffStrbufAppendS(&path, pathCpuEntry->d_name); + parseCpuCache(&path, result, &buffer, &added); + ffStrbufSubstrBefore(&path, baseLen); + } + return NULL; +} diff --git a/src/detection/cpucache/cpucache_windows.c b/src/detection/cpucache/cpucache_windows.c new file mode 100644 index 000000000..6fac3bcc9 --- /dev/null +++ b/src/detection/cpucache/cpucache_windows.c @@ -0,0 +1,42 @@ +#include "cpucache.h" +#include "util/mallocHelper.h" + +#include + +const char* ffDetectCPUCache(FFCPUCacheResult* result) +{ + DWORD length = 0; + GetLogicalProcessorInformationEx(RelationCache, NULL, &length); + if (length == 0) + return "GetLogicalProcessorInformationEx(RelationCache, NULL, &length) failed"; + + SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX* FF_AUTO_FREE + pProcessorInfo = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX*)malloc(length); + + if (!pProcessorInfo || !GetLogicalProcessorInformationEx(RelationCache, pProcessorInfo, &length)) + return "GetLogicalProcessorInformationEx(RelationCache, pProcessorInfo, &length) failed"; + + for( + SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX* ptr = pProcessorInfo; + (uint8_t*)ptr < ((uint8_t*)pProcessorInfo) + length; + ptr = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX*)(((uint8_t*)ptr) + ptr->Size) + ) + { + if(__builtin_expect(ptr->Relationship == RelationCache && ptr->Cache.Level > 0 && ptr->Cache.Level <= 4, true)) + { + FFCPUCacheType cacheType = 0; + switch (ptr->Cache.Type) + { + case CacheUnified: cacheType = FF_CPU_CACHE_TYPE_UNIFIED; break; + case CacheInstruction: cacheType = FF_CPU_CACHE_TYPE_INSTRUCTION; break; + case CacheData: cacheType = FF_CPU_CACHE_TYPE_DATA; break; + case CacheTrace: cacheType = FF_CPU_CACHE_TYPE_TRACE; break; + default: __builtin_unreachable(); break; + } + + ffCPUCacheAddItem(result, ptr->Cache.Level, ptr->Cache.CacheSize, cacheType); + } + } + + return NULL; +} diff --git a/src/modules/cpu/cpu.c b/src/modules/cpu/cpu.c index 39e96ce15..044284a63 100644 --- a/src/modules/cpu/cpu.c +++ b/src/modules/cpu/cpu.c @@ -23,11 +23,6 @@ void ffPrintCPU(FFCPUOptions* options) .frequencyBiosLimit = 0.0/0.0, .name = ffStrbufCreate(), .vendor = ffStrbufCreate(), - .caches = { - ffListCreate(sizeof (FFCPUCache)), - ffListCreate(sizeof (FFCPUCache)), - ffListCreate(sizeof (FFCPUCache)), - }, }; const char* error = ffDetectCPU(options, &cpu); @@ -128,9 +123,6 @@ void ffPrintCPU(FFCPUOptions* options) ffStrbufDestroy(&cpu.name); ffStrbufDestroy(&cpu.vendor); - ffListDestroy(&cpu.caches[0]); - ffListDestroy(&cpu.caches[1]); - ffListDestroy(&cpu.caches[2]); } bool ffParseCPUCommandOptions(FFCPUOptions* options, const char* key, const char* value) @@ -216,11 +208,6 @@ void ffGenerateCPUJsonResult(FFCPUOptions* options, yyjson_mut_doc* doc, yyjson_ .frequencyBiosLimit = 0.0/0.0, .name = ffStrbufCreate(), .vendor = ffStrbufCreate(), - .caches = { - ffListCreate(sizeof (FFCPUCache)), - ffListCreate(sizeof (FFCPUCache)), - ffListCreate(sizeof (FFCPUCache)), - }, }; const char* error = ffDetectCPU(options, &cpu); @@ -250,27 +237,6 @@ void ffGenerateCPUJsonResult(FFCPUOptions* options, yyjson_mut_doc* doc, yyjson_ yyjson_mut_obj_add_real(doc, frequency, "min", cpu.frequencyMin); yyjson_mut_obj_add_real(doc, frequency, "biosLimit", cpu.frequencyBiosLimit); - yyjson_mut_val* caches = yyjson_mut_obj_add_obj(doc, obj, "cache"); - for (uint32_t i = 0; i < sizeof (cpu.caches) / sizeof (cpu.caches[0]) && cpu.caches[i].length > 0; i++) - { - yyjson_mut_val* level = yyjson_mut_obj_add_arr(doc, caches, i == 0 ? "L1" : (i == 1 ? "L2" : "L3")); - FF_LIST_FOR_EACH(FFCPUCache, src, cpu.caches[i]) - { - yyjson_mut_val* item = yyjson_mut_arr_add_obj(doc, level); - yyjson_mut_obj_add_uint(doc, item, "size", src->size); - yyjson_mut_obj_add_uint(doc, item, "num", src->num); - const char* typeStr = "unknown"; - switch (src->type) - { - case FF_CPU_CACHE_TYPE_DATA: typeStr = "data"; break; - case FF_CPU_CACHE_TYPE_INSTRUCTION: typeStr = "instruction"; break; - case FF_CPU_CACHE_TYPE_UNIFIED: typeStr = "unified"; break; - case FF_CPU_CACHE_TYPE_TRACE: typeStr = "trace"; break; - } - yyjson_mut_obj_add_str(doc, item, "type", typeStr); - } - } - yyjson_mut_val* coreTypes = yyjson_mut_obj_add_arr(doc, obj, "coreTypes"); for (uint32_t i = 0; i < sizeof (cpu.coreTypes) / sizeof (cpu.coreTypes[0]) && cpu.coreTypes[i].count > 0; i++) { @@ -284,9 +250,6 @@ void ffGenerateCPUJsonResult(FFCPUOptions* options, yyjson_mut_doc* doc, yyjson_ ffStrbufDestroy(&cpu.name); ffStrbufDestroy(&cpu.vendor); - ffListDestroy(&cpu.caches[0]); - ffListDestroy(&cpu.caches[1]); - ffListDestroy(&cpu.caches[2]); } void ffPrintCPUHelpFormat(void) diff --git a/src/modules/cpucache/cpucache.c b/src/modules/cpucache/cpucache.c new file mode 100644 index 000000000..b16ed1a8a --- /dev/null +++ b/src/modules/cpucache/cpucache.c @@ -0,0 +1,165 @@ +#include "common/printing.h" +#include "common/jsonconfig.h" +#include "detection/cpucache/cpucache.h" +#include "modules/cpucache/cpucache.h" +#include "util/stringUtils.h" + +#define FF_CPUCACHE_NUM_FORMAT_ARGS 4 + +void ffPrintCPUCache(FFCPUCacheOptions* options) +{ + FFCPUCacheResult result = { + .caches = { + ffListCreate(sizeof(FFCPUCache)), + ffListCreate(sizeof(FFCPUCache)), + ffListCreate(sizeof(FFCPUCache)), + ffListCreate(sizeof(FFCPUCache)), + }, + }; + + const char* error = ffDetectCPUCache(&result); + + if(error) + { + ffPrintError(FF_CPUCACHE_MODULE_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, "%s", error); + goto exit; + } + + if(options->moduleArgs.outputFormat.length == 0) + { + ffPrintLogoAndKey(FF_CPUCACHE_MODULE_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT); + // ffStrbufWriteTo(&result.type, stdout); + // if (result.version.length) + // printf(" (%s)", result.version.chars); + putchar('\n'); + } + else + { + // FF_PRINT_FORMAT_CHECKED(FF_CPUCACHE_MODULE_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, FF_CPUCACHE_NUM_FORMAT_ARGS, ((FFformatarg[]) { + // {FF_FORMAT_ARG_TYPE_STRBUF, &result.type, "type"}, + // {FF_FORMAT_ARG_TYPE_STRBUF, &result.vendor, "vendor"}, + // {FF_FORMAT_ARG_TYPE_STRBUF, &result.version, "version"}, + // {FF_FORMAT_ARG_TYPE_STRBUF, &result.serial, "serial"}, + // })); + } + +exit: + ffListDestroy(&result.caches[0]); + ffListDestroy(&result.caches[1]); + ffListDestroy(&result.caches[2]); + ffListDestroy(&result.caches[3]); +} + +bool ffParseCPUCacheCommandOptions(FFCPUCacheOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_CPUCACHE_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + return false; +} + +void ffParseCPUCacheJsonObject(FFCPUCacheOptions* options, yyjson_val* module) +{ + yyjson_val *key_, *val; + size_t idx, max; + yyjson_obj_foreach(module, idx, max, key_, val) + { + const char* key = yyjson_get_str(key_); + if(ffStrEqualsIgnCase(key, "type")) + continue; + + if (ffJsonConfigParseModuleArgs(key, val, &options->moduleArgs)) + continue; + + ffPrintError(FF_CPUCACHE_MODULE_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, "Unknown JSON key %s", key); + } +} + +void ffGenerateCPUCacheJsonConfig(FFCPUCacheOptions* options, yyjson_mut_doc* doc, yyjson_mut_val* module) +{ + __attribute__((__cleanup__(ffDestroyCPUCacheOptions))) FFCPUCacheOptions defaultOptions; + ffInitCPUCacheOptions(&defaultOptions); + + ffJsonConfigGenerateModuleArgsConfig(doc, module, &defaultOptions.moduleArgs, &options->moduleArgs); +} + +void ffGenerateCPUCacheJsonResult(FF_MAYBE_UNUSED FFCPUCacheOptions* options, yyjson_mut_doc* doc, yyjson_mut_val* module) +{ + FFCPUCacheResult result = { + .caches = { + ffListCreate(sizeof(FFCPUCache)), + ffListCreate(sizeof(FFCPUCache)), + ffListCreate(sizeof(FFCPUCache)), + ffListCreate(sizeof(FFCPUCache)), + }, + }; + + const char* error = ffDetectCPUCache(&result); + + if (error) + { + yyjson_mut_obj_add_str(doc, module, "error", error); + goto exit; + } + + yyjson_mut_val* caches = yyjson_mut_obj_add_obj(doc, module, "result"); + + for (uint32_t i = 0; i < sizeof (result.caches) / sizeof (result.caches[0]) && result.caches[i].length > 0; i++) + { + yyjson_mut_val* level = yyjson_mut_obj_add_arr(doc, caches, i == 0 ? "L1" : (i == 1 ? "L2" : "L3")); + FF_LIST_FOR_EACH(FFCPUCache, src, result.caches[i]) + { + yyjson_mut_val* item = yyjson_mut_arr_add_obj(doc, level); + yyjson_mut_obj_add_uint(doc, item, "size", src->size); + yyjson_mut_obj_add_uint(doc, item, "num", src->num); + const char* typeStr = "unknown"; + switch (src->type) + { + case FF_CPU_CACHE_TYPE_DATA: typeStr = "data"; break; + case FF_CPU_CACHE_TYPE_INSTRUCTION: typeStr = "instruction"; break; + case FF_CPU_CACHE_TYPE_UNIFIED: typeStr = "unified"; break; + case FF_CPU_CACHE_TYPE_TRACE: typeStr = "trace"; break; + } + yyjson_mut_obj_add_str(doc, item, "type", typeStr); + } + } + +exit: + ffListDestroy(&result.caches[0]); + ffListDestroy(&result.caches[1]); + ffListDestroy(&result.caches[2]); + ffListDestroy(&result.caches[3]); +} + +void ffPrintCPUCacheHelpFormat(void) +{ + FF_PRINT_MODULE_FORMAT_HELP_CHECKED(FF_CPUCACHE_MODULE_NAME, "{1}", FF_CPUCACHE_NUM_FORMAT_ARGS, ((const char* []) { + "cpucache type - type", + "cpucache vendor - vendor", + "cpucache version - version", + "cpucache serial number - serial", + })); +} + +void ffInitCPUCacheOptions(FFCPUCacheOptions* options) +{ + ffOptionInitModuleBaseInfo( + &options->moduleInfo, + FF_CPUCACHE_MODULE_NAME, + "Print CPU cache sizes", + ffParseCPUCacheCommandOptions, + ffParseCPUCacheJsonObject, + ffPrintCPUCache, + ffGenerateCPUCacheJsonResult, + ffPrintCPUCacheHelpFormat, + ffGenerateCPUCacheJsonConfig + ); + ffOptionInitModuleArg(&options->moduleArgs); +} + +void ffDestroyCPUCacheOptions(FFCPUCacheOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); +} diff --git a/src/modules/cpucache/cpucache.h b/src/modules/cpucache/cpucache.h new file mode 100644 index 000000000..c6d5d8ef6 --- /dev/null +++ b/src/modules/cpucache/cpucache.h @@ -0,0 +1,9 @@ +#pragma once + +#include "fastfetch.h" + +#define FF_CPUCACHE_MODULE_NAME "CPUCache" + +void ffPrintCPUCache(FFCPUCacheOptions* options); +void ffInitCPUCacheOptions(FFCPUCacheOptions* options); +void ffDestroyCPUCacheOptions(FFCPUCacheOptions* options); diff --git a/src/modules/cpucache/option.h b/src/modules/cpucache/option.h new file mode 100644 index 000000000..02895c463 --- /dev/null +++ b/src/modules/cpucache/option.h @@ -0,0 +1,11 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef struct FFCPUCacheOptions +{ + FFModuleBaseInfo moduleInfo; + FFModuleArgs moduleArgs; +} FFCPUCacheOptions; diff --git a/src/modules/modules.h b/src/modules/modules.h index aebd0ac6f..0e4587691 100644 --- a/src/modules/modules.h +++ b/src/modules/modules.h @@ -12,6 +12,7 @@ #include "modules/camera/camera.h" #include "modules/chassis/chassis.h" #include "modules/cpu/cpu.h" +#include "modules/cpucache/cpucache.h" #include "modules/cpuusage/cpuusage.h" #include "modules/command/command.h" #include "modules/colors/colors.h" diff --git a/src/modules/options.h b/src/modules/options.h index f3df14ee2..7c0ff7129 100644 --- a/src/modules/options.h +++ b/src/modules/options.h @@ -12,6 +12,7 @@ #include "modules/camera/option.h" #include "modules/chassis/option.h" #include "modules/cpu/option.h" +#include "modules/cpucache/option.h" #include "modules/cpuusage/option.h" #include "modules/colors/option.h" #include "modules/cursor/option.h" diff --git a/src/options/modules.c b/src/options/modules.c index 728bccf4d..095449a8e 100644 --- a/src/options/modules.c +++ b/src/options/modules.c @@ -13,6 +13,7 @@ void ffOptionsInitModules(FFOptionsModules* options) ffInitCameraOptions(&options->camera); ffInitCPUOptions(&options->cpu); ffInitCPUUsageOptions(&options->cpuUsage); + ffInitCPUCacheOptions(&options->cpuCache); ffInitChassisOptions(&options->chassis); ffInitColorsOptions(&options->colors); ffInitCommandOptions(&options->command); @@ -81,6 +82,7 @@ void ffOptionsDestroyModules(FFOptionsModules* options) ffDestroyBrightnessOptions(&options->brightness); ffDestroyCameraOptions(&options->camera); ffDestroyCPUOptions(&options->cpu); + ffDestroyCPUCacheOptions(&options->cpuCache); ffDestroyCPUUsageOptions(&options->cpuUsage); ffDestroyChassisOptions(&options->chassis); ffDestroyColorsOptions(&options->colors); diff --git a/src/options/modules.h b/src/options/modules.h index 79e25ce2e..c8f46b892 100644 --- a/src/options/modules.h +++ b/src/options/modules.h @@ -12,6 +12,7 @@ typedef struct FFOptionsModules FFBreakOptions break_; FFBrightnessOptions brightness; FFCPUOptions cpu; + FFCPUCacheOptions cpuCache; FFCPUUsageOptions cpuUsage; FFCameraOptions camera; FFChassisOptions chassis;