aboutsummaryrefslogtreecommitdiff
path: root/bb.c
diff options
context:
space:
mode:
Diffstat (limited to 'bb.c')
-rw-r--r--bb.c77
1 files 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)));