commit 3025f65
shrub
·
2026-07-01 13:55:48 +0000 UTC
parent b9b99b8
handle comment in submake recipe + test
7 files changed,
+64,
-1
+1,
-0
1@@ -527,6 +527,7 @@ static const struct func funcs[] = {
2 {"subst", FNEXP3, {.f3 = fnsubst}},
3 {"patsubst", FNEXP3, {.f3 = fnpatsubst}},
4 {"if", FNEXP3, {.f3 = fnif}},
5+ {"or", FNCTX, {.ctx = fnor}},
6 {"call", FNCTX, {.ctx = fncall}},
7 {"foreach", FNCTX, {.ctx = fnforeach}},
8 {"eval", FNCTX, {.ctx = fneval}},
+20,
-0
1@@ -1202,6 +1202,26 @@ fnabspath(const char *names)
2 return out;
3 }
4
5+char *
6+fnor(struct EvalCtx *ctx, const char *args)
7+{
8+ char **raw;
9+ char *val;
10+ size_t argc, i;
11+
12+ raw = splitargsraw(args, &argc);
13+ for (i = 0; i < argc; i++) {
14+ val = expandstr(ctx, raw[i]);
15+ if (val[0]) {
16+ freeargsraw(raw, argc);
17+ return val;
18+ }
19+ free(val);
20+ }
21+ freeargsraw(raw, argc);
22+ return xstrdup("");
23+}
24+
25 char *
26 fncall(struct EvalCtx *ctx, const char *args)
27 {
+1,
-0
1@@ -107,6 +107,7 @@ char *fnbasename(const char *names);
2 char *fnsubst(const char *from, const char *to, const char *text);
3 char *fnpatsubst(const char *pattern, const char *replacement, const char *text);
4 char *fnif(const char *cond, const char *then, const char *otherwise);
5+char *fnor(struct EvalCtx *ctx, const char *args);
6 char *fnwords(const char *text);
7 char *fnword(const char *n, const char *list);
8 char *fnwordlist(const char *s, const char *e, const char *list);
+15,
-1
1@@ -4,7 +4,16 @@
2 #include <stdlib.h>
3 #include <string.h>
4
5-/* recursive make handling */
6+/* recursive make handling: sort of done naively, doesent always work.
7+ *
8+ * TODO:
9+ * idea for a better implementation: create a new binary. shin replaces $(MAKE) with the
10+ * name of this new binary that we create. this binary is a program that simply expands the
11+ * graph of the submake and returns some sort of graph IR. shin pre-emptively runs all submake
12+ * recipes with the new helper binary sibstituted in as $(MAKE), then it reads the output
13+ * for each one and parses the graph IR into subgraphs. because we just shell out pre-emnptively,
14+ * we don't have to implement a small shell parser (like the one down below) and it will work
15+ * in 99% if not 100% of cases. */
16
17 static void
18 tokview(const char *s, const char **out, size_t *n)
19@@ -140,6 +149,9 @@ tokenizecmd(struct StrList *out, const char *s)
20 i++;
21 if (!s[i])
22 break;
23+ /* comment after recope shouldnt get parsed as a target*/
24+ if (s[i] == '#')
25+ break;
26 if (s[i] == '&' && s[i + 1] == '&') {
27 addtok(out, "&&", 2);
28 i += 2;
29@@ -152,6 +164,8 @@ tokenizecmd(struct StrList *out, const char *s)
30 break;
31 if (!quote && s[i] == '&' && s[i + 1] == '&')
32 break;
33+ if (!quote && s[i] == '#')
34+ break;
35 if (s[i] == '\\' && s[i + 1]) {
36 i += 2;
37 continue;
+2,
-0
1@@ -0,0 +1,2 @@
2+all:
3+ @$(MAKE) -f sub.mk show NAME=moon #_all
+1,
-0
1@@ -0,0 +1 @@
2+name=moon
+24,
-0
1@@ -0,0 +1,24 @@
2+{
3+ "case": "t003",
4+ "category": "recursion",
5+ "compare_output": true,
6+ "description": "recursive make ignores shell comments after submake arguments",
7+ "details": "",
8+ "env": {},
9+ "expected_exit": 0,
10+ "options": "",
11+ "options_mode": "argv",
12+ "output_mode": "exact",
13+ "setup": [
14+ {
15+ "kind": "file",
16+ "mode": "0644",
17+ "mtime": 0,
18+ "path": "sub.mk",
19+ "content": "show:\n\t@echo name=$(NAME)\n"
20+ }
21+ ],
22+ "stdin": "",
23+ "suite": "shin",
24+ "timeout_seconds": 60
25+}