mirror of
https://github.com/Ed94/Odin.git
synced 2026-06-13 01:21:38 -07:00
Library collections
This commit is contained in:
@@ -43,7 +43,7 @@ del *.ilk > NUL 2> NUL
|
||||
|
||||
cl %compiler_settings% "src\main.cpp" ^
|
||||
/link %linker_settings% -OUT:%exe_name% ^
|
||||
&& odin run examples/demo.odin -opt=0
|
||||
&& odin run examples/demo.odin -opt=0 -collection=foo=W:\Odin\core
|
||||
rem && odin docs core/fmt.odin
|
||||
|
||||
del *.obj > NUL 2> NUL
|
||||
|
||||
+4
-6
@@ -1,9 +1,9 @@
|
||||
#shared_global_scope;
|
||||
|
||||
import "os.odin";
|
||||
import "fmt.odin"; // TODO(bill): Remove the need for `fmt` here
|
||||
import "utf8.odin";
|
||||
import "raw.odin";
|
||||
import "core:os.odin";
|
||||
import "core:fmt.odin"; // TODO(bill): Remove the need for `fmt` here
|
||||
import "core:utf8.odin";
|
||||
import "core:raw.odin";
|
||||
|
||||
// Naming Conventions:
|
||||
// In general, Ada_Case for types and snake_case for values
|
||||
@@ -621,8 +621,6 @@ panic :: proc(message := "", using location := #caller_location) #cc_contextless
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
__string_eq :: proc(a, b: string) -> bool #cc_contextless {
|
||||
match {
|
||||
case len(a) != len(b): return false;
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
// TODO(bill): Use assembly instead here to implement atomics
|
||||
// Inline vs external file?
|
||||
|
||||
import win32 "sys/windows.odin" when ODIN_OS == "windows";
|
||||
import win32 "core:sys/windows.odin" when ODIN_OS == "windows";
|
||||
_ :: compile_assert(ODIN_ARCH == "amd64"); // TODO(bill): x86 version
|
||||
|
||||
|
||||
|
||||
+6
-6
@@ -1,9 +1,9 @@
|
||||
import "os.odin";
|
||||
import "mem.odin";
|
||||
import "utf8.odin";
|
||||
import "types.odin";
|
||||
import "strconv.odin";
|
||||
import "raw.odin";
|
||||
import "core:os.odin";
|
||||
import "core:mem.odin";
|
||||
import "core:utf8.odin";
|
||||
import "core:types.odin";
|
||||
import "core:strconv.odin";
|
||||
import "core:raw.odin";
|
||||
|
||||
|
||||
_BUFFER_SIZE :: 1<<12;
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
import "mem.odin";
|
||||
import "core:mem.odin";
|
||||
|
||||
adler32 :: proc(data: []u8) -> u32 {
|
||||
ADLER_CONST :: 65521;
|
||||
|
||||
+3
-3
@@ -1,6 +1,6 @@
|
||||
import "fmt.odin";
|
||||
import "os.odin";
|
||||
import "raw.odin";
|
||||
import "core:fmt.odin";
|
||||
import "core:os.odin";
|
||||
import "core:raw.odin";
|
||||
|
||||
foreign __llvm_core {
|
||||
swap :: proc(b: u16) -> u16 #link_name "llvm.bswap.i16" ---;
|
||||
|
||||
+3
-3
@@ -1,9 +1,9 @@
|
||||
foreign_system_library lib "opengl32.lib" when ODIN_OS == "windows";
|
||||
foreign_system_library lib "gl" when ODIN_OS == "linux";
|
||||
|
||||
import win32 "sys/windows.odin" when ODIN_OS == "windows";
|
||||
import "sys/wgl.odin" when ODIN_OS == "windows";
|
||||
export "opengl_constants.odin";
|
||||
import win32 "core:sys/windows.odin" when ODIN_OS == "windows";
|
||||
import "core:sys/wgl.odin" when ODIN_OS == "windows";
|
||||
export "core:opengl_constants.odin";
|
||||
|
||||
_ := compile_assert(ODIN_OS != "osx");
|
||||
|
||||
|
||||
+3
-3
@@ -1,6 +1,6 @@
|
||||
export "os_windows.odin" when ODIN_OS == "windows";
|
||||
export "os_x.odin" when ODIN_OS == "osx";
|
||||
export "os_linux.odin" when ODIN_OS == "linux";
|
||||
export "core:os_windows.odin" when ODIN_OS == "windows";
|
||||
export "core:os_x.odin" when ODIN_OS == "osx";
|
||||
export "core:os_linux.odin" when ODIN_OS == "linux";
|
||||
|
||||
write_string :: proc(fd: Handle, str: string) -> (int, Errno) {
|
||||
return write(fd, cast([]u8)str);
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
foreign_system_library dl "dl";
|
||||
foreign_system_library libc "c";
|
||||
|
||||
import "strings.odin";
|
||||
import "core:strings.odin";
|
||||
|
||||
Handle :: i32;
|
||||
File_Time :: u64;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import win32 "sys/windows.odin";
|
||||
import "mem.odin";
|
||||
import win32 "core:sys/windows.odin";
|
||||
import "core:mem.odin";
|
||||
|
||||
Handle :: int;
|
||||
File_Time :: u64;
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
foreign_system_library dl "dl";
|
||||
foreign_system_library libc "c";
|
||||
|
||||
import "strings.odin";
|
||||
import "core:strings.odin";
|
||||
|
||||
Handle :: i32;
|
||||
File_Time :: u64;
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
using import "decimal.odin";
|
||||
using import "core:decimal.odin";
|
||||
|
||||
Int_Flag :: enum {
|
||||
Prefix = 1<<0,
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
import "mem.odin";
|
||||
import "core:mem.odin";
|
||||
|
||||
new_string :: proc(s: string) -> string {
|
||||
c := make([]u8, len(s)+1);
|
||||
|
||||
+2
-2
@@ -1,2 +1,2 @@
|
||||
export "sync_windows.odin" when ODIN_OS == "windows";
|
||||
export "sync_linux.odin" when ODIN_OS == "linux";
|
||||
export "core:sync_windows.odin" when ODIN_OS == "windows";
|
||||
export "core:sync_linux.odin" when ODIN_OS == "linux";
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import "atomics.odin";
|
||||
import "os.odin";
|
||||
import "core:atomics.odin";
|
||||
import "core:os.odin";
|
||||
|
||||
Semaphore :: struct {
|
||||
// _handle: win32.Handle;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import win32 "sys/windows.odin" when ODIN_OS == "windows";
|
||||
import "atomics.odin";
|
||||
import win32 "core:sys/windows.odin" when ODIN_OS == "windows";
|
||||
import "core:atomics.odin";
|
||||
|
||||
Semaphore :: struct {
|
||||
_handle: win32.Handle;
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
foreign_system_library "opengl32.lib" when ODIN_OS == "windows";
|
||||
using import "windows.odin";
|
||||
using import "core:sys/windows.odin";
|
||||
|
||||
|
||||
CONTEXT_MAJOR_VERSION_ARB :: 0x2091;
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
_ :: compile_assert(ODIN_OS == "windows");
|
||||
|
||||
import win32 "sys/windows.odin";
|
||||
import win32 "core:sys/windows.odin";
|
||||
|
||||
Thread :: struct {
|
||||
using specific: Os_Specific;
|
||||
|
||||
+18
-18
@@ -1,21 +1,21 @@
|
||||
import "fmt.odin";
|
||||
import "strconv.odin";
|
||||
import "mem.odin";
|
||||
import "thread.odin" when ODIN_OS == "windows";
|
||||
import win32 "sys/windows.odin" when ODIN_OS == "windows";
|
||||
import "atomics.odin";
|
||||
import "bits.odin";
|
||||
import "hash.odin";
|
||||
import "math.odin";
|
||||
import "opengl.odin";
|
||||
import "os.odin";
|
||||
import "raw.odin";
|
||||
import "sort.odin";
|
||||
import "strings.odin";
|
||||
import "sync.odin";
|
||||
import "types.odin";
|
||||
import "utf8.odin";
|
||||
import "utf16.odin";
|
||||
import "core:fmt.odin";
|
||||
import "core:strconv.odin";
|
||||
import "core:mem.odin";
|
||||
import "core:thread.odin" when ODIN_OS == "windows";
|
||||
import win32 "core:sys/windows.odin" when ODIN_OS == "windows";
|
||||
import "core:atomics.odin";
|
||||
import "core:bits.odin";
|
||||
import "core:hash.odin";
|
||||
import "core:math.odin";
|
||||
import "core:opengl.odin";
|
||||
import "core:os.odin";
|
||||
import "core:raw.odin";
|
||||
import "core:sort.odin";
|
||||
import "core:strings.odin";
|
||||
import "core:sync.odin";
|
||||
import "core:types.odin";
|
||||
import "core:utf8.odin";
|
||||
import "core:utf16.odin";
|
||||
|
||||
general_stuff :: proc() {
|
||||
{ // `do` for inline statmes rather than block
|
||||
|
||||
+43
-21
@@ -29,7 +29,28 @@ struct BuildContext {
|
||||
gb_global BuildContext build_context = {0};
|
||||
|
||||
|
||||
struct LibraryCollections {
|
||||
String name;
|
||||
String path;
|
||||
};
|
||||
|
||||
gb_global Array<LibraryCollections> library_collections = {0};
|
||||
|
||||
void add_library_collection(String name, String path) {
|
||||
// TODO(bill): Check the path is valid and a directory
|
||||
LibraryCollections lc = {name, string_trim_whitespace(path)};
|
||||
array_add(&library_collections, lc);
|
||||
}
|
||||
|
||||
bool find_library_collection_path(String name, String *path) {
|
||||
for_array(i, library_collections) {
|
||||
if (library_collections[i].name == name) {
|
||||
if (path) *path = library_collections[i].path;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// TODO(bill): OS dependent versions for the BuildContext
|
||||
@@ -248,38 +269,39 @@ String path_to_fullpath(gbAllocator a, String s) {
|
||||
|
||||
|
||||
String get_fullpath_relative(gbAllocator a, String base_dir, String path) {
|
||||
String res = {0};
|
||||
isize str_len = base_dir.len+path.len;
|
||||
|
||||
u8 *str = gb_alloc_array(heap_allocator(), u8, str_len+1);
|
||||
u8 *str = gb_alloc_array(heap_allocator(), u8, base_dir.len+1+path.len+1);
|
||||
defer (gb_free(heap_allocator(), str));
|
||||
|
||||
isize i = 0;
|
||||
gb_memmove(str+i, &base_dir[0], base_dir.len); i += base_dir.len;
|
||||
gb_memmove(str+i, &path[0], path.len);
|
||||
str[str_len] = '\0';
|
||||
res = path_to_fullpath(a, make_string(str, str_len));
|
||||
gb_free(heap_allocator(), str);
|
||||
return res;
|
||||
gb_memmove(str+i, base_dir.text, base_dir.len); i += base_dir.len;
|
||||
gb_memmove(str+i, "/", 1); i += 1;
|
||||
gb_memmove(str+i, path.text, path.len); i += path.len;
|
||||
str[i] = 0;
|
||||
|
||||
String res = make_string(str, i);
|
||||
res = string_trim_whitespace(res);
|
||||
return path_to_fullpath(a, res);
|
||||
}
|
||||
|
||||
|
||||
String get_fullpath_core(gbAllocator a, String path) {
|
||||
String module_dir = odin_root_dir();
|
||||
String res = {0};
|
||||
|
||||
char core[] = "core/";
|
||||
isize core_len = gb_size_of(core)-1;
|
||||
String core = str_lit("core/");
|
||||
|
||||
isize str_len = module_dir.len + core_len + path.len;
|
||||
isize str_len = module_dir.len + core.len + path.len;
|
||||
u8 *str = gb_alloc_array(heap_allocator(), u8, str_len+1);
|
||||
defer (gb_free(heap_allocator(), str));
|
||||
|
||||
gb_memmove(str, &module_dir[0], module_dir.len);
|
||||
gb_memmove(str+module_dir.len, core, core_len);
|
||||
gb_memmove(str+module_dir.len+core_len, &path[0], path.len);
|
||||
str[str_len] = '\0';
|
||||
isize i = 0;
|
||||
gb_memmove(str+i, module_dir.text, module_dir.len); i += module_dir.len;
|
||||
gb_memmove(str+i, core.text, core.len); i += core.len;
|
||||
gb_memmove(str+i, path.text, path.len); i += path.len;
|
||||
str[i] = 0;
|
||||
|
||||
res = path_to_fullpath(a, make_string(str, str_len));
|
||||
gb_free(heap_allocator(), str);
|
||||
return res;
|
||||
String res = make_string(str, i);
|
||||
res = string_trim_whitespace(res);
|
||||
return path_to_fullpath(a, res);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -463,3 +463,31 @@ wchar_t **command_line_to_wargv(wchar_t *cmd_line, int *_argc) {
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(GB_SYSTEM_WINDOWS)
|
||||
bool path_is_directory(String path) {
|
||||
gbAllocator a = heap_allocator();
|
||||
String16 wstr = string_to_string16(a, path);
|
||||
defer (gb_free(a, wstr.text));
|
||||
|
||||
i32 attribs = GetFileAttributesW(wstr.text);
|
||||
if (attribs < 0) return false;
|
||||
|
||||
return (attribs & FILE_ATTRIBUTE_DIRECTORY) != 0;
|
||||
}
|
||||
|
||||
#else
|
||||
bool path_is_directory(String path) {
|
||||
gbAllocator a = heap_allocator();
|
||||
String copy = copy_string(a, path);
|
||||
defer (gb_free(a, copy.text));
|
||||
|
||||
struct stat s;
|
||||
if (stat(copy.text, &s) == 0) {
|
||||
return (s.st_mode & S_IFDIR) != 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -177,6 +177,7 @@ enum BuildFlagKind {
|
||||
BuildFlag_ShowTimings,
|
||||
BuildFlag_ThreadCount,
|
||||
BuildFlag_KeepTempFiles,
|
||||
BuildFlag_Collection,
|
||||
|
||||
BuildFlag_COUNT,
|
||||
};
|
||||
@@ -204,6 +205,36 @@ void add_flag(Array<BuildFlag> *build_flags, BuildFlagKind kind, String name, Bu
|
||||
array_add(build_flags, flag);
|
||||
}
|
||||
|
||||
bool string_is_valid_identifier(String str) {
|
||||
if (str.len <= 0) return false;
|
||||
|
||||
isize rune_count = 0;
|
||||
|
||||
isize w = 0;
|
||||
isize offset = 0;
|
||||
while (offset < str.len) {
|
||||
Rune r = 0;
|
||||
w = gb_utf8_decode(str.text, str.len, &r);
|
||||
if (r == GB_RUNE_INVALID) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (rune_count == 0) {
|
||||
if (!rune_is_letter(r)) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (!rune_is_letter(r) && !rune_is_digit(r)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
rune_count += 1;
|
||||
offset += w;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool parse_build_flags(Array<String> args) {
|
||||
Array<BuildFlag> build_flags = {};
|
||||
array_init(&build_flags, heap_allocator(), BuildFlag_COUNT);
|
||||
@@ -211,6 +242,7 @@ bool parse_build_flags(Array<String> args) {
|
||||
add_flag(&build_flags, BuildFlag_ShowTimings, str_lit("show-timings"), BuildFlagParam_None);
|
||||
add_flag(&build_flags, BuildFlag_ThreadCount, str_lit("thread-count"), BuildFlagParam_Integer);
|
||||
add_flag(&build_flags, BuildFlag_KeepTempFiles, str_lit("keep-temp-files"), BuildFlagParam_None);
|
||||
add_flag(&build_flags, BuildFlag_Collection, str_lit("collection"), BuildFlagParam_String);
|
||||
|
||||
|
||||
Array<String> flag_args = args;
|
||||
@@ -358,6 +390,68 @@ bool parse_build_flags(Array<String> args) {
|
||||
GB_ASSERT(value.kind == ExactValue_Invalid);
|
||||
build_context.keep_temp_files = true;
|
||||
break;
|
||||
|
||||
case BuildFlag_Collection: {
|
||||
GB_ASSERT(value.kind == ExactValue_String);
|
||||
String str = value.value_string;
|
||||
isize eq_pos = -1;
|
||||
for (isize i = 0; i < str.len; i++) {
|
||||
if (str[i] == '=') {
|
||||
eq_pos = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (eq_pos < 0) {
|
||||
gb_printf_err("Expected `name=path`, got `%.*s`\n", LIT(param));
|
||||
ok = false;
|
||||
bad_flags = true;
|
||||
break;
|
||||
}
|
||||
String name = substring(str, 0, eq_pos);
|
||||
String path = substring(str, eq_pos+1, str.len);
|
||||
if (name.len == 0 || path.len == 0) {
|
||||
gb_printf_err("Expected `name=path`, got `%.*s`\n", LIT(param));
|
||||
ok = false;
|
||||
bad_flags = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!string_is_valid_identifier(name)) {
|
||||
gb_printf_err("Library collection name `%.*s` must be a valid identifier\n", LIT(name));
|
||||
ok = false;
|
||||
bad_flags = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (name == "_") {
|
||||
gb_printf_err("Library collection name cannot be an underscore\n");
|
||||
ok = false;
|
||||
bad_flags = true;
|
||||
break;
|
||||
}
|
||||
|
||||
String prev_path = {};
|
||||
bool found = find_library_collection_path(name, &prev_path);
|
||||
if (found) {
|
||||
gb_printf_err("Library collection `%.*s` already exists with path `%.*s`\n", LIT(name), LIT(prev_path));
|
||||
ok = false;
|
||||
bad_flags = true;
|
||||
break;
|
||||
}
|
||||
|
||||
gbAllocator a = heap_allocator();
|
||||
String fullpath = path_to_fullpath(a, path);
|
||||
if (!path_is_directory(fullpath)) {
|
||||
gb_printf_err("Library collection `%.*s` path must be a directory, got `%.*s`\n", LIT(name), LIT(fullpath));
|
||||
gb_free(a, fullpath.text);
|
||||
ok = false;
|
||||
bad_flags = true;
|
||||
break;
|
||||
}
|
||||
|
||||
add_library_collection(name, path);
|
||||
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -449,6 +543,10 @@ int main(int arg_count, char **arg_ptr) {
|
||||
init_scratch_memory(gb_megabytes(10));
|
||||
init_global_error_collector();
|
||||
|
||||
array_init(&library_collections, heap_allocator());
|
||||
add_library_collection(str_lit("core"), get_fullpath_relative(heap_allocator(), odin_root_dir(), str_lit("core")));
|
||||
add_library_collection(str_lit("shared"), get_fullpath_relative(heap_allocator(), odin_root_dir(), str_lit("shared")));
|
||||
|
||||
Array<String> args = setup_args(arg_count, arg_ptr);
|
||||
|
||||
#if 1
|
||||
|
||||
+61
-48
@@ -4796,6 +4796,54 @@ bool is_import_path_valid(String path) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool determine_path_from_string(Parser *p, AstNode *node, String base_dir, String original_string, String *path) {
|
||||
GB_ASSERT(path != nullptr);
|
||||
|
||||
gbAllocator a = heap_allocator();
|
||||
String collection_name = {};
|
||||
|
||||
isize colon_pos = -1;
|
||||
for (isize j = 0; j < original_string.len; j++) {
|
||||
if (original_string[j] == ':') {
|
||||
colon_pos = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
String file_str = {};
|
||||
if (colon_pos == 0) {
|
||||
syntax_error(node, "Expected a collection name");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (original_string.len > 0 && colon_pos > 0) {
|
||||
collection_name = substring(original_string, 0, colon_pos);
|
||||
file_str = substring(original_string, colon_pos+1, original_string.len);
|
||||
} else {
|
||||
file_str = original_string;
|
||||
}
|
||||
|
||||
if (!is_import_path_valid(file_str)) {
|
||||
syntax_error(node, "Invalid import path: `%.*s`", LIT(file_str));
|
||||
return false;
|
||||
}
|
||||
|
||||
gb_mutex_lock(&p->file_decl_mutex);
|
||||
defer (gb_mutex_unlock(&p->file_decl_mutex));
|
||||
|
||||
if (collection_name.len > 0) {
|
||||
if (!find_library_collection_path(collection_name, &base_dir)) {
|
||||
// NOTE(bill): It's a naughty name
|
||||
syntax_error(node, "Unknown library colleciton: `%.*s`", LIT(base_dir));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
String fullpath = string_trim_whitespace(get_fullpath_relative(a, base_dir, file_str));
|
||||
*path = fullpath;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void parse_setup_file_decls(Parser *p, AstFile *f, String base_dir, Array<AstNode *> decls) {
|
||||
for_array(i, decls) {
|
||||
AstNode *node = decls[i];
|
||||
@@ -4803,73 +4851,38 @@ void parse_setup_file_decls(Parser *p, AstFile *f, String base_dir, Array<AstNod
|
||||
node->kind != AstNode_BadStmt &&
|
||||
node->kind != AstNode_EmptyStmt) {
|
||||
// NOTE(bill): Sanity check
|
||||
syntax_error(node, "Only declarations are allowed at file scope %.*s", LIT(ast_node_strings[node->kind]));
|
||||
syntax_error(node, "Only declarations are allowed at file scope, got %.*s", LIT(ast_node_strings[node->kind]));
|
||||
} else if (node->kind == AstNode_ImportDecl) {
|
||||
ast_node(id, ImportDecl, node);
|
||||
String collection_name = {};
|
||||
String oirignal_string = id->relpath.string;
|
||||
String file_str = id->relpath.string;
|
||||
gbAllocator a = heap_allocator(); // TODO(bill): Change this allocator
|
||||
String import_file = {};
|
||||
String rel_path = {};
|
||||
|
||||
if (!is_import_path_valid(file_str)) {
|
||||
syntax_error(node, "Invalid import path: `%.*s`", LIT(file_str));
|
||||
// NOTE(bill): It's a naughty name
|
||||
String original_string = id->relpath.string;
|
||||
String import_path = {};
|
||||
bool ok = determine_path_from_string(p, node, base_dir, original_string, &import_path);
|
||||
if (!ok) {
|
||||
decls[i] = ast_bad_decl(f, id->relpath, id->relpath);
|
||||
continue;
|
||||
}
|
||||
|
||||
gb_mutex_lock(&p->file_decl_mutex);
|
||||
defer (gb_mutex_unlock(&p->file_decl_mutex));
|
||||
|
||||
rel_path = get_fullpath_relative(a, base_dir, file_str);
|
||||
import_file = rel_path;
|
||||
if (!gb_file_exists(cast(char *)rel_path.text)) { // NOTE(bill): This should be null terminated
|
||||
String abs_path = get_fullpath_core(a, file_str);
|
||||
if (gb_file_exists(cast(char *)abs_path.text)) {
|
||||
import_file = abs_path;
|
||||
}
|
||||
}
|
||||
|
||||
import_file = string_trim_whitespace(import_file);
|
||||
|
||||
id->fullpath = import_file;
|
||||
try_add_import_path(p, import_file, file_str, ast_node_token(node).pos);
|
||||
id->fullpath = import_path;
|
||||
try_add_import_path(p, import_path, original_string, ast_node_token(node).pos);
|
||||
} else if (node->kind == AstNode_ExportDecl) {
|
||||
ast_node(ed, ExportDecl, node);
|
||||
String collection_name = {};
|
||||
String oirignal_string = ed->relpath.string;
|
||||
String file_str = ed->relpath.string;
|
||||
gbAllocator a = heap_allocator(); // TODO(bill): Change this allocator
|
||||
String export_path = {};
|
||||
String rel_path = {};
|
||||
|
||||
if (!is_import_path_valid(file_str)) {
|
||||
syntax_error(node, "Invalid export path: `%.*s`", LIT(file_str));
|
||||
// NOTE(bill): It's a naughty name
|
||||
String original_string = ed->relpath.string;
|
||||
String export_path = {};
|
||||
bool ok = determine_path_from_string(p, node, base_dir, original_string, &export_path);
|
||||
if (!ok) {
|
||||
decls[i] = ast_bad_decl(f, ed->relpath, ed->relpath);
|
||||
continue;
|
||||
}
|
||||
|
||||
gb_mutex_lock(&p->file_decl_mutex);
|
||||
defer (gb_mutex_unlock(&p->file_decl_mutex));
|
||||
|
||||
rel_path = get_fullpath_relative(a, base_dir, file_str);
|
||||
export_path = rel_path;
|
||||
if (!gb_file_exists(cast(char *)rel_path.text)) { // NOTE(bill): This should be null terminated
|
||||
String abs_path = get_fullpath_core(a, file_str);
|
||||
if (gb_file_exists(cast(char *)abs_path.text)) {
|
||||
export_path = abs_path;
|
||||
}
|
||||
}
|
||||
|
||||
export_path = string_trim_whitespace(export_path);
|
||||
|
||||
ed->fullpath = export_path;
|
||||
try_add_import_path(p, export_path, file_str, ast_node_token(node).pos);
|
||||
try_add_import_path(p, export_path, original_string, ast_node_token(node).pos);
|
||||
} else if (node->kind == AstNode_ForeignLibraryDecl) {
|
||||
ast_node(fl, ForeignLibraryDecl, node);
|
||||
|
||||
String file_str = fl->filepath.string;
|
||||
if (!is_import_path_valid(file_str)) {
|
||||
syntax_error(node, "Invalid `%.*s` path", LIT(fl->token.string));
|
||||
|
||||
+19
-4
@@ -16,11 +16,11 @@ struct String {
|
||||
isize len;
|
||||
|
||||
u8 &operator[](isize i) {
|
||||
GB_ASSERT(0 <= i && i < len);
|
||||
GB_ASSERT_MSG(0 <= i && i < len, "[%td]", i);
|
||||
return text[i];
|
||||
}
|
||||
u8 const &operator[](isize i) const {
|
||||
GB_ASSERT(0 <= i && i < len);
|
||||
GB_ASSERT_MSG(0 <= i && i < len, "[%td]", i);
|
||||
return text[i];
|
||||
}
|
||||
};
|
||||
@@ -38,11 +38,11 @@ struct String16 {
|
||||
wchar_t *text;
|
||||
isize len;
|
||||
wchar_t &operator[](isize i) {
|
||||
GB_ASSERT(0 <= i && i < len);
|
||||
GB_ASSERT_MSG(0 <= i && i < len, "[%td]", i);
|
||||
return text[i];
|
||||
}
|
||||
wchar_t const &operator[](isize i) const {
|
||||
GB_ASSERT(0 <= i && i < len);
|
||||
GB_ASSERT_MSG(0 <= i && i < len, "[%td]", i);
|
||||
return text[i];
|
||||
}
|
||||
};
|
||||
@@ -284,6 +284,21 @@ String remove_directory_from_path(String s) {
|
||||
}
|
||||
|
||||
|
||||
String concatenate_strings(gbAllocator a, String x, String y) {
|
||||
isize len = x.len+y.len;
|
||||
u8 *data = gb_alloc_array(a, u8, len+1);
|
||||
gb_memmove(data, x.text, x.len);
|
||||
gb_memmove(data+x.len, y.text, y.len);
|
||||
data[len] = 0;
|
||||
return make_string(data, len);
|
||||
}
|
||||
|
||||
String copy_string(gbAllocator a, String s) {
|
||||
u8 *data = gb_alloc_array(a, u8, s.len+1);
|
||||
gb_memmove(data, s.text, s.len);
|
||||
data[s.len] = 0;
|
||||
return make_string(data, s.len);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user