summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arr.c6
-rw-r--r--ted.h2
-rw-r--r--ui.c45
-rw-r--r--util.c11
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);