aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJeroen van Rijn <Kelimion@users.noreply.github.com>2022-04-26 13:14:09 +0200
committerJeroen van Rijn <Kelimion@users.noreply.github.com>2022-04-26 13:14:09 +0200
commita5342a01267f55dec5a5b9f775cec8c8379139b1 (patch)
treedf6aec12051d2bb82790cf56ebe24147c54c2dd4 /src
parent9f8d90f466454f4d14e755d44e4ba47ccbf0c92e (diff)
Address edge cases.
Diffstat (limited to 'src')
-rw-r--r--src/build_settings.cpp42
-rw-r--r--src/path.cpp67
-rw-r--r--src/string.cpp35
3 files changed, 99 insertions, 45 deletions
diff --git a/src/build_settings.cpp b/src/build_settings.cpp
index 212ded5c8..89d370144 100644
--- a/src/build_settings.cpp
+++ b/src/build_settings.cpp
@@ -1276,16 +1276,44 @@ bool init_build_paths(String init_filename) {
if (bc->out_filepath.len > 0) {
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 {
- 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);
diff --git a/src/path.cpp b/src/path.cpp
index 8d8e532b8..6f83c39ea 100644
--- a/src/path.cpp
+++ b/src/path.cpp
@@ -1,6 +1,46 @@
/*
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)
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);
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 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;
}
@@ -116,6 +160,23 @@ Path path_from_string(gbAllocator a, String const &path) {
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) {
String path_string = path_to_full_path(heap_allocator(), path);
defer (gb_free(heap_allocator(), path_string.text));
diff --git a/src/string.cpp b/src/string.cpp
index 3515df48e..616761265 100644
--- a/src/string.cpp
+++ b/src/string.cpp
@@ -298,41 +298,6 @@ String filename_from_path(String s) {
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) {
isize len = x.len+y.len;
u8 *data = gb_alloc_array(a, u8, len+1);