From 02bfe587c882ecae0ac7fba22f48808113d4f93d Mon Sep 17 00:00:00 2001 From: Martin Fouilleul Date: Wed, 24 May 2023 16:27:39 +0200 Subject: [PATCH] [path] adding platform path functions --- examples/atlas/main.c | 4 +- examples/canvas/main.c | 2 +- examples/image/main.c | 4 +- examples/perf_text/main.c | 2 +- examples/smooth_resize/main.c | 2 +- examples/test_app/build.sh | 11 -- examples/test_app/main.c | 275 ---------------------------------- examples/tiger/main.c | 2 +- examples/triangleMetal/main.m | 2 +- examples/ui/main.c | 2 +- src/milepost.h | 1 + src/milepost.m | 1 + src/mp_app.h | 4 - src/mtl_renderer.m | 2 +- src/osx_app.m | 40 ----- src/platform/osx_path.m | 64 ++++++++ src/platform/platform_path.c | 87 +++++++++++ src/platform/platform_path.h | 25 ++++ src/util/strings.c | 37 ----- src/util/strings.h | 7 +- 20 files changed, 190 insertions(+), 384 deletions(-) delete mode 100755 examples/test_app/build.sh delete mode 100644 examples/test_app/main.c create mode 100644 src/platform/osx_path.m create mode 100644 src/platform/platform_path.c create mode 100644 src/platform/platform_path.h diff --git a/examples/atlas/main.c b/examples/atlas/main.c index 44953c9..093a401 100644 --- a/examples/atlas/main.c +++ b/examples/atlas/main.c @@ -48,8 +48,8 @@ int main() mg_rect_atlas* atlas = mg_rect_atlas_create(&permanentArena, 16000, 16000); mg_image atlasImage = mg_image_create(16000, 16000); - str8 path1 = mp_app_get_resource_path(mem_scratch(), "../resources/triceratops.png"); - str8 path2 = mp_app_get_resource_path(mem_scratch(), "../resources/Top512.png"); + str8 path1 = path_find_resource(mem_scratch(), STR8("../resources/triceratops.png")); + str8 path2 = path_find_resource(mem_scratch(), STR8("../resources/Top512.png")); mg_image_region image1 = mg_image_atlas_alloc_from_file(atlas, atlasImage, path1, false); mg_image_region image2 = mg_image_atlas_alloc_from_file(atlas, atlasImage, path2, false); diff --git a/examples/canvas/main.c b/examples/canvas/main.c index ddc8a4e..8013ecf 100644 --- a/examples/canvas/main.c +++ b/examples/canvas/main.c @@ -22,7 +22,7 @@ mg_font create_font() { //NOTE(martin): create font - str8 fontPath = mp_app_get_resource_path(mem_scratch(), "../resources/OpenSansLatinSubset.ttf"); + str8 fontPath = path_find_resource(mem_scratch(), STR8("../resources/OpenSansLatinSubset.ttf")); char* fontPathCString = str8_to_cstring(mem_scratch(), fontPath); FILE* fontFile = fopen(fontPathCString, "r"); diff --git a/examples/image/main.c b/examples/image/main.c index 025d338..28c2ccb 100644 --- a/examples/image/main.c +++ b/examples/image/main.c @@ -38,11 +38,11 @@ int main() } //NOTE: create image - str8 imagePath = mp_app_get_resource_path(mem_scratch(), "../resources/triceratops.png"); + str8 imagePath = path_find_resource(mem_scratch(), STR8("../resources/triceratops.png")); mg_image image = mg_image_create_from_file(surface, imagePath, false); vec2 imageSize = mg_image_size(image); - str8 imagePath2 = mp_app_get_resource_path(mem_scratch(), "../resources/Top512.png"); + str8 imagePath2 = path_find_resource(mem_scratch(), STR8("../resources/Top512.png")); mg_image image2 = mg_image_create_from_file(surface, imagePath2, false); vec2 imageSize2 = mg_image_size(image2); diff --git a/examples/perf_text/main.c b/examples/perf_text/main.c index 7e69264..98f31cf 100644 --- a/examples/perf_text/main.c +++ b/examples/perf_text/main.c @@ -63,7 +63,7 @@ static const char* TEST_STRING = mg_font create_font(const char* path) { //NOTE(martin): create font - str8 fontPath = mp_app_get_resource_path(mem_scratch(), path); + str8 fontPath = path_find_resource(mem_scratch(), STR8(path)); char* fontPathCString = str8_to_cstring(mem_scratch(), fontPath); FILE* fontFile = fopen(fontPathCString, "r"); diff --git a/examples/smooth_resize/main.c b/examples/smooth_resize/main.c index 6126eb6..4ebe7f5 100644 --- a/examples/smooth_resize/main.c +++ b/examples/smooth_resize/main.c @@ -23,7 +23,7 @@ mg_font create_font() { //NOTE(martin): create font - str8 fontPath = mp_app_get_resource_path(mem_scratch(), "../resources/OpenSansLatinSubset.ttf"); + str8 fontPath = path_find_resource(mem_scratch(), STR8("../resources/OpenSansLatinSubset.ttf")); char* fontPathCString = str8_to_cstring(mem_scratch(), fontPath); FILE* fontFile = fopen(fontPathCString, "r"); diff --git a/examples/test_app/build.sh b/examples/test_app/build.sh deleted file mode 100755 index e62fb81..0000000 --- a/examples/test_app/build.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/bash - -BINDIR=../../bin -RESDIR=../../resources -SRCDIR=../../src - -INCLUDES="-I$SRCDIR -I$SRCDIR/util -I$SRCDIR/platform -I$SRCDIR/app" -LIBS="-L$BINDIR -lmilepost -framework Carbon -framework Cocoa -framework Metal -framework QuartzCore" -FLAGS="-mmacos-version-min=10.15.4 -DDEBUG -DLOG_COMPILE_DEBUG" - -clang -g $FLAGS $LIBS $INCLUDES -o $BINDIR/test_app main.c diff --git a/examples/test_app/main.c b/examples/test_app/main.c deleted file mode 100644 index 85e6197..0000000 --- a/examples/test_app/main.c +++ /dev/null @@ -1,275 +0,0 @@ -/************************************************************//** -* -* @file: main.cpp -* @author: Martin Fouilleul -* @date: 30/07/2022 -* @revision: -* -*****************************************************************/ -#include -#include -#include"milepost.h" - -#define LOG_SUBSYSTEM "Main" - -int main() -{ - LogLevel(LOG_LEVEL_DEBUG); - - mp_init(); - - mp_rect rect = {.x = 100, .y = 100, .w = 800, .h = 600}; - mp_window window = mp_window_create(rect, "test", 0); - - mg_init(); - ui_init(); -/* - mp_rect frame = {0, 0, 800, 600}; - mp_view view = mp_view_create(window, frame); - mg_surface surface = mg_surface_create_for_view(view, MG_BACKEND_METAL); -/*/ - mg_surface surface = mg_surface_create_for_window(window, MG_BACKEND_METAL); -//*/ - mg_canvas canvas = mg_canvas_create(surface, (mp_rect){0, 0, 800, 600}); - mg_image image = mg_image_create_from_file(canvas, STR8("Top512.png"), true); - - u8 colors[64]; - for(int i=0; i<64; i+=4) - { - colors[i] = 255; - colors[i+1] = 0; - colors[i+2] = 0; - colors[i+3] = 255; - } - mg_image image3 = mg_image_create_from_rgba8(canvas, 4, 4, colors); - - mg_image image2 = mg_image_create_from_file(canvas, STR8("triceratops.png"), true); - - //NOTE(martin): create font - char* fontPath = 0; - mp_app_get_resource_path("../resources/Andale Mono.ttf", &fontPath); - FILE* fontFile = fopen(fontPath, "r"); - free(fontPath); - if(!fontFile) - { - log_error("Could not load font file '%s'\n", fontPath); - return(-1); - } - unsigned char* fontData = 0; - fseek(fontFile, 0, SEEK_END); - u32 fontDataSize = ftell(fontFile); - rewind(fontFile); - fontData = (unsigned char*)malloc(fontDataSize); - fread(fontData, 1, fontDataSize, fontFile); - fclose(fontFile); - - unicode_range ranges[5] = {UNICODE_RANGE_BASIC_LATIN, - UNICODE_RANGE_C1_CONTROLS_AND_LATIN_1_SUPPLEMENT, - UNICODE_RANGE_LATIN_EXTENDED_A, - UNICODE_RANGE_LATIN_EXTENDED_B, - UNICODE_RANGE_SPECIALS}; - - mg_font font = mg_font_create_from_memory(fontDataSize, fontData, 5, ranges); - free(fontData); - - mp_window_bring_to_front_and_focus(window); - - mp_pump_events(-1); - while(!mp_should_quit()) - { - mp_event event = {}; - mp_pump_events(0); - while(mp_next_event(&event)) - { - switch(event.type) - { - case MP_EVENT_KEYBOARD_CHAR: - { - printf("entered char %s\n", event.character.sequence); - } break; - - case MP_EVENT_WINDOW_CLOSE: - { - mp_do_quit(); - } break; - - case MP_EVENT_WINDOW_RESIZE: - { - /* - mp_rect frame = {0, 0, event.frame.rect.w, event.frame.rect.h}; - mp_view_set_frame(view, frame); - */ - mg_canvas_viewport(canvas, (mp_rect){0, 0, event.frame.rect.w, event.frame.rect.h}); - - } break; - - case MP_EVENT_FRAME: - { - } break; - - default: - break; - } - } - mg_surface_prepare(surface); - - mg_set_color_rgba(canvas, 1, 1, 1, 1); - mg_clear(canvas); - - mg_move_to(canvas, 0, 0); - mg_line_to(canvas, 400, 300); - mg_set_width(canvas, 5); - mg_set_color_rgba(canvas, 1, 0, 0, 1); - mg_stroke(canvas); - - mg_image_draw(canvas, image, (mp_rect){400, 300, 200, 200}); - - mg_rounded_image_draw(canvas, image2, (mp_rect){200, 20, 200, 200}, 50); - - mg_set_color_rgba(canvas, 0, 1, 0, 0.5); - mg_rectangle_fill(canvas, 800, 800, 400, 200); - - mg_set_font(canvas, font); - mg_set_font_size(canvas, 32); - mg_move_to(canvas, 500, 500); - mg_text_outlines(canvas, STR8("Hello, world!")); - mg_set_color_rgba(canvas, 0, 0, 0, 1); - mg_fill(canvas); - - mp_rect windowRect = mp_window_get_content_rect(window); - - ui_style defaultStyle = {.bgColor = {0.9, 0.9, 0.9, 1}, - .borderSize = 2, - .borderColor = {0, 0, 1, 1}, - .fontColor = {0, 0, 0, 1}, - .font = font, - .fontSize = 32}; - - ui_begin_frame(windowRect.w, windowRect.h, defaultStyle); - { - ui_push_bg_color_ext(UI_STYLE_TAG_BUTTON, UI_STYLE_SEL_ANY, (mg_color){0.8, 0.8, 0.8, 1}); - ui_push_fg_color_ext(UI_STYLE_TAG_BUTTON, UI_STYLE_SEL_ANY, (mg_color){0.5, 0.5, 0.5, 1}); - ui_push_border_color_ext(UI_STYLE_TAG_BUTTON, UI_STYLE_SEL_ANY, (mg_color){0, 0, 1, 1}); - - ui_push_border_color_ext(UI_STYLE_TAG_BUTTON, UI_STYLE_SEL_HOT|UI_STYLE_SEL_ACTIVE, (mg_color){1, 0, 0, 1}); - ui_push_fg_color_ext(UI_STYLE_TAG_BUTTON, UI_STYLE_SEL_ACTIVE, (mg_color){0.1, 0.1, 0.1, 1}); - - ui_push_size(UI_AXIS_X, UI_SIZE_PIXELS, 600, 0); - ui_push_size(UI_AXIS_Y, UI_SIZE_PIXELS, 200, 0); - - ui_menu_bar("menu") - { - ui_menu("File") - { - ui_button("Open"); - ui_button("Save"); - ui_button("Save As"); - } - - ui_menu("Edit") - { - ui_button("Cut"); - ui_button("Copy"); - ui_button("Paste"); - } - - ui_menu("View") - { - ui_button("History"); - ui_button("Bookmarks"); - } - } - - ui_box* container = ui_box_begin("Test", UI_FLAG_DRAW_BORDER | UI_FLAG_DRAW_BACKGROUND); - ui_box_set_layout(container, UI_AXIS_X, UI_ALIGN_END, UI_ALIGN_CENTER); - { - ui_push_size(UI_AXIS_X, UI_SIZE_TEXT, 0, 0); - ui_push_size(UI_AXIS_Y, UI_SIZE_PARENT_RATIO, 0.25, 0); - - ui_sig sig1 = ui_button("Child1"); - if(sig1.hovering) - { - ui_tooltip("tip") - { - ui_label("Click me!"); - } - } - if(sig1.triggered) - { - printf("clicked child 1!\n"); - } - if(ui_button("Child2").triggered) - { - printf("clicked child 2!\n"); - } - - ui_box* block = ui_box_make("block", UI_FLAG_DRAW_BACKGROUND | UI_FLAG_DRAW_BORDER | UI_FLAG_DRAW_TEXT | UI_FLAG_BLOCK_MOUSE); - ui_box_set_size(block, UI_AXIS_X, UI_SIZE_TEXT, 0, 0); - ui_box_set_size(block, UI_AXIS_Y, UI_SIZE_TEXT, 0, 0); - ui_box_set_floating(block, UI_AXIS_X, 100); - ui_box_set_floating(block, UI_AXIS_Y, 100); - - ui_push_size(UI_AXIS_X, UI_SIZE_PIXELS, 200, 0); - ui_push_size(UI_AXIS_Y, UI_SIZE_PIXELS, 20, 0); - - static f32 scrollValue = 0.; - ui_scrollbar("scroll", .25, &scrollValue); - - ui_pop_size(UI_AXIS_X); - ui_pop_size(UI_AXIS_Y); - - ui_pop_size(UI_AXIS_X); - ui_pop_size(UI_AXIS_Y); - - } ui_box_end(); - - ui_pop_size(UI_AXIS_X); - ui_pop_size(UI_AXIS_Y); - - ui_push_size(UI_AXIS_X, UI_SIZE_PIXELS, 200, 0); - ui_push_size(UI_AXIS_Y, UI_SIZE_PIXELS, 200, 0); - ui_panel_begin("panel"); - - ui_push_size(UI_AXIS_X, UI_SIZE_TEXT, 0, 0); - ui_push_size(UI_AXIS_Y, UI_SIZE_TEXT, 0, 0); - - ui_box* b = ui_box_begin("container", 0); - ui_box_set_size(b, UI_AXIS_X, UI_SIZE_CHILDREN, 0, 0); - ui_box_set_size(b, UI_AXIS_Y, UI_SIZE_PIXELS, 300, 0); - ui_button("Hello 1"); - ui_button("Hello 2"); - ui_button("Hello 3"); - - const u32 backingMaxSize = 4096; - static char backing[4096]; - static str8 text = {}; - - ui_text_box_result res = ui_text_box("textbox", mem_scratch(), text); - memcpy(backing, res.text.ptr, minimum(res.text.len, backingMaxSize)); - text = str8_from_buffer(res.text.len, backing); - - ui_box_end(); - - ui_pop_size(UI_AXIS_X); - ui_pop_size(UI_AXIS_Y); - - ui_panel_end(); - ui_pop_size(UI_AXIS_X); - ui_pop_size(UI_AXIS_Y); - - - } ui_end_frame(); - - ui_draw(canvas); - - mg_canvas_flush(canvas); - - mg_surface_present(surface); - - mem_arena_clear(mem_scratch()); - } - - mg_surface_destroy(surface); - mp_terminate(); - return(0); -} diff --git a/examples/tiger/main.c b/examples/tiger/main.c index 6ec1ffe..226b2d7 100644 --- a/examples/tiger/main.c +++ b/examples/tiger/main.c @@ -21,7 +21,7 @@ mg_font create_font() { //NOTE(martin): create font - str8 fontPath = mp_app_get_resource_path(mem_scratch(), "../resources/OpenSansLatinSubset.ttf"); + str8 fontPath = path_find_resource(mem_scratch(), STR8("../resources/OpenSansLatinSubset.ttf")); char* fontPathCString = str8_to_cstring(mem_scratch(), fontPath); FILE* fontFile = fopen(fontPathCString, "r"); diff --git a/examples/triangleMetal/main.m b/examples/triangleMetal/main.m index 78a2d3a..b8a2142 100644 --- a/examples/triangleMetal/main.m +++ b/examples/triangleMetal/main.m @@ -41,7 +41,7 @@ int main() //NOTE(martin): load the library id device = MTLCreateSystemDefaultDevice(); - str8 shaderPath = mp_app_get_resource_path(mem_scratch(), "triangle_shader.metallib"); + str8 shaderPath = path_find_resource(mem_scratch(), STR8("triangle_shader.metallib")); const char* shaderPathCString = str8_to_cstring(mem_scratch(), shaderPath); NSString* metalFileName = [[NSString alloc] initWithCString: shaderPathCString encoding: NSUTF8StringEncoding]; NSError* err = 0; diff --git a/examples/ui/main.c b/examples/ui/main.c index fa63e87..7234b8e 100644 --- a/examples/ui/main.c +++ b/examples/ui/main.c @@ -152,7 +152,7 @@ void debug_print_styles(ui_box* box, int indent) mg_font create_font() { //NOTE(martin): create font - str8 fontPath = mp_app_get_resource_path(mem_scratch(), "../resources/OpenSansLatinSubset.ttf"); + str8 fontPath = path_find_resource(mem_scratch(), STR8("../resources/OpenSansLatinSubset.ttf")); char* fontPathCString = str8_to_cstring(mem_scratch(), fontPath); FILE* fontFile = fopen(fontPathCString, "r"); diff --git a/src/milepost.h b/src/milepost.h index e3e8bc6..cc77276 100644 --- a/src/milepost.h +++ b/src/milepost.h @@ -25,6 +25,7 @@ //---------------------------------------------------------------- // platform layer //---------------------------------------------------------------- +#include"platform_path.h" #include"platform_clock.h" /* #include"platform_rng.h" diff --git a/src/milepost.m b/src/milepost.m index 5ebfc55..6cfb464 100644 --- a/src/milepost.m +++ b/src/milepost.m @@ -7,6 +7,7 @@ * *****************************************************************/ +#include"osx_path.m" #include"osx_app.m" #include"graphics_common.c" #include"graphics_surface.c" diff --git a/src/mp_app.h b/src/mp_app.h index 722415b..b9c6a22 100644 --- a/src/mp_app.h +++ b/src/mp_app.h @@ -361,10 +361,6 @@ MP_API int mp_file_remove(str8 path); MP_API int mp_directory_create(str8 path); -MP_API str8 mp_app_get_resource_path(mem_arena* arena, const char* name); -MP_API str8 mp_app_get_executable_path(mem_arena* arena); - - #ifdef __cplusplus } // extern "C" #endif diff --git a/src/mtl_renderer.m b/src/mtl_renderer.m index 3c45b73..0546342 100644 --- a/src/mtl_renderer.m +++ b/src/mtl_renderer.m @@ -1329,7 +1329,7 @@ mg_canvas_backend* mtl_canvas_backend_create(mg_mtl_surface* surface) @autoreleasepool{ //NOTE: load metal library - str8 shaderPath = mp_app_get_resource_path(mem_scratch(), "mtl_renderer.metallib"); + str8 shaderPath = path_find_resource(mem_scratch(), STR8("mtl_renderer.metallib")); NSString* metalFileName = [[NSString alloc] initWithBytes: shaderPath.ptr length:shaderPath.len encoding: NSUTF8StringEncoding]; NSError* err = 0; id library = [surface->device newLibraryWithFile: metalFileName error:&err]; diff --git a/src/osx_app.m b/src/osx_app.m index 56e3a26..681447d 100644 --- a/src/osx_app.m +++ b/src/osx_app.m @@ -1990,46 +1990,6 @@ void mp_pump_events(f64 timeout) } } -//-------------------------------------------------------------------- -// app resources -//-------------------------------------------------------------------- - -#import -#include - -str8 mp_app_get_resource_path(mem_arena* arena, const char* name) -{ - str8_list list = {}; - mem_arena* scratch = mem_scratch(); - - str8 executablePath = mp_app_get_executable_path(scratch); - str8 dirPath = mp_path_directory(executablePath); - - str8_list_push(scratch, &list, dirPath); - str8_list_push(scratch, &list, STR8("/")); - str8_list_push(scratch, &list, str8_push_cstring(scratch, name)); - str8 path = str8_list_join(scratch, list); - char* pathCString = str8_to_cstring(scratch, path); - char* buffer = mem_arena_alloc_array(scratch, char, path.len+1); - char* real = realpath(pathCString, buffer); - - str8 result = str8_push_cstring(arena, real); - return(result); -} - - -#include -str8 mp_app_get_executable_path(mem_arena* arena) -{@autoreleasepool{ - str8 result = {}; - u32 size = 0; - _NSGetExecutablePath(0, &size); - result.len = size; - result.ptr = mem_arena_alloc_array(arena, char, result.len); - _NSGetExecutablePath(result.ptr, &size); - return(result); -}} - //-------------------------------------------------------------------- // system dialogs windows //-------------------------------------------------------------------- diff --git a/src/platform/osx_path.m b/src/platform/osx_path.m new file mode 100644 index 0000000..d015358 --- /dev/null +++ b/src/platform/osx_path.m @@ -0,0 +1,64 @@ +/************************************************************//** +* +* @file: osx_path.m +* @author: Martin Fouilleul +* @date: 24/05/2023 +* +*****************************************************************/ + +#import +#include +#include + +#include"platform_path.c" + +str8 path_find_executable(mem_arena* arena) +{@autoreleasepool{ + str8 result = {}; + u32 size = 0; + _NSGetExecutablePath(0, &size); + result.len = size; + result.ptr = mem_arena_alloc_array(arena, char, result.len); + _NSGetExecutablePath(result.ptr, &size); + return(result); +}} + +str8 path_find_resource(mem_arena* arena, str8 relPath) +{ + str8_list list = {}; + mem_arena* scratch = mem_scratch(); + + str8 executablePath = path_find_executable(scratch); + str8 dirPath = path_slice_directory(executablePath); + + str8_list_push(scratch, &list, dirPath); + str8_list_push(scratch, &list, STR8("/")); + str8_list_push(scratch, &list, relPath); + str8 path = str8_list_join(scratch, list); + char* pathCString = str8_to_cstring(scratch, path); + char* buffer = mem_arena_alloc_array(scratch, char, path.len+1); + char* real = realpath(pathCString, buffer); + + str8 result = str8_push_cstring(arena, real); + return(result); +} + +str8 path_find_canonical(mem_arena* arena, str8 path) +{ + mem_arena* scratch = mem_scratch(); + char* pathCString = str8_to_cstring(scratch, path); + + char* real = realpath(pathCString, 0); + str8 result = str8_push_cstring(arena, real); + + free(real); + + return(result); +} + +/*TODO +str8 path_find_restricted(mem_arena* arena, str8 root, str8 relPath) +{ + +} +*/ diff --git a/src/platform/platform_path.c b/src/platform/platform_path.c new file mode 100644 index 0000000..cb012a8 --- /dev/null +++ b/src/platform/platform_path.c @@ -0,0 +1,87 @@ +/************************************************************//** +* +* @file: platform_path.c +* @author: Martin Fouilleul +* @date: 24/05/2023 +* +*****************************************************************/ + +#include"platform_path.h" + +str8 path_slice_directory(str8 fullPath) +{ + i64 lastSlashIndex = -1; + + for(i64 i = fullPath.len-1; i >= 0; i--) + { + if(fullPath.ptr[i] == '/') + { + lastSlashIndex = i; + break; + } + } + str8 directory = str8_slice(fullPath, 0, lastSlashIndex+1); + return(directory); +} + +str8 path_slice_filename(str8 fullPath) +{ + i64 lastSlashIndex = -1; + + for(i64 i = fullPath.len-1; i >= 0; i--) + { + if(fullPath.ptr[i] == '/') + { + lastSlashIndex = i; + break; + } + } + + str8 basename = str8_slice(fullPath, lastSlashIndex+1, fullPath.len); + return(basename); +} + +str8_list path_split(mem_arena* arena, str8 path) +{ + //TODO: use secondary scratch arena + str8_list split = {0}; + str8_list_push(arena, &split, STR8("/")); + str8_list res = str8_split(arena, path, split); + return(res); +} + +str8 path_join(mem_arena* arena, str8_list elements) +{ + str8 res = str8_list_collate(arena, elements, STR8("/"), STR8("/"), (str8){0}); + return(res); +} + +str8 path_append_relative(mem_arena* arena, str8 parent, str8 relPath) +{ + //TODO: use secondary scratch arena + + str8 result = {0}; + + if(parent.len == 0) + { + result = str8_push_copy(arena, relPath); + } + else if(relPath.len == 0) + { + result = str8_push_copy(arena, parent); + } + else + { + str8_list list = {0}; + str8_list_push(arena, &list, parent); + if( (parent.ptr[parent.len-1] != '/') + &&(relPath.ptr[relPath.len-1] != '/')) + { + str8_list_push(arena, &list, STR8("/")); + } + str8_list_push(arena, &list, relPath); + + result = str8_list_join(arena, list); + } + return(result); +} diff --git a/src/platform/platform_path.h b/src/platform/platform_path.h new file mode 100644 index 0000000..961e680 --- /dev/null +++ b/src/platform/platform_path.h @@ -0,0 +1,25 @@ +/************************************************************//** +* +* @file: platform_path.h +* @author: Martin Fouilleul +* @date: 24/05/2023 +* +*****************************************************************/ +#ifndef __PLATFORM_PATH_H_ +#define __PLATFORM_PATH_H_ + +#include"util/strings.h" + +MP_API str8 path_slice_directory(str8 path); +MP_API str8 path_slice_filename(str8 path); + +MP_API str8_list path_split(mem_arena* arena, str8 path); +MP_API str8 path_join(mem_arena* arena, str8_list elements); +MP_API str8 path_append_relative(mem_arena* arena, str8 parent, str8 relPath); + +MP_API str8 path_find_executable(mem_arena* arena); +MP_API str8 path_find_resource(mem_arena* arena, str8 relPath); +MP_API str8 path_find_canonical(mem_arena* arena, str8 path); +MP_API str8 path_find_restricted(mem_arena* arena, str8 root, str8 relPath); + +#endif //__PLATFORM_PATH_H_ diff --git a/src/util/strings.c b/src/util/strings.c index 41553f2..511e7e2 100644 --- a/src/util/strings.c +++ b/src/util/strings.c @@ -304,40 +304,3 @@ str32 str32_list_join(mem_arena* arena, str32_list list) str32 empty = {.len = 0, .ptr = 0}; return(str32_list_collate(arena, list, empty, empty, empty)); } - - -//---------------------------------------------------------------------------------- -// Paths helpers -//---------------------------------------------------------------------------------- -str8 mp_path_directory(str8 fullPath) -{ - i64 lastSlashIndex = -1; - - for(i64 i = fullPath.len-1; i >= 0; i--) - { - if(fullPath.ptr[i] == '/') - { - lastSlashIndex = i; - break; - } - } - str8 directory = str8_slice(fullPath, 0, lastSlashIndex+1); - return(directory); -} - -str8 mp_path_base_name(str8 fullPath) -{ - i64 lastSlashIndex = -1; - - for(i64 i = fullPath.len-1; i >= 0; i--) - { - if(fullPath.ptr[i] == '/') - { - lastSlashIndex = i; - break; - } - } - - str8 basename = str8_slice(fullPath, lastSlashIndex+1, fullPath.len); - return(basename); -} diff --git a/src/util/strings.h b/src/util/strings.h index cbb4b47..04cfd4c 100644 --- a/src/util/strings.h +++ b/src/util/strings.h @@ -66,6 +66,7 @@ typedef struct str8_list MP_API void str8_list_push(mem_arena* arena, str8_list* list, str8 str); MP_API void str8_list_pushf(mem_arena* arena, str8_list* list, const char* format, ...); +MP_API str8 str8_list_collate(mem_arena* arena, str8_list list, str8 prefix, str8 separator, str8 postfix); MP_API str8 str8_list_join(mem_arena* arena, str8_list list); MP_API str8_list str8_split(mem_arena* arena, str8 str, str8_list separators); @@ -102,12 +103,6 @@ MP_API void str32_list_push(mem_arena* arena, str32_list* list, str32 str); MP_API str32 str32_list_join(mem_arena* arena, str32_list list); MP_API str32_list str32_split(mem_arena* arena, str32 str, str32_list separators); -//---------------------------------------------------------------------------------- -// Paths helpers -//---------------------------------------------------------------------------------- -MP_API str8 mp_path_directory(str8 fullPath); -MP_API str8 mp_path_base_name(str8 fullPath); - #ifdef __cplusplus } // extern "C" #endif