Browse Source

Address edge cases.

Jeroen van Rijn 3 years ago
parent
commit
a5342a0126

+ 3 - 8
.github/workflows/ci.yml

@@ -39,9 +39,7 @@ jobs:
           make
           make
         timeout-minutes: 10
         timeout-minutes: 10
       - name: Odin issues tests
       - name: Odin issues tests
-        run: |
-          cd tests/issues
-          ./run.sh
+        run: tests/issues/run.sh
         timeout-minutes: 10
         timeout-minutes: 10
       - name: Odin check examples/all for Linux i386
       - name: Odin check examples/all for Linux i386
         run: ./odin check examples/all -vet -strict-style -target:linux_i386
         run: ./odin check examples/all -vet -strict-style -target:linux_i386
@@ -93,9 +91,7 @@ jobs:
           make
           make
         timeout-minutes: 10
         timeout-minutes: 10
       - name: Odin issues tests
       - name: Odin issues tests
-        run: |
-          cd tests/issues
-          ./run.sh
+        run: tests/issues/run.sh
         timeout-minutes: 10
         timeout-minutes: 10
       - name: Odin check examples/all for Darwin arm64
       - name: Odin check examples/all for Darwin arm64
         run: ./odin check examples/all -vet -strict-style -target:darwin_arm64
         run: ./odin check examples/all -vet -strict-style -target:darwin_arm64
@@ -167,8 +163,7 @@ jobs:
         shell: cmd
         shell: cmd
         run: |
         run: |
           call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvars64.bat
           call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvars64.bat
-          cd tests\issues
-          call run.bat
+          call tests\issues\run.bat
         timeout-minutes: 10
         timeout-minutes: 10
       - name: Odin check examples/all for Windows 32bits
       - name: Odin check examples/all for Windows 32bits
         shell: cmd
         shell: cmd

+ 0 - 1
.gitignore

@@ -269,7 +269,6 @@ bin/
 # - Linux/MacOS
 # - Linux/MacOS
 odin
 odin
 odin.dSYM
 odin.dSYM
-*.bin
 
 
 # shared collection
 # shared collection
 shared/
 shared/

+ 2 - 2
Makefile

@@ -1,7 +1,7 @@
-all: debug
+all: debug demo
 
 
 demo:
 demo:
-	./odin run examples/demo
+	./odin run examples/demo/demo.odin
 
 
 report:
 report:
 	./odin report
 	./odin report

+ 2 - 2
build_odin.sh

@@ -102,7 +102,7 @@ build_odin() {
 }
 }
 
 
 run_demo() {
 run_demo() {
-	./odin run examples/demo
+	./odin run examples/demo/demo.odin -file
 }
 }
 
 
 case $OS in
 case $OS in
