mirror of
https://github.com/fastfetch-cli/fastfetch.git
synced 2026-11-05 22:44:18 +01:00
173 lines
4.6 KiB
C
173 lines
4.6 KiB
C
#include "fastfetch.h"
|
|
#include "common/properties.h"
|
|
#include "common/io.h"
|
|
#include "common/mallocHelper.h"
|
|
|
|
#include <stdlib.h>
|
|
#include <ctype.h>
|
|
#ifdef _WIN32
|
|
#include "common/windows/getline.h"
|
|
#endif
|
|
|
|
bool ffParsePropLinePointer(const char** line, const char* start, FFstrbuf* buffer) {
|
|
if (**line == '\0') {
|
|
return false;
|
|
}
|
|
|
|
// Skip any amount of whitespace at the begin of line
|
|
while (**line == ' ' || **line == '\t') {
|
|
++(*line);
|
|
}
|
|
|
|
while (*start != '\0') {
|
|
// Any amount of whitespace in the format string matches any amount of whitespace in the line, even none
|
|
if (*start == ' ' || *start == '\t') {
|
|
while (*start == ' ' || *start == '\t') {
|
|
++start;
|
|
}
|
|
|
|
while (**line == ' ' || **line == '\t') {
|
|
++(*line);
|
|
}
|
|
|
|
continue;
|
|
}
|
|
|
|
// Line doesn't match start, skip it
|
|
if (tolower(**line) != tolower(*start) || **line == '\0') {
|
|
return false;
|
|
}
|
|
|
|
// Line and start match, continue testing
|
|
++(*line);
|
|
++start;
|
|
}
|
|
|
|
char valueEnd = '\n';
|
|
|
|
// Allow faster parsing of XML
|
|
if (*(*line - 1) == '>') {
|
|
valueEnd = '<';
|
|
}
|
|
|
|
// Skip any amount of whitespace at the begin of the value
|
|
while (**line == ' ' || **line == '\t') {
|
|
++(*line);
|
|
}
|
|
|
|
// Allow faster parsing of quoted values
|
|
if (**line == '"' || **line == '\'') {
|
|
valueEnd = **line;
|
|
++(*line);
|
|
}
|
|
|
|
// Copy the value to the buffer
|
|
while (**line != valueEnd && **line != '\n' && **line != '\0') {
|
|
ffStrbufAppendC(buffer, **line);
|
|
++(*line);
|
|
}
|
|
|
|
ffStrbufTrimRight(buffer, ' ');
|
|
|
|
return true;
|
|
}
|
|
|
|
bool ffParsePropLines(const char* lines, const char* start, FFstrbuf* buffer) {
|
|
while (!ffParsePropLinePointer(&lines, start, buffer)) {
|
|
while (*lines != '\0' && *lines != '\n') {
|
|
++lines;
|
|
}
|
|
|
|
if (*lines == '\0') {
|
|
return false;
|
|
}
|
|
|
|
// Skip '\n'
|
|
++lines;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
// The following functions return true if the file was found, independently if start was found
|
|
// Buffers which already contain content are not overwritten
|
|
// The last occurrence of start in the first file will be the one used
|
|
|
|
bool ffParsePropFileValues(const char* filename, uint32_t numQueries, FFpropquery* queries) {
|
|
FF_AUTO_CLOSE_FILE FILE* file = fopen(filename, "r");
|
|
if (file == nullptr) {
|
|
return false;
|
|
}
|
|
|
|
bool valueStorage[32];
|
|
bool* unsetValues = valueStorage;
|
|
|
|
if (numQueries > ARRAY_SIZE(valueStorage)) {
|
|
unsetValues = malloc(sizeof(bool) * numQueries);
|
|
}
|
|
|
|
bool allSet = true;
|
|
for (uint32_t i = 0; i < numQueries; i++) {
|
|
unsetValues[i] = queries[i].buffer->length == 0;
|
|
if (unsetValues[i]) {
|
|
allSet = false;
|
|
}
|
|
}
|
|
|
|
if (!allSet) {
|
|
FF_AUTO_FREE char* line = nullptr;
|
|
size_t len = 0;
|
|
|
|
while (getline(&line, &len, file) != -1) {
|
|
for (uint32_t i = 0; i < numQueries; i++) {
|
|
if (!unsetValues[i]) {
|
|
continue;
|
|
}
|
|
|
|
uint32_t currentLength = queries[i].buffer->length;
|
|
queries[i].buffer->length = 0;
|
|
if (!ffParsePropLine(line, queries[i].start, queries[i].buffer)) {
|
|
queries[i].buffer->length = currentLength;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (unsetValues != valueStorage) {
|
|
free(unsetValues);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool ffParsePropFileHomeValues(const char* relativeFile, uint32_t numQueries, FFpropquery* queries) {
|
|
FF_STRBUF_AUTO_DESTROY absolutePath = ffStrbufCreateF("%s/%s", instance.state.platform.homeDir.chars, relativeFile);
|
|
return ffParsePropFileValues(absolutePath.chars, numQueries, queries);
|
|
}
|
|
|
|
bool ffParsePropFileListValues(const FFlist* list, const char* relativeFile, uint32_t numQueries, FFpropquery* queries) {
|
|
bool foundAFile = false;
|
|
|
|
FF_LIST_FOR_EACH (FFstrbuf, dirPrefix, *list) {
|
|
const uint32_t dirPrefixLength = dirPrefix->length;
|
|
ffStrbufAppendS(dirPrefix, relativeFile);
|
|
if (ffParsePropFileValues(dirPrefix->chars, numQueries, queries)) {
|
|
foundAFile = true;
|
|
}
|
|
ffStrbufSubstrBefore(dirPrefix, dirPrefixLength);
|
|
|
|
bool allSet = true;
|
|
for (uint32_t k = 0; k < numQueries; k++) {
|
|
if (queries[k].buffer->length == 0) {
|
|
allSet = false;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (allSet) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
return foundAFile;
|
|
}
|