aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bb.c45
1 files changed, 27 insertions, 18 deletions
diff --git a/bb.c b/bb.c
index c324a74..0d8c7f3 100644
--- a/bb.c
+++ b/bb.c
@@ -817,9 +817,9 @@ void sort_files(bb_t *bb)
}
/*
- * Prepend `root` to relative paths, replace "~" with $HOME, remove ".",
- * replace "/foo/baz/../" with "/foo/", and make sure there's a trailing
- * slash. The normalized path is stored in `normalized`.
+ * Prepend `root` to relative paths, replace "~" with $HOME, replace "/foo/."
+ * with "/foo", replace "/foo/baz/.." with "/foo".
+ * The normalized path is stored in `normalized`.
*/
void normalize_path(const char *root, const char *path, char *normalized)
{
@@ -835,17 +835,17 @@ void normalize_path(const char *root, const char *path, char *normalized)
}
strcat(normalized, path);
- if (normalized[strlen(normalized)-1] != '/')
- strcat(normalized, "/");
-
char *src = normalized, *dest = normalized;
while (*src) {
- if (strncmp(src, "/./", 3) == 0) {
- src += 2;
- } else if (strncmp(src, "/../", 4) == 0) {
- src += 3;
- while (dest > normalized && *(--dest) != '/')
- ;
+ 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++);
}
@@ -866,6 +866,8 @@ int cd_to(bb_t *bb, const char *path)
if (chdir(pbuf)) return -1;
} else {
normalize_path(bb->path, path, pbuf);
+ if (pbuf[strlen(pbuf)-1] != '/')
+ strcat(pbuf, "/");
if (chdir(pbuf)) return -1;
}
@@ -944,6 +946,7 @@ void populate_files(bb_t *bb, const char *path)
if ((size_t)bb->nfiles + 1 > space)
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);
if (!entry) err("Failed to load entry: '%s'", dp->d_name);
entry->index = bb->nfiles;
@@ -1026,14 +1029,16 @@ bb_result_t process_cmd(bb_t *bb, const char *cmd)
case 'e': { // +deselect:
if (!value && !bb->nfiles) return BB_INVALID;
if (!value) value = bb->files[bb->cursor]->fullname;
- entry_t *e = load_entry(bb, value);
+ char pbuf[PATH_MAX];
+ normalize_path(bb->path, value, pbuf);
+ entry_t *e = load_entry(bb, pbuf);
if (e) {
deselect_entry(bb, e);
return BB_OK;
}
// Filename may no longer exist:
for (e = bb->firstselected; e; e = e->selected.next) {
- if (strcmp(e->fullname, value) == 0) {
+ if (strcmp(e->fullname, pbuf) == 0) {
deselect_entry(bb, e);
break;
}
@@ -1146,13 +1151,15 @@ bb_result_t process_cmd(bb_t *bb, const char *cmd)
return BB_OK;
}
- case '\0': case 'e': // +select:
+ case '\0': case 'e': { // +select:
if (!value && !bb->nfiles) return BB_INVALID;
if (!value) value = bb->files[bb->cursor]->fullname;
- entry_t *e = load_entry(bb, value);
+ char pbuf[PATH_MAX];
+ normalize_path(bb->path, value, pbuf);
+ entry_t *e = load_entry(bb, pbuf);
if (e) select_entry(bb, e);
return BB_OK;
-
+ }
case 'o': // +sort:
if (!value) return BB_INVALID;
set_sort(bb, value);
@@ -1165,7 +1172,9 @@ 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;
- entry_t *e = load_entry(bb, value);
+ char pbuf[PATH_MAX];
+ normalize_path(bb->path, value, pbuf);
+ entry_t *e = load_entry(bb, pbuf);
if (e) toggle_entry(bb, e);
return BB_OK;
}