mirror of
https://github.com/fastfetch-cli/fastfetch.git
synced 2026-09-13 10:24:58 +02:00
better cpu output
This commit is contained in:
+1
-1
@@ -115,7 +115,7 @@ void ffParsePropFile(const char* fileName, const char* regex, char* buffer)
|
||||
buffer[0] = '\0'; //If an error occures, this is the indicator
|
||||
|
||||
char* line = NULL;
|
||||
size_t len;
|
||||
size_t len = 0;
|
||||
|
||||
FILE* file = fopen(fileName, "r");
|
||||
if(file == NULL)
|
||||
|
||||
+1
-1
@@ -232,7 +232,7 @@ static inline void printCommandHelp(const char* command)
|
||||
else if(strcasecmp(command, "terminal-font-format") == 0)
|
||||
constructAndPrintCommandHelpFormat("terminal-font", "{}", 1, "Terminal font name");
|
||||
else if(strcasecmp(command, "cpu-format") == 0)
|
||||
constructAndPrintCommandHelpFormat("cpu", "{} ({}) @ {}GHz", 3, "CPU name", "CPU logical core count", "CPU frequency");
|
||||
constructAndPrintCommandHelpFormat("cpu", "{2} ({4}) @ {7}GHz", 11, "CPU name", "Prettified CPU name", "CPU Vendor name (Vendor ID)", "CPU logical core count online", "CPU logical core count configured", "CPU physical core count", "frequency bios limit", "frequency scaling max", "frequency scaling min", "frequency info max", "frequency info min");
|
||||
else if(strcasecmp(command, "gpu-format") == 0)
|
||||
constructAndPrintCommandHelpFormat("gpu", "{} {}", 2, "GPU vendor", "GPU name");
|
||||
else if(strcasecmp(command, "memory-format") == 0)
|
||||
|
||||
+110
-26
@@ -1,53 +1,137 @@
|
||||
#include "fastfetch.h"
|
||||
|
||||
static double getGhz(const char* file)
|
||||
{
|
||||
FF_STRBUF_CREATE(content);
|
||||
ffGetFileContent(file, &content);
|
||||
|
||||
if(content.length == 0)
|
||||
return 0;
|
||||
|
||||
uint32_t herz;
|
||||
if(sscanf(content.chars, "%u", &herz) != 1)
|
||||
return 0;
|
||||
|
||||
ffStrbufDestroy(&content);
|
||||
|
||||
herz /= 1000; //to MHz
|
||||
return (double) herz / 1000.0; //to GHz
|
||||
}
|
||||
|
||||
void ffPrintCPU(FFinstance* instance)
|
||||
{
|
||||
if(ffPrintCachedValue(instance, "CPU"))
|
||||
return;
|
||||
|
||||
char name[256];
|
||||
ffParsePropFile("/proc/cpuinfo", "model name%*s %[^\n]", name);
|
||||
if(name[0] == '\0')
|
||||
char name[256]; name[0] = '\0';
|
||||
char vendor[256]; vendor[0] = '\0';
|
||||
int physicalCores = 0;
|
||||
|
||||
FILE* cpuinfo = fopen("/proc/cpuinfo", "r");
|
||||
|
||||
char* line = NULL;
|
||||
size_t len = 0;
|
||||
|
||||
while(getline(&line, &len, cpuinfo) != -1)
|
||||
{
|
||||
ffPrintError(instance, "CPU", "\"model name%*s %[^\\n]\" not found in \"/proc/cpuinfo\"");
|
||||
return;
|
||||
sscanf(line, "model name%*s %[^\n]", name);
|
||||
sscanf(line, "vendor_id%*s %[^\n]", vendor);
|
||||
sscanf(line, "cpu cores%*s %i", &physicalCores);
|
||||
|
||||
//Stop after the first CPU
|
||||
if(strstr(line, "flags") != NULL)
|
||||
break;
|
||||
}
|
||||
|
||||
FILE* frequencyFile = fopen("/sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq", "r");
|
||||
if(frequencyFile == NULL)
|
||||
{
|
||||
ffPrintError(instance, "CPU", "fopen(\"/sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq\", \"r\") == NULL");
|
||||
return;
|
||||
}
|
||||
uint32_t frequency;
|
||||
int scanned = fscanf(frequencyFile, "%u", &frequency);
|
||||
if(scanned != 1)
|
||||
{
|
||||
ffPrintError(instance, "CPU", "fscanf(frequencyFile, \"%s\", frequency) != 1");
|
||||
return;
|
||||
}
|
||||
fclose(frequencyFile);
|
||||
if(line != NULL)
|
||||
free(line);
|
||||
|
||||
frequency /= 1000; //to MHz
|
||||
double ghz = (double) frequency / 1000.0; //to GHz
|
||||
fclose(cpuinfo);
|
||||
|
||||
int numProcs = get_nprocs();
|
||||
FFstrbuf namePretty;
|
||||
ffStrbufInitA(&namePretty, 256);
|
||||
ffStrbufAppendS(&namePretty, name);
|
||||
ffStrbufRemoveStrings(&namePretty, 11,
|
||||
"(R)", "(r)", "(TM)", "(tm)", " CPU", " FPU", " Processor", " Dual-Core", " Quad-Core", " Six-Core", " Eight-Core"
|
||||
);
|
||||
ffStrbufLimitLength(&namePretty, ffStrbufLastIndexC(&namePretty, '@')); //Cut the speed output in the name as we append our own
|
||||
ffStrbufTrimRight(&namePretty, ' '); //If we removed the @ in previous step there was most likely a space before it
|
||||
|
||||
double biosLimit = getGhz("/sys/devices/system/cpu/cpu0/cpufreq/bios_limit");
|
||||
double scalingMaxFreq = getGhz("/sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq");
|
||||
double scalingMinFreq = getGhz("/sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq");
|
||||
double infoMaxFreq = getGhz("/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq");
|
||||
double infoMinFreq = getGhz("/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_min_freq");
|
||||
|
||||
int numProcsOnline = get_nprocs();
|
||||
int numProcsAvailable = get_nprocs_conf();
|
||||
|
||||
FF_STRBUF_CREATE(cpu);
|
||||
|
||||
if(instance->config.cpuFormat.length == 0)
|
||||
{
|
||||
ffStrbufSetF(&cpu, "%s (%i) @ %.9gGHz", name, numProcs, ghz);
|
||||
//The current get_nprocs* returns 1 on failure. It also makes no sense to have a (1) as count
|
||||
int numProcs = numProcsOnline;
|
||||
if(numProcs <= 1)
|
||||
numProcs = numProcsAvailable;
|
||||
if(numProcs <= 1)
|
||||
numProcs = physicalCores;
|
||||
|
||||
double ghz = biosLimit;
|
||||
if(ghz == 0)
|
||||
ghz = scalingMaxFreq;
|
||||
if(ghz == 0)
|
||||
ghz = infoMaxFreq;
|
||||
if(ghz == 0)
|
||||
ghz = scalingMinFreq;
|
||||
if(ghz == 0)
|
||||
ghz = infoMinFreq;
|
||||
|
||||
|
||||
if(namePretty.length > 0)
|
||||
ffStrbufAppend(&cpu, &namePretty);
|
||||
else if(name[0] != '\0')
|
||||
ffStrbufAppendS(&cpu, name);
|
||||
else if(vendor[0] != '\0')
|
||||
{
|
||||
ffStrbufAppendS(&cpu, vendor);
|
||||
ffStrbufAppendS(&cpu, " unknown processor");
|
||||
}
|
||||
else if(numProcs > 1 || ghz > 0)
|
||||
ffStrbufAppendS(&cpu, " unknwon processor");
|
||||
else
|
||||
{
|
||||
ffPrintError(instance, "CPU", "No CPU info found in /proc/cpuinfo");
|
||||
ffStrbufDestroy(&cpu);
|
||||
ffStrbufDestroy(&namePretty);
|
||||
return;
|
||||
}
|
||||
|
||||
if(numProcs > 1)
|
||||
ffStrbufAppendF(&cpu, " (%i)", numProcs);
|
||||
|
||||
if(ghz > 0)
|
||||
ffStrbufAppendF(&cpu, " @ %.9gGHz", ghz);
|
||||
}
|
||||
else
|
||||
{
|
||||
ffParseFormatString(&cpu, &instance->config.cpuFormat, 3,
|
||||
ffParseFormatString(&cpu, &instance->config.cpuFormat, 11,
|
||||
(FFformatarg){FF_FORMAT_ARG_TYPE_STRING, name},
|
||||
(FFformatarg){FF_FORMAT_ARG_TYPE_INT, &numProcs},
|
||||
(FFformatarg){FF_FORMAT_ARG_TYPE_DOUBLE, &ghz}
|
||||
(FFformatarg){FF_FORMAT_ARG_TYPE_STRBUF, &namePretty},
|
||||
(FFformatarg){FF_FORMAT_ARG_TYPE_STRING, vendor},
|
||||
(FFformatarg){FF_FORMAT_ARG_TYPE_INT, &numProcsOnline},
|
||||
(FFformatarg){FF_FORMAT_ARG_TYPE_INT, &numProcsAvailable},
|
||||
(FFformatarg){FF_FORMAT_ARG_TYPE_INT, &physicalCores},
|
||||
(FFformatarg){FF_FORMAT_ARG_TYPE_DOUBLE, &biosLimit},
|
||||
(FFformatarg){FF_FORMAT_ARG_TYPE_DOUBLE, &scalingMaxFreq},
|
||||
(FFformatarg){FF_FORMAT_ARG_TYPE_DOUBLE, &scalingMinFreq},
|
||||
(FFformatarg){FF_FORMAT_ARG_TYPE_DOUBLE, &infoMaxFreq},
|
||||
(FFformatarg){FF_FORMAT_ARG_TYPE_DOUBLE, &infoMinFreq}
|
||||
);
|
||||
}
|
||||
|
||||
ffPrintAndSaveCachedValue(instance, "CPU", &cpu);
|
||||
ffStrbufDestroy(&cpu);
|
||||
|
||||
ffStrbufDestroy(&namePretty);
|
||||
}
|
||||
|
||||
+1
-1
@@ -25,7 +25,7 @@ void ffPrintOS(FFinstance* instance)
|
||||
osRelease = fopen("/usr/lib/os-release", "r");
|
||||
|
||||
char* line = NULL;
|
||||
size_t len;
|
||||
size_t len = 0;
|
||||
|
||||
while (getline(&line, &len, osRelease) != -1)
|
||||
{
|
||||
|
||||
+58
-1
@@ -278,7 +278,7 @@ void ffStrbufTrimLeft(FFstrbuf* strbuf, char c)
|
||||
if(index == 0)
|
||||
return;
|
||||
|
||||
memcpy(strbuf->chars, strbuf->chars + index, index);
|
||||
memmove(strbuf->chars, strbuf->chars + index, index);
|
||||
strbuf->length -= index;
|
||||
}
|
||||
|
||||
@@ -296,6 +296,63 @@ void ffStrbufTrim(FFstrbuf* strbuf, char c)
|
||||
ffStrbufTrimLeft(strbuf, c);
|
||||
}
|
||||
|
||||
static bool strbufRemoveTest(FFstrbuf* strbuf, uint32_t i, const char* substr)
|
||||
{
|
||||
uint32_t k;
|
||||
for(k = 0; substr[k] != '\0'; k++)
|
||||
{
|
||||
if(i + k > strbuf->length)
|
||||
return false;
|
||||
|
||||
if(strbuf->chars[i + k] != substr[k])
|
||||
return false;
|
||||
}
|
||||
|
||||
memmove(&strbuf->chars[i], &strbuf->chars[i + k], strbuf->length - i - k);
|
||||
strbuf->length -= k;
|
||||
strbuf->chars[strbuf->length] = '\0';
|
||||
return true;
|
||||
}
|
||||
|
||||
void ffStrbufRemoveStrings(FFstrbuf* strbuf, uint32_t numStrings, ...)
|
||||
{
|
||||
const char* strings[numStrings];
|
||||
|
||||
va_list argp;
|
||||
va_start(argp, numStrings);
|
||||
|
||||
for(uint32_t i = 0; i < numStrings; i++)
|
||||
strings[i] = va_arg(argp, const char*);
|
||||
|
||||
va_end(argp);
|
||||
|
||||
for(uint32_t i = 0; i < strbuf->length; i++)
|
||||
{
|
||||
for(uint32_t k = 0; k < numStrings; k++)
|
||||
while(strbufRemoveTest(strbuf, i, strings[k]));
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t ffStrbufLastIndexC(FFstrbuf* strbuf, const char c)
|
||||
{
|
||||
//We need to loop one higher than the actual index, because uint32_t is guranteed to be >= 0, so this statement would always be true
|
||||
for(uint32_t i = strbuf->length; i > 0; i--)
|
||||
{
|
||||
if(strbuf->chars[i - 1] == c)
|
||||
return i - 1;
|
||||
}
|
||||
return strbuf->length;
|
||||
}
|
||||
|
||||
void ffStrbufLimitLength(FFstrbuf* strbuf, uint32_t length)
|
||||
{
|
||||
if(strbuf->length <= length)
|
||||
return;
|
||||
|
||||
strbuf->length = length;
|
||||
strbuf->chars[strbuf->length] = '\0';
|
||||
}
|
||||
|
||||
void ffStrbufDestroy(FFstrbuf* strbuf)
|
||||
{
|
||||
free(strbuf->chars);
|
||||
|
||||
@@ -66,6 +66,12 @@ void ffStrbufTrimLeft(FFstrbuf* strbuf, char c);
|
||||
void ffStrbufTrimRight(FFstrbuf* strbuf, char c);
|
||||
void ffStrbufTrim(FFstrbuf* strbuf, char c);
|
||||
|
||||
void ffStrbufRemoveStrings(FFstrbuf* strbuf, uint32_t numStrings, ...);
|
||||
|
||||
uint32_t ffStrbufLastIndexC(FFstrbuf* strbuf, const char c);
|
||||
|
||||
void ffStrbufLimitLength(FFstrbuf* strbuf, uint32_t length);
|
||||
|
||||
void ffStrbufDestroy(FFstrbuf* strbuf);
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user