Mercurial > repos > blastem
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; |