commit 4aa3f55
afiw
·
2026-05-12 22:52:34 +0000 UTC
parent 4de1ba7
abspath, realpath
3 files changed,
+144,
-7
+42,
-7
1@@ -414,13 +414,46 @@ struct func {
2 };
3
4 static const char *const allfuncs[] = {
5- "abspath", "addprefix", "addsuffix", "and", "basename",
6- "call", "dir", "error", "eval", "file", "filter",
7- "filter-out", "findstring", "firstword", "flavor", "foreach",
8- "guile", "if", "info", "intcmp", "join", "lastword", "let",
9- "notdir", "or", "origin", "patsubst", "realpath", "shell",
10- "sort", "strip", "subst", "suffix", "value", "warning",
11- "wildcard", "word", "wordlist", "words", 0,
12+ "abspath",
13+ "addprefix",
14+ "addsuffix",
15+ "and",
16+ "basename",
17+ "call",
18+ "dir",
19+ "error",
20+ "eval",
21+ "file",
22+ "filter",
23+ "filter-out",
24+ "findstring",
25+ "firstword",
26+ "flavor",
27+ "foreach",
28+ "guile",
29+ "if",
30+ "info",
31+ "intcmp",
32+ "join",
33+ "lastword",
34+ "let",
35+ "notdir",
36+ "or",
37+ "origin",
38+ "patsubst",
39+ "realpath",
40+ "shell",
41+ "sort",
42+ "strip",
43+ "subst",
44+ "suffix",
45+ "value",
46+ "warning",
47+ "wildcard",
48+ "word",
49+ "wordlist",
50+ "words",
51+ 0,
52 };
53
54 static const struct func funcs[] = {
55@@ -451,6 +484,8 @@ static const struct func funcs[] = {
56 {"wordlist", FNEXP3, {.f3 = fnwordlist}},
57 {"firstword", FNEXP1, {.f1 = fnfirstword}},
58 {"lastword", FNEXP1, {.f1 = fnlastword}},
59+ {"realpath", FNEXP1, {.f1 = fnrealpath}},
60+ {"abspath", FNEXP1, {.f1 = fnabspath}},
61 {0, FNEXP1, {.f1 = 0}},
62 };
63
+100,
-0
1@@ -1102,6 +1102,106 @@ trimspacesdup(const char *s)
2 return xstrndup(s + i, j - i);
3 }
4
5+char *
6+fnrealpath(const char *names)
7+{
8+ size_t i, j, cap, len, need, rplen;
9+ char *out, *rp, *w;
10+
11+ cap = strlen(names) + 1;
12+ if (cap < 16)
13+ cap = 16;
14+ len = 0;
15+ out = xmalloc(cap);
16+ out[0] = 0;
17+ for (i = 0; names[i];) {
18+ while (names[i] && isspace((unsigned char)names[i]))
19+ i++;
20+ if (!names[i])
21+ break;
22+ j = i;
23+ while (names[j] && !isspace((unsigned char)names[j]))
24+ j++;
25+ w = xstrndup(names + i, j - i);
26+ rp = realpath(w, NULL);
27+ free(w);
28+ rplen = rp ? strlen(rp) : 0;
29+ need = len + rplen + 2;
30+ if (need > cap) {
31+ while (cap < need)
32+ cap *= 2;
33+ out = xrealloc(out, cap);
34+ }
35+ if (rp) {
36+ if (len)
37+ out[len++] = ' ';
38+ memcpy(out + len, rp, rplen);
39+ free(rp);
40+ len += rplen;
41+ out[len] = 0;
42+ }
43+ i = j;
44+ }
45+ return out;
46+}
47+
48+static char *
49+normabspath(const char *path)
50+{
51+ char *cwd, *jp, *np;
52+
53+ if (*path == '/') {
54+ return normpath(path);
55+ }
56+ cwd = getcwddup();
57+ jp = joinpath(cwd, path);
58+ np = normpath(jp);
59+ free(cwd);
60+ free(jp);
61+ return np;
62+}
63+
64+char *
65+fnabspath(const char *names)
66+{
67+ size_t i, j, cap, len, need, nplen;
68+ char *out, *np, *w;
69+
70+ cap = strlen(names) + 1;
71+ if (cap < 16)
72+ cap = 16;
73+ len = 0;
74+ out = xmalloc(cap);
75+ out[0] = 0;
76+ for (i = 0; names[i];) {
77+ while (names[i] && isspace((unsigned char)names[i]))
78+ i++;
79+ if (!names[i])
80+ break;
81+ j = i;
82+ while (names[j] && !isspace((unsigned char)names[j]))
83+ j++;
84+ w = xstrndup(names + i, j - i);
85+ np = normabspath(w);
86+ free(w);
87+ nplen = strlen(np);
88+ need = len + nplen + 2;
89+ if (need > cap) {
90+ while (cap < need)
91+ cap *= 2;
92+ out = xrealloc(out, cap);
93+ }
94+ if (len)
95+ out[len++] = ' ';
96+ memcpy(out + len, np, nplen);
97+ free(np);
98+ len += nplen;
99+ out[len] = 0;
100+ i = j;
101+ }
102+ return out;
103+}
104+
105 char *
106 fncall(struct EvalCtx *ctx, const char *args)
107 {
+2,
-0
1@@ -105,6 +105,8 @@ char *fnword(const char *n, const char *list);
2 char *fnwordlist(const char *s, const char *e, const char *list);
3 char *fnfirstword(const char *list);
4 char *fnlastword(const char *list);
5+char *fnrealpath(const char *path);
6+char *fnabspath(const char *path);
7
8 char *fncall(struct EvalCtx *ctx, const char *args);
9 char *fnforeach(struct EvalCtx *ctx, const char *args);