@@ -147,4 +147,4 @@ if [[ $# -eq 1 ]]; then
 	exit 0
 	exit 0
 else
 else
 	panic "Too many arguments!"
 	panic "Too many arguments!"
-fi
+fi

+ 0 - 1
core/crypto/util/util.odin

@@ -11,7 +11,6 @@ package util
 */
 */
 
 
 import "core:mem"
 import "core:mem"
-_ :: mem
 
 
 // @note(bp): this can replace the other two
 // @note(bp): this can replace the other two
 cast_slice :: #force_inline proc "contextless" ($D: typeid/[]$DE, src: $S/[]$SE) -> D {
 cast_slice :: #force_inline proc "contextless" ($D: typeid/[]$DE, src: $S/[]$SE) -> D {

+ 35 - 7
src/build_settings.cpp

@@ -1276,16 +1276,44 @@ bool init_build_paths(String init_filename) {
 
 
 	if (bc->out_filepath.len > 0) {
 	if (bc->out_filepath.len > 0) {
 		bc->build_paths[BuildPath_Output] = path_from_string(ha, bc->out_filepath);
 		bc->build_paths[BuildPath_Output] = path_from_string(ha, bc->out_filepath);
+		if (build_context.metrics.os == TargetOs_windows) {
+			String output_file = path_to_string(ha, bc->build_paths[BuildPath_Output]);
+			defer (gb_free(ha, output_file.text));
+			if (path_is_directory(bc->build_paths[BuildPath_Output])) {
+				gb_printf_err("Output path %.*s is a directory.\n", LIT(output_file));
+				return false;
+			} else if (bc->build_paths[BuildPath_Output].ext.len == 0) {
+				gb_printf_err("Output path %.*s must have an appropriate extension.\n", LIT(output_file));
+				return false;				
+			}
+		}
 	} else {
 	} else {
-		String output_name = remove_directory_from_path(init_filename);
-		output_name        = remove_extension_from_path(output_name);
-		output_name        = copy_string(ha, string_trim_whitespace(output_name));
+		Path output_path;
 
 
-		Path output_path = path_from_string(ha, output_name);
+		if (str_eq(init_filename, str_lit("."))) {
+			// We must name the output file after the current directory.
+			debugf("Output name will be created from current base name %.*s.\n", LIT(bc->build_paths[BuildPath_Main_Package].basename));
+			String last_element  = last_path_element(bc->build_paths[BuildPath_Main_Package].basename);
 
 
-		// Replace extension.
-		if (output_path.ext.len > 0) {
-			gb_free(ha, output_path.ext.text);
+			if (last_element.len == 0) {
+				gb_printf_err("The output name is created from the last path element. `%.*s` has none. Use `-out:output_name.ext` to set it.\n", LIT(bc->build_paths[BuildPath_Main_Package].basename));
+				return false;
+			}
+			output_path.basename = copy_string(ha, bc->build_paths[BuildPath_Main_Package].basename);
+			output_path.name     = copy_string(ha, last_element);
+
+		} else {
+			// Init filename was not 'current path'.
+			// Contruct the output name from the path elements as usual.
+			String output_name = remove_directory_from_path(init_filename);
+			output_name        = remove_extension_from_path(output_name);
+			output_name        = copy_string(ha, string_trim_whitespace(output_name));
+			output_path        = path_from_string(ha, output_name);
+
+			// Replace extension.
+			if (output_path.ext.len > 0) {
+				gb_free(ha, output_path.ext.text);
+			}
 		}
 		}
 		output_path.ext  = copy_string(ha, output_extension);
 		output_path.ext  = copy_string(ha, output_extension);
 
 

+ 64 - 3
src/path.cpp

@@ -1,6 +1,46 @@
 /*
 /*
 	Path handling utilities.
 	Path handling utilities.
 */
 */
+String remove_extension_from_path(String const &s) {
+	for (isize i = s.len-1; i >= 0; i--) {
+		if (s[i] == '.') {
+			return substring(s, 0, i);
+		}
+	}
+	return s;
+}
+
+String remove_directory_from_path(String const &s) {
+	isize len = 0;
+	for (isize i = s.len-1; i >= 0; i--) {
+		if (s[i] == '/' ||
+		    s[i] == '\\') {
+			break;
+		}
+		len += 1;
+	}
+	return substring(s, s.len-len, s.len);
+}
+
+bool path_is_directory(String path);
+
+String directory_from_path(String const &s) {
+	if (path_is_directory(s)) {
+		return s;
+	}
+
+	isize i = s.len-1;
+	for (; i >= 0; i--) {
+		if (s[i] == '/' ||
+		    s[i] == '\\') {
+			break;
+		}
+	}
+	if (i >= 0) {
+		return substring(s, 0, i);	
+	}
+	return substring(s, 0, 0);
+}
 
 
 #if defined(GB_SYSTEM_WINDOWS)
 #if defined(GB_SYSTEM_WINDOWS)
 	bool path_is_directory(String path) {
 	bool path_is_directory(String path) {
@@ -98,11 +138,15 @@ Path path_from_string(gbAllocator a, String const &path) {
 	String fullpath = path_to_full_path(a, path);
 	String fullpath = path_to_full_path(a, path);
 	defer (gb_free(heap_allocator(), fullpath.text));
 	defer (gb_free(heap_allocator(), fullpath.text));
 
 
-	res.basename     = directory_from_path(fullpath);
-	res.basename     = copy_string(a, res.basename);
+	res.basename = directory_from_path(fullpath);	
+	res.basename = copy_string(a, res.basename);
 
 
-	if (string_ends_with(fullpath, '/')) {
+	if (path_is_directory(fullpath)) {
 		// It's a directory. We don't need to tinker with the name and extension.
 		// It's a directory. We don't need to tinker with the name and extension.
+		// It could have a superfluous trailing `/`. Remove it if so.
+		if (res.basename.len > 0 && res.basename.text[res.basename.len - 1] == '/') {
+			res.basename.len--;
+		}
 		return res;
 		return res;
 	}
 	}
 
 
@@ -116,6 +160,23 @@ Path path_from_string(gbAllocator a, String const &path) {
 	return res;
 	return res;
 }
 }
 
 
+// NOTE(Jeroen): Takes a path String and returns the last path element.
+String last_path_element(String const &path) {
+	isize count = 0;
+	u8 * start = (u8 *)(&path.text[path.len - 1]);
+	for (isize length = path.len; length > 0 && path.text[length - 1] != '/'; length--) {
+		count++;
+		start--;
+	}
+	if (count > 0) {
+		start++; // Advance past the `/` and return the substring.
+		String res = make_string(start, count);
+		return res;
+	}
+	// Must be a root path like `/` or `C:/`, return empty String.
+	return STR_LIT("");
+}
+
 bool path_is_directory(Path path) {
 bool path_is_directory(Path path) {
 	String path_string = path_to_full_path(heap_allocator(), path);
 	String path_string = path_to_full_path(heap_allocator(), path);
 	defer (gb_free(heap_allocator(), path_string.text));
 	defer (gb_free(heap_allocator(), path_string.text));

+ 0 - 35
src/string.cpp

@@ -298,41 +298,6 @@ String filename_from_path(String s) {
 	return make_string(nullptr, 0);
 	return make_string(nullptr, 0);
 }
 }
 
 
-String remove_extension_from_path(String const &s) {
-	for (isize i = s.len-1; i >= 0; i--) {
-		if (s[i] == '.') {
-			return substring(s, 0, i);
-		}
-	}
-	return s;
-}
-
-String remove_directory_from_path(String const &s) {
-	isize len = 0;
-	for (isize i = s.len-1; i >= 0; i--) {
-		if (s[i] == '/' ||
-		    s[i] == '\\') {
-			break;
-		}
-		len += 1;
-	}
-	return substring(s, s.len-len, s.len);
-}
-
-String directory_from_path(String const &s) {
-	isize i = s.len-1;
-	for (; i >= 0; i--) {
-		if (s[i] == '/' ||
-		    s[i] == '\\') {
-			break;
-		}
-	}
-	if (i >= 0) {
-		return substring(s, 0, i);	
-	}
-	return substring(s, 0, 0);
-}
-
 String concatenate_strings(gbAllocator a, String const &x, String const &y) {
 String concatenate_strings(gbAllocator a, String const &x, String const &y) {
 	isize len = x.len+y.len;
 	isize len = x.len+y.len;
 	u8 *data = gb_alloc_array(a, u8, len+1);
 	u8 *data = gb_alloc_array(a, u8, len+1);

+ 14 - 15
tests/core/Makefile

@@ -1,6 +1,5 @@
 ODIN=../../odin
 ODIN=../../odin
 PYTHON=$(shell which python3)
 PYTHON=$(shell which python3)
-OUT_FILE=test_binary.bin
 
 
 all: download_test_assets image_test compress_test strings_test hash_test crypto_test noise_test encoding_test \
 all: download_test_assets image_test compress_test strings_test hash_test crypto_test noise_test encoding_test \
 	 math_test linalg_glsl_math_test filepath_test reflect_test os_exit_test
 	 math_test linalg_glsl_math_test filepath_test reflect_test os_exit_test
@@ -9,39 +8,39 @@ download_test_assets:
 	$(PYTHON) download_assets.py
 	$(PYTHON) download_assets.py
 
 
 image_test:
 image_test:
-	$(ODIN) run image/test_core_image.odin -out=$(OUT_FILE) -file
+	$(ODIN) run image/test_core_image.odin -file
 
 
 compress_test:
 compress_test:
-	$(ODIN) run compress/test_core_compress.odin -out=$(OUT_FILE) -file
+	$(ODIN) run compress/test_core_compress.odin -file
 
 
 strings_test:
 strings_test:
-	$(ODIN) run strings/test_core_strings.odin -out=$(OUT_FILE) -file
+	$(ODIN) run strings/test_core_strings.odin -file
 
 
 hash_test:
 hash_test:
-	$(ODIN) run hash -out=$(OUT_FILE) -o:speed -no-bounds-check
+	$(ODIN) run hash -out=test_hash -o:speed -no-bounds-check
 
 
 crypto_test:
 crypto_test:
-	$(ODIN) run crypto -out=$(OUT_FILE) -o:speed -no-bounds-check
+	$(ODIN) run crypto -out=test_crypto_hash -o:speed -no-bounds-check
 
 
 noise_test:
 noise_test:
-	$(ODIN) run math/noise -out=$(OUT_FILE)
+	$(ODIN) run math/noise -out=test_noise
 
 
 encoding_test:
 encoding_test:
-	$(ODIN) run encoding/hxa -out=$(OUT_FILE) -collection:tests=..
-	$(ODIN) run encoding/json -out=$(OUT_FILE)
-	$(ODIN) run encoding/varint -out=$(OUT_FILE)
+	$(ODIN) run encoding/hxa -out=test_hxa -collection:tests=..
+	$(ODIN) run encoding/json -out=test_json
+	$(ODIN) run encoding/varint -out=test_varint
 
 
 math_test:
 math_test:
-	$(ODIN) run math/test_core_math.odin -out=$(OUT_FILE) -file -collection:tests=..
+	$(ODIN) run math/test_core_math.odin -out=test_core_math -file -collection:tests=..
 
 
 linalg_glsl_math_test:
 linalg_glsl_math_test:
-	$(ODIN) run math/linalg/glsl/test_linalg_glsl_math.odin -file -out=$(OUT_FILE) -collection:tests=..
+	$(ODIN) run math/linalg/glsl/test_linalg_glsl_math.odin -file -out=test_linalg_glsl_math -collection:tests=..
 
 
 filepath_test:
 filepath_test:
-	$(ODIN) run path/filepath/test_core_filepath.odin -file -out=$(OUT_FILE) -collection:tests=..
+	$(ODIN) run path/filepath/test_core_filepath.odin -file -out=test_core_filepath -collection:tests=..
 
 
 reflect_test:
 reflect_test:
-	$(ODIN) run reflect/test_core_reflect.odin -file -out=$(OUT_FILE) -collection:tests=..
+	$(ODIN) run reflect/test_core_reflect.odin -file -out=test_core_reflect -collection:tests=..
 
 
 os_exit_test:
 os_exit_test:
-	$(ODIN) run os/test_core_os_exit.odin -file -out=$(OUT_FILE) && exit 1 || exit 0
+	$(ODIN) run os/test_core_os_exit.odin -file -out=test_core_os_exit && exit 1 || exit 0

+ 4 - 6
tests/core/build.bat

@@ -1,8 +1,6 @@
 @echo off
 @echo off
-set OUT_FILE=test_binary.exe
-set COMMON=-show-timings -no-bounds-check -vet -strict-style -collection:tests=.. -out:%OUT_FILE%
+set COMMON=-show-timings -no-bounds-check -vet -strict-style -collection:tests=..
 set PATH_TO_ODIN==..\..\odin
 set PATH_TO_ODIN==..\..\odin
-
 python3 download_assets.py
 python3 download_assets.py
 echo ---
 echo ---
 echo Running core:image tests
 echo Running core:image tests
@@ -37,14 +35,14 @@ echo ---
 echo ---
 echo ---
 echo Running core:encoding tests
 echo Running core:encoding tests
 echo ---
 echo ---
-%PATH_TO_ODIN% run encoding/hxa    %COMMON%
-%PATH_TO_ODIN% run encoding/json   %COMMON%
+%PATH_TO_ODIN% run encoding/hxa %COMMON%
+%PATH_TO_ODIN% run encoding/json %COMMON%
 %PATH_TO_ODIN% run encoding/varint %COMMON%
 %PATH_TO_ODIN% run encoding/varint %COMMON%
 
 
 echo ---
 echo ---
 echo Running core:math/noise tests
 echo Running core:math/noise tests
 echo ---
 echo ---
-%PATH_TO_ODIN% run math/noise      %COMMON%
+%PATH_TO_ODIN% run math/noise %COMMON%
 
 
 echo ---
 echo ---
 echo Running core:math tests
 echo Running core:math tests

+ 1 - 1
tests/core/math/big/build.bat

@@ -4,7 +4,7 @@ set PATH_TO_ODIN==..\..\..\..\odin
 set TEST_ARGS=-fast-tests
 set TEST_ARGS=-fast-tests
 set TEST_ARGS=-no-random
 set TEST_ARGS=-no-random
 set TEST_ARGS=
 set TEST_ARGS=
-set OUT_NAME=math_big_test_library.dll
+set OUT_NAME=math_big_test_library
 set COMMON=-build-mode:shared -show-timings -no-bounds-check -define:MATH_BIG_EXE=false -vet -strict-style
 set COMMON=-build-mode:shared -show-timings -no-bounds-check -define:MATH_BIG_EXE=false -vet -strict-style
 echo ---
 echo ---
 echo Running core:math/big tests
 echo Running core:math/big tests

+ 13 - 8
tests/issues/run.bat

@@ -1,12 +1,17 @@
 @echo off
 @echo off
-set PATH_TO_ODIN==..\..\odin
-set COMMON=-collection:tests=.. -out:build\test_issue
-if not exist "build" mkdir build
 
 
-%PATH_TO_ODIN% build test_issue_829.odin %COMMON% -file
-build\test_issue
+if not exist "tests\issues\build\" mkdir tests\issues\build
 
 
-%PATH_TO_ODIN% build test_issue_1592.odin %COMMON% -file
-build\test_issue
+set COMMON=-collection:tests=tests -out:tests\issues\build\test_issue
 
 
-rmdir /S /Q build
+@echo on
+
+.\odin build tests\issues\test_issue_829.odin %COMMON% -file
+tests\issues\build\test_issue
+
+.\odin build tests\issues\test_issue_1592.odin %COMMON% -file
+tests\issues\build\test_issue
+
+@echo off
+
+rmdir /S /Q tests\issues\build

+ 10 - 9
tests/issues/run.sh

@@ -1,17 +1,18 @@
 #!/bin/bash
 #!/bin/bash
-ODIN=../../odin
-COMMON="-collection:tests=.. -out:build/test_issue.bin"
-
 set -eu
 set -eu
-mkdir -p build
+
+mkdir -p tests/issues/build
+
+COMMON="-collection:tests=tests -out:tests/issues/build/test_issue"
+
 set -x
 set -x
 
 
-$ODIN build test_issue_829.odin $COMMON -file
-build/test_issue.bin
+./odin build tests/issues/test_issue_829.odin $COMMON -file
+tests/issues/build/test_issue
 
 
-$ODIN build test_issue_1592.odin $COMMON -file
-build/test_issue.bin
+./odin build tests/issues/test_issue_1592.odin $COMMON -file
+tests/issues/build/test_issue
 
 
 set +x
 set +x
 
 
-rm -rf build
+rm -rf tests/issues/build

+ 1 - 2
tests/vendor/Makefile

@@ -1,6 +1,5 @@
 ODIN=../../odin
 ODIN=../../odin
 ODINFLAGS=
 ODINFLAGS=
-OUT_FILE=test_binary.bin
 
 
 OS=$(shell uname)
 OS=$(shell uname)
 
 
@@ -11,4 +10,4 @@ endif
 all: botan_test
 all: botan_test
 
 
 botan_test:
 botan_test:
-	$(ODIN) run botan -out=$(OUT_FILE) -o:speed -no-bounds-check $(ODINFLAGS)
+	$(ODIN) run botan -out=botan_hash -o:speed -no-bounds-check $(ODINFLAGS)

+ 1 - 2
tests/vendor/build.bat

@@ -1,6 +1,5 @@
 @echo off
 @echo off
-set OUT_FILE=test_binary.exe
-set COMMON=-show-timings -no-bounds-check -vet -strict-style -out:%OUT_FILE%
+set COMMON=-show-timings -no-bounds-check -vet -strict-style
 set PATH_TO_ODIN==..\..\odin
 set PATH_TO_ODIN==..\..\odin
 
 
 echo ---
 echo ---