diff options
Diffstat (limited to 'bb.c')
| -rw-r--r-- | bb.c | 446 |
1 files changed, 195 insertions, 251 deletions
@@ -34,10 +34,15 @@ #define BB_VERSION "0.31.0" #define MAX_BINDINGS 1024 -#define SCROLLOFF MIN(5, (winsize.ws_row-4)/2) +#define SCROLLOFF MIN(5, (winsize.ws_row - 4) / 2) #define ONSCREEN (winsize.ws_row - 3) -#define LOG(...) do { FILE *f = fopen("log.txt", "a"); fprintf(f, __VA_ARGS__); fclose(f); } while (0) +#define LOG(...) \ + do { \ + FILE *f = fopen("log.txt", "a"); \ + fprintf(f, __VA_ARGS__); \ + fclose(f); \ + } while (0) // Functions void bb_browse(bb_t *bb, int argc, char *argv[]); @@ -45,14 +50,13 @@ static void check_cmdfile(bb_t *bb); static void cleanup(void); static void cleanup_and_raise(int sig); static int compare_files(const void *v1, const void *v2); -__attribute__((format(printf,2,3))) -void flash_warn(bb_t *bb, const char *fmt, ...); +__attribute__((format(printf, 2, 3))) void flash_warn(bb_t *bb, const char *fmt, ...); static void handle_next_key_binding(bb_t *bb); static void init_term(void); static int is_simple_bbcmd(const char *s); -static entry_t* load_entry(bb_t *bb, const char *path); +static entry_t *load_entry(bb_t *bb, const char *path); static int matches_cmd(const char *str, const char *cmd); -static char* normalize_path(const char *path, char *pbuf); +static char *normalize_path(const char *path, char *pbuf); static int populate_files(bb_t *bb, const char *path); static void print_bindings(FILE *f); static void run_bbcmd(bb_t *bb, const char *cmd); @@ -73,12 +77,14 @@ static void update_term_size(int sig); static int wait_for_process(proc_t **proc); // Constants -static const char *T_ENTER_BBMODE = T_OFF(T_SHOW_CURSOR ";" T_WRAP) T_ON(T_ALT_SCREEN ";" T_MOUSE_XY ";" T_MOUSE_CELL ";" T_MOUSE_SGR); -static const char *T_LEAVE_BBMODE = T_OFF(T_MOUSE_XY ";" T_MOUSE_CELL ";" T_MOUSE_SGR ";" T_ALT_SCREEN) T_ON(T_SHOW_CURSOR ";" T_WRAP); +static const char *T_ENTER_BBMODE = + T_OFF(T_SHOW_CURSOR ";" T_WRAP) T_ON(T_ALT_SCREEN ";" T_MOUSE_XY ";" T_MOUSE_CELL ";" T_MOUSE_SGR); +static const char *T_LEAVE_BBMODE = + T_OFF(T_MOUSE_XY ";" T_MOUSE_CELL ";" T_MOUSE_SGR ";" T_ALT_SCREEN) T_ON(T_SHOW_CURSOR ";" T_WRAP); static const char *T_LEAVE_BBMODE_PARTIAL = T_OFF(T_MOUSE_XY ";" T_MOUSE_CELL ";" T_MOUSE_SGR) T_ON(T_WRAP); -static const char *description_str = BB_NAME" - an itty bitty console TUI file browser\n"; -static const char *usage_str = "Usage: "BB_NAME" (-h/--help | -v/--version | -s | -d | -0 | +command)* [[--] directory]\n"; - +static const char *description_str = BB_NAME " - an itty bitty console TUI file browser\n"; +static const char *usage_str = + "Usage: " BB_NAME " (-h/--help | -v/--version | -s | -d | -0 | +command)* [[--] directory]\n"; // Variables used within this file to track global state static binding_t bindings[MAX_BINDINGS]; @@ -95,21 +101,20 @@ typedef struct { char filename[PATH_MAX]; } outbuf_t; outbuf_t output_buffers[] = { - {.name="stdout", .orig_fd=STDOUT_FILENO, .dup_fd=-1, .tmp_fd=-1}, - {.name="stderr", .orig_fd=STDERR_FILENO, .dup_fd=-1, .tmp_fd=-1}, + {.name = "stdout", .orig_fd = STDOUT_FILENO, .dup_fd = -1, .tmp_fd = -1}, + {.name = "stderr", .orig_fd = STDERR_FILENO, .dup_fd = -1, .tmp_fd = -1}, }; // // Use bb to browse the filesystem. // -void bb_browse(bb_t *bb, int argc, char *argv[]) -{ +void bb_browse(bb_t *bb, int argc, char *argv[]) { const char *initial_path; - if (argc >= 3 && streq(argv[argc-2], "--")) { - initial_path = argv[argc-1]; + if (argc >= 3 && streq(argv[argc - 2], "--")) { + initial_path = argv[argc - 1]; argc -= 2; - } else if (argc >= 2 && argv[argc-1][0] != '-' && argv[argc-1][0] != '+') { - initial_path = argv[argc-1]; + } else if (argc >= 2 && argv[argc - 1][0] != '-' && argv[argc - 1][0] != '+') { + initial_path = argv[argc - 1]; argc -= 1; } else { initial_path = "."; @@ -124,7 +129,7 @@ void bb_browse(bb_t *bb, int argc, char *argv[]) if (!S_ISDIR(path_stat.st_mode)) { char *slash = strrchr(full_initial_path, '/'); *slash = '\0'; - goto_file = slash+1; + goto_file = slash + 1; } if (populate_files(bb, full_initial_path)) @@ -137,8 +142,7 @@ void bb_browse(bb_t *bb, int argc, char *argv[]) system("bbstartup"); FILE *cmdfile = fopen(cmdfilename, "a"); - if (goto_file) - fprintf(cmdfile, "%cgoto:%s", '\0', goto_file); + if (goto_file) fprintf(cmdfile, "%cgoto:%s", '\0', goto_file); for (int i = 0; i < argc; i++) { if (argv[i][0] == '+') { char *cmd = argv[i] + 1; @@ -166,8 +170,7 @@ void bb_browse(bb_t *bb, int argc, char *argv[]) // Check the bb command file and run any and all commands that have been // written to it. // -static void check_cmdfile(bb_t *bb) -{ +static void check_cmdfile(bb_t *bb) { FILE *cmdfile = fopen(cmdfilename, "r"); if (!cmdfile) return; char *cmd = NULL; @@ -177,7 +180,7 @@ static void check_cmdfile(bb_t *bb) run_bbcmd(bb, cmd); if (bb->should_quit) break; } - delete(&cmd); + delete (&cmd); fclose(cmdfile); unlink(cmdfilename); } @@ -185,8 +188,7 @@ static void check_cmdfile(bb_t *bb) // // Clean up the terminal before going to the default signal handling behavior. // -static void cleanup_and_raise(int sig) -{ +static void cleanup_and_raise(int sig) { cleanup(); int childsig = (sig == SIGTSTP || sig == SIGSTOP) ? sig : SIGHUP; if (current_bb) { @@ -205,8 +207,7 @@ static void cleanup_and_raise(int sig) // // Reset the screen, delete the cmdfile, and print the stdout/stderr buffers // -static void cleanup(void) -{ +static void cleanup(void) { if (cmdfilename[0]) { unlink(cmdfilename); cmdfilename[0] = '\0'; @@ -216,13 +217,13 @@ static void cleanup(void) fflush(tty_out); tcsetattr(fileno(tty_out), TCSANOW, &orig_termios); } - FOREACH(outbuf_t*, ob, output_buffers) { + FOREACH(outbuf_t *, ob, output_buffers) { if (ob->tmp_fd == -1) continue; fflush(ob->orig_fd == STDOUT_FILENO ? stdout : stderr); dup2(ob->dup_fd, ob->orig_fd); lseek(ob->tmp_fd, 0, SEEK_SET); char buf[256]; - for (ssize_t len; (len = read(ob->tmp_fd, buf, LEN(buf))) > 0; ) + for (ssize_t len; (len = read(ob->tmp_fd, buf, LEN(buf))) > 0;) write(ob->orig_fd, buf, len); close(ob->tmp_fd); ob->tmp_fd = ob->dup_fd = -1; @@ -234,12 +235,14 @@ static void cleanup(void) // Used for sorting, this function compares files according to the sorting-related options, // like bb->sort // -static int compare_files(const void *v1, const void *v2) -{ -#define COMPARE(a, b) if ((a) != (b)) { return sign*((a) < (b) ? 1 : -1); } +static int compare_files(const void *v1, const void *v2) { +#define COMPARE(a, b) \ + if ((a) != (b)) { \ + return sign * ((a) < (b) ? 1 : -1); \ + } #define COMPARE_TIME(t1, t2) COMPARE((t1).tv_sec, (t2).tv_sec) COMPARE((t1).tv_nsec, (t2).tv_nsec) bb_t *bb = current_bb; - const entry_t *e1 = *((const entry_t**)v1), *e2 = *((const entry_t**)v2); + const entry_t *e1 = *((const entry_t **)v1), *e2 = *((const entry_t **)v2); int sign = 1; if (!bb->interleave_dirs) { @@ -262,8 +265,8 @@ static int compare_files(const void *v1, const void *v2) while (*n1 && *n2) { char c1 = tolower(*n1), c2 = tolower(*n2); if ('0' <= c1 && c1 <= '9' && '0' <= c2 && c2 <= '9') { - long i1 = strtol(n1, (char**)&n1, 10); - long i2 = strtol(n2, (char**)&n2, 10); + long i1 = strtol(n1, (char **)&n1, 10); + long i2 = strtol(n2, (char **)&n2, 10); // Shorter numbers always go before longer. In practice, I assume // filenames padded to the same number of digits should be grouped // together, instead of @@ -273,7 +276,8 @@ static int compare_files(const void *v1, const void *v2) COMPARE(i2, i1); } else { COMPARE(c2, c1); - ++n1; ++n2; + ++n1; + ++n2; } } COMPARE(tolower(*n2), tolower(*n1)); @@ -297,7 +301,7 @@ static int compare_files(const void *v1, const void *v2) // Flash a warning message at the bottom of the screen. // void flash_warn(bb_t *bb, const char *fmt, ...) { - move_cursor(tty_out, 0, winsize.ws_row-1); + move_cursor(tty_out, 0, winsize.ws_row - 1); fputs("\033[41;33;1m", tty_out); va_list args; va_start(args, fmt); @@ -305,7 +309,8 @@ void flash_warn(bb_t *bb, const char *fmt, ...) { va_end(args); fputs(" Press any key to continue...\033[0m ", tty_out); fflush(tty_out); - while (bgetkey(tty_in, NULL, NULL) == -1) usleep(100); + while (bgetkey(tty_in, NULL, NULL) == -1) + usleep(100); bb->dirty = 1; } @@ -313,8 +318,7 @@ void flash_warn(bb_t *bb, const char *fmt, ...) { // Wait until the user has pressed a key with an associated key binding and run // that binding. // -static void handle_next_key_binding(bb_t *bb) -{ +static void handle_next_key_binding(bb_t *bb) { int key, mouse_x, mouse_y; binding_t *binding; do { @@ -322,13 +326,12 @@ static void handle_next_key_binding(bb_t *bb) struct winsize prevsize = winsize; key = bgetkey(tty_in, &mouse_x, &mouse_y); // Window size changed while waiting for keypress: - if (winsize.ws_row != prevsize.ws_row || winsize.ws_col != prevsize.ws_col) - bb->dirty = 1; + if (winsize.ws_row != prevsize.ws_row || winsize.ws_col != prevsize.ws_col) bb->dirty = 1; if (key == -1 && bb->dirty) return; } while (key == -1); binding = NULL; - FOREACH(binding_t*, b, bindings) { + FOREACH(binding_t *, b, bindings) { if (key == b->key) { binding = b; break; @@ -338,7 +341,7 @@ static void handle_next_key_binding(bb_t *bb) char bbmousecol[2] = {0, 0}, bbclicked[PATH_MAX]; if (mouse_x != -1 && mouse_y != -1) { - int *colwidths = get_column_widths(bb->columns, winsize.ws_col-1); + int *colwidths = get_column_widths(bb->columns, winsize.ws_col - 1); // Get bb column: for (int col = 0, x = 0; bb->columns[col]; col++, x++) { x += colwidths[col]; @@ -349,8 +352,7 @@ static void handle_next_key_binding(bb_t *bb) } if (mouse_y == 1) { strcpy(bbclicked, "<column label>"); - } else if (2 <= mouse_y && mouse_y <= winsize.ws_row - 2 - && bb->scroll + (mouse_y - 2) <= bb->nfiles - 1) { + } else if (2 <= mouse_y && mouse_y <= winsize.ws_row - 2 && bb->scroll + (mouse_y - 2) <= bb->nfiles - 1) { strcpy(bbclicked, bb->files[bb->scroll + (mouse_y - 2)]->fullname); } else { bbclicked[0] = '\0'; @@ -362,15 +364,14 @@ static void handle_next_key_binding(bb_t *bb) if (is_simple_bbcmd(binding->script)) { run_bbcmd(bb, binding->script); } else { - move_cursor(tty_out, 0, winsize.ws_row-1); + move_cursor(tty_out, 0, winsize.ws_row - 1); fputs("\033[K", tty_out); restore_term(&orig_termios); run_script(bb, binding->script); for (entry_t *next, *e = bb->selected; e; e = next) { next = e->selected.next; struct stat buf; - if (stat(e->fullname, &buf) != 0) - set_selected(bb, e, 0); + if (stat(e->fullname, &buf) != 0) set_selected(bb, e, 0); } init_term(); set_title(bb); @@ -386,8 +387,7 @@ static void handle_next_key_binding(bb_t *bb) // Initialize the terminal files for /dev/tty and set up some desired // attributes like passing Ctrl-c as a key instead of interrupting // -static void init_term(void) -{ +static void init_term(void) { nonnegative(tcsetattr(fileno(tty_out), TCSANOW, &bb_termios)); update_term_size(0); // Initiate mouse tracking and disable text wrapping: @@ -399,16 +399,14 @@ static void init_term(void) // Return whether or not 's' is a simple bb command that doesn't need // a full shell instance (e.g. "bbcmd cd:.." or "bbcmd move:+1"). // -static int is_simple_bbcmd(const char *s) -{ +static int is_simple_bbcmd(const char *s) { if (!s) return 0; - while (*s == ' ') ++s; - if (strncmp(s, "bbcmd ", strlen("bbcmd ")) != 0) - return 0; + while (*s == ' ') + ++s; + if (strncmp(s, "bbcmd ", strlen("bbcmd ")) != 0) return 0; const char *special = ";$&<>|\n*?\\\"'"; for (const char *p = special; *p; ++p) { - if (strchr(s, *p)) - return 0; + if (strchr(s, *p)) return 0; } return 1; } @@ -419,22 +417,19 @@ static int is_simple_bbcmd(const char *s) // Warning: this does not deduplicate entries, and it's best if there aren't // duplicate entries hanging around. // -static entry_t* load_entry(bb_t *bb, const char *path) -{ +static entry_t *load_entry(bb_t *bb, const char *path) { struct stat linkedstat, filestat; if (!path || !path[0]) return NULL; if (lstat(path, &filestat) == -1) return NULL; char pbuf[PATH_MAX]; - if (path[0] == '/') - strcpy(pbuf, path); - else - sprintf(pbuf, "%s%s", bb->path, path); - if (pbuf[strlen(pbuf)-1] == '/' && pbuf[1]) - pbuf[strlen(pbuf)-1] = '\0'; + if (path[0] == '/') strcpy(pbuf, path); + else sprintf(pbuf, "%s%s", bb->path, path); + if (pbuf[strlen(pbuf) - 1] == '/' && pbuf[1]) pbuf[strlen(pbuf) - 1] = '\0'; // Check for pre-existing: for (entry_t *e = bb->hash[(int)filestat.st_ino & HASH_MASK]; e; e = e->hash.next) { - if (e->info.st_ino == filestat.st_ino && e->info.st_dev == filestat.st_dev + if (e->info.st_ino == filestat.st_ino + && e->info.st_dev == filestat.st_dev // Need to check filename in case of hard links && streq(pbuf, e->fullname)) return e; @@ -445,25 +440,22 @@ static entry_t* load_entry(bb_t *bb, const char *path) if (S_ISLNK(filestat.st_mode)) { linkpathlen = nonnegative(readlink(pbuf, linkbuf, sizeof(linkbuf)), "Couldn't read link: '%s'", pbuf); linkbuf[linkpathlen] = '\0'; - while (linkpathlen > 0 && linkbuf[linkpathlen-1] == '/') linkbuf[--linkpathlen] = '\0'; + while (linkpathlen > 0 && linkbuf[linkpathlen - 1] == '/') + linkbuf[--linkpathlen] = '\0'; if (stat(pbuf, &linkedstat) == -1) memset(&linkedstat, 0, sizeof(linkedstat)); } size_t pathlen = strlen(pbuf); size_t entry_size = sizeof(entry_t) + (pathlen + 1) + (size_t)(linkpathlen + 1); entry_t *entry = new_bytes(entry_size); char *end = stpcpy(entry->fullname, pbuf); - if (linkpathlen >= 0) - entry->linkname = strcpy(end + 1, linkbuf); + if (linkpathlen >= 0) entry->linkname = strcpy(end + 1, linkbuf); if (streq(entry->fullname, "/")) { entry->name = entry->fullname; } else { - if (strncmp(entry->fullname, bb->path, strlen(bb->path)) == 0) - entry->name = entry->fullname + strlen(bb->path); - else - entry->name = strrchr(entry->fullname, '/') + 1; // Last path component + if (strncmp(entry->fullname, bb->path, strlen(bb->path)) == 0) entry->name = entry->fullname + strlen(bb->path); + else entry->name = strrchr(entry->fullname, '/') + 1; // Last path component } - if (S_ISLNK(filestat.st_mode)) - entry->linkedmode = linkedstat.st_mode; + if (S_ISLNK(filestat.st_mode)) entry->linkedmode = linkedstat.st_mode; entry->info = filestat; LL_PREPEND(bb->hash[(int)filestat.st_ino & HASH_MASK], entry, hash); entry->index = -1; @@ -475,11 +467,10 @@ static entry_t* load_entry(bb_t *bb, const char *path) // Return whether a string matches a command // e.g. matches_cmd("sel:x", "select:") == 1, matches_cmd("q", "quit") == 1 // -static int matches_cmd(const char *str, const char *cmd) -{ - if ((strchr(cmd, ':') == NULL) != (strchr(str, ':') == NULL)) - return 0; - while (*str == *cmd && *cmd && *cmd != ':') ++str, ++cmd; +static int matches_cmd(const char *str, const char *cmd) { + if ((strchr(cmd, ':') == NULL) != (strchr(str, ':') == NULL)) return 0; + while (*str == *cmd && *cmd && *cmd != ':') + ++str, ++cmd; return *str == '\0' || *str == ':'; } @@ -487,8 +478,7 @@ static int matches_cmd(const char *str, const char *cmd) // Prepend `./` to relative paths, replace "~" with $HOME. // The normalized path is stored in `normalized`. // -static char *normalize_path(const char *path, char *normalized) -{ +static char *normalize_path(const char *path, char *normalized) { char pbuf[PATH_MAX] = {0}; if (path[0] == '~' && (path[1] == '\0' || path[1] == '/')) { char *home; @@ -510,25 +500,19 @@ static char *normalize_path(const char *path, char *normalized) // Remove all the files currently stored in bb->files and if `bb->path` is // non-NULL, update `bb` with a listing of the files in `path` // -static int populate_files(bb_t *bb, const char *path) -{ +static int populate_files(bb_t *bb, const char *path) { int clear_future_history = 0; if (path == NULL) ; else if (streq(path, "-")) { - if (!bb->history) - return -1; - if (bb->history->prev) - bb->history = bb->history->prev; + if (!bb->history) return -1; + if (bb->history->prev) bb->history = bb->history->prev; path = bb->history->path; } else if (streq(path, "+")) { - if (!bb->history) - return -1; - if (bb->history->next) - bb->history = bb->history->next; + if (!bb->history) return -1; + if (bb->history->next) bb->history = bb->history->next; path = bb->history->path; - } else - clear_future_history = 1; + } else clear_future_history = 1; int samedir = path && streq(bb->path, path); int old_scroll = bb->scroll; @@ -539,10 +523,8 @@ static int populate_files(bb_t *bb, const char *path) char pbuf[PATH_MAX] = {0}, prev[PATH_MAX] = {0}; strcpy(prev, bb->path); if (path != NULL) { - if (!normalize_path(path, pbuf)) - flash_warn(bb, "Could not normalize path: \"%s\"", path); - if (pbuf[strlen(pbuf)-1] != '/') - strcat(pbuf, "/"); + if (!normalize_path(path, pbuf)) flash_warn(bb, "Could not normalize path: \"%s\"", path); + if (pbuf[strlen(pbuf) - 1] != '/') strcat(pbuf, "/"); if (chdir(pbuf)) { flash_warn(bb, "Could not cd to: \"%s\"", pbuf); return -1; @@ -552,10 +534,10 @@ static int populate_files(bb_t *bb, const char *path) if (clear_future_history && !samedir) { for (bb_history_t *next, *h = bb->history ? bb->history->next : NULL; h; h = next) { next = h->next; - delete(&h); + delete (&h); } - bb_history_t *h = new(bb_history_t); + bb_history_t *h = new (bb_history_t); strcpy(h->path, pbuf); h->prev = bb->history; if (bb->history) bb->history->next = h; @@ -573,21 +555,20 @@ static int populate_files(bb_t *bb, const char *path) try_free_entry(bb->files[i]); bb->files[i] = NULL; } - delete(&bb->files); + delete (&bb->files); } bb->nfiles = 0; bb->cursor = 0; bb->scroll = 0; - if (!bb->path[0]) - return 0; + if (!bb->path[0]) return 0; size_t space = 0; glob_t globbuf = {0}; char *pat, *tmpglob = check_strdup(bb->globpats); while ((pat = strsep(&tmpglob, " ")) != NULL) - glob(pat, GLOB_NOSORT|GLOB_APPEND, NULL, &globbuf); - delete(&tmpglob); + glob(pat, GLOB_NOSORT | GLOB_APPEND, NULL, &globbuf); + delete (&tmpglob); for (size_t i = 0; i < globbuf.gl_pathc; i++) { // Don't normalize path so we can get "." and ".." entry_t *entry = load_entry(bb, globbuf.gl_pathv[i]); @@ -596,8 +577,7 @@ static int populate_files(bb_t *bb, const char *path) continue; } entry->index = bb->nfiles; - if ((size_t)bb->nfiles + 1 > space) - bb->files = grow(bb->files, space += 100); + if ((size_t)bb->nfiles + 1 > space) bb->files = grow(bb->files, space += 100); bb->files[bb->nfiles++] = entry; } globfree(&globbuf); @@ -609,7 +589,7 @@ static int populate_files(bb_t *bb, const char *path) seed ^= ((bb->files[i]->info.st_ino ^ 89869747UL) ^ (bb->files[i]->info.st_ino << 16)) * 3644798167UL; srand((unsigned int)seed); for (int i = 0; i < bb->nfiles; i++) { - int j = rand() % (i+1); // This introduces some RNG bias, but it's not important here + int j = rand() % (i + 1); // This introduces some RNG bias, but it's not important here bb->files[i]->shufflepos = bb->files[j]->shufflepos; bb->files[j]->shufflepos = i; } @@ -617,7 +597,7 @@ static int populate_files(bb_t *bb, const char *path) sort_files(bb); if (samedir) { set_scroll(bb, old_scroll); - bb->cursor = old_cursor > bb->nfiles-1 ? bb->nfiles-1 : old_cursor; + bb->cursor = old_cursor > bb->nfiles - 1 ? bb->nfiles - 1 : old_cursor; if (old_selected[0]) { entry_t *e = load_entry(bb, old_selected); if (e) set_cursor(bb, e->index); @@ -635,25 +615,25 @@ static int populate_files(bb_t *bb, const char *path) // // Print the current key bindings // -static void print_bindings(FILE *f) -{ - FOREACH(binding_t*, b, bindings) { +static void print_bindings(FILE *f) { + FOREACH(binding_t *, b, bindings) { if (!b->description) break; if (b->key == -1) { const char *label = b->description; - fprintf(f, "\n\033[33;1;4m\033[%dG%s\033[0m\n", (winsize.ws_col-(int)strlen(label))/2, label); + fprintf(f, "\n\033[33;1;4m\033[%dG%s\033[0m\n", (winsize.ws_col - (int)strlen(label)) / 2, label); continue; } char buf[1000]; char *p = buf; - for (binding_t *next = b; next < &bindings[LEN(bindings)] && next->script && streq(b->description, next->description); next++) { + for (binding_t *next = b; + next < &bindings[LEN(bindings)] && next->script && streq(b->description, next->description); next++) { if (next > b) p = stpcpy(p, ", "); p = bkeyname(next->key, p); b = next; } *p = '\0'; - fprintf(f, "\033[1m\033[%dG%s\033[0m", winsize.ws_col/2 - 1 - (int)strlen(buf), buf); - fprintf(f, "\033[1m\033[%dG\033[34m%s\033[0m", winsize.ws_col/2 + 1, b->description); + fprintf(f, "\033[1m\033[%dG%s\033[0m", winsize.ws_col / 2 - 1 - (int)strlen(buf), buf); + fprintf(f, "\033[1m\033[%dG\033[34m%s\033[0m", winsize.ws_col / 2 + 1, b->description); fprintf(f, "\033[0m\n"); } fprintf(f, "\n"); @@ -663,19 +643,22 @@ static void print_bindings(FILE *f) // Run a bb internal command (e.g. "+refresh") and return an indicator of what // needs to happen next. // -static void run_bbcmd(bb_t *bb, const char *cmd) -{ - while (*cmd == ' ' || *cmd == '\n') ++cmd; +static void run_bbcmd(bb_t *bb, const char *cmd) { + while (*cmd == ' ' || *cmd == '\n') + ++cmd; if (strncmp(cmd, "bbcmd ", strlen("bbcmd ")) == 0) cmd = &cmd[strlen("bbcmd ")]; const char *value = strchr(cmd, ':'); if (value) ++value; if (matches_cmd(cmd, "bind:")) { // +bind:<keys>:<script> char *value_copy = check_strdup(value); char *keys = trim(value_copy); - if (!keys[0]) { delete(&value_copy); return; } - char *script = strchr(keys+1, ':'); + if (!keys[0]) { + delete (&value_copy); + return; + } + char *script = strchr(keys + 1, ':'); if (!script) { - delete(&value_copy); + delete (&value_copy); flash_warn(bb, "No script provided."); return; } @@ -684,10 +667,10 @@ static void run_bbcmd(bb_t *bb, const char *cmd) char *description; if (script[0] == '#') { description = trim(strsep(&script, "\n") + 1); - if (!script) script = (char*)""; + if (!script) script = (char *)""; else script = trim(script); } else description = script; - for (char *key; (key = strsep(&keys, ",")); ) { + for (char *key; (key = strsep(&keys, ","));) { int keyval; if (streq(key, "Section")) { keyval = -1; @@ -695,32 +678,29 @@ static void run_bbcmd(bb_t *bb, const char *cmd) keyval = bkeywithname(key); if (keyval == -1) continue; // Delete existing bindings for this key (if any): - FOREACH(binding_t*, b, bindings) { + FOREACH(binding_t *, b, bindings) { if (b->key == keyval) { - delete((char**)&b->description); - delete((char**)&b->script); + delete ((char **)&b->description); + delete ((char **)&b->script); int i = (int)(b - bindings); - memmove(&bindings[i], &bindings[i+1], sizeof(binding_t)*(LEN(bindings) - i - 1)); - memset(&bindings[LEN(bindings)-1], 0, sizeof(binding_t)); + memmove(&bindings[i], &bindings[i + 1], sizeof(binding_t) * (LEN(bindings) - i - 1)); + memset(&bindings[LEN(bindings) - 1], 0, sizeof(binding_t)); } } } // Append binding: - FOREACH(binding_t*, b, bindings) { + FOREACH(binding_t *, b, bindings) { if (b->script) continue; b->key = keyval; - if (is_simple_bbcmd(script)) - b->script = check_strdup(script); - else - nonnegative(asprintf((char**)&b->script, "set -e\n%s", script), "Could not copy script"); + if (is_simple_bbcmd(script)) b->script = check_strdup(script); + else nonnegative(asprintf((char **)&b->script, "set -e\n%s", script), "Could not copy script"); b->description = check_strdup(description); break; } } - delete(&value_copy); + delete (&value_copy); } else if (matches_cmd(cmd, "cd:")) { // +cd: - if (populate_files(bb, value)) - flash_warn(bb, "Could not open directory: \"%s\"", value); + if (populate_files(bb, value)) flash_warn(bb, "Could not open directory: \"%s\"", value); } else if (matches_cmd(cmd, "columns:")) { // +columns: set_columns(bb, value); } else if (matches_cmd(cmd, "deselect")) { // +deselect @@ -743,14 +723,15 @@ static void run_bbcmd(bb_t *bb, const char *cmd) } } else if (matches_cmd(cmd, "fg:") || matches_cmd(cmd, "fg")) { // +fg: int nprocs = 0; - for (proc_t *p = bb->running_procs; p; p = p->running.next) ++nprocs; + for (proc_t *p = bb->running_procs; p; p = p->running.next) + ++nprocs; int fg = value ? nprocs - (int)strtol(value, NULL, 10) : 0; proc_t *child = NULL; for (proc_t *p = bb->running_procs; p && !child; p = p->running.next) { if (fg-- == 0) child = p; } if (!child) return; - move_cursor(tty_out, 0, winsize.ws_row-1); + move_cursor(tty_out, 0, winsize.ws_row - 1); fputs("\033[K", tty_out); restore_term(&orig_termios); signal(SIGTTOU, SIG_IGN); @@ -779,12 +760,11 @@ static void run_bbcmd(bb_t *bb, const char *cmd) try_free_entry(e); // Move to dir and reselect populate_files(bb, pbuf); - e = load_entry(bb, lastslash+1); + e = load_entry(bb, lastslash + 1); if (!e) { - flash_warn(bb, "Could not find file again: \"%s\"", lastslash+1); + flash_warn(bb, "Could not find file again: \"%s\"", lastslash + 1); } - if (IS_VIEWED(e)) - set_cursor(bb, e->index); + if (IS_VIEWED(e)) set_cursor(bb, e->index); else try_free_entry(e); } else if (matches_cmd(cmd, "help")) { // +help FILE *p = popen("less -rfKX >/dev/tty", "w"); @@ -797,13 +777,12 @@ static void run_bbcmd(bb_t *bb, const char *cmd) sort_files(bb); } else if (matches_cmd(cmd, "move:")) { // +move: int oldcur, isdelta, n; - move: + move: if (bb->nfiles == 0) return; oldcur = bb->cursor; isdelta = value[0] == '-' || value[0] == '+'; - n = (int)strtol(value, (char**)&value, 10); - if (*value == '%') - n = (n * (value[1] == 'n' ? bb->nfiles : winsize.ws_row)) / 100; + n = (int)strtol(value, (char **)&value, 10); + if (*value == '%') n = (n * (value[1] == 'n' ? bb->nfiles : winsize.ws_row)) / 100; if (isdelta) set_cursor(bb, bb->cursor + n); else set_cursor(bb, n); if (matches_cmd(cmd, "spread:")) { // +spread: @@ -818,13 +797,10 @@ static void run_bbcmd(bb_t *bb, const char *cmd) } else if (matches_cmd(cmd, "scroll:")) { // +scroll: // TODO: figure out the best version of this int isdelta = value[0] == '+' || value[0] == '-'; - int n = (int)strtol(value, (char**)&value, 10); - if (*value == '%') - n = (n * (value[1] == 'n' ? bb->nfiles : winsize.ws_row)) / 100; - if (isdelta) - set_scroll(bb, bb->scroll + n); - else - set_scroll(bb, n); + int n = (int)strtol(value, (char **)&value, 10); + if (*value == '%') n = (n * (value[1] == 'n' ? bb->nfiles : winsize.ws_row)) / 100; + if (isdelta) set_scroll(bb, bb->scroll + n); + else set_scroll(bb, n); } else if (matches_cmd(cmd, "select")) { // +select for (int i = 0; i < bb->nfiles; i++) set_selected(bb, bb->files[i], 1); @@ -852,8 +828,7 @@ static void run_bbcmd(bb_t *bb, const char *cmd) // // Close the /dev/tty terminals and restore some of the attributes. // -static void restore_term(const struct termios *term) -{ +static void restore_term(const struct termios *term) { tcsetattr(fileno(tty_out), TCSANOW, term); fputs(T_LEAVE_BBMODE_PARTIAL, tty_out); fflush(tty_out); @@ -864,19 +839,18 @@ static void restore_term(const struct termios *term) // the script (or pass the cursor file if none are selected). // Return the exit status of the script. // -static int run_script(bb_t *bb, const char *cmd) -{ - proc_t *proc = new(proc_t); +static int run_script(bb_t *bb, const char *cmd) { + proc_t *proc = new (proc_t); signal(SIGTTOU, SIG_IGN); if ((proc->pid = nonnegative(fork())) == 0) { pid_t pgrp = getpid(); (void)setpgid(0, pgrp); nonnegative(tcsetpgrp(STDIN_FILENO, pgrp)); - const char **args = new(char*[4 + (size_t)bb->nselected + 1]); + const char **args = new (char * [4 + (size_t)bb->nselected + 1]); int i = 0; args[i++] = "sh"; args[i++] = "-c"; - args[i++] = (char*)cmd; + args[i++] = (char *)cmd; args[i++] = "--"; // ensure files like "-i" are not interpreted as flags for sh // bb->selected is in most-recent order, so populate args in reverse to make sure // that $1 is the first selected, etc. @@ -889,7 +863,7 @@ static int run_script(bb_t *bb, const char *cmd) dup2(fileno(tty_out), STDOUT_FILENO); dup2(fileno(tty_out), STDERR_FILENO); dup2(fileno(tty_in), STDIN_FILENO); - execvp(args[0], (char**)args); + execvp(args[0], (char **)args); err(EXIT_FAILURE, "Failed to execute command: '%s'", cmd); return -1; } @@ -904,8 +878,7 @@ static int run_script(bb_t *bb, const char *cmd) // // Set the columns displayed by bb. // -static void set_columns(bb_t *bb, const char *cols) -{ +static void set_columns(bb_t *bb, const char *cols) { strncpy(bb->columns, cols, MAX_COLS); setenv("BBCOLUMNS", bb->columns, 1); } @@ -913,8 +886,7 @@ static void set_columns(bb_t *bb, const char *cols) // // Set bb's file cursor to the given index (and adjust the scroll as necessary) // -static void set_cursor(bb_t *bb, int newcur) -{ +static void set_cursor(bb_t *bb, int newcur) { int oldcur = bb->cursor; if (newcur > bb->nfiles - 1) newcur = bb->nfiles - 1; if (newcur < 0) newcur = 0; @@ -925,36 +897,30 @@ static void set_cursor(bb_t *bb, int newcur) } if (oldcur < bb->cursor) { - if (bb->scroll > bb->cursor) - bb->scroll = MAX(0, bb->cursor); + if (bb->scroll > bb->cursor) bb->scroll = MAX(0, bb->cursor); else if (bb->scroll < bb->cursor - ONSCREEN + 1 + SCROLLOFF) - bb->scroll = MIN(bb->nfiles - 1 - ONSCREEN + 1, - bb->scroll + (newcur - oldcur)); + bb->scroll = MIN(bb->nfiles - 1 - ONSCREEN + 1, bb->scroll + (newcur - oldcur)); } else { if (bb->scroll > bb->cursor - SCROLLOFF) - bb->scroll = MAX(0, bb->scroll + (newcur - oldcur));//bb->cursor - SCROLLOFF); + bb->scroll = MAX(0, bb->scroll + (newcur - oldcur)); // bb->cursor - SCROLLOFF); else if (bb->scroll < bb->cursor - ONSCREEN + 1) - bb->scroll = MIN(bb->cursor - ONSCREEN + 1, - bb->nfiles - 1 - ONSCREEN + 1); + bb->scroll = MIN(bb->cursor - ONSCREEN + 1, bb->nfiles - 1 - ONSCREEN + 1); } } // // Set the glob pattern(s) used by bb. Patterns are ' ' delimited // -static void set_globs(bb_t *bb, const char *globs) -{ - delete(&bb->globpats); +static void set_globs(bb_t *bb, const char *globs) { + delete (&bb->globpats); bb->globpats = check_strdup(globs); setenv("BBGLOB", bb->globpats, 1); } - // // Set whether or not bb should interleave directories and files. // -static void set_interleave(bb_t *bb, int interleave) -{ +static void set_interleave(bb_t *bb, int interleave) { bb->interleave_dirs = interleave; if (interleave) setenv("BBINTERLEAVE", "interleave", 1); else unsetenv("BBINTERLEAVE"); @@ -964,14 +930,12 @@ static void set_interleave(bb_t *bb, int interleave) // // Set bb's scroll to the given index (and adjust the cursor as necessary) // -static void set_scroll(bb_t *bb, int newscroll) -{ +static void set_scroll(bb_t *bb, int newscroll) { int delta = newscroll - bb->scroll; if (bb->nfiles <= ONSCREEN) { newscroll = 0; } else { - if (newscroll > bb->nfiles - 1 - ONSCREEN + 1) - newscroll = bb->nfiles - 1 - ONSCREEN + 1; + if (newscroll > bb->nfiles - 1 - ONSCREEN + 1) newscroll = bb->nfiles - 1 - ONSCREEN + 1; if (newscroll < 0) newscroll = 0; } @@ -984,12 +948,10 @@ static void set_scroll(bb_t *bb, int newscroll) // // Select or deselect a file. // -static void set_selected(bb_t *bb, entry_t *e, int selected) -{ +static void set_selected(bb_t *bb, entry_t *e, int selected) { if (IS_SELECTED(e) == selected) return; - if (bb->nfiles > 0 && e != bb->files[bb->cursor]) - bb->dirty = 1; + if (bb->nfiles > 0 && e != bb->files[bb->cursor]) bb->dirty = 1; if (selected) { LL_PREPEND(bb->selected, e, selected); @@ -1004,21 +966,18 @@ static void set_selected(bb_t *bb, entry_t *e, int selected) // // Set the sorting method used by bb to display files. // -static void set_sort(bb_t *bb, const char *sort) -{ - char sortbuf[MAX_SORT+1]; +static void set_sort(bb_t *bb, const char *sort) { + char sortbuf[MAX_SORT + 1]; strncpy(sortbuf, sort, MAX_SORT); for (char *s = sortbuf; s[0] && s[1]; s += 2) { char *found = strchr(bb->sort, s[1]); if (found) { - if (*s == '~') - *s = found[-1] == '+' && found == &bb->sort[1] ? '-' : '+'; - memmove(found-1, found+1, strlen(found+1)+1); - } else if (*s == '~') - *s = '+'; + if (*s == '~') *s = found[-1] == '+' && found == &bb->sort[1] ? '-' : '+'; + memmove(found - 1, found + 1, strlen(found + 1) + 1); + } else if (*s == '~') *s = '+'; } size_t len = MIN(MAX_SORT, strlen(sort)); - memmove(bb->sort + len, bb->sort, MAX_SORT+1 - len); + memmove(bb->sort + len, bb->sort, MAX_SORT + 1 - len); memmove(bb->sort, sortbuf, len); setenv("BBSORT", bb->sort, 1); } @@ -1026,33 +985,29 @@ static void set_sort(bb_t *bb, const char *sort) // // Set the xwindow title property to: bb - current path // -static void set_title(bb_t *bb) -{ +static void set_title(bb_t *bb) { char *home = getenv("HOME"); if (home && strncmp(bb->path, home, strlen(home)) == 0) - fprintf(tty_out, "\033]2;"BB_NAME": ~%s\007", bb->path + strlen(home)); - else - fprintf(tty_out, "\033]2;"BB_NAME": %s\007", bb->path); + fprintf(tty_out, "\033]2;" BB_NAME ": ~%s\007", bb->path + strlen(home)); + else fprintf(tty_out, "\033]2;" BB_NAME ": %s\007", bb->path); } // // If the given entry is not viewed or selected, remove it from the // hash, free it, and return 1. // -static int try_free_entry(entry_t *e) -{ +static int try_free_entry(entry_t *e) { if (IS_SELECTED(e) || IS_VIEWED(e) || !IS_LOADED(e)) return 0; LL_REMOVE(e, hash); - delete(&e); + delete (&e); return 1; } // // Sort the files in bb according to bb's settings. // -static void sort_files(bb_t *bb) -{ - qsort(bb->files, (size_t)bb->nfiles, sizeof(entry_t*), compare_files); +static void sort_files(bb_t *bb) { + qsort(bb->files, (size_t)bb->nfiles, sizeof(entry_t *), compare_files); for (int i = 0; i < bb->nfiles; i++) bb->files[i]->index = i; bb->dirty = 1; @@ -1062,12 +1017,12 @@ static void sort_files(bb_t *bb) // Trim trailing whitespace by inserting '\0' and return a pointer to after the // first non-whitespace char // -static char *trim(char *s) -{ +static char *trim(char *s) { if (!s) return NULL; - while (*s == ' ' || *s == '\n') ++s; + while (*s == ' ' || *s == '\n') + ++s; char *end; - for (end = &s[strlen(s)-1]; end >= s && (*end == ' ' || *end == '\n'); end--) + for (end = &s[strlen(s) - 1]; end >= s && (*end == ' ' || *end == '\n'); end--) *end = '\0'; return s; } @@ -1075,8 +1030,7 @@ static char *trim(char *s) // // Hanlder for SIGWINCH events // -static void update_term_size(int sig) -{ +static void update_term_size(int sig) { (void)sig; ioctl(STDIN_FILENO, TIOCGWINSZ, &winsize); } @@ -1084,43 +1038,38 @@ static void update_term_size(int sig) // // Wait for a process to either suspend or exit and return the status. // -static int wait_for_process(proc_t **proc) -{ +static int wait_for_process(proc_t **proc) { tcsetpgrp(fileno(tty_out), (*proc)->pid); int status; while (*proc) { - if (waitpid((*proc)->pid, &status, WUNTRACED) < 0) - continue; + if (waitpid((*proc)->pid, &status, WUNTRACED) < 0) continue; if (WIFEXITED(status) || WIFSIGNALED(status)) { LL_REMOVE((*proc), running); - delete(proc); - } else if (WIFSTOPPED(status)) - break; + delete (proc); + } else if (WIFSTOPPED(status)) break; } nonnegative(tcsetpgrp(fileno(tty_out), getpid())); signal(SIGTTOU, SIG_DFL); return status; } -int main(int argc, char *argv[]) -{ +int main(int argc, char *argv[]) { char sep = '\n'; int print_dir = 0, print_selection = 0; for (int i = 1; i < argc; i++) { // Commands are processed below, after flags have been parsed if (argv[i][0] == '+') { char *colon = strchr(argv[i], ':'); - if (colon && !colon[1]) - break; + if (colon && !colon[1]) break; } else if (streq(argv[i], "--")) { break; } else if (streq(argv[i], "--help")) { - help: + help: printf("%s%s", description_str, usage_str); return 0; } else if (streq(argv[i], "--version")) { - version: - printf(BB_NAME" "BB_VERSION"\n"); + version: + printf(BB_NAME " " BB_VERSION "\n"); return 0; } else if (argv[i][0] == '-' && argv[i][1] != '-') { for (char *c = &argv[i][1]; *c; c++) { @@ -1130,11 +1079,10 @@ int main(int argc, char *argv[]) case 'd': print_dir = 1; break; case '0': sep = '\0'; break; case 's': print_selection = 1; break; - default: printf("Unknown command line argument: -%c\n%s", *c, usage_str); - return 1; + default: printf("Unknown command line argument: -%c\n%s", *c, usage_str); return 1; } } - } else if (i < argc-1) { + } else if (i < argc - 1) { printf("Unknown command line argument: \"%s\"\n%s", argv[i], usage_str); return 1; } @@ -1150,10 +1098,9 @@ int main(int argc, char *argv[]) // Set up environment variables // Default values setenv("TMPDIR", "/tmp", 0); - sprintf(cmdfilename, "%s/"BB_NAME".cmd.XXXXXX", getenv("TMPDIR")); - int cmdfd = nonnegative( - mkostemp(cmdfilename, O_APPEND), - "Couldn't create "BB_NAME" command file: '%s'", cmdfilename); + sprintf(cmdfilename, "%s/" BB_NAME ".cmd.XXXXXX", getenv("TMPDIR")); + int cmdfd = + nonnegative(mkostemp(cmdfilename, O_APPEND), "Couldn't create " BB_NAME " command file: '%s'", cmdfilename); close(cmdfd); setenv("BBCMD", cmdfilename, 1); char xdg_config_home[PATH_MAX], xdg_data_home[PATH_MAX]; @@ -1174,15 +1121,13 @@ int main(int argc, char *argv[]) setenv("BBPATH", bbpath, 1); } if (getenv("BBPATH")) { - nonnegative( - asprintf(&newpath, "%s/"BB_NAME":%s/scripts:%s", - getenv("XDG_CONFIG_HOME"), getenv("BBPATH"), getenv("PATH")), - "Could not allocate memory for PATH"); + nonnegative(asprintf(&newpath, "%s/" BB_NAME ":%s/scripts:%s", getenv("XDG_CONFIG_HOME"), getenv("BBPATH"), + getenv("PATH")), + "Could not allocate memory for PATH"); } else { - nonnegative( - asprintf(&newpath, "%s/"BB_NAME":%s/"BB_NAME":%s", - getenv("XDG_CONFIG_HOME"), getenv("sysconfdir"), getenv("PATH")), - "Could not allocate memory for PATH"); + nonnegative(asprintf(&newpath, "%s/" BB_NAME ":%s/" BB_NAME ":%s", getenv("XDG_CONFIG_HOME"), + getenv("sysconfdir"), getenv("PATH")), + "Could not allocate memory for PATH"); } setenv("PATH", newpath, 1); @@ -1196,8 +1141,8 @@ int main(int argc, char *argv[]) atexit(cleanup); - FOREACH(outbuf_t*, ob, output_buffers) { - sprintf(ob->filename, "%s/"BB_NAME".%s.XXXXXX", getenv("TMPDIR"), ob->name); + FOREACH(outbuf_t *, ob, output_buffers) { + sprintf(ob->filename, "%s/" BB_NAME ".%s.XXXXXX", getenv("TMPDIR"), ob->name); ob->tmp_fd = nonnegative(mkostemp(ob->filename, O_RDWR), "Couldn't create error file"); ob->dup_fd = nonnegative(dup(ob->orig_fd)); nonnegative(dup2(ob->tmp_fd, ob->orig_fd), "Couldn't redirect error output"); @@ -1234,17 +1179,16 @@ int main(int argc, char *argv[]) } } - if (print_dir) - printf("%s\n", bb.path); + if (print_dir) printf("%s\n", bb.path); // Cleanup: populate_files(&bb, NULL); while (bb.selected) set_selected(&bb, bb.selected, 0); - delete(&bb.globpats); + delete (&bb.globpats); for (bb_history_t *next; bb.history; bb.history = next) { next = bb.history->next; - delete(&bb.history); + delete (&bb.history); } return 0; } |
