commit 38b7f57
shrub
·
2026-05-04 18:40:25 +0000 UTC
parent 1beb2a2
implement !=
1 files changed,
+49,
-1
+49,
-1
1@@ -58,6 +58,51 @@ copyenv(struct Env *dst, const struct Env *src)
2 dst->cap = src->n;
3 }
4
5+static char *
6+runshellassign(const char *cmd)
7+{
8+ FILE *fp;
9+ char buf[4096];
10+ char *out;
11+ size_t len, cap, nread, i;
12+
13+ fp = popen(cmd, "r");
14+ if (!fp)
15+ return xstrdup("");
16+
17+ cap = 64;
18+ len = 0;
19+ out = xmalloc(cap);
20+ out[0] = 0;
21+
22+ while ((nread = fread(buf, 1, sizeof(buf), fp)) > 0) {
23+ if (len + nread + 1 > cap) {
24+ while (cap < len + nread + 1)
25+ cap *= 2;
26+ out = xrealloc(out, cap);
27+ }
28+ memcpy(out + len, buf, nread);
29+ len += nread;
30+ }
31+ out[len] = 0;
32+ pclose(fp);
33+ if (len > 0 && out[len - 1] == '\n') {
34+ len--;
35+ if (len > 0 && out[len - 1] == '\r')
36+ len--;
37+ out[len] = 0;
38+ } else if (len > 0 && out[len - 1] == '\r') {
39+ len--;
40+ out[len] = 0;
41+ }
42+
43+ for (i = 0; i < len; i++) {
44+ if (out[i] == '\n' || out[i] == '\r')
45+ out[i] = ' ';
46+ }
47+ return out;
48+}
49+
50 void
51 evalassign(struct EvalCtx *ctx, const struct AssignNode *in)
52 {
53@@ -97,7 +142,10 @@ evalassign(struct EvalCtx *ctx, const struct AssignNode *in)
54 v->exported = 1;
55 break;
56 case ASSIGN_BANG_EQ:
57- envsetvar(env, in->lhs, expandstr(ctx, in->rhs), 1, o, in->exported);
58+ rhs = expandstr(ctx, in->rhs);
59+ joined = runshellassign(rhs);
60+ free(rhs);
61+ envsetvar(env, in->lhs, joined, 1, o, in->exported);
62 break;
63 }
64 }