From 18ea9b03508268b083ce5b73fecc819264c0171d Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Sat, 15 Jun 2019 17:43:55 -0700 Subject: Silenced some error messages from `which` --- Makefile | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/Makefile b/Makefile index 3902c84..b799664 100644 --- a/Makefile +++ b/Makefile @@ -19,18 +19,18 @@ ifeq (, $(PICKER)) endif ifneq (, $(PICKER)) PICKER_FLAG=-D"PICK(prompt, initial)=\"$(PICKER)\"" -endif -ifeq ($(shell which $(PICKER)),$(shell which fzy || echo '')) - PICKER_FLAG=-D'PICK(prompt, initial)="{ printf \"\\033[3A\" >/dev/tty; fzy --lines=3 --prompt=\"" prompt "\" --query=\"" initial "\"; }"' -endif -ifeq ($(shell which $(PICKER)),$(shell which fzf || echo '')) - PICKER_FLAG=-D'PICK(prompt, initial)="{ printf \"\\033[3A\" >/dev/tty; fzf --height=4 --prompt=\"" prompt "\" --query=\"" initial "\"; }"' -endif -ifeq ($(shell which $(PICKER)),$(shell which ask || echo '')) - PICKER_FLAG=-D'PICK(prompt, initial)="ask --prompt=\"" prompt "\" --query=\"" initial "\""' -endif -ifeq ($(shell which $(PICKER)),$(shell which pick || echo '')) - PICKER_FLAG=-D'PICK(prompt, initial)="pick -q \"" initial "\""' + ifeq ($(shell which $(PICKER)),$(shell which fzy 2>/dev/null || echo '')) + PICKER_FLAG=-D'PICK(prompt, initial)="{ printf \"\\033[3A\" >/dev/tty; fzy --lines=3 --prompt=\"" prompt "\" --query=\"" initial "\"; }"' + endif + ifeq ($(shell which $(PICKER)),$(shell which fzf 2>/dev/null || echo '')) + PICKER_FLAG=-D'PICK(prompt, initial)="{ printf \"\\033[3A\" >/dev/tty; fzf --height=4 --prompt=\"" prompt "\" --query=\"" initial "\"; }"' + endif + ifeq ($(shell which $(PICKER)),$(shell which ask 2>/dev/null || echo '')) + PICKER_FLAG=-D'PICK(prompt, initial)="ask --prompt=\"" prompt "\" --query=\"" initial "\""' + endif + ifeq ($(shell which $(PICKER)),$(shell which pick 2>/dev/null || echo '')) + PICKER_FLAG=-D'PICK(prompt, initial)="pick -q \"" initial "\""' + endif endif CFLAGS += $(PICKER_FLAG) -- cgit v1.2.3 From 302ed33d9c37272f554be2987e4d850b6c444a69 Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Sat, 15 Jun 2019 18:02:14 -0700 Subject: Sorted function declarations alphabetically, got rid of clear_selection (now just inlined), and replaced remove_entry() with try_free_entry() to eliminate duplicate safety checks. --- bb.c | 87 ++++++++++++++++++++++++++++++++------------------------------------ 1 file changed, 41 insertions(+), 46 deletions(-) diff --git a/bb.c b/bb.c index a4f3d7b..285538e 100644 --- a/bb.c +++ b/bb.c @@ -118,37 +118,36 @@ typedef struct bb_s { typedef enum { BB_OK = 0, BB_INVALID, BB_QUIT } bb_result_t; // Functions -static void update_term_size(int sig); -static void init_term(void); -static void close_term(void); -static void cleanup_and_exit(int sig); -static void cleanup(void); -static void* memcheck(void *p); -static int run_script(bb_t *bb, const char *cmd); -static int fputs_escaped(FILE *f, const char *str, const char *color); +static void bb_browse(bb_t *bb, const char *path); +static int cd_to(bb_t *bb, const char *path); static const char* color_of(mode_t mode); -static void set_sort(bb_t *bb, const char *sort); -static void render(bb_t *bb); +static void cleanup(void); +static void cleanup_and_exit(int sig); +static void close_term(void); #ifdef __APPLE__ static int compare_files(void *v, const void *v1, const void *v2); #else static int compare_files(const void *v1, const void *v2, void *v); #endif -static void clear_selection(bb_t *bb); -static void select_entry(bb_t *bb, entry_t *e); static void deselect_entry(bb_t *bb, entry_t *e); -static void toggle_entry(bb_t *bb, entry_t *e); -static void set_cursor(bb_t *bb, int i); -static void set_scroll(bb_t *bb, int i); +static int fputs_escaped(FILE *f, const char *str, const char *color); +static void init_term(void); static entry_t* load_entry(bb_t *bb, const char *path); -static void remove_entry(entry_t *e); -static void sort_files(bb_t *bb); +static void* memcheck(void *p); static void normalize_path(const char *root, const char *path, char *pbuf); -static int cd_to(bb_t *bb, const char *path); static void populate_files(bb_t *bb, const char *path); -static bb_result_t process_cmd(bb_t *bb, const char *cmd); -static void bb_browse(bb_t *bb, const char *path); static void print_bindings(void); +static bb_result_t process_cmd(bb_t *bb, const char *cmd); +static void render(bb_t *bb); +static int run_script(bb_t *bb, const char *cmd); +static void select_entry(bb_t *bb, entry_t *e); +static void set_cursor(bb_t *bb, int i); +static void set_scroll(bb_t *bb, int i); +static void set_sort(bb_t *bb, const char *sort); +static void sort_files(bb_t *bb); +static void toggle_entry(bb_t *bb, entry_t *e); +static int try_free_entry(entry_t *e); +static void update_term_size(int sig); // Config options extern binding_t bindings[]; @@ -618,21 +617,6 @@ int compare_files(const void *v1, const void *v2, void *v) #undef COMPARE_TIME } -/* - * Deselect all files - */ -void clear_selection(bb_t *bb) -{ - for (entry_t *next, *e = bb->firstselected; e; e = next) { - next = e->selected.next; - e->selected.atme = NULL; - e->selected.next = NULL; - if (!IS_VIEWED(e)) remove_entry(e); - } - bb->firstselected = NULL; - bb->dirty = 1; -} - /* * Select a file */ @@ -663,7 +647,7 @@ void deselect_entry(bb_t *bb, entry_t *e) e->selected.next = NULL; e->selected.atme = NULL; } - if (!IS_VIEWED(e)) remove_entry(e); + try_free_entry(e); } /* @@ -792,18 +776,25 @@ entry_t* load_entry(bb_t *bb, const char *path) return entry; } -void remove_entry(entry_t *e) +/* + * If the given entry is not viewed or selected, remove it from the + * hash, free it, and return 1. + */ +int try_free_entry(entry_t *e) { - if (IS_SELECTED(e)) err("Attempt to remove an entry while it is still selected."); - if (IS_VIEWED(e)) err("Attempt to remove an entry while it is still being viewed."); + if (IS_SELECTED(e) || IS_VIEWED(e)) return 0; if (e->hash.next) e->hash.next->hash.atme = e->hash.atme; *(e->hash.atme) = e->hash.next; e->hash.atme = NULL; e->hash.next = NULL; - if (!IS_SELECTED(e)) free(e); + free(e); + return 1; } +/* + * Sort the files in bb according to bb's settings. + */ void sort_files(bb_t *bb) { #ifdef __APPLE__ @@ -881,7 +872,7 @@ int cd_to(bb_t *bb, const char *path) entry_t *p = load_entry(bb, prev); if (p) { if (IS_VIEWED(p)) set_cursor(bb, p->index); - else if (!IS_SELECTED(p)) remove_entry(p); + else try_free_entry(p); } } return 0; @@ -899,8 +890,7 @@ void populate_files(bb_t *bb, const char *path) if (bb->files) { for (int i = 0; i < bb->nfiles; i++) { bb->files[i]->index = -1; - if (!IS_SELECTED(bb->files[i])) - remove_entry(bb->files[i]); + try_free_entry(bb->files[i]); bb->files[i] = NULL; } free(bb->files); @@ -1071,8 +1061,7 @@ bb_result_t process_cmd(bb_t *bb, const char *cmd) if (IS_VIEWED(e)) { set_cursor(bb, e->index); return BB_OK; - } else if (!IS_SELECTED(e)) - remove_entry(e); + } else try_free_entry(e); return BB_OK; } case 'i': { // +interleave @@ -1548,7 +1537,13 @@ int main(int argc, char *argv[]) if (print_dir) printf("%s\n", bb->path); - clear_selection(bb); + for (entry_t *next, *e = bb->firstselected; e; e = next) { + next = e->selected.next; + e->selected.atme = NULL; + e->selected.next = NULL; + try_free_entry(e); + } + bb->firstselected = NULL; for (int m = 0; m < 128; m++) if (bb->marks[m]) free(bb->marks[m]); free(bb); -- cgit v1.2.3 From 4c717185de001c0d74c8d498e42facedc03de176 Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Sat, 15 Jun 2019 18:13:44 -0700 Subject: Cleaned up and deduplicated some of the path normalization code. --- bb.c | 77 +++++++++++++++++++++++++++----------------------------------------- 1 file changed, 31 insertions(+), 46 deletions(-) diff --git a/bb.c b/bb.c index 285538e..197ec36 100644 --- a/bb.c +++ b/bb.c @@ -132,9 +132,9 @@ static int compare_files(const void *v1, const void *v2, void *v); static void deselect_entry(bb_t *bb, entry_t *e); static int fputs_escaped(FILE *f, const char *str, const char *color); static void init_term(void); -static entry_t* load_entry(bb_t *bb, const char *path); +static entry_t* load_entry(bb_t *bb, const char *path, int clear_dots); static void* memcheck(void *p); -static void normalize_path(const char *root, const char *path, char *pbuf); +static void normalize_path(const char *root, const char *path, char *pbuf, int clear_dots); static void populate_files(bb_t *bb, const char *path); static void print_bindings(void); static bb_result_t process_cmd(bb_t *bb, const char *cmd); @@ -714,24 +714,13 @@ void set_scroll(bb_t *bb, int newscroll) * Warning: this does not deduplicate entries, and it's best if there aren't * duplicate entries hanging around. */ -entry_t* load_entry(bb_t *bb, const char *path) +entry_t* load_entry(bb_t *bb, const char *path, int clear_dots) { struct stat linkedstat, filestat; if (!path || !path[0]) return NULL; if (lstat(path, &filestat) == -1) return NULL; char pbuf[PATH_MAX]; - if (path[0] == '~' && (path[1] == '\0' || path[1] == '/')) { - char *home; - if (!(home = getenv("HOME"))) - return NULL; - strcpy(pbuf, home); - strcat(pbuf, path+1); - } else if (path[0] == '/') { - strcpy(pbuf, path); - } else { - strcpy(pbuf, bb->path); - strcat(pbuf, path); - } + normalize_path(bb->path, path, pbuf, clear_dots); if (pbuf[strlen(pbuf)-1] == '/' && pbuf[1]) pbuf[strlen(pbuf)-1] = '\0'; @@ -808,11 +797,11 @@ void sort_files(bb_t *bb) } /* - * Prepend `root` to relative paths, replace "~" with $HOME, replace "/foo/." - * with "/foo", replace "/foo/baz/.." with "/foo". + * Prepend `root` to relative paths, replace "~" with $HOME. + * If clear_dots is 1, then also replace "/foo/." with "/foo" and replace "/foo/baz/.." with "/foo". * The normalized path is stored in `normalized`. */ -void normalize_path(const char *root, const char *path, char *normalized) +void normalize_path(const char *root, const char *path, char *normalized, int clear_dots) { if (path[0] == '~' && (path[1] == '\0' || path[1] == '/')) { char *home; @@ -826,21 +815,23 @@ void normalize_path(const char *root, const char *path, char *normalized) } strcat(normalized, path); - char *src = normalized, *dest = normalized; - while (*src) { - while (src[0] == '/' && src[1] == '.') { - // Replace "foo/./?" with "foo/?" - if (src[2] == '/' || src[2] == '\0') { - src += 2; - } else if (src[2] == '.' && (src[3] == '/' || src[3] == '\0')) { - // Replace "foo/baz/../?" with "foo/?" - src += 3; - while (dest > normalized && *(--dest) != '/'); - } else break; + if (clear_dots) { + char *src = normalized, *dest = normalized; + while (*src) { + while (src[0] == '/' && src[1] == '.') { + // Replace "foo/./?" with "foo/?" + if (src[2] == '/' || src[2] == '\0') { + src += 2; + } else if (src[2] == '.' && (src[3] == '/' || src[3] == '\0')) { + // Replace "foo/baz/../?" with "foo/?" + src += 3; + while (dest > normalized && *(--dest) != '/'); + } else break; + } + *(dest++) = *(src++); } - *(dest++) = *(src++); + *dest = '\0'; } - *dest = '\0'; } int cd_to(bb_t *bb, const char *path) @@ -856,7 +847,7 @@ int cd_to(bb_t *bb, const char *path) strcpy(pbuf, bb->marks['-']); if (chdir(pbuf)) return -1; } else { - normalize_path(bb->path, path, pbuf); + normalize_path(bb->path, path, pbuf, 1); if (pbuf[strlen(pbuf)-1] != '/') strcat(pbuf, "/"); if (chdir(pbuf)) return -1; @@ -869,7 +860,7 @@ int cd_to(bb_t *bb, const char *path) populate_files(bb, pbuf); if (prev[0]) { - entry_t *p = load_entry(bb, prev); + entry_t *p = load_entry(bb, prev, 0); if (p) { if (IS_VIEWED(p)) set_cursor(bb, p->index); else try_free_entry(p); @@ -937,7 +928,7 @@ void populate_files(bb_t *bb, const char *path) bb->files = memcheck(realloc(bb->files, (space += 100)*sizeof(void*))); strcpy(&pathbuf[pathbuflen], dp->d_name); // Don't normalize path so we can get "." and ".." - entry_t *entry = load_entry(bb, pathbuf); + entry_t *entry = load_entry(bb, pathbuf, 0); if (!entry) err("Failed to load entry: '%s'", dp->d_name); entry->index = bb->nfiles; bb->files[bb->nfiles++] = entry; @@ -1020,8 +1011,8 @@ bb_result_t process_cmd(bb_t *bb, const char *cmd) if (!value && !bb->nfiles) return BB_INVALID; if (!value) value = bb->files[bb->cursor]->fullname; char pbuf[PATH_MAX]; - normalize_path(bb->path, value, pbuf); - entry_t *e = load_entry(bb, pbuf); + normalize_path(bb->path, value, pbuf, 1); + entry_t *e = load_entry(bb, pbuf, 0); if (e) { deselect_entry(bb, e); return BB_OK; @@ -1044,7 +1035,7 @@ bb_result_t process_cmd(bb_t *bb, const char *cmd) } case 'g': { // +goto: if (!value) return BB_INVALID; - entry_t *e = load_entry(bb, value); + entry_t *e = load_entry(bb, value, 1); if (!e) return BB_INVALID; if (IS_VIEWED(e)) { set_cursor(bb, e->index); @@ -1056,8 +1047,6 @@ bb_result_t process_cmd(bb_t *bb, const char *cmd) if (!lastslash) return BB_INVALID; *lastslash = '\0'; // Split in two cd_to(bb, pbuf); - e = load_entry(bb, lastslash+1); - if (!e) return BB_INVALID; if (IS_VIEWED(e)) { set_cursor(bb, e->index); return BB_OK; @@ -1143,9 +1132,7 @@ bb_result_t process_cmd(bb_t *bb, const char *cmd) case '\0': case 'e': { // +select: if (!value && !bb->nfiles) return BB_INVALID; if (!value) value = bb->files[bb->cursor]->fullname; - char pbuf[PATH_MAX]; - normalize_path(bb->path, value, pbuf); - entry_t *e = load_entry(bb, pbuf); + entry_t *e = load_entry(bb, value, 1); if (e) select_entry(bb, e); return BB_OK; } @@ -1161,9 +1148,7 @@ bb_result_t process_cmd(bb_t *bb, const char *cmd) case 't': { // +toggle: if (!value && !bb->nfiles) return BB_INVALID; if (!value) value = bb->files[bb->cursor]->fullname; - char pbuf[PATH_MAX]; - normalize_path(bb->path, value, pbuf); - entry_t *e = load_entry(bb, pbuf); + entry_t *e = load_entry(bb, value, 1); if (e) toggle_entry(bb, e); return BB_OK; } @@ -1511,7 +1496,7 @@ int main(int argc, char *argv[]) char path[PATH_MAX], curdir[PATH_MAX]; getcwd(curdir, PATH_MAX); strcat(curdir, "/"); - normalize_path(curdir, initial_path, path); + normalize_path(curdir, initial_path, path, 1); if (chdir(path)) err("Not a valid path: %s\n", path); bb_t *bb = memcheck(calloc(1, sizeof(bb_t))); -- cgit v1.2.3 From f2298a5786325f994aa4d0b070ed7566c3069957 Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Sat, 15 Jun 2019 18:21:37 -0700 Subject: Condensed selection code by converting select_entry()/deselect_entry() to set_selected() with an argument for whether the file should be selected. --- bb.c | 58 ++++++++++++++++++++-------------------------------------- 1 file changed, 20 insertions(+), 38 deletions(-) diff --git a/bb.c b/bb.c index 197ec36..b4a9a49 100644 --- a/bb.c +++ b/bb.c @@ -129,7 +129,6 @@ static int compare_files(void *v, const void *v1, const void *v2); #else static int compare_files(const void *v1, const void *v2, void *v); #endif -static void deselect_entry(bb_t *bb, entry_t *e); static int fputs_escaped(FILE *f, const char *str, const char *color); static void init_term(void); static entry_t* load_entry(bb_t *bb, const char *path, int clear_dots); @@ -140,12 +139,11 @@ static void print_bindings(void); static bb_result_t process_cmd(bb_t *bb, const char *cmd); static void render(bb_t *bb); static int run_script(bb_t *bb, const char *cmd); -static void select_entry(bb_t *bb, entry_t *e); static void set_cursor(bb_t *bb, int i); +static void set_selected(bb_t *bb, entry_t *e, int selected); static void set_scroll(bb_t *bb, int i); static void set_sort(bb_t *bb, const char *sort); static void sort_files(bb_t *bb); -static void toggle_entry(bb_t *bb, entry_t *e); static int try_free_entry(entry_t *e); static void update_term_size(int sig); @@ -618,27 +616,22 @@ int compare_files(const void *v1, const void *v2, void *v) } /* - * Select a file + * Select or deselect a file. */ -void select_entry(bb_t *bb, entry_t *e) +void set_selected(bb_t *bb, entry_t *e, int selected) { - if (IS_SELECTED(e)) return; + if (IS_SELECTED(e) == selected) return; + if (bb->nfiles > 0 && e != bb->files[bb->cursor]) bb->dirty = 1; - if (bb->firstselected) - bb->firstselected->selected.atme = &e->selected.next; - e->selected.next = bb->firstselected; - e->selected.atme = &bb->firstselected; - bb->firstselected = e; -} -/* - * Deselect a file - */ -void deselect_entry(bb_t *bb, entry_t *e) -{ - (void)bb; - if (IS_SELECTED(e)) { + if (selected) { + if (bb->firstselected) + bb->firstselected->selected.atme = &e->selected.next; + e->selected.next = bb->firstselected; + e->selected.atme = &bb->firstselected; + bb->firstselected = e; + } else { if (bb->nfiles > 0 && e != bb->files[bb->cursor]) bb->dirty = 1; if (e->selected.next) @@ -646,17 +639,8 @@ void deselect_entry(bb_t *bb, entry_t *e) *(e->selected.atme) = e->selected.next; e->selected.next = NULL; e->selected.atme = NULL; + try_free_entry(e); } - try_free_entry(e); -} - -/* - * Toggle a file's selection state - */ -void toggle_entry(bb_t *bb, entry_t *e) -{ - if (IS_SELECTED(e)) deselect_entry(bb, e); - else select_entry(bb, e); } /* @@ -1014,13 +998,13 @@ bb_result_t process_cmd(bb_t *bb, const char *cmd) normalize_path(bb->path, value, pbuf, 1); entry_t *e = load_entry(bb, pbuf, 0); if (e) { - deselect_entry(bb, e); + set_selected(bb, e, 0); return BB_OK; } // Filename may no longer exist: for (e = bb->firstselected; e; e = e->selected.next) { if (strcmp(e->fullname, pbuf) == 0) { - deselect_entry(bb, e); + set_selected(bb, e, 0); break; } } @@ -1098,10 +1082,8 @@ bb_result_t process_cmd(bb_t *bb, const char *cmd) else set_cursor(bb, n); if (cmd[0] == 's') { // +spread: int sel = IS_SELECTED(bb->files[oldcur]); - for (int i = bb->cursor; i != oldcur; i += (oldcur > i ? 1 : -1)) { - if (sel != IS_SELECTED(bb->files[i])) - toggle_entry(bb, bb->files[i]); - } + for (int i = bb->cursor; i != oldcur; i += (oldcur > i ? 1 : -1)) + set_selected(bb, bb->files[i], sel); } return BB_OK; } @@ -1133,7 +1115,7 @@ bb_result_t process_cmd(bb_t *bb, const char *cmd) if (!value && !bb->nfiles) return BB_INVALID; if (!value) value = bb->files[bb->cursor]->fullname; entry_t *e = load_entry(bb, value, 1); - if (e) select_entry(bb, e); + if (e) set_selected(bb, e, 1); return BB_OK; } case 'o': // +sort: @@ -1149,7 +1131,7 @@ bb_result_t process_cmd(bb_t *bb, const char *cmd) if (!value && !bb->nfiles) return BB_INVALID; if (!value) value = bb->files[bb->cursor]->fullname; entry_t *e = load_entry(bb, value, 1); - if (e) toggle_entry(bb, e); + if (e) set_selected(bb, e, !IS_SELECTED(e)); return BB_OK; } default: err("UNKNOWN COMMAND: '%s'", cmd); break; @@ -1257,7 +1239,7 @@ void bb_browse(bb_t *bb, const char *path) int clicked = bb->scroll + (mouse_y - 2); if (clicked > bb->nfiles - 1) goto next_input; if (column[1] == COL_SELECTED) { - toggle_entry(bb, bb->files[clicked]); + set_selected(bb, bb->files[clicked], !IS_SELECTED(bb->files[clicked])); bb->dirty = 1; goto redraw; } -- cgit v1.2.3