| 170 | | /* ENOCOFFEE */; |
|---|
| | 171 | struct parser_res *entry, *evar; |
|---|
| | 172 | char ch, *cp, *tp, *dp; |
|---|
| | 173 | bool do_again; |
|---|
| | 174 | |
|---|
| | 175 | expand_loop: |
|---|
| | 176 | do_again = false; |
|---|
| | 177 | CIRCLEQ_FOREACH(entry, head, e) { |
|---|
| | 178 | if ((cp = entry->value) == NULL) |
|---|
| | 179 | continue; |
|---|
| | 180 | /* scan the value for variable references */ |
|---|
| | 181 | while ((ch = *cp++)) |
|---|
| | 182 | if (ch == '\\') |
|---|
| | 183 | cp++; |
|---|
| | 184 | else if (ch == '$') |
|---|
| | 185 | break; |
|---|
| | 186 | if (!ch) |
|---|
| | 187 | continue; |
|---|
| | 188 | /* cp points to a dollar sign, copy head */ |
|---|
| | 189 | dp = str_nsave(entry->value, cp - entry->value); |
|---|
| | 190 | /* read variable name */ |
|---|
| | 191 | if (*++cp != '{' /*}*/) |
|---|
| | 192 | goto copy_rest; |
|---|
| | 193 | tp = ++cp; |
|---|
| | 194 | while (*tp && (*tp != /*{*/ '}')) |
|---|
| | 195 | ++tp; |
|---|
| | 196 | if (*tp != /*{*/ '}') |
|---|
| | 197 | goto copy_rest; |
|---|
| | 198 | *tp++ = '\0'; |
|---|
| | 199 | /* variable name in cp, rest of string in tp */ |
|---|
| | 200 | evar = parse_lookupbyname(head, cp); |
|---|
| | 201 | cp = tp; |
|---|
| | 202 | /* variable content in evar, rest of string in cp */ |
|---|
| | 203 | if (evar && evar->value) |
|---|
| | 204 | dp = str_add(dp, evar->value); |
|---|
| | 205 | copy_rest: |
|---|
| | 206 | dp = str_add(dp, cp); |
|---|
| | 207 | free(entry->value); |
|---|
| | 208 | entry->value = dp; |
|---|
| | 209 | /* string was modified, so reloop */ |
|---|
| | 210 | do_again = true; |
|---|
| | 211 | break; |
|---|
| | 212 | } |
|---|
| | 213 | if (do_again) |
|---|
| | 214 | goto expand_loop; |
|---|
| | 215 | /* all variable references have been expanded */ |
|---|
| | 216 | CIRCLEQ_FOREACH(entry, head, e) { |
|---|
| | 217 | if ((cp = entry->value) == NULL) |
|---|
| | 218 | continue; |
|---|
| | 219 | /* unescape backslashes */ |
|---|
| | 220 | tp = dp = str_save(cp); |
|---|
| | 221 | while ((ch = *cp++)) { |
|---|
| | 222 | if (ch == '\\') |
|---|
| | 223 | ch = *cp++; |
|---|
| | 224 | *tp++ = ch; |
|---|
| | 225 | } |
|---|
| | 226 | free(entry->value); |
|---|
| | 227 | entry->value = dp; |
|---|
| | 228 | } |
|---|