commit f57d326

shrub  ·  2026-04-21 19:39:49 +0000 UTC
parent 1e4639b
handle origin
3 files changed,  +71, -0
+1, -0
1@@ -399,6 +399,7 @@ static const struct func funcs[] = {
2     {"shell", FNEXP1, {.f1 = fnshell}},
3     {"sort", FNEXP1, {.f1 = fnsort}},
4     {"info", FNCTX, {.ctx = fninfo}},
5+    {"origin", FNCTX, {.ctx = fnorigin}},
6     {"notdir", FNEXP1, {.f1 = fnnotdir}},
7     {"dir", FNEXP1, {.f1 = fndir}},
8     {"basename", FNEXP1, {.f1 = fnbasename}},
+69, -0
 1@@ -9,6 +9,8 @@
 2 
 3 /* implementations of gnu make builtin functions*/
 4 
 5+static char *trimspacesdup(const char *s);
 6+
 7 static int
 8 matchword(const char *patterns, const char *word, size_t nword)
 9 {
10@@ -487,6 +489,73 @@ fninfo(struct EvalCtx *ctx, const char *args)
11 	return xstrdup("");
12 }
13 
14+char *
15+fnorigin(struct EvalCtx *ctx, const char *args)
16+{
17+	char *name, *trimmed;
18+	struct Var *v;
19+	const char *origin;
20+
21+	name = expandstr(ctx, args);
22+	trimmed = trimspacesdup(name);
23+	free(name);
24+
25+	if (trimmed[0] == '@' && trimmed[1] == 0) {
26+		free(trimmed);
27+		return xstrdup("automatic");
28+	}
29+	if (trimmed[0] == '<' && trimmed[1] == 0) {
30+		free(trimmed);
31+		return xstrdup("automatic");
32+	}
33+	if (trimmed[0] == '^' && trimmed[1] == 0) {
34+		free(trimmed);
35+		return xstrdup("automatic");
36+	}
37+	if (trimmed[0] == '+' && trimmed[1] == 0) {
38+		free(trimmed);
39+		return xstrdup("automatic");
40+	}
41+	if (trimmed[0] == '?' && trimmed[1] == 0) {
42+		free(trimmed);
43+		return xstrdup("automatic");
44+	}
45+	if (trimmed[0] == '*' && trimmed[1] == 0) {
46+		free(trimmed);
47+		return xstrdup("automatic");
48+	}
49+	if (trimmed[0] == '%' && trimmed[1] == 0) {
50+		free(trimmed);
51+		return xstrdup("automatic");
52+	}
53+
54+	v = findvar(ctx->env, trimmed);
55+	if (!v) {
56+		free(trimmed);
57+		return xstrdup("undefined");
58+	}
59+
60+	switch (v->origin) {
61+	case ORIGIN_DEFAULT:
62+		origin = "default";
63+		break;
64+	case ORIGIN_FILE:
65+		origin = "file";
66+		break;
67+	case ORIGIN_COMMAND:
68+		origin = "command line";
69+		break;
70+	case ORIGIN_OVERRIDE:
71+		origin = "override";
72+		break;
73+	default:
74+		origin = "undefined";
75+		break;
76+	}
77+	free(trimmed);
78+	return xstrdup(origin);
79+}
80+
81 char *
82 fnnotdir(const char *names)
83 {
+1, -0
1@@ -68,6 +68,7 @@ char *fnaddsuffix(const char *suffix, const char *names);
2 char *fnstrip(const char *text);
3 char *fnsort(const char *text);
4 char *fninfo(struct EvalCtx *ctx, const char *args);
5+char *fnorigin(struct EvalCtx *ctx, const char *args);
6 char *fnnotdir(const char *names);
7 char *fndir(const char *names);
8 char *fnbasename(const char *names);