More code cleanup, including tweaking matches_cmd() to figure out if
there are required arguments or not, and refactoring run_bbcmd() to no longer return a value (which was ignored), but instead just spit out error messages to stderr if necessary.
This commit is contained in:
parent
d77907783f
commit
55daca6a2f
97
bb.c
97
bb.c
@ -27,8 +27,8 @@ void bb_browse(bb_t *bb, const char *path)
|
|||||||
bb->scroll = 0;
|
bb->scroll = 0;
|
||||||
bb->cursor = 0;
|
bb->cursor = 0;
|
||||||
bb->dirty = 0;
|
bb->dirty = 0;
|
||||||
|
bb->should_quit = 0;
|
||||||
|
|
||||||
init_term();
|
|
||||||
goto force_check_cmds;
|
goto force_check_cmds;
|
||||||
|
|
||||||
while (!bb->should_quit) {
|
while (!bb->should_quit) {
|
||||||
@ -400,11 +400,13 @@ entry_t* load_entry(bb_t *bb, const char *path, int clear_dots)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Return whether a string matches a command
|
* Return whether a string matches a command
|
||||||
* e.g. matches_cmd("cd:..", "cd") == 1, matches_cmd("q", "quit") == 1
|
* e.g. matches_cmd("sel:x", "select:") == 1, matches_cmd("q", "quit") == 1
|
||||||
*/
|
*/
|
||||||
static inline int matches_cmd(const char *str, const char *cmd)
|
static inline int matches_cmd(const char *str, const char *cmd)
|
||||||
{
|
{
|
||||||
while (*str == *cmd && *cmd) ++str, ++cmd;
|
if ((strchr(cmd, ':') == NULL) != (strchr(str, ':') == NULL))
|
||||||
|
return 0;
|
||||||
|
while (*str == *cmd && *cmd && *cmd != ':') ++str, ++cmd;
|
||||||
return *str == '\0' || *str == ':';
|
return *str == '\0' || *str == ':';
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -568,7 +570,7 @@ void print_bindings(int fd)
|
|||||||
* Run a bb internal command (e.g. "+refresh") and return an indicator of what
|
* Run a bb internal command (e.g. "+refresh") and return an indicator of what
|
||||||
* needs to happen next.
|
* needs to happen next.
|
||||||
*/
|
*/
|
||||||
bb_result_t run_bbcmd(bb_t *bb, const char *cmd)
|
void run_bbcmd(bb_t *bb, const char *cmd)
|
||||||
{
|
{
|
||||||
if (cmd[0] == '+') ++cmd;
|
if (cmd[0] == '+') ++cmd;
|
||||||
else if (strncmp(cmd, "bb +", 4) == 0) cmd = &cmd[4];
|
else if (strncmp(cmd, "bb +", 4) == 0) cmd = &cmd[4];
|
||||||
@ -581,14 +583,15 @@ bb_result_t run_bbcmd(bb_t *bb, const char *cmd)
|
|||||||
} else if (matches_cmd(cmd, ".")) { // +.
|
} else if (matches_cmd(cmd, ".")) { // +.
|
||||||
set_bool(bb->show_dot);
|
set_bool(bb->show_dot);
|
||||||
populate_files(bb, 1);
|
populate_files(bb, 1);
|
||||||
} else if (matches_cmd(cmd, "bind")) { // +bind:<keys>:<script>
|
} else if (matches_cmd(cmd, "bind:")) { // +bind:<keys>:<script>
|
||||||
if (!value || !value[0])
|
|
||||||
return BB_INVALID;
|
|
||||||
char *value_copy = memcheck(strdup(value));
|
char *value_copy = memcheck(strdup(value));
|
||||||
char *keys = trim(value_copy);
|
char *keys = trim(value_copy);
|
||||||
if (!keys[0]) { free(value_copy); return BB_OK; }
|
if (!keys[0]) { free(value_copy); return; }
|
||||||
char *script = strchr(keys+1, ':');
|
char *script = strchr(keys+1, ':');
|
||||||
if (!script) { free(value_copy); return BB_INVALID; }
|
if (!script) {
|
||||||
|
free(value_copy);
|
||||||
|
goto invalid_cmd;
|
||||||
|
}
|
||||||
*script = '\0';
|
*script = '\0';
|
||||||
script = trim(script + 1);
|
script = trim(script + 1);
|
||||||
char *description;
|
char *description;
|
||||||
@ -617,25 +620,18 @@ bb_result_t run_bbcmd(bb_t *bb, const char *cmd)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
free(value_copy);
|
free(value_copy);
|
||||||
} else if (matches_cmd(cmd, "cd")) { // +cd:
|
} else if (matches_cmd(cmd, "cd:")) { // +cd:
|
||||||
if (!value) return BB_INVALID;
|
if (cd_to(bb, value)) goto invalid_cmd;
|
||||||
if (cd_to(bb, value)) return BB_INVALID;
|
} else if (matches_cmd(cmd, "columns:")) { // +columns:
|
||||||
} else if (matches_cmd(cmd, "columns")) { // +columns:
|
|
||||||
if (!value) return BB_INVALID;
|
|
||||||
strncpy(bb->columns, value, MAX_COLS);
|
strncpy(bb->columns, value, MAX_COLS);
|
||||||
bb->dirty = 1;
|
bb->dirty = 1;
|
||||||
} else if (matches_cmd(cmd, "deselect")) { // +deselect
|
} else if (matches_cmd(cmd, "deselect:")) { // +deselect
|
||||||
if (!value) {
|
|
||||||
while (bb->firstselected)
|
|
||||||
set_selected(bb, bb->firstselected, 0);
|
|
||||||
return BB_OK;
|
|
||||||
}
|
|
||||||
char pbuf[PATH_MAX];
|
char pbuf[PATH_MAX];
|
||||||
normalize_path(bb->path, value, pbuf, 1);
|
normalize_path(bb->path, value, pbuf, 1);
|
||||||
entry_t *e = load_entry(bb, pbuf, 0);
|
entry_t *e = load_entry(bb, pbuf, 0);
|
||||||
if (e) {
|
if (e) {
|
||||||
set_selected(bb, e, 0);
|
set_selected(bb, e, 0);
|
||||||
return BB_OK;
|
return;
|
||||||
}
|
}
|
||||||
// Filename may no longer exist:
|
// Filename may no longer exist:
|
||||||
for (e = bb->firstselected; e; e = e->selected.next) {
|
for (e = bb->firstselected; e; e = e->selected.next) {
|
||||||
@ -644,28 +640,30 @@ bb_result_t run_bbcmd(bb_t *bb, const char *cmd)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (matches_cmd(cmd, "dotfiles")) { // +dotfiles:
|
} else if (matches_cmd(cmd, "deselect")) { // +deselect
|
||||||
|
while (bb->firstselected)
|
||||||
|
set_selected(bb, bb->firstselected, 0);
|
||||||
|
return;
|
||||||
|
} else if (matches_cmd(cmd, "dotfiles:") || matches_cmd(cmd, "dotfiles")) { // +dotfiles:
|
||||||
set_bool(bb->show_dotfiles);
|
set_bool(bb->show_dotfiles);
|
||||||
populate_files(bb, 1);
|
populate_files(bb, 1);
|
||||||
} else if (matches_cmd(cmd, "execute")) { // +execute:
|
} else if (matches_cmd(cmd, "execute:")) { // +execute:
|
||||||
if (!value || !value[0]) return BB_INVALID;
|
|
||||||
move_cursor(tty_out, 0, termheight-1);
|
move_cursor(tty_out, 0, termheight-1);
|
||||||
fputs(T_ON(T_SHOW_CURSOR), tty_out);
|
fputs(T_ON(T_SHOW_CURSOR), tty_out);
|
||||||
restore_term(&default_termios);
|
restore_term(&default_termios);
|
||||||
run_script(bb, value);
|
run_script(bb, value);
|
||||||
init_term();
|
init_term();
|
||||||
} else if (matches_cmd(cmd, "goto")) { // +goto:
|
} else if (matches_cmd(cmd, "goto:")) { // +goto:
|
||||||
if (!value) return BB_INVALID;
|
|
||||||
entry_t *e = load_entry(bb, value, 1);
|
entry_t *e = load_entry(bb, value, 1);
|
||||||
if (!e) return BB_INVALID;
|
if (!e) goto invalid_cmd;
|
||||||
if (IS_VIEWED(e)) {
|
if (IS_VIEWED(e)) {
|
||||||
set_cursor(bb, e->index);
|
set_cursor(bb, e->index);
|
||||||
return BB_OK;
|
return;
|
||||||
}
|
}
|
||||||
char pbuf[PATH_MAX];
|
char pbuf[PATH_MAX];
|
||||||
strcpy(pbuf, e->fullname);
|
strcpy(pbuf, e->fullname);
|
||||||
char *lastslash = strrchr(pbuf, '/');
|
char *lastslash = strrchr(pbuf, '/');
|
||||||
if (!lastslash) return BB_INVALID;
|
if (!lastslash) err("No slash found in filename: %s", pbuf);
|
||||||
*lastslash = '\0'; // Split in two
|
*lastslash = '\0'; // Split in two
|
||||||
cd_to(bb, pbuf);
|
cd_to(bb, pbuf);
|
||||||
if (IS_VIEWED(e))
|
if (IS_VIEWED(e))
|
||||||
@ -691,16 +689,15 @@ bb_result_t run_bbcmd(bb_t *bb, const char *cmd)
|
|||||||
init_term();
|
init_term();
|
||||||
signal(SIGINT, old_handler);
|
signal(SIGINT, old_handler);
|
||||||
bb->dirty = 1;
|
bb->dirty = 1;
|
||||||
} else if (matches_cmd(cmd, "interleave")) { // +interleave
|
} else if (matches_cmd(cmd, "interleave:") || matches_cmd(cmd, "interleave")) { // +interleave
|
||||||
set_bool(bb->interleave_dirs);
|
set_bool(bb->interleave_dirs);
|
||||||
sort_files(bb);
|
sort_files(bb);
|
||||||
} else if (matches_cmd(cmd, "kill")) { // +kill
|
} else if (matches_cmd(cmd, "kill")) { // +kill
|
||||||
exit(1);
|
exit(EXIT_FAILURE);
|
||||||
} else if (matches_cmd(cmd, "move")) { // +move:
|
} else if (matches_cmd(cmd, "move:")) { // +move:
|
||||||
int oldcur, isdelta, n;
|
int oldcur, isdelta, n;
|
||||||
move:
|
move:
|
||||||
if (!value) return BB_INVALID;
|
if (bb->nfiles == 0) return;
|
||||||
if (!bb->nfiles) return BB_INVALID;
|
|
||||||
oldcur = bb->cursor;
|
oldcur = bb->cursor;
|
||||||
isdelta = value[0] == '-' || value[0] == '+';
|
isdelta = value[0] == '-' || value[0] == '+';
|
||||||
n = (int)strtol(value, (char**)&value, 10);
|
n = (int)strtol(value, (char**)&value, 10);
|
||||||
@ -708,7 +705,7 @@ bb_result_t run_bbcmd(bb_t *bb, const char *cmd)
|
|||||||
n = (n * (value[1] == 'n' ? bb->nfiles : termheight)) / 100;
|
n = (n * (value[1] == 'n' ? bb->nfiles : termheight)) / 100;
|
||||||
if (isdelta) set_cursor(bb, bb->cursor + n);
|
if (isdelta) set_cursor(bb, bb->cursor + n);
|
||||||
else set_cursor(bb, n);
|
else set_cursor(bb, n);
|
||||||
if (matches_cmd(cmd, "spread")) { // +spread:
|
if (matches_cmd(cmd, "spread:")) { // +spread:
|
||||||
int sel = IS_SELECTED(bb->files[oldcur]);
|
int sel = IS_SELECTED(bb->files[oldcur]);
|
||||||
for (int i = bb->cursor; i != oldcur; i += (oldcur > i ? 1 : -1))
|
for (int i = bb->cursor; i != oldcur; i += (oldcur > i ? 1 : -1))
|
||||||
set_selected(bb, bb->files[i], sel);
|
set_selected(bb, bb->files[i], sel);
|
||||||
@ -717,8 +714,7 @@ bb_result_t run_bbcmd(bb_t *bb, const char *cmd)
|
|||||||
bb->should_quit = 1;
|
bb->should_quit = 1;
|
||||||
} else if (matches_cmd(cmd, "refresh")) { // +refresh
|
} else if (matches_cmd(cmd, "refresh")) { // +refresh
|
||||||
populate_files(bb, 1);
|
populate_files(bb, 1);
|
||||||
} else if (matches_cmd(cmd, "scroll")) { // +scroll:
|
} else if (matches_cmd(cmd, "scroll:")) { // +scroll:
|
||||||
if (!value) return BB_INVALID;
|
|
||||||
// TODO: figure out the best version of this
|
// TODO: figure out the best version of this
|
||||||
int isdelta = value[0] == '+' || value[0] == '-';
|
int isdelta = value[0] == '+' || value[0] == '-';
|
||||||
int n = (int)strtol(value, (char**)&value, 10);
|
int n = (int)strtol(value, (char**)&value, 10);
|
||||||
@ -728,16 +724,15 @@ bb_result_t run_bbcmd(bb_t *bb, const char *cmd)
|
|||||||
set_scroll(bb, bb->scroll + n);
|
set_scroll(bb, bb->scroll + n);
|
||||||
else
|
else
|
||||||
set_scroll(bb, n);
|
set_scroll(bb, n);
|
||||||
} else if (matches_cmd(cmd, "select")) { // +select:
|
} else if (matches_cmd(cmd, "select:") || matches_cmd(cmd, "select")) { // +select:
|
||||||
if (!value && !bb->nfiles) return BB_INVALID;
|
if (!value && !bb->nfiles) return;
|
||||||
if (!value) value = bb->files[bb->cursor]->fullname;
|
if (!value) value = bb->files[bb->cursor]->fullname;
|
||||||
entry_t *e = load_entry(bb, value, 1);
|
entry_t *e = load_entry(bb, value, 1);
|
||||||
if (e) set_selected(bb, e, 1);
|
if (e) set_selected(bb, e, 1);
|
||||||
} else if (matches_cmd(cmd, "sort")) { // +sort:
|
} else if (matches_cmd(cmd, "sort:")) { // +sort:
|
||||||
if (!value) return BB_INVALID;
|
|
||||||
set_sort(bb, value);
|
set_sort(bb, value);
|
||||||
sort_files(bb);
|
sort_files(bb);
|
||||||
} else if (matches_cmd(cmd, "spread")) { // +spread:
|
} else if (matches_cmd(cmd, "spread:")) { // +spread:
|
||||||
goto move;
|
goto move;
|
||||||
} else if (matches_cmd(cmd, "suspend")) { // +suspend
|
} else if (matches_cmd(cmd, "suspend")) { // +suspend
|
||||||
fputs(T_LEAVE_BBMODE, tty_out);
|
fputs(T_LEAVE_BBMODE, tty_out);
|
||||||
@ -745,22 +740,20 @@ bb_result_t run_bbcmd(bb_t *bb, const char *cmd)
|
|||||||
raise(SIGTSTP);
|
raise(SIGTSTP);
|
||||||
init_term();
|
init_term();
|
||||||
bb->dirty = 1;
|
bb->dirty = 1;
|
||||||
} else if (matches_cmd(cmd, "toggle")) { // +toggle
|
} else if (matches_cmd(cmd, "toggle:") || matches_cmd(cmd, "toggle")) { // +toggle
|
||||||
if (!value && !bb->nfiles) return BB_INVALID;
|
if (!value && !bb->nfiles) return;
|
||||||
if (!value) value = bb->files[bb->cursor]->fullname;
|
if (!value) value = bb->files[bb->cursor]->fullname;
|
||||||
entry_t *e = load_entry(bb, value, 1);
|
entry_t *e = load_entry(bb, value, 1);
|
||||||
if (e) set_selected(bb, e, !IS_SELECTED(e));
|
if (!e) goto invalid_cmd;
|
||||||
|
set_selected(bb, e, !IS_SELECTED(e));
|
||||||
} else {
|
} else {
|
||||||
|
invalid_cmd:
|
||||||
fputs(T_LEAVE_BBMODE, tty_out);
|
fputs(T_LEAVE_BBMODE, tty_out);
|
||||||
restore_term(&orig_termios);
|
restore_term(&orig_termios);
|
||||||
const char *msg = "Invalid bb command: ";
|
fprintf(stderr, "Invalid bb command: %s", cmd);
|
||||||
write(STDERR_FILENO, msg, strlen(msg));
|
fprintf(stderr, "\n");
|
||||||
write(STDERR_FILENO, cmd, strlen(cmd));
|
|
||||||
write(STDERR_FILENO, "\n", 1);
|
|
||||||
init_term();
|
init_term();
|
||||||
return BB_INVALID;
|
|
||||||
}
|
}
|
||||||
return BB_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1297,8 +1290,8 @@ int main(int argc, char *argv[])
|
|||||||
cmdfd = -1;
|
cmdfd = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
init_term();
|
||||||
bb_browse(bb, path);
|
bb_browse(bb, path);
|
||||||
|
|
||||||
if (tty_out) {
|
if (tty_out) {
|
||||||
fputs(T_LEAVE_BBMODE, tty_out);
|
fputs(T_LEAVE_BBMODE, tty_out);
|
||||||
cleanup();
|
cleanup();
|
||||||
|
12
bb.h
12
bb.h
@ -61,6 +61,14 @@
|
|||||||
exit(EXIT_FAILURE); \
|
exit(EXIT_FAILURE); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
#define warn(...) do { \
|
||||||
|
fputs(T_LEAVE_BBMODE, tty_out); \
|
||||||
|
restore_term(&orig_termios); \
|
||||||
|
fprintf(stderr, __VA_ARGS__); \
|
||||||
|
fprintf(stderr, "\n"); \
|
||||||
|
init_term(); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
// Types:
|
// Types:
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int key;
|
int key;
|
||||||
@ -129,8 +137,6 @@ typedef struct bb_s {
|
|||||||
unsigned int should_quit : 1;
|
unsigned int should_quit : 1;
|
||||||
} bb_t;
|
} bb_t;
|
||||||
|
|
||||||
typedef enum { BB_OK = 0, BB_INVALID } bb_result_t;
|
|
||||||
|
|
||||||
// Configurable options:
|
// Configurable options:
|
||||||
#define SCROLLOFF MIN(5, (termheight-4)/2)
|
#define SCROLLOFF MIN(5, (termheight-4)/2)
|
||||||
#define CMDFILE_FORMAT "/tmp/bb.XXXXXX"
|
#define CMDFILE_FORMAT "/tmp/bb.XXXXXX"
|
||||||
@ -182,7 +188,7 @@ static void* memcheck(void *p);
|
|||||||
static void normalize_path(const char *root, const char *path, char *pbuf, int clear_dots);
|
static void normalize_path(const char *root, const char *path, char *pbuf, int clear_dots);
|
||||||
static void populate_files(bb_t *bb, int samedir);
|
static void populate_files(bb_t *bb, int samedir);
|
||||||
static void print_bindings(int fd);
|
static void print_bindings(int fd);
|
||||||
static bb_result_t run_bbcmd(bb_t *bb, const char *cmd);
|
static void run_bbcmd(bb_t *bb, const char *cmd);
|
||||||
static void render(bb_t *bb);
|
static void render(bb_t *bb);
|
||||||
static void restore_term(const struct termios *term);
|
static void restore_term(const struct termios *term);
|
||||||
static int run_script(bb_t *bb, const char *cmd);
|
static int run_script(bb_t *bb, const char *cmd);
|
||||||
|
Loading…
Reference in New Issue
Block a user