changeset 824:4a913f093f56

load_options_from(): - do not copy option name and value anywhere, only copy value_all to a separate buffer - allow more relaxed syntax on read, so we can correctly read option name and value even if user made some errors like replacing ':' by '=' or inserting a space before ':'. - minor aesthetical changes
author zas_
date Thu, 12 Jun 2008 22:43:32 +0000
parents ed82f5bf8082
children ee33d2ddb661
files src/rcfile.c
diffstat 1 files changed, 24 insertions(+), 16 deletions(-) [+]
line wrap: on
line diff
--- a/src/rcfile.c	Thu Jun 12 21:21:32 2008 +0000
+++ b/src/rcfile.c	Thu Jun 12 22:43:32 2008 +0000
@@ -49,7 +49,7 @@
 
 	if (l == 0) return retval;
 
-	while (c < l && text[c] !='"') c++;
+	while (c < l && text[c] != '"') c++;
 	if (text[c] == '"')
 		{
 		gint e;
@@ -81,7 +81,7 @@
 		 * read a line without quotes too */
 		{
 		c = 0;
-		while (c < l && text[c] !=' ' && text[c] !=8 && text[c] != '\n') c++;
+		while (c < l && text[c] != '\n' && !g_ascii_isspace(text[c])) c++;
 		if (c != 0)
 			{
 			retval = g_strndup(text, c);
@@ -642,16 +642,16 @@
 	return TRUE;
 }
 
-
+#define OPTION_READ_BUFFER_SIZE 1024
 
 static gboolean load_options_from(const gchar *utf8_path, ConfOptions *options)
 {
 	FILE *f;
 	gchar *rc_pathl;
-	gchar s_buf[1024];
-	gchar option[1024];
-	gchar value[1024];
-	gchar value_all[1024];
+	gchar s_buf[OPTION_READ_BUFFER_SIZE];
+	gchar value_all[OPTION_READ_BUFFER_SIZE];
+	gchar *option;
+	gchar *value;
 	gint i;
 
 	rc_pathl = path_from_utf8(utf8_path);
@@ -661,23 +661,31 @@
 
 	while (fgets(s_buf, sizeof(s_buf), f))
 		{
-		gchar *option_start, *value_start;
+		gchar *value_end;
 		gchar *p = s_buf;
 
+		/* skip empty lines and comments */
 		while (g_ascii_isspace(*p)) p++;
 		if (!*p || *p == '\n' || *p == '#') continue;
-		option_start = p;
-		while (*p && *p != ':') p++;
+
+		/* parse option name */
+		option = p;
+		while (g_ascii_isalnum(*p) || *p == '_' || *p == '.') p++;
 		if (!*p) continue;
 		*p = '\0';
 		p++;
-		strncpy(option, option_start, sizeof(option));
-		while (g_ascii_isspace(*p)) p++;
-		value_start = p;
-		strncpy(value_all, value_start, sizeof(value_all));
+
+		/* search for value start, name and value are normally separated by ': '
+		 * but we allow relaxed syntax here, so '=', ':=' or just a tab will work too */
+		while (*p == ':' || g_ascii_isspace(*p) || *p == '=') p++;
+		value = p;
+
 		while (*p && !g_ascii_isspace(*p) && *p != '\n') p++;
-		*p = '\0';
-		strncpy(value, value_start, sizeof(value));
+		value_end = p; /* value part up to the first whitespace or end of line */
+		while (*p != '\0') p++;
+		memcpy(value_all, value, 1 + p - value);
+
+		*value_end = '\0';
 
 #define READ_BOOL(_name_) if (read_bool_option(f, option, #_name_, value, &options->_name_)) continue;
 #define READ_INT(_name_) if (read_int_option(f, option, #_name_, value, &options->_name_)) continue;