Mercurial > repos > blastem
comparison util.c @ 1292:5905593d6828
Allow initial_path to contain variable references which allows the default value to be actually specified in the default config file
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Tue, 21 Mar 2017 00:40:25 -0700 |
parents | a344885e7c79 |
children | 96ad1b9bbb3a |
comparison
equal
deleted
inserted
replaced
1291:f17fe0d00626 | 1292:5905593d6828 |
---|---|
53 *ret = 0; | 53 *ret = 0; |
54 for (int i = 0; i < num_parts; i++) { | 54 for (int i = 0; i < num_parts; i++) { |
55 strcat(ret, parts[i]); | 55 strcat(ret, parts[i]); |
56 } | 56 } |
57 return ret; | 57 return ret; |
58 } | |
59 | |
60 typedef struct { | |
61 uint32_t start; | |
62 uint32_t end; | |
63 char *value; | |
64 } var_pos; | |
65 | |
66 char *replace_vars(char *base, tern_node *vars, uint8_t allow_env) | |
67 { | |
68 uint32_t num_vars = 0; | |
69 for (char *cur = base; *cur; ++cur) | |
70 { | |
71 //TODO: Support escaping $ and allow brace syntax | |
72 if (*cur == '$') { | |
73 num_vars++; | |
74 } | |
75 } | |
76 var_pos *positions = calloc(num_vars, sizeof(var_pos)); | |
77 num_vars = 0; | |
78 uint8_t in_var = 0; | |
79 uint32_t max_var_len = 0; | |
80 for (char *cur = base; *cur; ++cur) | |
81 { | |
82 if (in_var) { | |
83 if (!(*cur == '_' || isalnum(*cur))) { | |
84 positions[num_vars].end = cur-base; | |
85 if (positions[num_vars].end - positions[num_vars].start > max_var_len) { | |
86 max_var_len = positions[num_vars].end - positions[num_vars].start; | |
87 } | |
88 num_vars++; | |
89 in_var = 0; | |
90 } | |
91 } else if (*cur == '$') { | |
92 positions[num_vars].start = cur-base+1; | |
93 in_var = 1; | |
94 } | |
95 } | |
96 if (in_var) { | |
97 positions[num_vars].end = strlen(base); | |
98 if (positions[num_vars].end - positions[num_vars].start > max_var_len) { | |
99 max_var_len = positions[num_vars].end - positions[num_vars].start; | |
100 } | |
101 num_vars++; | |
102 } | |
103 char *varname = malloc(max_var_len+1); | |
104 uint32_t total_len = 0; | |
105 uint32_t cur = 0; | |
106 for (uint32_t i = 0; i < num_vars; i++) | |
107 { | |
108 total_len += (positions[i].start - 1) - cur; | |
109 cur = positions[i].start; | |
110 memcpy(varname, base + positions[i].start, positions[i].end-positions[i].start); | |
111 varname[positions[i].end-positions[i].start] = 0; | |
112 positions[i].value = tern_find_ptr(vars, varname); | |
113 if (!positions[i].value && allow_env) { | |
114 positions[i].value = getenv(varname); | |
115 } | |
116 if (positions[i].value) { | |
117 total_len += strlen(positions[i].value); | |
118 } | |
119 } | |
120 total_len += strlen(base+cur); | |
121 free(varname); | |
122 char *output = malloc(total_len+1); | |
123 cur = 0; | |
124 char *curout = output; | |
125 for (uint32_t i = 0; i < num_vars; i++) | |
126 { | |
127 if (positions[i].start-1 > cur) { | |
128 memcpy(curout, base + cur, (positions[i].start-1) - cur); | |
129 curout += (positions[i].start-1) - cur; | |
130 } | |
131 if (positions[i].value) { | |
132 strcpy(curout, positions[i].value); | |
133 curout += strlen(curout); | |
134 } | |
135 cur = positions[i].end; | |
136 }; | |
137 if (base[cur]) { | |
138 strcpy(curout, base+cur); | |
139 } else { | |
140 *curout = 0; | |
141 } | |
142 free(positions); | |
143 return output; | |
58 } | 144 } |
59 | 145 |
60 void byteswap_rom(int filesize, uint16_t *cart) | 146 void byteswap_rom(int filesize, uint16_t *cart) |
61 { | 147 { |
62 for(uint16_t *cur = cart; cur - cart < filesize/2; ++cur) | 148 for(uint16_t *cur = cart; cur - cart < filesize/2; ++cur) |