aboutsummaryrefslogtreecommitdiffstats
path: root/Alc
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2013-06-16 18:42:27 -0700
committerChris Robinson <[email protected]>2013-06-16 18:42:27 -0700
commit8bd77be5222a62b060f1cfeb5d62cb44ced3a250 (patch)
tree67363e7aa555cbf0df1bce23c80688e91bb3fbac /Alc
parentff44ebfd5baca42bf2516c620af3216c88dffd39 (diff)
Improve parsing of the config files
This will also now recognize (and strip) quotation marks from around values.
Diffstat (limited to 'Alc')
-rw-r--r--Alc/alcConfig.c128
1 files changed, 59 insertions, 69 deletions
diff --git a/Alc/alcConfig.c b/Alc/alcConfig.c
index 49a02b23..8757c3ff 100644
--- a/Alc/alcConfig.c
+++ b/Alc/alcConfig.c
@@ -55,6 +55,22 @@ static unsigned int cfgCount;
static char buffer[1024];
+static char *lstrip(char *line)
+{
+ while(isspace(line[0]))
+ line++;
+ return line;
+}
+
+static char *rstrip(char *line)
+{
+ size_t len = strlen(line);
+ while(len > 0 && isspace(line[len-1]))
+ len--;
+ line[len] = 0;
+ return line;
+}
+
static void LoadConfigFromFile(FILE *f)
{
ConfigBlock *curBlock = cfgBlocks;
@@ -62,45 +78,40 @@ static void LoadConfigFromFile(FILE *f)
while(fgets(buffer, sizeof(buffer), f))
{
- int i = 0;
+ char *line, *comment;
+ char key[256] = "";
+ char value[256] = "";
- while(isspace(buffer[i]))
- i++;
- if(!buffer[i] || buffer[i] == '#')
- continue;
+ comment = strchr(buffer, '#');
+ if(comment)
+ {
+ *(comment++) = 0;
+ comment = rstrip(lstrip(comment));
+ }
- memmove(buffer, buffer+i, strlen(buffer+i)+1);
+ line = rstrip(lstrip(buffer));
+ if(!line[0])
+ continue;
- if(buffer[0] == '[')
+ if(line[0] == '[')
{
ConfigBlock *nextBlock;
+ char *section = line+1;
+ char *endsection;
unsigned int i;
- i = 1;
- while(buffer[i] && buffer[i] != ']')
- i++;
-
- if(!buffer[i])
+ endsection = strchr(section, ']');
+ if(!endsection || section == endsection || endsection[1] != 0)
{
- ERR("config parse error: bad line \"%s\"\n", buffer);
+ ERR("config parse error: bad line \"%s\"\n", line);
continue;
}
- buffer[i] = 0;
-
- do {
- i++;
- if(buffer[i] && !isspace(buffer[i]))
- {
- if(buffer[i] != '#')
- WARN("config warning: extra data after block: \"%s\"\n", buffer+i);
- break;
- }
- } while(buffer[i]);
+ *endsection = 0;
nextBlock = NULL;
for(i = 0;i < cfgCount;i++)
{
- if(strcasecmp(cfgBlocks[i].name, buffer+1) == 0)
+ if(strcasecmp(cfgBlocks[i].name, section) == 0)
{
nextBlock = cfgBlocks+i;
TRACE("found block '%s'\n", nextBlock->name);
@@ -120,7 +131,7 @@ static void LoadConfigFromFile(FILE *f)
nextBlock = cfgBlocks+cfgCount;
cfgCount++;
- nextBlock->name = strdup(buffer+1);
+ nextBlock->name = strdup(section);
nextBlock->entries = NULL;
nextBlock->entryCount = 0;
@@ -130,41 +141,32 @@ static void LoadConfigFromFile(FILE *f)
continue;
}
- /* Look for the option name */
- i = 0;
- while(buffer[i] && buffer[i] != '#' && buffer[i] != '=' &&
- !isspace(buffer[i]))
- i++;
-
- if(!buffer[i] || buffer[i] == '#' || i == 0)
- {
- ERR("config parse error: malformed option line: \"%s\"\n", buffer);
- continue;
- }
-
- /* Seperate the option */
- if(buffer[i] != '=')
+ if(sscanf(line, "%255[^=] = \"%255[^\"]\"", key, value) == 2 ||
+ sscanf(line, "%255[^=] = '%255[^\']'", key, value) == 2 ||
+ sscanf(line, "%255[^=] = %255[^\n]", key, value) == 2)
{
- buffer[i++] = 0;
-
- while(isspace(buffer[i]))
- i++;
- if(buffer[i] != '=')
- {
- ERR("config parse error: option without a value: \"%s\"\n", buffer);
- continue;
- }
- }
- /* Find the start of the value */
- buffer[i++] = 0;
- while(isspace(buffer[i]))
- i++;
+ /* sscanf doesn't handle '' or "" as empty values, so clip it
+ * manually. */
+ if(strcmp(value, "\"\"") == 0 || strcmp(value, "''") == 0)
+ value[0] = 0;
+ }
+ else if(sscanf(line, "%255[^=] %255[=]", key, value) == 2)
+ {
+ /* Special case for 'key =' */
+ value[0] = 0;
+ }
+ else
+ {
+ ERR("config parse error: malformed option line: \"%s\"\n\n", line);
+ continue;
+ }
+ rstrip(key);
/* Check if we already have this option set */
ent = curBlock->entries;
while((unsigned int)(ent-curBlock->entries) < curBlock->entryCount)
{
- if(strcasecmp(ent->key, buffer) == 0)
+ if(strcasecmp(ent->key, key) == 0)
break;
ent++;
}
@@ -182,24 +184,12 @@ static void LoadConfigFromFile(FILE *f)
ent = curBlock->entries + curBlock->entryCount;
curBlock->entryCount++;
- ent->key = strdup(buffer);
+ ent->key = strdup(key);
ent->value = NULL;
}
- /* Look for the end of the line (Null term, new-line, or #-symbol) and
- eat up the trailing whitespace */
- memmove(buffer, buffer+i, strlen(buffer+i)+1);
-
- i = 0;
- while(buffer[i] && buffer[i] != '#' && buffer[i] != '\n')
- i++;
- do {
- i--;
- } while(i >= 0 && isspace(buffer[i]));
- buffer[++i] = 0;
-
free(ent->value);
- ent->value = strdup(buffer);
+ ent->value = strdup(value);
TRACE("found '%s' = '%s'\n", ent->key, ent->value);
}