summaryrefslogtreecommitdiff
path: root/src/platform_shared.c
diff options
context:
space:
mode:
authorAldrik Ramaekers <aldrik.ramaekers@protonmail.com>2020-01-30 21:11:12 +0100
committerAldrik Ramaekers <aldrik.ramaekers@protonmail.com>2020-01-30 21:11:12 +0100
commit260f05025631031b7cc4904805d5017feaf53eda (patch)
treed5a723bb7bbbc9f8b598712723fe3d8290c0a54c /src/platform_shared.c
initial commit
Diffstat (limited to 'src/platform_shared.c')
-rw-r--r--src/platform_shared.c244
1 files changed, 244 insertions, 0 deletions
diff --git a/src/platform_shared.c b/src/platform_shared.c
new file mode 100644
index 0000000..4107ca3
--- /dev/null
+++ b/src/platform_shared.c
@@ -0,0 +1,244 @@
+/*
+* BSD 2-Clause “Simplified” License
+* Copyright (c) 2019, Aldrik Ramaekers, aldrik.ramaekers@protonmail.com
+* All rights reserved.
+*/
+
+void get_name_from_path(char *buffer, char *path)
+{
+ buffer[0] = 0;
+
+ s32 len = strlen(path);
+ if (len == 1)
+ {
+ return;
+ }
+
+ char *path_end = path + len;
+#ifdef OS_LINUX
+ while (*path_end != '/' && path_end >= path)
+ {
+ --path_end;
+ }
+#endif
+#ifdef OS_WIN
+ while (*path_end != '\\' && path_end >= path)
+ {
+ --path_end;
+ }
+#endif
+
+ string_copyn(buffer, path_end+1, MAX_INPUT_LENGTH);
+}
+
+void get_directory_from_path(char *buffer, char *path)
+{
+ buffer[0] = 0;
+
+ s32 len = strlen(path);
+ if (len == 1)
+ {
+ return;
+ }
+
+ char *path_end = path + len;
+#ifdef OS_LINUX
+ while (*path_end != '/' && path_end >= path)
+ {
+ --path_end;
+ }
+#endif
+#ifdef OS_WIN
+ while (*path_end != '\\' && path_end >= path)
+ {
+ --path_end;
+ }
+#endif
+
+ s32 offset = path_end - path;
+ char ch = path[offset+1];
+ path[offset+1] = 0;
+ string_copyn(buffer, path, MAX_INPUT_LENGTH);
+ path[offset+1] = ch;
+}
+
+void platform_autocomplete_path(char *buffer, bool want_dir)
+{
+ char dir[MAX_INPUT_LENGTH];
+ char name[MAX_INPUT_LENGTH];
+ get_directory_from_path(dir, buffer);
+ get_name_from_path(name, buffer);
+
+ // nothing to autocomplete
+ if (name[0] == 0)
+ {
+ return;
+ }
+
+ // create filter
+ string_appendn(name, "*", MAX_INPUT_LENGTH);
+
+ array files = array_create(sizeof(found_file));
+ array filters = get_filters(name);
+ bool is_cancelled = false;
+ platform_list_files_block(&files, dir, filters, false, 0, want_dir, &is_cancelled);
+
+ s32 index_to_take = -1;
+ if (want_dir)
+ {
+ for (s32 i = 0; i < files.length; i++)
+ {
+ found_file *file = array_at(&files, i);
+
+ if (platform_directory_exists(file->path))
+ {
+ index_to_take = i;
+ break;
+ }
+ }
+ }
+ else
+ {
+ index_to_take = 0;
+ }
+
+ array_destroy(&filters);
+
+ if (files.length > 0 && index_to_take != -1)
+ {
+ found_file *file = array_at(&files, index_to_take);
+ string_copyn(buffer, file->path, MAX_INPUT_LENGTH);
+ }
+
+ for (s32 i = 0; i < files.length; i++)
+ {
+ found_file *match = array_at(&files, i);
+ mem_free(match->matched_filter);
+ mem_free(match->path);
+ }
+ array_destroy(&files);
+}
+
+array get_filters(char *pattern)
+{
+ array result = array_create(MAX_INPUT_LENGTH);
+
+ char current_filter[MAX_INPUT_LENGTH];
+ s32 filter_len = 0;
+ while(*pattern)
+ {
+ char ch = *pattern;
+
+ if (ch == ',')
+ {
+ current_filter[filter_len] = 0;
+ array_push(&result, current_filter);
+ filter_len = 0;
+ }
+ else
+ {
+ if(filter_len < MAX_INPUT_LENGTH-1)
+ {
+ current_filter[filter_len++] = ch;
+ }
+ else
+ {
+ current_filter[filter_len] = ch;
+ }
+ }
+
+ pattern++;
+ }
+ current_filter[filter_len] = 0;
+ array_push(&result, current_filter);
+
+ return result;
+}
+
+void *platform_list_files_thread(void *args)
+{
+ list_file_args *info = args;
+
+ array filters = get_filters(info->pattern);
+
+ array *list = info->list;
+ char *start_dir = info->start_dir;
+ bool recursive = info->recursive;
+
+ platform_list_files_block(info->list, info->start_dir, filters, info->recursive, info->bucket, info->include_directories, info->is_cancelled);
+
+ mutex_lock(&info->list->mutex);
+ //if (!(*info->is_cancelled))
+ *(info->state) = true;
+ mutex_unlock(&info->list->mutex);
+
+ array_destroy(&filters);
+
+ return 0;
+}
+
+void platform_list_files(array *list, char *start_dir, char *filter, bool recursive, memory_bucket *bucket, bool *is_cancelled, bool *state)
+{
+ list_file_args *args = memory_bucket_reserve(bucket, sizeof(list_file_args));
+ args->list = list;
+ args->start_dir = start_dir;
+ args->pattern = filter;
+ args->recursive = recursive;
+ args->state = state;
+ args->include_directories = 0;
+ args->bucket = bucket;
+ args->is_cancelled = is_cancelled;
+
+ thread thr = thread_start(platform_list_files_thread, args);
+ thread_detach(&thr);
+}
+
+void platform_open_file_dialog(file_dialog_type type, char *buffer, char *file_filter, char *start_path)
+{
+ struct open_dialog_args *args = mem_alloc(sizeof(struct open_dialog_args));
+ args->buffer = buffer;
+ args->type = type;
+ args->file_filter = file_filter;
+ args->start_path = start_path;
+
+ thread thr;
+ thr.valid = false;
+
+ while (!thr.valid)
+ thr = thread_start(platform_open_file_dialog_block, args);
+ thread_detach(&thr);
+}
+
+void destroy_found_file_array(array *found_files)
+{
+ for (s32 i = 0; i < found_files->length; i++)
+ {
+ found_file *f = array_at(found_files, i);
+ mem_free(f->matched_filter);
+ mem_free(f->path);
+ }
+ array_destroy(found_files);
+}
+
+char *get_file_extension(char *path)
+{
+ while(*path != '.' && *path)
+ {
+ path++;
+ }
+ return path;
+}
+
+s32 filter_matches(array *filters, char *string, char **matched_filter)
+{
+ for (s32 i = 0; i < filters->length; i++)
+ {
+ char *filter = array_at(filters, i);
+ if (string_match(filter, string))
+ {
+ *matched_filter = filter;
+ return strlen(filter);
+ }
+ }
+ return -1;
+}