diff options
| -rw-r--r-- | builtins/path.c | 14 | ||||
| -rw-r--r-- | builtins/path.h | 1 | ||||
| -rw-r--r-- | compile.c | 5 |
3 files changed, 14 insertions, 6 deletions
diff --git a/builtins/path.c b/builtins/path.c index fa09082a..e63e4e42 100644 --- a/builtins/path.c +++ b/builtins/path.c @@ -35,8 +35,12 @@ PUREFUNC public Path_t Path$escape_path(Path_t path) return path; } -static Path_t Path$_cleanup(Path_t path) +public Path_t Path$cleanup(Path_t path) { + if (!Text$starts_with(path, Path("/")) && !Text$starts_with(path, Path("./")) + && !Text$starts_with(path, Path("../")) && !Text$starts_with(path, Path("~/"))) + path = Text$concat(Text("./"), path); + // Not fully resolved, but at least get rid of some of the cruft like "/./" // and "/foo/../" and "//" bool trailing_slash = Text$ends_with(path, Path("/")); @@ -119,7 +123,7 @@ public Path_t Path$_concat(int n, Path_t items[n]) .data=items, .data_refcount=1, }; - Path_t cleaned_up = Path$_cleanup(Text$join(Text("/"), items_array)); + Path_t cleaned_up = Path$cleanup(Text$join(Text("/"), items_array)); if (cleaned_up.length > PATH_MAX) fail("Path exceeds the maximum path length: %k", &cleaned_up); return cleaned_up; @@ -127,7 +131,7 @@ public Path_t Path$_concat(int n, Path_t items[n]) public Text_t Path$resolved(Path_t path, Path_t relative_to) { - path = Path$_cleanup(path); + path = Path$cleanup(path); const char *path_str = Text$as_c_string(path); const char *relative_to_str = Text$as_c_string(relative_to); @@ -393,12 +397,12 @@ public Text_t Path$write_unique(Path_t path, Text_t text) public Path_t Path$parent(Path_t path) { - return Path$_cleanup(Text$concat(path, Path("/../"))); + return Path$cleanup(Text$concat(path, Path("/../"))); } public Text_t Path$base_name(Path_t path) { - path = Path$_cleanup(path); + path = Path$cleanup(path); if (Text$ends_with(path, Path("/"))) return Text$replace(path, Pattern("{0+..}/{!/}/{end}"), Text("@2"), Text("@"), false); else diff --git a/builtins/path.h b/builtins/path.h index c5acbf34..06bc2ec6 100644 --- a/builtins/path.h +++ b/builtins/path.h @@ -13,6 +13,7 @@ #define Path(text) ((Path_t)Text(text)) #define Paths(...) Path$concat(__VA_ARGS__) +Path_t Path$cleanup(Path_t path); Path_t Path$_concat(int n, Path_t items[n]); #define Path$concat(...) Path$_concat(sizeof((Path_t[]){__VA_ARGS__})/sizeof(Path_t), (Path_t[]){__VA_ARGS__}) PUREFUNC Path_t Path$escape_text(Text_t text); @@ -3222,7 +3222,7 @@ CORD compile_cli_arg_call(env_t *env, CORD fn_name, type_t *fn_type) } case TextType: { code = CORD_all(code, "else if (pop_flag(argv, &i, \"", flag, "\", &flag)) {\n", - "$", arg->name, " = flag;\n", + "$", arg->name, " = ", streq(Match(t, TextType)->lang, "Path") ? "Path$cleanup(flag)" : "flag",";\n", arg->name, "$is_set = yes;\n" "}\n"); break; @@ -3304,6 +3304,9 @@ CORD compile_cli_arg_call(env_t *env, CORD fn_name, type_t *fn_type) "if (i < argc) {"); if (t->tag == TextType) { code = CORD_all(code, "$", arg->name, " = Text$from_str(argv[i]);\n"); + if (streq(Match(t, TextType)->lang, "Path")) + code = CORD_all(code, "$", arg->name, " = Path$cleanup($", arg->name, ");\n"); + } else if (t->tag == EnumType) { env_t *enum_env = Match(t, EnumType)->env; for (tag_t *tag = Match(t, EnumType)->tags; tag; tag = tag->next) { |
