comparison config.c @ 766:1b2f8280ba81

WIP changes to support reading cart memory map from ROM DB
author Michael Pavone <pavone@retrodev.com>
date Sun, 05 Jul 2015 14:21:34 -0700
parents 2e1b3b258523
children 724bbec47f86 bce97fc0bb8a
comparison
equal deleted inserted replaced
765:dc54387ee1cd 766:1b2f8280ba81
6 #include "tern.h" 6 #include "tern.h"
7 #include "util.h" 7 #include "util.h"
8 #include <stdio.h> 8 #include <stdio.h>
9 #include <stdlib.h> 9 #include <stdlib.h>
10 #include <string.h> 10 #include <string.h>
11
12 #define MAX_NEST 30 //way more than I'll ever need
13 11
14 #ifdef _WIN32 12 #ifdef _WIN32
15 char * strtok_r(char * input, char * sep, char ** state) 13 char * strtok_r(char * input, char * sep, char ** state)
16 { 14 {
17 if (input) { 15 if (input) {
30 } 28 }
31 return NULL; 29 return NULL;
32 } 30 }
33 #endif 31 #endif
34 32
35 tern_node * parse_config(char * config_data) 33 tern_node * parse_config_int(char **state, int started, int *line)
36 { 34 {
37 char *state, *curline; 35 char *config_data, *curline;
38 char *prefix = NULL;
39 int nest_level = 0;
40 char * prefix_parts[MAX_NEST];
41 int line = 1;
42 tern_node * head = NULL; 36 tern_node * head = NULL;
43 while ((curline = strtok_r(config_data, "\n", &state))) 37 config_data = started ? NULL : *state;
38 while ((curline = strtok_r(config_data, "\n", state)))
44 { 39 {
40
45 config_data = NULL; 41 config_data = NULL;
46 curline = strip_ws(curline); 42 curline = strip_ws(curline);
47 int len = strlen(curline); 43 int len = strlen(curline);
48 if (!len) { 44 if (!len) {
45 *line++;
49 continue; 46 continue;
50 } 47 }
51 if (curline[0] == '#') { 48 if (curline[0] == '#') {
49 *line++;
52 continue; 50 continue;
53 } 51 }
54 if (curline[0] == '}') { 52 if (curline[0] == '}') {
55 if (!nest_level) { 53 if (started) {
56 fprintf(stderr, "unexpected } on line %d\n", line); 54 return head;
57 exit(1);
58 } 55 }
59 if (prefix) { 56 fprintf(stderr, "unexpected } on line %d\n", *line);
60 free(prefix); 57 exit(1);
61 prefix = NULL;
62 }
63 nest_level--;
64 curline = strip_ws(curline+1);
65 } 58 }
59
66 char * end = curline + len - 1; 60 char * end = curline + len - 1;
67 if (*end == '{') { 61 if (*end == '{') {
68 *end = 0; 62 *end = 0;
69 curline = strip_ws(curline); 63 curline = strip_ws(curline);
70 prefix_parts[nest_level++] = curline; 64 *line++;
71 if (prefix) { 65 head = tern_insert_node(head, curline, parse_config_int(state, 1, line));
72 free(prefix);
73 prefix = NULL;
74 }
75 } else { 66 } else {
76 if (nest_level && !prefix) {
77 prefix = alloc_concat_m(nest_level, prefix_parts);
78 }
79 char * val = strip_ws(split_keyval(curline)); 67 char * val = strip_ws(split_keyval(curline));
80 char * key = curline; 68 char * key = curline;
81 if (*key) { 69 if (*val) {
82 if (prefix) {
83 key = alloc_concat(prefix, key);
84 }
85 head = tern_insert_ptr(head, key, strdup(val)); 70 head = tern_insert_ptr(head, key, strdup(val));
86 if (prefix) { 71 } else {
87 free(key); 72 fprintf(stderr, "Key %s is missing a value on line %d\n", key, *line);
88 }
89 } 73 }
74 *line++;
90 } 75 }
91 } 76 }
92 if (prefix) {
93 free(prefix);
94 }
95 return head; 77 return head;
78 }
79
80 tern_node * parse_config(char * config_data)
81 {
82 int line = 1;
83 return parse_config_int(&config_data, 0, &line);
96 } 84 }
97 85
98 tern_node * parse_config_file(char * config_path) 86 tern_node * parse_config_file(char * config_path)
99 { 87 {
100 tern_node * ret = NULL; 88 tern_node * ret = NULL;