Browse Source

Merge branch 'master' of https://github.com/odin-lang/Odin

gingerBill 7 years ago
parent
commit
5660f98cc3
4 changed files with 171 additions and 63 deletions
  1. 103 44
      core/os/essence.odin
  2. 2 0
      src/build_settings.cpp
  3. 6 5
      src/checker.cpp
  4. 60 14
      src/main.cpp

+ 103 - 44
core/os/essence.odin

@@ -3,10 +3,36 @@ foreign import api "system:api"
 Handle    :: distinct int;
 Errno     :: distinct int;
 
-O_RDONLY   :: 1;
-O_WRONLY   :: 2;
-O_CREATE   :: 4;
-O_TRUNC    :: 4;
+O_RDONLY   :: 0x00001;
+O_WRONLY   :: 0x00002;
+O_RDWR     :: 0x00003;
+O_CREATE   :: 0x00040;
+O_EXCL     :: 0x00080;
+O_TRUNC    :: 0x00200;
+O_APPEND   :: 0x00400;
+
+ERROR_NONE				: Errno : -1 ;
+ERROR_UNKNOWN_OPERATION_FAILURE 	: Errno : -7 ;
+ERROR_PATH_NOT_WITHIN_MOUNTED_VOLUME	: Errno : -14;
+ERROR_PATH_NOT_FOUND			: Errno : -15;
+ERROR_FILE_EXISTS			: Errno : -19;
+ERROR_FILE_NOT_FOUND			: Errno : -20;
+ERROR_DRIVE_ERROR_FILE_DAMAGED		: Errno : -21; 
+ERROR_ACCESS_NOT_WITHIN_FILE_BOUNDS	: Errno : -22; 
+ERROR_ACCESS_DENIED			: Errno : -23;
+ERROR_FILE_IN_EXCLUSIVE_USE		: Errno : -24;
+ERROR_FILE_CANNOT_GET_EXCLUSIVE_USE	: Errno : -25;
+ERROR_INCORRECT_NODE_TYPE		: Errno : -26;
+ERROR_EVENT_NOT_SET			: Errno : -27;
+ERROR_TIMEOUT_REACHED			: Errno : -29;
+ERROR_REQUEST_CLOSED_BEFORE_COMPLETE 	: Errno : -30;
+ERROR_NO_CHARACTER_AT_COORDINATE	: Errno : -31;
+ERROR_FILE_ON_READ_ONLY_VOLUME		: Errno : -32;
+ERROR_USER_CANCELED_IO			: Errno : -33;
+ERROR_DRIVE_CONTROLLER_REPORTED		: Errno : -35;
+ERROR_COULD_NOT_ISSUE_PACKET		: Errno : -36;
+
+ERROR_NOT_IMPLEMENTED			: Errno : 1;
 
 OS_Node_Type :: enum i32 {
 	File      = 0,
@@ -18,22 +44,23 @@ OS_Node_Information :: struct {
 	id:       [16]byte,
 	ntype:    OS_Node_Type,
 	size:     i64,
+
+	// Our additions...
 	position: i64,
 }
 
 foreign api {
-	@(link_name="OSHelloWorld")       os_hello_world       :: proc() ---;
-	@(link_name="OSPrintDirect")      os_print_direct      :: proc(str: cstring, length: int) ---;
-	@(link_name="OSHeapAllocate")     os_heap_allocate     :: proc(bytes: int, zero: bool) -> rawptr ---;
-	@(link_name="OSHeapFree")         os_heap_free         :: proc(address: rawptr) ---;
-	@(link_name="OSOpenNode")         os_open_node         :: proc(path: cstring, path_length: int, flags: u64, information: ^OS_Node_Information) -> Errno ---;
-	@(link_name="OSResizeFile")       os_resize_file       :: proc(handle: Handle, new_size: u64) -> Errno ---;
-	@(link_name="OSCloseHandle")      os_close_handle      :: proc(handle: Handle) ---;
-	@(link_name="OSWriteFileSync")    os_write_file_sync   :: proc(handle: Handle, offset: i64, size: i64, buffer: rawptr) -> i64 ---;
-	@(link_name="OSReadFileSync")     os_read_file_sync    :: proc(handle: Handle, offset: i64, size: i64, buffer: rawptr) -> i64 ---;
-	@(link_name="OSInitialiseAPI")    os_initialise_api    :: proc() -> int ---;
-	@(link_name="OSTerminateProcess") os_terminate_process :: proc(handle: Handle) ---;
-	@(link_name="realloc")            os_heap_reallocate   :: proc(address: rawptr, size: int) -> rawptr ---;
+	@(link_name="OSPrintDirect")    OSPrintDirect      	:: proc(str: ^u8, length: int) ---;
+	@(link_name="malloc")     	OSMalloc     		:: proc(bytes: int) -> rawptr ---;
+	@(link_name="free")         	OSFree         		:: proc(address: rawptr) ---;
+	@(link_name="OSOpenNode")       OSOpenNode         	:: proc(path: ^u8, path_length: int, flags: u64, information: ^OS_Node_Information) -> Errno ---;
+	@(link_name="OSResizeFile")     OSResizeFile       	:: proc(handle: Handle, new_size: u64) -> Errno ---;
+	@(link_name="OSCloseHandle")    OSCloseHandle      	:: proc(handle: Handle) ---;
+	@(link_name="OSWriteFileSync")  OSWriteFileSync   	:: proc(handle: Handle, offset: i64, size: i64, buffer: rawptr) -> i64 ---;
+	@(link_name="OSReadFileSync")   OSReadFileSync    	:: proc(handle: Handle, offset: i64, size: i64, buffer: rawptr) -> i64 ---;
+	@(link_name="realloc")          OSRealloc   		:: proc(address: rawptr, size: int) -> rawptr ---;
+	@(link_name="OSGetThreadID") 	OSGetThreadID 		:: proc(handle: Handle) -> int ---;
+	@(link_name="OSRefreshNodeInformation") OSRefreshNodeInformation :: proc(information: ^OS_Node_Information) ---;
 }
 
 stdin  := Handle(-1); // Not implemented
@@ -41,56 +68,91 @@ stdout := Handle(0);
 stderr := Handle(0);
 
 current_thread_id :: proc() -> int {
-	// Not implemented
-	return -1;
+	return OSGetThreadID(Handle(0x1000));
 }
 
 heap_alloc :: proc(size: int) -> rawptr {
-	return os_heap_allocate(size, true);
+	return OSMalloc(size);
 }
 
 heap_free :: proc(address: rawptr) {
-	os_heap_free(address);
+	OSFree(address);
 }
 
 heap_resize :: proc(address: rawptr, new_size: int) -> rawptr {
-	return os_heap_reallocate(address, new_size);
+	return OSRealloc(address, new_size);
 }
 
 open :: proc(path: string, mode: int = O_RDONLY, perm: u32 = 0) -> (Handle, Errno) {
+	flags : u64 = 0;
+
+	if mode & O_CREATE == O_CREATE {
+		flags = flags | 0x9000; // Fail if found and create directories leading to the file if they don't exist
+	} else {
+		flags = flags | 0x2000; // Fail if not found
+	}
+
+	if mode & O_EXCL == O_EXCL {
+		flags = flags | 0x111; // Block opening the node for any reason
+	}
+
+	if mode & O_RDONLY == O_RDONLY {
+		flags = flags | 0x2; // Read access
+	}
+
+	if mode & O_WRONLY == O_WRONLY {
+		flags = flags | 0x220; // Write and resize access
+	}
+
+	if mode & O_TRUNC == O_TRUNC {
+		flags = flags | 0x200; // Resize access
+	}
+
 	information := new(OS_Node_Information);
-	error := os_open_node(&path[0], len(path), u64(mode), information);
-	if error < -1 do return 0, 1;
-	information.position = 0;
-	if mode&O_TRUNC==O_TRUNC {
-		error := os_resize_file(information.handle, 0);
-		if error < -1 do return 0, 1;
+	error := OSOpenNode(&path[0], len(path), flags, information);
+
+	if error < ERROR_NONE {
+		free(information);
+		return 0, error;
+	}
+
+	if mode & O_TRUNC == O_TRUNC {
+		error := OSResizeFile(information.handle, 0);
+		if error < ERROR_NONE do return 0, ERROR_UNKNOWN_OPERATION_FAILURE;
 	}
-	return Handle(uintptr(information)), 0;
+
+	if mode & O_APPEND == O_APPEND {
+		information.position = information.size;
+	} else {
+		information.position = 0;
+	}
+
+	return Handle(uintptr(information)), ERROR_NONE;
 }
 
 close :: proc(fd: Handle) {
 	information := (^OS_Node_Information)(uintptr(fd));
-	os_close_handle(information.handle);
+	OSCloseHandle(information.handle);
 	free(information);
 }
 
 file_size :: proc(fd: Handle) -> (i64, Errno) {
-	// Not (properly) implemented
-	information := cast(^OS_Node_Information)uintptr(fd);
-	return information.size,0;
+	x : OS_Node_Information;
+	OSRefreshNodeInformation(&x);
+	return x.size, ERROR_NONE;
 }
 
 write :: proc(fd: Handle, data: []byte) -> (int, Errno) {
 	if fd == 0 {
-		os_print_direct(&data[0], len(data));
-		return len(data), 0;
+		OSPrintDirect(&data[0], len(data));
+		return len(data), ERROR_NONE;
 	} else if fd == 1 {
 		assert(false);
-		return 0, 1;
+		return 0, ERROR_NOT_IMPLEMENTED;
 	}
+
 	information := (^OS_Node_Information)(uintptr(fd));
-	count := os_write_file_sync(information.handle, information.position, i64(len(data)), &data[0]);
+	count := OSWriteFileSync(information.handle, information.position, i64(len(data)), &data[0]);
 	if count < 0 do  return 0, 1;
 	information.position += count;
 	return int(count), 0;
@@ -99,15 +161,12 @@ write :: proc(fd: Handle, data: []byte) -> (int, Errno) {
 read :: proc(fd: Handle, data: []byte) -> (int, Errno) {
 	if (fd == 0 || fd == 1) {
 		assert(false);
-		return 0, 1;
+		return 0, ERROR_NOT_IMPLEMENTED;
 	}
+
 	information := (^OS_Node_Information)(uintptr(fd));
-	count := os_read_file_sync(information.handle, information.position, i64(len(data)), &data[0]);
-	if count < 0 do return 0, 1;
+	count := OSReadFileSync(information.handle, information.position, i64(len(data)), &data[0]);
+	if count < 0 do return 0, ERROR_UNKNOWN_OPERATION_FAILURE;
 	information.position += count;
-	return int(count), 0;
-}
-
-os_terminate_this_process :: proc() {
-	os_terminate_process(0x1001);
+	return int(count), ERROR_NONE;
 }

+ 2 - 0
src/build_settings.cpp

@@ -16,6 +16,8 @@ struct BuildContext {
 	String command;
 
 	String out_filepath;
+	String resource_filepath;
+	bool   has_resource;
 	String opt_flags;
 	String llc_flags;
 	String link_flags;

+ 6 - 5
src/checker.cpp

@@ -1603,11 +1603,12 @@ void check_decl_attributes(Checker *c, Array<AstNode *> attributes, DeclAttribut
 			if (value != nullptr) {
 				Operand op = {};
 				check_expr(c, &op, value);
-				if (op.mode )
-				if (op.mode != Addressing_Constant) {
-					error(value, "An attribute element must be constant");
-				} else {
-					ev = op.value;
+				if (op.mode) {
+					if (op.mode != Addressing_Constant) {
+						error(value, "An attribute element must be constant");
+					} else {
+						ev = op.value;
+					}
 				}
 			}
 

+ 60 - 14
src/main.cpp

@@ -46,7 +46,6 @@ i32 system_exec_command_line_app(char *name, bool is_silent, char *fmt, ...) {
 	defer (gb_temp_arena_memory_end(tmp));
 
 	cmd = string_to_string16(string_buffer_allocator, make_string(cast(u8 *)cmd_line, cmd_len-1));
-
 	if (CreateProcessW(nullptr, cmd.text,
 	                   nullptr, nullptr, true, 0, nullptr, nullptr,
 	                   &start_info, &pi)) {
@@ -202,6 +201,7 @@ enum BuildFlagKind {
 	BuildFlag_Invalid,
 
 	BuildFlag_OutFile,
+	BuildFlag_ResourceFile,
 	BuildFlag_OptimizationLevel,
 	BuildFlag_ShowTimings,
 	BuildFlag_ThreadCount,
@@ -241,6 +241,7 @@ void add_flag(Array<BuildFlag> *build_flags, BuildFlagKind kind, String name, Bu
 bool parse_build_flags(Array<String> args) {
 	auto build_flags = array_make<BuildFlag>(heap_allocator(), 0, BuildFlag_COUNT);
 	add_flag(&build_flags, BuildFlag_OutFile,           str_lit("out"),             BuildFlagParam_String);
+	add_flag(&build_flags, BuildFlag_ResourceFile,      str_lit("resource"),        BuildFlagParam_String);
 	add_flag(&build_flags, BuildFlag_OptimizationLevel, str_lit("opt"),             BuildFlagParam_Integer);
 	add_flag(&build_flags, BuildFlag_ShowTimings,       str_lit("show-timings"),    BuildFlagParam_None);
 	add_flag(&build_flags, BuildFlag_ThreadCount,       str_lit("thread-count"),    BuildFlagParam_Integer);
@@ -388,6 +389,24 @@ bool parse_build_flags(Array<String> args) {
 							}
 							break;
 						}
+						case BuildFlag_ResourceFile: {
+							GB_ASSERT(value.kind == ExactValue_String);
+							String path = value.value_string;
+							path = string_trim_whitespace(path);
+							if (is_import_path_valid(path)) {
+								if(!string_ends_with(path, str_lit(".rc"))) {
+									gb_printf_err("Invalid -resource path %.*s, missing .rc\n", LIT(path));
+									bad_flags = true;
+									break;
+								}
+								build_context.resource_filepath = substring(path, 0, string_extension_position(path));
+								build_context.has_resource = true;
+							} else {
+								gb_printf_err("Invalid -resource path, got %.*s\n", LIT(path));
+								bad_flags = true;
+							}
+							break;
+						}
 						case BuildFlag_OptimizationLevel:
 							GB_ASSERT(value.kind == ExactValue_Integer);
 							build_context.optimization_level = cast(i32)value.value_integer;
@@ -602,6 +621,7 @@ void remove_temp_files(String output_base) {
 	EXT_REMOVE(".bc");
 #if defined(GB_SYSTEM_WINDOWS)
 	EXT_REMOVE(".obj");
+	EXT_REMOVE(".res");
 #else
 	EXT_REMOVE(".o");
 #endif
@@ -839,18 +859,44 @@ int main(int arg_count, char **arg_ptr) {
 			link_settings = gb_string_append_fmt(link_settings, " /DEBUG");
 		}
 
-		exit_code = system_exec_command_line_app("msvc-link", true,
-			"link \"%.*s.obj\" -OUT:\"%.*s.%s\" %s "
-			"/defaultlib:libcmt "
-			// "/nodefaultlib "
-			"/nologo /incremental:no /opt:ref /subsystem:CONSOLE "
-			" %.*s "
-			" %s "
-			"",
-			LIT(output_base), LIT(output_base), output_ext,
-			lib_str, LIT(build_context.link_flags),
-			link_settings
-		);
+		if(build_context.has_resource) {
+			exit_code = system_exec_command_line_app("msvc-link", true,
+                "rc /nologo /fo \"%.*s.res\" \"%.*s.rc\"",
+                LIT(output_base),
+                LIT(build_context.resource_filepath)
+            );
+
+            if (exit_code != 0) {
+				return exit_code;
+			}
+
+			exit_code = system_exec_command_line_app("msvc-link", true,
+				"link \"%.*s.obj\" \"%.*s.res\" -OUT:\"%.*s.%s\" %s "
+				"/defaultlib:libcmt "
+				// "/nodefaultlib "
+				"/nologo /incremental:no /opt:ref /subsystem:CONSOLE "
+				" %.*s "
+				" %s "
+				"",
+				LIT(output_base), LIT(output_base), LIT(output_base), output_ext,
+				lib_str, LIT(build_context.link_flags),
+				link_settings
+			);
+		} else {
+			exit_code = system_exec_command_line_app("msvc-link", true,
+				"link \"%.*s.obj\" -OUT:\"%.*s.%s\" %s "
+				"/defaultlib:libcmt "
+				// "/nodefaultlib "
+				"/nologo /incremental:no /opt:ref /subsystem:CONSOLE "
+				" %.*s "
+				" %s "
+				"",
+				LIT(output_base), LIT(output_base), output_ext,
+				lib_str, LIT(build_context.link_flags),
+				link_settings
+			);
+		}
+
 		if (exit_code != 0) {
 			return exit_code;
 		}
@@ -967,7 +1013,7 @@ int main(int arg_count, char **arg_ptr) {
 			#endif
 			, linker, LIT(output_base), LIT(output_base), output_ext,
 			lib_str,
-			str_eq_ignore_case(cross_compile_target, str_lit("Essence")) ? "" : "-lc -lm",
+			str_eq_ignore_case(cross_compile_target, str_lit("Essence")) ? "-lfreetype -lglue" : "-lc -lm",
 			LIT(build_context.link_flags),
 			link_settings,
 			LIT(cross_compile_lib_dir)