diff --git a/src/common.c b/src/common.c index d1da3c56b..14607c0a2 100644 --- a/src/common.c +++ b/src/common.c @@ -17,7 +17,8 @@ void ffInitState(FFstate* state) void ffDefaultConfig(FFconfig* config) { config->color[0] = '\0'; - config->logo_seperator = 4; + config->logo_spacer = 4; + strcpy(config->seperator, ": "); config->offsetx = 0; config->titleLength = 20; // This is overwritten by ffPrintTitle config->colorLogo = true; @@ -34,7 +35,7 @@ void ffDefaultConfig(FFconfig* config) void ffPrintKey(FFconfig* config, const char* key) { - printf(FASTFETCH_TEXT_MODIFIER_BOLT"%s%s"FASTFETCH_TEXT_MODIFIER_RESET": ", config->color, key); + printf(FASTFETCH_TEXT_MODIFIER_BOLT"%s%s"FASTFETCH_TEXT_MODIFIER_RESET"%s", config->color, key, config->seperator); } void ffPrintLogoAndKey(FFinstance* instance, const char* key) diff --git a/src/fastfetch.c b/src/fastfetch.c index 23929757f..a36426692 100644 --- a/src/fastfetch.c +++ b/src/fastfetch.c @@ -22,7 +22,8 @@ "\n" \ "## General options:\n" \ "# --structure "FASTFETCH_DEFAULT_STRUCTURE"\n" \ - "# --seperator 4\n" \ + "# --spacer 4\n" \ + "# --seperator \": \"\n" \ "# --offsetx 0\n" \ "# --recache false\n" \ "# --show-errors false\n" \ @@ -59,17 +60,18 @@ static void printHelp() " --print-default-config: prints the default config and exits\n" "\n" "General options:\n" - " --structure : sets the structure of the fetch. Must be a colon seperated list of keys\n" - " --set : hard set the value of an key\n" - " -c , --color : sets the color of the keys. Must be a linux console color code (+)\n" - " -s , --seperator : sets the distance between logo and text\n" - " -x , --offsetx : sets the x offset. Can be negative to cut the logo, but no more than logo width.\n" - " --show-errors : print occuring errors\n" - " -r --recache : if set to true, no cached values will be used\n" + " --structure : sets the structure of the fetch. Must be a colon seperated list of keys\n" + " --set : hard set the value of an key\n" + " -c , --color : sets the color of the keys. Must be a linux console color code (+)\n" + " --spacer : sets the distance between logo and text\n" + " -s , --seperator : sets the seperator between key and value. Default is a colon with a space\n" + " -x , --offsetx : sets the x offset. Can be negative to cut the logo, but no more than logo width.\n" + " --show-errors : print occuring errors\n" + " -r --recache : if set to true, no cached values will be used\n" "\n" "Logo options:\n" - " -l , --logo : sets the shown logo. Also changes the main color accordingly\n" - " --color-logo : if set to false, the logo will be black / white\n" + " -l , --logo : sets the shown logo. Also changes the main color accordingly\n" + " --color-logo : if set to false, the logo will be black / white\n" "\n" "Battery options:\n" " --battery-manufacturer : Show the manufacturer of the battery, if possible\n" @@ -234,7 +236,7 @@ static void parseOption(FFinstance* instance, FFdata* data, const char* key, con if(value == NULL) { printf("Error: usage: %s \n", key); - exit(41); + exit(401); } strcpy(data->logoName, value); @@ -251,40 +253,55 @@ static void parseOption(FFinstance* instance, FFdata* data, const char* key, con if(value == NULL) { printf("Error: usage: %s \n", key); - exit(42); + exit(402); } size_t len = strlen(value); if(len > 28) { printf("Error: max color string length is 28, %zu given\n", len); - exit(43); + exit(403); } sprintf(instance->config.color, "\033[%sm", value); } + else if(strcasecmp(key, "--spacer") == 0) + { + if(value == NULL) + { + printf("Error: usage: %s \n", key); + exit(404); + } + if(sscanf(value, "%hd", &instance->config.logo_spacer) != 1) + { + printf("Error: couldn't parse %s to uint16_t\n", value); + exit(405); + } + } else if(strcasecmp(key, "-s") == 0 || strcasecmp(key, "--seperator") == 0) { if(value == NULL) { - printf("Error: usage: %s \n", key); - exit(44); + printf("Error: usage: %s \n", key); + exit(406); } - if(sscanf(value, "%hd", &instance->config.logo_seperator) != 1) + size_t len = strlen(value); + if(len > 15) { - printf("Error: couldn't parse %s to uint16_t\n", value); - exit(45); + printf("Error: max seperator length is 15, %zu given\n", len); + exit(407); } + strcpy(instance->config.seperator, value); } else if(strcasecmp(key, "-x") == 0 || strcasecmp(key, "--offsetx") == 0) { if(value == NULL) { printf("Error: usage: %s \n", key); - exit(46); + exit(408); } if(sscanf(value, "%hi", &instance->config.offsetx) != 1) { printf("Error: couldn't parse %s to int16_t\n", value); - exit(47); + exit(409); } } else if(strcasecmp(key, "--structure") == 0) @@ -292,7 +309,7 @@ static void parseOption(FFinstance* instance, FFdata* data, const char* key, con if(value == NULL) { printf("Error: usage: %s \n", key); - exit(46); + exit(410); } strcpy(data->structure, value); } @@ -301,10 +318,17 @@ static void parseOption(FFinstance* instance, FFdata* data, const char* key, con if(value == NULL) { printf("Error: usage: %s \n", key); - exit(47); + exit(411); } char* seperator = strchr(value, '='); + + if(seperator == NULL) + { + printf("Error: usage: %s , '=' missing\n", key); + exit(412); + } + *seperator = '\0'; ffValuestoreSet(&data->valuestore, value, seperator + 1); @@ -356,20 +380,20 @@ static void parseOption(FFinstance* instance, FFdata* data, const char* key, con if(value == NULL) { printf("Error: usage: %s \n", key); - exit(48); + exit(413); } size_t len = strlen(value); if(len > 32) { printf("max battery format string length is 32, %zu given\n", len); - exit(49); + exit(414); } strcpy(instance->config.batteryFormat, value); } else { printf("Error: unknown option: %s\n", key); - exit(40); + exit(400); } } @@ -404,11 +428,14 @@ static void parseConfigFile(FFinstance* instance, FFdata* data) FILE* file = fopen(fileName, "r"); - char* line = NULL; + char* lineStart = NULL; size_t len = 0; ssize_t read; - while ((read = getline(&line, &len, file)) != -1) { + while ((read = getline(&lineStart, &len, file)) != -1) { + + //We need to copy lineStart because we modify this value, but need the original for free + char* line = lineStart; if(line[read - 1] == '\n') line[read - 1] = '\0'; @@ -418,27 +445,44 @@ static void parseConfigFile(FFinstance* instance, FFdata* data) ffTrimTrailingWhitespace(line); //This trims leading whitespace - while(line[0] == ' ') + while(*line == ' ') ++line; if(line[0] == '\0' || line[0] == '#') continue; - char* firstIndex = strchr(line, ' '); - - if(firstIndex == NULL) + char* valueStart = strchr(line, ' '); + if(valueStart == NULL) { parseOption(instance, data, line, NULL); } else { - *firstIndex = '\0'; - parseOption(instance, data, line, firstIndex + 1); + //Seperate key and value by simply replacing the first space with a \0 + *valueStart = '\0'; + ++valueStart; + + //Trim whitespace at beginn of value + while(*valueStart == ' ') + ++valueStart; + + //If we want whitespace in values, we need to quote it. This is done to keep consistency whith shell. + if(*valueStart == '"') + { + char* last = valueStart + strlen(valueStart) - 1; + if(*last == '"') + { + ++valueStart; + *last = '\0'; + } + } + + parseOption(instance, data, line, valueStart); } } - if(line) - free(line); + if(lineStart != NULL) + free(lineStart); fclose(file); } @@ -505,7 +549,7 @@ int main(int argc, const char** argv) FFdata data; ffValuestoreInit(&data.valuestore); data.structure[0] = '\0'; //We use this in run to detect if a structure was set - data.logoName[0] = '\0'; + data.logoName[0] = '\0'; //We use this in applyData to detect if a logo was set parseConfigFile(&instance, &data); parseArguments(&instance, &data, argc, argv); diff --git a/src/fastfetch.h b/src/fastfetch.h index a43a38561..4e73e9a83 100644 --- a/src/fastfetch.h +++ b/src/fastfetch.h @@ -32,7 +32,8 @@ typedef struct FFlogo typedef struct FFconfig { FFlogo logo; - uint16_t logo_seperator; + uint16_t logo_spacer; + char seperator[16]; int16_t offsetx; char color[32]; uint8_t titleLength; diff --git a/src/logo.c b/src/logo.c index 21830da1c..4fc58a216 100644 --- a/src/logo.c +++ b/src/logo.c @@ -70,7 +70,7 @@ void ffLoadLogoSet(FFconfig* config, const char* logo) if(strcasecmp(logo, "none") == 0) { loadNoneLogo(&config->logo); - config->logo_seperator = 0; //This is wanted in most cases, so just set it + config->logo_spacer = 0; //This is wanted in most cases, so just set it } else if(strcasecmp(logo, "arch") == 0) { @@ -118,7 +118,7 @@ void ffPrintLogoLine(FFinstance* instance) putchar(' '); } - for(uint16_t i = 0; i < instance->config.logo_seperator; i++) + for(uint16_t i = 0; i < instance->config.logo_spacer; i++) putchar(' '); ++instance->state.current_row;