diff options
| -rw-r--r-- | src/settings.c | 65 | 
1 files changed, 59 insertions, 6 deletions
| diff --git a/src/settings.c b/src/settings.c index 36245de..b15053d 100644 --- a/src/settings.c +++ b/src/settings.c @@ -27,11 +27,13 @@ THE SOFTWARE.  #include "settings.h"  #include "config.h" +#include "ui.h"  #include "ui_dispatch.h"  #include <stdlib.h>  #include <assert.h>  #include <memory.h>  #include <string.h> +#include <ctype.h>  #define PACKAGE_CONFIG	PACKAGE ".cfg"  #define PACKAGE_STATE	PACKAGE ".state" @@ -214,8 +216,9 @@ void BarSettingsRead (BarSettings_t *settings) {  	/* read config files */  	for (size_t j = 0; j < sizeof (configfiles) / sizeof (*configfiles); j++) {  		static const char *formatMsgPrefix = "format_msg_"; -		char key[256], val[256];  		FILE *configfd; +		char line[512]; +		size_t lineNum = 0;  		char * const path = BarGetXdgConfigDir (configfiles[j]);  		assert (path != NULL); @@ -225,14 +228,64 @@ void BarSettingsRead (BarSettings_t *settings) {  		}  		while (1) { -			char lwhite, rwhite; -			int scanRet = fscanf (configfd, "%255s%c=%c%255[^\n]", key, &lwhite, &rwhite, val); -			if (scanRet == EOF) { +			++lineNum; +			char * const ret = fgets (line, sizeof (line), configfd); +			if (ret == NULL) { +				/* EOF or error */  				break; -			} else if (scanRet != 4 || lwhite != ' ' || rwhite != ' ') { -				/* invalid config line */ +			} +			if (strchr (line, '\n') == NULL && !feof (configfd)) { +				BarUiMsg (settings, MSG_INFO, "Line %s:%zu too long, " +						"ignoring\n", path, lineNum); +				continue; +			} +			/* parse lines that match "^\s*(.*?)\s?=\s?(.*)$". Windows and Unix +			 * line terminators are supported. */ +			char *key = line; + +			/* skip leading spaces */ +			while (isspace ((unsigned char) key[0])) { +				++key; +			} + +			/* skip comments */ +			if (key[0] == '#') {  				continue;  			} + +			/* search for delimiter and split key-value pair */ +			char *val = strchr (line, '='); +			if (val == NULL) { +				/* no warning for empty lines */ +				if (key[0] != '\0') { +					BarUiMsg (settings, MSG_INFO, +							"Invalid line at %s:%zu\n", path, lineNum); +				} +				/* invalid line */ +				continue; +			} +			*val = '\0'; +			++val; + +			/* drop spaces at the end */ +			char *keyend = &key[strlen (key)-1]; +			while (keyend >= key && isspace ((unsigned char) *keyend)) { +				*keyend = '\0'; +				--keyend; +			} + +			/* strip at most one space, legacy cruft, required for values with +			 * leading spaces like love_icon */ +			if (isspace ((unsigned char) val[0])) { +				++val; +			} +			/* drop trailing cr/lf */ +			char *valend = &val[strlen (val)-1]; +			while (valend >= val && (*valend == '\r' || *valend == '\n')) { +				*valend = '\0'; +				--valend; +			} +  			if (streq ("control_proxy", key)) {  				settings->controlProxy = strdup (val);  			} else if (streq ("proxy", key)) { | 
