aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBruce Hill <bruce@bruce-hill.com>2025-03-30 15:20:53 -0400
committerBruce Hill <bruce@bruce-hill.com>2025-03-30 15:20:53 -0400
commit50bc9f42d5658818347b50f452445f5bcdb7c75d (patch)
treeea9291e4c91681d0434d60e0fda282605067bdb8
parent67f088689019bfc3c731f8157e50c560fabddb04 (diff)
Fix some relative path stuff
-rw-r--r--src/compile.c12
-rw-r--r--src/parse.c9
-rw-r--r--src/stdlib/paths.c7
-rw-r--r--src/stdlib/paths.h1
-rw-r--r--src/tomo.c31
-rw-r--r--src/typecheck.c26
6 files changed, 53 insertions, 33 deletions
diff --git a/src/compile.c b/src/compile.c
index abccc599..18a1e9a1 100644
--- a/src/compile.c
+++ b/src/compile.c
@@ -4398,17 +4398,13 @@ CORD compile_statement_type_header(env_t *env, Path_t header_path, ast_t *ast)
auto use = Match(ast, Use);
Path_t source_path = Path$from_str(ast->file->filename);
Path_t source_dir = Path$parent(source_path);
- char cwd[PATH_MAX];
- getcwd(cwd, sizeof(cwd));
- Path_t build_dir = Path$resolved(Path$parent(header_path), Path(cwd));
+ Path_t build_dir = Path$resolved(Path$parent(header_path), Path$current_dir());
switch (use->what) {
case USE_MODULE: {
return CORD_all("#include <", use->path, "/", use->path, ".h>\n");
}
case USE_LOCAL: {
- Path_t used_path = Path$from_str(use->path);
- if (used_path.type.$tag == PATH_RELATIVE)
- used_path = Path$concat(source_dir, used_path);
+ Path_t used_path = Path$resolved(Path$from_str(use->path), source_dir);
Path_t used_build_dir = Path$with_component(Path$parent(used_path), Text(".build"));
Path_t used_header_path = Path$with_component(used_build_dir, Texts(Path$base_name(used_path), Text(".h")));
return CORD_all("#include \"", Path$as_c_string(Path$relative_to(used_header_path, build_dir)), "\"\n");
@@ -4417,9 +4413,7 @@ CORD compile_statement_type_header(env_t *env, Path_t header_path, ast_t *ast)
if (use->path[0] == '<') {
return CORD_all("#include ", use->path, "\n");
} else {
- Path_t used_path = Path$from_str(use->path);
- if (used_path.type.$tag == PATH_RELATIVE)
- used_path = Path$concat(source_dir, used_path);
+ Path_t used_path = Path$resolved(Path$from_str(use->path), source_dir);
return CORD_all("#include \"", Path$as_c_string(Path$relative_to(used_path, build_dir)), "\"\n");
}
default:
diff --git a/src/parse.c b/src/parse.c
index ff46fd03..0eba5d2a 100644
--- a/src/parse.c
+++ b/src/parse.c
@@ -23,6 +23,7 @@
#include "cordhelpers.h"
#include "stdlib/integers.h"
#include "stdlib/patterns.h"
+#include "stdlib/paths.h"
#include "stdlib/print.h"
#include "stdlib/stdlib.h"
#include "stdlib/tables.h"
@@ -2515,12 +2516,8 @@ PARSER(parse_use) {
}
ast_t *parse_file(const char *path, jmp_buf *on_err) {
- if (path[0] != '<') {
- const char *resolved = resolve_path(path, ".", ".");
- if (!resolved)
- print_err("Could not resolve path: ", path);
- path = resolved;
- }
+ if (path[0] != '<' && path[0] != '/')
+ fail("Path is not fully resolved: ", path);
// NOTE: this cache leaks a bounded amount of memory. The cache will never
// hold more than PARSE_CACHE_SIZE entries (see below), but each entry's
// AST holds onto a reference to the file it came from, so they could
diff --git a/src/stdlib/paths.c b/src/stdlib/paths.c
index 7f881c00..c7b560b9 100644
--- a/src/stdlib/paths.c
+++ b/src/stdlib/paths.c
@@ -710,6 +710,13 @@ public Array_t Path$glob(Path_t path)
return glob_files;
}
+public Path_t Path$current_dir(void)
+{
+ char cwd[PATH_MAX];
+ getcwd(cwd, sizeof(cwd));
+ return Path$from_str(cwd);
+}
+
public PUREFUNC uint64_t Path$hash(const void *obj, const TypeInfo_t *type)
{
(void)type;
diff --git a/src/stdlib/paths.h b/src/stdlib/paths.h
index 8bdbb2f3..02afc494 100644
--- a/src/stdlib/paths.h
+++ b/src/stdlib/paths.h
@@ -53,6 +53,7 @@ Text_t Path$base_name(Path_t path);
Text_t Path$extension(Path_t path, bool full);
Path_t Path$with_component(Path_t path, Text_t component);
Path_t Path$with_extension(Path_t path, Text_t extension, bool replace);
+Path_t Path$current_dir(void);
Closure_t Path$by_line(Path_t path);
Array_t Path$glob(Path_t path);
diff --git a/src/tomo.c b/src/tomo.c
index 3a73707e..9e0038d7 100644
--- a/src/tomo.c
+++ b/src/tomo.c
@@ -213,11 +213,16 @@ int main(int argc, char *argv[])
return 0;
}
- // Convert `foo` to `foo/foo.tm`
+ // Convert `foo` to `foo/foo.tm` and resolve all paths to absolute paths:
+ Path_t cur_dir = Path$current_dir();
for (int64_t i = 0; i < files.length; i++) {
Path_t *path = (Path_t*)(files.data + i*files.stride);
if (Path$is_directory(*path, true))
*path = Path$with_component(*path, Texts(Path$base_name(*path), Text(".tm")));
+
+ *path = Path$resolved(*path, cur_dir);
+ if (!Path$exists(*path))
+ fail("File not found: ", *path);
}
if (files.length < 1)
@@ -370,7 +375,7 @@ static void _compile_file_header_for_library(env_t *env, Path_t header_path, Pat
auto use = Match(ast, Use);
if (use->what == USE_LOCAL) {
- Path_t resolved = Path$resolved(Path$from_str(use->path), Path("./"));
+ Path_t resolved = Path$resolved(Path$from_str(use->path), Path$parent(path));
_compile_file_header_for_library(env, header_path, resolved, visited_files, used_imports, output);
}
}
@@ -389,6 +394,16 @@ void build_library(Text_t lib_dir_name)
env_t *env = fresh_scope(global_env());
Array_t object_files = {},
extra_ldlibs = {};
+
+ // Resolve all files to absolute paths:
+ Path_t cur_dir = Path$current_dir();
+ for (int64_t i = 0; i < tm_files.length; i++) {
+ Path_t *path = (Path_t*)(tm_files.data + i*tm_files.stride);
+ *path = Path$resolved(*path, cur_dir);
+ if (!Path$exists(*path))
+ fail("File not found: ", *path);
+ }
+
compile_files(env, tm_files, &object_files, &extra_ldlibs);
// Library name replaces all stretchs of non-alphanumeric chars with an underscore
@@ -404,8 +419,7 @@ void build_library(Text_t lib_dir_name)
Table_t used_imports = {};
for (int64_t i = 0; i < tm_files.length; i++) {
Path_t f = *(Path_t*)(tm_files.data + i*tm_files.stride);
- Path_t resolved = Path$resolved(f, Path("."));
- _compile_file_header_for_library(env, header_path, resolved, &visited_files, &used_imports, header);
+ _compile_file_header_for_library(env, header_path, f, &visited_files, &used_imports, header);
}
if (fclose(header) == -1)
print_err("Failed to write header file: ", lib_dir_name, ".h");
@@ -446,7 +460,7 @@ void build_library(Text_t lib_dir_name)
errx(WEXITSTATUS(status), "Failed to run `patchelf` to rename dynamic symbols with library prefix");
if (verbose)
- CORD_printf("Successfully renamed symbols with library prefix!\n");
+ print("Successfully renamed symbols with library prefix!");
if (should_install) {
char library_directory[PATH_MAX];
@@ -473,10 +487,9 @@ void compile_files(env_t *env, Array_t to_compile, Array_t *object_files, Array_
Text_t extension = Path$extension(filename, true);
if (!Text$equal_values(extension, Text("tm")))
print_err("Not a valid .tm file: \x1b[31;1m", filename, "\x1b[m");
- Path_t resolved = Path$resolved(filename, Path("./"));
- if (!Path$is_file(resolved, true))
- print_err("Couldn't find file: ", resolved);
- build_file_dependency_graph(resolved, &dependency_files, &to_link);
+ if (!Path$is_file(filename, true))
+ print_err("Couldn't find file: ", filename);
+ build_file_dependency_graph(filename, &dependency_files, &to_link);
}
int status;
diff --git a/src/typecheck.c b/src/typecheck.c
index 861431e0..ba03e968 100644
--- a/src/typecheck.c
+++ b/src/typecheck.c
@@ -13,6 +13,7 @@
#include "environment.h"
#include "parse.h"
#include "stdlib/patterns.h"
+#include "stdlib/paths.h"
#include "stdlib/tables.h"
#include "stdlib/text.h"
#include "stdlib/util.h"
@@ -179,16 +180,19 @@ static env_t *load_module(env_t *env, ast_t *module_ast)
auto use = Match(module_ast, Use);
switch (use->what) {
case USE_LOCAL: {
- const char *resolved_path = resolve_path(use->path, module_ast->file->filename, module_ast->file->filename);
- env_t *module_env = Table$str_get(*env->imports, resolved_path);
- if (module_env)
- return module_env;
+ Path_t source_path = Path$from_str(module_ast->file->filename);
+ Path_t source_dir = Path$parent(source_path);
+ Path_t used_path = Path$resolved(Path$from_str(use->path), source_dir);
- if (!resolved_path)
+ if (!Path$exists(used_path))
code_err(module_ast, "No such file exists: ", quoted(use->path));
- ast_t *ast = parse_file(resolved_path, NULL);
- if (!ast) print_err("Could not compile file ", resolved_path);
+ env_t *module_env = Table$str_get(*env->imports, String(used_path));
+ if (module_env)
+ return module_env;
+
+ ast_t *ast = parse_file(String(used_path), NULL);
+ if (!ast) print_err("Could not compile file ", used_path);
return load_module_env(env, ast);
}
case USE_MODULE: {
@@ -972,8 +976,12 @@ type_t *get_type(env_t *env, ast_t *ast)
}
case Use: {
switch (Match(ast, Use)->what) {
- case USE_LOCAL:
- return Type(ModuleType, resolve_path(Match(ast, Use)->path, ast->file->filename, ast->file->filename));
+ case USE_LOCAL: {
+ Path_t source_path = Path$from_str(ast->file->filename);
+ Path_t source_dir = Path$parent(source_path);
+ Path_t used_path = Path$resolved(Path$from_str(Match(ast, Use)->path), source_dir);
+ return Type(ModuleType, Path$as_c_string(used_path));
+ }
default:
return Type(ModuleType, Match(ast, Use)->path);
}