Allow using absolute path's in foreign import's (#6999)

Document that `-collection` can be used for foreign imports.
Fix absolute path detection on Windows.
This commit is contained in:
callframe
2026-07-10 20:45:59 +02:00
committed by GitHub
parent a6ba977a38
commit cb7d7a5b7d
3 changed files with 42 additions and 11 deletions

View File

@@ -6054,6 +6054,19 @@ gb_internal bool is_import_path_valid(String const &path) {
return false;
}
gb_internal bool is_import_path_absolute(String const &path) {
if (path.len > 0 && path[0] == '/') {
return true;
}
if (path.len > 2 &&
gb_char_is_alpha(path[0]) &&
path[1] == ':' &&
(path[2] == '/' || path[2] == '\\')) {
return true;
}
return false;
}
gb_internal bool is_build_flag_path_valid(String const &path) {
if (path.len > 0) {
u8 *start = path.text;
@@ -6116,12 +6129,13 @@ gb_internal bool determine_path_from_string(BlockingMutex *file_mutex, Ast *node
do_warning = &syntax_warning;
if (use_check_errors) {
do_error = &error;
do_error = &warning;
do_warning = &warning;
}
// NOTE(bill): if file_mutex == nullptr, this means that the code is used within the semantics stage
String collection_name = {};
bool is_import_decl_path = node->kind == Ast_ImportDecl || node->kind == Ast_ForeignImportDecl;
isize colon_pos = -1;
for (isize j = 0; j < original_string.len; j++) {
@@ -6134,11 +6148,13 @@ gb_internal bool determine_path_from_string(BlockingMutex *file_mutex, Ast *node
bool has_windows_drive = false;
#if defined(GB_SYSTEM_WINDOWS)
if (file_mutex == nullptr) {
if (colon_pos == 1 && original_string.len > 2) {
if (original_string[2] == '/' || original_string[2] == '\\') {
colon_pos = -1;
has_windows_drive = true;
}
if (!is_import_decl_path &&
colon_pos == 1 &&
original_string.len > 2 &&
gb_char_is_alpha(original_string[0]) &&
(original_string[2] == '/' || original_string[2] == '\\')) {
colon_pos = -1;
has_windows_drive = true;
}
for (isize i = 0; i < original_string.len; i++) {
@@ -6162,6 +6178,10 @@ gb_internal bool determine_path_from_string(BlockingMutex *file_mutex, Ast *node
file_str = original_string;
}
if (is_import_decl_path && is_import_path_absolute(file_str)) {
do_error(node, "Invalid import path: '%.*s'", LIT(file_str));
return false;
}
if (has_windows_drive) {
String sub_file_path = substring(file_str, 3, file_str.len);
@@ -6234,8 +6254,7 @@ gb_internal bool determine_path_from_string(BlockingMutex *file_mutex, Ast *node
if (has_windows_drive) {
*path = file_str;
} else {
bool ok = false;
String fullpath = string_trim_whitespace(get_fullpath_relative(permanent_allocator(), base_dir, file_str, &ok));
String fullpath = string_trim_whitespace(get_fullpath_relative(permanent_allocator(), base_dir, file_str, nullptr));
*path = fullpath;
}
return true;
@@ -6287,6 +6306,12 @@ gb_internal void parse_setup_file_decls(Parser *p, AstFile *f, String const &bas
ast_node(id, ImportDecl, node);
String original_string = string_trim_whitespace(string_value_from_token(f, id->relpath));
if (is_import_path_absolute(original_string)) {
syntax_error(node, "Invalid import path: '%.*s'", LIT(original_string));
decls[i] = ast_bad_decl(f, id->relpath, id->relpath);
continue;
}
String import_path = {};
bool ok = determine_path_from_string(&p->file_decl_mutex, node, base_dir, original_string, &import_path);
if (!ok) {
@@ -6313,6 +6338,12 @@ gb_internal void parse_setup_file_decls(Parser *p, AstFile *f, String const &bas
GB_ASSERT(fp->kind == Ast_BasicLit);
Token fp_token = fp->BasicLit.token;
String file_str = string_trim_whitespace(string_value_from_token(f, fp_token));
if (is_import_path_absolute(file_str)) {
syntax_error(node, "Invalid import path: '%.*s'", LIT(file_str));
decls[i] = ast_bad_decl(f, fp_token, fp_token);
goto end;
}
String fullpath = file_str;
if (!is_arch_wasm() || string_ends_with(fullpath, str_lit(".o"))) {
String foreign_path = {};
@@ -7100,4 +7131,3 @@ gb_internal ParseFileError parse_packages(Parser *p, String init_filename) {
return ParseFile_None;
}