summaryrefslogtreecommitdiff
path: root/src/lib/config_file.c
diff options
context:
space:
mode:
authornpmccallum <npmccallum@c587cffe-e639-0410-9787-d7902ae8ed56>2008-06-05 20:56:04 +0000
committernpmccallum <npmccallum@c587cffe-e639-0410-9787-d7902ae8ed56>2008-06-05 20:56:04 +0000
commit9a401f3d7392134859a809905b11b7bcfaeea50b (patch)
treef34c169d4e4f43546bd4404af8c69be09e30ea55 /src/lib/config_file.c
parent197ba7edc0ce6f6758b198821a9c6bf7c1fd1932 (diff)
downloadlibproxy-git-libproxy-0.2.3.tar.gz
The real 0.2.3 releaselibproxy-0.2.3
Diffstat (limited to 'src/lib/config_file.c')
-rw-r--r--src/lib/config_file.c158
1 files changed, 130 insertions, 28 deletions
diff --git a/src/lib/config_file.c b/src/lib/config_file.c
index 8e32cab..69f5fec 100644
--- a/src/lib/config_file.c
+++ b/src/lib/config_file.c
@@ -24,64 +24,130 @@
#include <string.h>
#include "misc.h"
-#include "strdict.h"
#include "config_file.h"
+struct _pxConfigFileSection {
+ char *name;
+ char **keys;
+ char **vals;
+};
+typedef struct _pxConfigFileSection pxConfigFileSection;
+
struct _pxConfigFile {
- char *filename;
- time_t mtime;
- pxStrDict *sections;
+ char *filename;
+ time_t mtime;
+ pxConfigFileSection **sections;
};
pxConfigFile *
px_config_file_new(char *filename)
{
- /* Open the file and stat it */
+ // Open the file and stat it
struct stat st;
int fd = open(filename, O_RDONLY);
if (fd < 0) return NULL;
fstat(fd, &st);
- /* Allocate our structure; get mtime and filename */
+ // Allocate our structure; get mtime and filename
pxConfigFile *self = px_malloc0(sizeof(pxConfigFile));
- self->filename = px_strdup(filename);
self->mtime = st.st_mtime;
- self->sections = px_strdict_new((void *) px_strdict_free);
+ self->filename = px_strdup(filename);
- /* Add one section (PX_CONFIG_FILE_DEFAULT_SECTION) */
- px_strdict_set(self->sections, PX_CONFIG_FILE_DEFAULT_SECTION, px_strdict_new(free));
- pxStrDict *current = (pxStrDict *) px_strdict_get(self->sections, PX_CONFIG_FILE_DEFAULT_SECTION);
+ // Add one section (PX_CONFIG_FILE_DEFAULT_SECTION)
+ self->sections = px_malloc0(sizeof(pxConfigFileSection *) * 2);
+ self->sections[0] = px_malloc0(sizeof(pxConfigFileSection));
+ self->sections[0]->name = px_strdup(PX_CONFIG_FILE_DEFAULT_SECTION);
+ pxConfigFileSection *current = self->sections[0];
- /* Parse our file */
+ // Parse our file
for (char *line=NULL ; (line = px_readline(fd)) ; px_free(line))
{
- /* Strip */
+ // Strip
char *tmp = px_strstrip(line);
px_free(line); line = tmp;
- /* Check for comment and/or empty line */
+ // Check for comment and/or empty line
if (*line == '#' || !strcmp(line, "")) continue;
- /* If we have a new section */
+ // If we have a new section
if (*line == '[' || line[strlen(line)-1] == ']')
{
- /* Get just the section name */
+ // Get just the section name
memmove(line, line+1, strlen(line)-1);
line[strlen(line)-2] = '\0';
- if (px_strdict_get(self->sections, line))
- current = (pxStrDict *) px_strdict_get(self->sections, line);
- else
- px_strdict_set(self->sections, line, px_strdict_new(free));
+ // Check for each section...
+ for (int i=0 ; self->sections[i] ; i++)
+ {
+ // If we found the section already, set it as current and move on
+ if (!strcmp(self->sections[i]->name, line))
+ {
+ current = self->sections[i];
+ break;
+ }
+
+ // If the section wasn't found, add a new section
+ if (!self->sections[i+1])
+ {
+ // Create new section
+ current = px_malloc0(sizeof(pxConfigFileSection));
+ current->name = px_strdup(line);
+
+ // Add section to the end
+ pxConfigFileSection **sections = self->sections;
+ self->sections = px_malloc0(sizeof(pxConfigFileSection *) * (i+3));
+ memcpy(self->sections, sections, sizeof(pxConfigFileSection) * (i+1));
+ self->sections[i+1] = current;
+ px_free(sections);
+
+ break;
+ }
+ }
+ continue;
}
- /* If this is a key/val line, get the key/val. */
- else if ((tmp = strchr(line, '=')) && tmp[1])
+ // If this is a key/val line, get the key/val.
+ if ((tmp = strchr(line, '=')) && tmp[1])
{
- *tmp = '\0';
- char *key = px_strstrip(line);
- px_strdict_set(current, key, px_strstrip(tmp+1));
- px_free(key);
+ // If this is our first key/val, create a new array
+ if (!current->keys || !current->vals)
+ {
+ // Add key
+ current->keys = px_malloc0(sizeof(char *) * 2);
+ current->keys[0] = px_strndup(line, tmp - line);
+ current->keys[1] = NULL;
+
+ // Add val
+ current->vals = px_malloc0(sizeof(char *) * 2);
+ current->vals[0] = px_strdup(tmp+1);
+ current->vals[1] = NULL;
+ }
+
+ // If this is not our first key/val, tack it on the end
+ else
+ {
+ for (int i=0 ; current->keys[i] ; i++)
+ {
+ if (!current->keys[i+1])
+ {
+ // Add val
+ char **vals = px_malloc0(sizeof(char *) * (i+3));
+ memcpy(vals, current->vals, sizeof(char *) * (i+1));
+ vals[i+1] = px_strstrip(tmp+1);
+ px_free(current->vals); current->vals = vals;
+
+ // Add key
+ *tmp = '\0';
+ char **keys = px_malloc0(sizeof(char *) * (i+3));
+ memcpy(keys, current->keys, sizeof(char *) * (i+1));
+ keys[i+1] = px_strstrip(line);
+ px_free(current->keys); current->keys = keys;
+
+ break;
+ }
+ }
+ }
+ continue;
}
}
@@ -96,10 +162,39 @@ px_config_file_is_stale(pxConfigFile *self)
return (!stat(self->filename, &st) && st.st_mtime > self->mtime);
}
+char **
+px_config_file_get_sections(pxConfigFile *self)
+{
+ int count;
+ for (count=0 ; self->sections[count] ; count++);
+ char **output = px_malloc0(sizeof(char *) * ++count);
+ for (count=0 ; self->sections[count] ; count++)
+ output[count] = px_strdup(self->sections[count]->name);
+ return output;
+}
+
+char **
+px_config_file_get_keys(pxConfigFile *self, char *section)
+{
+ for (int i=0 ; self->sections[i] ; i++)
+ {
+ if (!strcmp(self->sections[i]->name, section))
+ return px_strdupv((const char **) self->sections[i]->keys);
+ }
+
+ return NULL;
+}
+
char *
px_config_file_get_value(pxConfigFile *self, char *section, char *key)
{
- return px_strdup(px_strdict_get((pxStrDict *) px_strdict_get(self->sections, section), key));
+ for (int i=0 ; self->sections[i] ; i++)
+ if (!strcmp(self->sections[i]->name, section))
+ for (int j=0 ; self->sections[i]->keys && self->sections[i]->keys[j] ; j++)
+ if (!strcmp(self->sections[i]->keys[j], key))
+ return px_strdup(self->sections[i]->vals[j]);
+
+ return NULL;
}
void
@@ -107,7 +202,14 @@ px_config_file_free(pxConfigFile *self)
{
if (!self) return;
- px_strdict_free(self->sections);
+ for (int i=0 ; self->sections && self->sections[i] ; i++)
+ {
+ px_free(self->sections[i]->name);
+ px_strfreev(self->sections[i]->keys);
+ px_strfreev(self->sections[i]->vals);
+ px_free(self->sections[i]);
+ }
+ px_free(self->sections);
px_free(self->filename);
px_free(self);
}