-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathnode_set.c
More file actions
148 lines (131 loc) · 3.25 KB
/
Copy pathnode_set.c
File metadata and controls
148 lines (131 loc) · 3.25 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
#ifndef _AMALGAMATE_
#include "script.h"
#include "xstr.h"
#include "utils.h"
#include "alloc.h"
#include "env.h"
#endif
static const char* _set_value_get(struct node *n);
static void _set_dispose(struct node *n) {
if ((uintptr_t) n->impl != (uintptr_t) -1) {
free(n->impl);
}
n->impl = 0;
}
static bool _set_is_let(struct node *n) {
return strcmp(n->value, "let") == 0;
}
static struct unit* _unit_for_set(struct node *n, struct node *nn, const char **keyp) {
if (nn->type == NODE_TYPE_BAG) {
if (strcmp(nn->value, "root") == 0) {
*keyp = node_value(nn->child);
return unit_root();
} else if (strcmp(nn->value, "parent") == 0) {
*keyp = node_value(nn->child);
return unit_parent(n);
}
} else {
*keyp = node_value(nn);
}
return unit_peek();
}
static void _set_init_impl(struct node *n) {
const char *key = 0;
struct unit *unit = n->child ? _unit_for_set(n, n->child, &key) : 0;
if (!key) {
node_warn(n, "No name specified for 'set' directive");
return;
}
unsigned tag = 0;
struct node *nn = unit_env_get_node(unit, key, &tag);
if (nn && nn != n) {
n->recur_next.n = nn;
}
unit_env_set_node(unit, key, n, 0);
}
static void _set_init(struct node *n) {
_set_init_impl(n);
}
static void _set_setup(struct node *n) {
if (_set_is_let(n)) {
_set_init_impl(n);
}
if (n->child && strcmp(n->value, "env") == 0) {
const char *v = _set_value_get(n);
if (v) {
const char *key = 0;
_unit_for_set(n, n->child, &key);
if (key) {
if (g_env.verbose) {
node_info(n, "%s=%s", key, v);
}
setenv(key, v, 1);
}
}
}
}
static void _set_build(struct node *n) {
if (_set_is_let(n)) {
_set_init_impl(n);
}
}
static const char* _set_value_get(struct node *n) {
if (n->recur_next.active && n->recur_next.n) {
return _set_value_get(n->recur_next.n);
}
n->recur_next.active = true;
struct node_foreach *fe = node_find_parent_foreach(n);
if (fe || _set_is_let(n)) {
if ((uintptr_t) n->impl != (uintptr_t) -1) {
free(n->impl);
}
n->impl = 0;
}
if ((uintptr_t) n->impl == (uintptr_t) -1) {
n->recur_next.active = false;
return 0;
} else if (n->impl) {
n->recur_next.active = false;
return n->impl;
}
n->impl = (void*) (uintptr_t) -1;
struct node *nn = n->child->next;
if (!nn) {
n->impl = xstrdup("");
n->recur_next.active = false;
return n->impl;
}
if (!nn->next && nn->value[0] != '.') { // Single value
const char *v = node_value(nn);
n->impl = xstrdup(v);
n->recur_next.active = false;
return n->impl;
}
struct xstr *xstr = xstr_create_empty();
for ( ; nn; nn = nn->next) {
const char *v = node_value(nn);
if (!v) {
v = "";
}
if (nn->value[0] == '.' && nn->value[1] == '.') {
utils_split_values_add(v, xstr);
} else {
if (!is_vlist(v)) {
xstr_cat(xstr, "\1");
}
xstr_cat(xstr, v);
}
}
n->impl = xstr_destroy_keep_ptr(xstr);
n->recur_next.active = false;
return n->impl;
}
int node_set_setup(struct node *n) {
n->flags |= NODE_FLG_NO_CWD;
n->init = _set_init;
n->setup = _set_setup;
n->build = _set_build;
n->value_get = _set_value_get;
n->dispose = _set_dispose;
return 0;
}