aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas White <taw@bitwiz.org.uk>2011-12-28 12:42:12 +0000
committerThomas White <taw@bitwiz.org.uk>2011-12-28 12:42:12 +0000
commitd0b29890a5c4722be9849ec05e6568fe3d59d109 (patch)
tree725dfa94be35ca03dd1ae514933967b952659280
parentad016176f56489d42543567eeb44c94893f5d2ca (diff)
Handle long lines in files
-rw-r--r--src/loadsave.c231
1 files changed, 149 insertions, 82 deletions
diff --git a/src/loadsave.c b/src/loadsave.c
index d67fb37..654b4e4 100644
--- a/src/loadsave.c
+++ b/src/loadsave.c
@@ -182,113 +182,180 @@ out:
}
-static int deserialize_file(FILE *fh, struct ds_node *root)
+static void parse_line(struct ds_node *root, struct ds_node **cn,
+ const char *line)
{
- char *rval = NULL;
- struct ds_node *cur_node = root;
+ size_t i;
+ size_t len, s_start;
+ size_t s_equals = 0;
+ size_t s_val = 0;
+ size_t s_openbracket = 0;
+ size_t s_closebracket = 0;
+ int h_start = 0;
+ int h_equals = 0;
+ int h_val = 0;
+ int h_openbracket = 0;
+ int h_closebracket = 0;
+ struct ds_node *cur_node = *cn;
+
+ len = strlen(line);
+
+ s_start = len;
- do {
- size_t i;
- char line[1024];
- size_t len, s_start;
- size_t s_equals = 0;
- size_t s_val = 0;
- size_t s_openbracket = 0;
- size_t s_closebracket = 0;
- int h_start = 0;
- int h_equals = 0;
- int h_val = 0;
- int h_openbracket = 0;
- int h_closebracket = 0;
-
- rval = fgets(line, 1023, fh);
- if ( rval == NULL ) {
- if ( ferror(fh) ) printf("Read error!\n");
- continue;
+ for ( i=0; i<len; i++ ) {
+ if ( !h_start && !isspace(line[i]) ) {
+ s_start = i;
+ h_start = 1;
+ }
+ if ( !h_val && h_equals && !isspace(line[i]) ) {
+ s_val = i;
+ h_val = 1;
+ }
+ if ( !h_equals && (line[i] == '=') ) {
+ s_equals = i;
+ h_equals = 1;
+ }
+ if ( !h_openbracket && (line[i] == '[') ) {
+ s_openbracket = i;
+ h_openbracket = 1;
}
+ if ( h_openbracket && !h_closebracket
+ && (line[i] == ']') )
+ {
+ s_closebracket = i;
+ h_closebracket = 1;
+ }
+ }
- len = strlen(line);
- s_start = len-1;
+ if ( (h_openbracket && !h_closebracket)
+ || (!h_openbracket && h_closebracket) )
+ {
+ fprintf(stderr, "Mismatched square brackets: %s", line);
+ return;
+ }
- for ( i=0; i<len-1; i++ ) {
- if ( !h_start && !isspace(line[i]) ) {
- s_start = i;
- h_start = 1;
- }
- if ( !h_val && h_equals && !isspace(line[i]) ) {
- s_val = i;
- h_val = 1;
- }
- if ( !h_equals && (line[i] == '=') ) {
- s_equals = i;
- h_equals = 1;
- }
- if ( !h_openbracket && (line[i] == '[') ) {
- s_openbracket = i;
- h_openbracket = 1;
- }
- if ( h_openbracket && !h_closebracket
- && (line[i] == ']') )
- {
- s_closebracket = i;
- h_closebracket = 1;
- }
+ if ( !h_openbracket && !h_equals ) return;
+
+ if ( !h_openbracket && (!h_start || !h_val || !h_equals) ) {
+ fprintf(stderr, "Incomplete assignment: %s", line);
+ return;
+ }
+
+ if ( h_equals && (h_openbracket || h_closebracket) ) {
+ fprintf(stderr, "Brackets and equals: %s", line);
+ return;
+ }
+
+ if ( !h_openbracket ) {
+
+ size_t pos = 0;
+ char *key;
+ char *value;
+ struct ds_node *node;
+
+ key = malloc(len);
+ value = malloc(len);
+
+ for ( i=s_start; i<s_equals; i++ ) {
+ if ( !isspace(line[i]) ) key[pos++] = line[i];
}
+ key[pos] = '\0';
- if ( (h_openbracket && !h_closebracket)
- || (!h_openbracket && h_closebracket) )
- {
- fprintf(stderr, "Mismatched square brackets: %s", line);
- continue;
+ pos = 0;
+ for ( i=s_val; i<len; i++ ) {
+ if ( line[i] != '\n' ) value[pos++] = line[i];
}
+ value[pos] = '\0';
- if ( !h_openbracket && !h_equals ) continue;
+ node = find_node(cur_node, key, 1);
+ node->value = strdup(value);
- if ( !h_openbracket && (!h_start || !h_val || !h_equals) ) {
- fprintf(stderr, "Incomplete assignment: %s", line);
- continue;
+ free(key);
+ free(value);
+
+ } else {
+
+ size_t pos = 0;
+ char *path;
+
+ path = malloc(len);
+
+ for ( i=s_openbracket+1; i<s_closebracket; i++ ) {
+ if ( !isspace(line[i]) ) path[pos++] = line[i];
}
+ path[pos] = '\0';
+ cur_node = find_node(root, path, 1);
- if ( h_equals && (h_openbracket || h_closebracket) ) {
- fprintf(stderr, "Brackets and equals: %s", line);
- continue;
+ free(path);
+
+ }
+
+ *cn = cur_node;
+}
+
+
+static char *fgets_long(FILE *fh)
+{
+ char *line;
+ size_t la, l;
+
+ la = 1024;
+ line = malloc(la);
+ if ( line == NULL ) return NULL;
+
+ do {
+
+ int r;
+
+ r = fgetc(fh);
+ if ( r == EOF ) {
+ free(line);
+ return NULL;
}
- if ( !h_openbracket ) {
+ if ( r == '\n' ) {
+ line[l++] = '\0';
+ return line;
+ }
- size_t pos = 0;
- char key[1024];
- char value[1024];
- struct ds_node *node;
+ line[l++] = r;
- for ( i=s_start; i<s_equals; i++ ) {
- if ( !isspace(line[i]) ) key[pos++] = line[i];
- }
- key[pos] = '\0';
+ if ( l == la ) {
- pos = 0;
- for ( i=s_val; i<len; i++ ) {
- if ( line[i] != '\n' ) value[pos++] = line[i];
+ char *ln;
+
+ la += 1024;
+ ln = realloc(line, la);
+ if ( ln == NULL ) {
+ free(line);
+ return NULL;
}
- value[pos] = '\0';
- node = find_node(cur_node, key, 1);
- node->value = strdup(value);
+ line = ln;
- } else {
+ }
+
+ } while ( 1 );
+}
- size_t pos = 0;
- char path[1024];
- for ( i=s_openbracket+1; i<s_closebracket; i++ ) {
- if ( !isspace(line[i]) ) path[pos++] = line[i];
- }
- path[pos] = '\0';
- cur_node = find_node(root, path, 1);
+static int deserialize_file(FILE *fh, struct ds_node *root)
+{
+ char *line;
+ struct ds_node *cur_node = root;
+
+ line = NULL;
+ do {
+ line = fgets_long(fh);
+ if ( line == NULL ) {
+ if ( ferror(fh) ) printf("Read error!\n");
+ continue;
}
- } while ( rval != NULL );
+ parse_line(root, &cur_node, line);
+
+ } while ( line != NULL );
return 0;
}