From 68b77c7a1cde7344702cf1d162e0124498a6b616 Mon Sep 17 00:00:00 2001 From: Leo Tenenbaum Date: Sat, 23 Jan 2021 13:48:07 -0500 Subject: got rid of dyn string array - that was unnecessarily complicated --- arr.c | 6 +++++- ted.h | 2 +- ui.c | 45 ++++++++++++++++++++++++--------------------- util.c | 11 ++++++++--- 4 files changed, 38 insertions(+), 26 deletions(-) diff --git a/arr.c b/arr.c index 2fa9b6b..56fbe47 100644 --- a/arr.c +++ b/arr.c @@ -218,6 +218,7 @@ static void arr_set_len_(void **arr, size_t member_size, size_t n) { // Similar to arr_reserve, but also sets the length of the array to n. #define arr_set_len(a, n) arr_set_len_((void **)&(a), sizeof *(a), (n)) +#if 0 static void arrcstr_append_strn_(char **a, char const *s, size_t s_len) { size_t curr_len = arr_len(*a); size_t new_len = curr_len + s_len; @@ -240,8 +241,9 @@ static void arrcstr_shrink_(char **a, u32 new_len) { #define arrcstr_append_strn(a, s, n) arrcstr_append_strn_(&(a), (s), (n)) // make the string smaller #define arrcstr_shrink(a, n) arrcstr_shrink_(&(a), (n)) +#endif - +#ifndef NDEBUG static void arr_test(void) { u32 *arr = NULL; u32 i; @@ -258,4 +260,6 @@ static void arr_test(void) { arr_remove_last(arr); assert(arr_len(arr) == 0); } +#endif + #endif // ARR_C_ diff --git a/ted.h b/ted.h index fedd317..d33c460 100644 --- a/ted.h +++ b/ted.h @@ -87,7 +87,7 @@ typedef struct { Rect bounds; u32 n_entries; FileEntry *entries; - char *cwd; // a dynamic null-terminated array of chars representing the current directory + char cwd[TED_PATH_MAX]; bool submitted; // set to true if the line buffer was just submitted this frame. } FileSelector; diff --git a/ui.c b/ui.c index 75057db..1e6702c 100644 --- a/ui.c +++ b/ui.c @@ -31,7 +31,7 @@ static void file_selector_clear_entries(FileSelector *fs) { static void file_selector_free(FileSelector *fs) { file_selector_clear_entries(fs); - arr_clear(fs->cwd); + fs->cwd[0] = '\0'; } static int qsort_file_entry_cmp(void const *av, void const *bv) { @@ -50,6 +50,8 @@ static void file_selector_cd_(FileSelector *fs, char const *path, int symlink_de // cd to the directory `name`. `name` cannot include any path separators. static void file_selector_cd1(FileSelector *fs, char const *name, size_t name_len, int symlink_depth) { + char *const cwd = fs->cwd; + if (name_len == 0 || (name_len == 1 && name[0] == '.')) { // no name, or . return; @@ -57,16 +59,16 @@ static void file_selector_cd1(FileSelector *fs, char const *name, size_t name_le if (name_len == 2 && name[0] == '.' && name[1] == '.') { // .. - char *last_sep = strrchr(fs->cwd, PATH_SEPARATOR); + char *last_sep = strrchr(cwd, PATH_SEPARATOR); if (last_sep) { - if (last_sep == fs->cwd // this is the starting "/" of a path + if (last_sep == cwd // this is the starting "/" of a path #if _WIN32 - || (last_sep == fs->cwd + 2 && fs->cwd[1] == ':') // this is the \ of C:\ . + || (last_sep == cwd + 2 && cwd[1] == ':') // this is the \ of C:\ . #endif ) { - arrcstr_shrink(fs->cwd, (u32)(last_sep + 1 - fs->cwd)); // include the last separator + last_sep[1] = '\0'; // include the last separator } else { - arrcstr_shrink(fs->cwd, (u32)(last_sep - fs->cwd)); + last_sep[0] = '\0'; } } } else { @@ -74,8 +76,8 @@ static void file_selector_cd1(FileSelector *fs, char const *name, size_t name_le if (symlink_depth < 32) { // on my system, MAXSYMLINKS is 20, so this should be plenty char path[TED_PATH_MAX], link_to[TED_PATH_MAX]; // join fs->cwd with name to get full path - str_printf(path, TED_PATH_MAX, "%s%s%*s", fs->cwd, - fs->cwd[strlen(fs->cwd) - 1] == PATH_SEPARATOR ? + str_printf(path, TED_PATH_MAX, "%s%s%*s", cwd, + cwd[strlen(cwd) - 1] == PATH_SEPARATOR ? "" : PATH_SEPARATOR_STR, (int)name_len, name); ssize_t bytes = readlink(path, link_to, sizeof link_to); @@ -90,15 +92,16 @@ static void file_selector_cd1(FileSelector *fs, char const *name, size_t name_le (void)symlink_depth; #endif // add path separator to end if not already there (which could happen in the case of /) - if (fs->cwd[strlen(fs->cwd) - 1] != PATH_SEPARATOR) - arrcstr_append_str(fs->cwd, PATH_SEPARATOR_STR); + if (cwd[strlen(cwd) - 1] != PATH_SEPARATOR) + str_cat(cwd, sizeof fs->cwd, PATH_SEPARATOR_STR); // add name itself - arrcstr_append_strn(fs->cwd, name, name_len); + strn_cat(cwd, sizeof fs->cwd, name, name_len); } } static void file_selector_cd_(FileSelector *fs, char const *path, int symlink_depth) { + char *const cwd = fs->cwd; if (path[0] == '\0') return; if (path[0] == PATH_SEPARATOR @@ -108,15 +111,14 @@ static void file_selector_cd_(FileSelector *fs, char const *path, int symlink_de ) { // absolute path (e.g. /foo, c:\foo) // start out by replacing cwd with the start of the absolute path - arr_clear(fs->cwd); + cwd[0] = '\0'; if (path[0] == PATH_SEPARATOR) { - arrcstr_append_str(fs->cwd, PATH_SEPARATOR_STR); - ++path; + str_cat(cwd, sizeof fs->cwd, PATH_SEPARATOR_STR); + path += 1; } #if _WIN32 else { - char s[] = {path[0], path[1], path[2], 0}; - arrcstr_append_str(fs->cwd, s); + strn_cat(cwd, sizeof fs->cwd, path, 3); path += 3; } #endif @@ -143,9 +145,11 @@ static void file_selector_cd(FileSelector *fs, char const *path) { static char *file_selector_update(Ted *ted, FileSelector *fs) { TextBuffer *line_buffer = &ted->line_buffer; String32 search_term32 = buffer_get_line(line_buffer, 0); - if (!fs->cwd) { + char *const cwd = fs->cwd; + + if (cwd[0] == '\0') { // set the file selector's directory to our current directory. - arrcstr_append_str(fs->cwd, ted->cwd); + str_cpy(cwd, sizeof fs->cwd, ted->cwd); } @@ -229,9 +233,8 @@ static char *file_selector_update(Ted *ted, FileSelector *fs) { // free previous entries file_selector_clear_entries(fs); // get new entries - char **files = fs_list_directory(fs->cwd); + char **files = fs_list_directory(cwd); if (files) { - char const *cwd = fs->cwd; u32 nfiles; for (nfiles = 0; files[nfiles]; ++nfiles); @@ -279,7 +282,7 @@ static char *file_selector_update(Ted *ted, FileSelector *fs) { free(files); } else { - ted_seterr(ted, "Couldn't list directory '%s'.", fs->cwd); + ted_seterr(ted, "Couldn't list directory '%s'.", cwd); } free(search_term); diff --git a/util.c b/util.c index 9dcb5ea..bf0f71f 100644 --- a/util.c +++ b/util.c @@ -62,9 +62,9 @@ static char *str_dup(char const *src) { // it is unusual to have a string that long. #define STRLEN_SAFE_MAX (UINT_MAX >> 2) -// safer version of strcat. dst_sz includes a null terminator. -static void str_cat(char *dst, size_t dst_sz, char const *src) { - size_t dst_len = strlen(dst), src_len = strlen(src); +// safer version of strncat. dst_sz includes a null terminator. +static void strn_cat(char *dst, size_t dst_sz, char const *src, size_t src_len) { + size_t dst_len = strlen(dst); // make sure dst_len + src_len + 1 doesn't overflow if (dst_len > STRLEN_SAFE_MAX || src_len > STRLEN_SAFE_MAX) { @@ -89,6 +89,11 @@ static void str_cat(char *dst, size_t dst_sz, char const *src) { } } +// safer version of strcat. dst_sz includes a null terminator. +static void str_cat(char *dst, size_t dst_sz, char const *src) { + strn_cat(dst, dst_sz, src, strlen(src)); +} + // safer version of strncpy. dst_sz includes a null terminator. static void str_cpy(char *dst, size_t dst_sz, char const *src) { size_t srclen = strlen(src); -- cgit v1.2.3