summaryrefslogtreecommitdiff
path: root/src/dirlist.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/dirlist.c')
-rw-r--r--src/dirlist.c161
1 files changed, 84 insertions, 77 deletions
diff --git a/src/dirlist.c b/src/dirlist.c
index 6fbe07f..f29dc21 100644
--- a/src/dirlist.c
+++ b/src/dirlist.c
@@ -25,39 +25,40 @@
#include "global.h"
+#include <stdlib.h>
#include <string.h>
/* public variables */
-struct dir *dirlist_parent = NULL;
-off_t dirlist_maxs = 0,
- dirlist_maxa = 0;
+compll_t dirlist_parent = (compll_t)0;
+off_t dirlist_maxs = 0,
+ dirlist_maxa = 0;
-int dirlist_sort_desc = 1,
- dirlist_sort_col = DL_COL_SIZE,
- dirlist_sort_df = 0,
- dirlist_hidden = 0;
+int dirlist_sort_desc = 1,
+ dirlist_sort_col = DL_COL_SIZE,
+ dirlist_sort_df = 0,
+ dirlist_hidden = 0;
/* private state vars */
-struct dir dirlist_parent_alloc;
-struct dir *head, *head_real, *selected, *top = NULL;
+compll_t dirlist_parent_alloc = (compll_t)0;
+compll_t head, head_real, selected, top = (compll_t)0;
-#define ISHIDDEN(d) (dirlist_hidden && (d) != dirlist_parent && (\
- (d)->flags & FF_EXL || (d)->name[0] == '.' || (d)->name[strlen((d)->name)-1] == '~'\
+#define ISHIDDEN(d) (dirlist_hidden && d != dirlist_parent && (\
+ DR(d)->flags & FF_EXL || DR(d)->name[0] == '.' || DR(d)->name[strlen(DR(d)->name)-1] == '~'\
))
-int dirlist_cmp(struct dir *x, struct dir *y) {
+int dirlist_cmp(compll_t x, compll_t y) {
int r;
/* dirs are always before files when that option is set */
if(dirlist_sort_df) {
- if(y->flags & FF_DIR && !(x->flags & FF_DIR))
+ if(DR(y)->flags & FF_DIR && !(DR(x)->flags & FF_DIR))
return 1;
- else if(!(y->flags & FF_DIR) && x->flags & FF_DIR)
+ else if(!(DR(y)->flags & FF_DIR) && DR(x)->flags & FF_DIR)
return -1;
}
@@ -69,9 +70,9 @@ int dirlist_cmp(struct dir *x, struct dir *y) {
*
* Note that the method used below is supposed to be fast, not readable :-)
*/
-#define CMP_NAME strcmp(x->name, y->name)
-#define CMP_SIZE (x->size > y->size ? 1 : (x->size == y->size ? 0 : -1))
-#define CMP_ASIZE (x->asize > y->asize ? 1 : (x->asize == y->asize ? 0 : -1))
+#define CMP_NAME strcmp(DR(x)->name, DR(y)->name)
+#define CMP_SIZE (DR(x)->size > DR(y)->size ? 1 : (DR(x)->size == DR(y)->size ? 0 : -1))
+#define CMP_ASIZE (DR(x)->asize > DR(y)->asize ? 1 : (DR(x)->asize == DR(y)->asize ? 0 : -1))
/* try 1 */
r = dirlist_sort_col == DL_COL_NAME ? CMP_NAME : dirlist_sort_col == DL_COL_SIZE ? CMP_SIZE : CMP_ASIZE;
@@ -90,15 +91,15 @@ int dirlist_cmp(struct dir *x, struct dir *y) {
}
-struct dir *dirlist_sort(struct dir *list) {
- struct dir *p, *q, *e, *tail;
+compll_t dirlist_sort(compll_t list) {
+ compll_t p, q, e, tail;
int insize, nmerges, psize, qsize, i;
insize = 1;
while(1) {
p = list;
- list = NULL;
- tail = NULL;
+ list = (compll_t)0;
+ tail = (compll_t)0;
nmerges = 0;
while(p) {
nmerges++;
@@ -106,31 +107,31 @@ struct dir *dirlist_sort(struct dir *list) {
psize = 0;
for(i=0; i<insize; i++) {
psize++;
- q = q->next;
+ q = DR(q)->next;
if(!q) break;
}
qsize = insize;
while(psize > 0 || (qsize > 0 && q)) {
if(psize == 0) {
- e = q; q = q->next; qsize--;
+ e = q; q = DR(q)->next; qsize--;
} else if(qsize == 0 || !q) {
- e = p; p = p->next; psize--;
+ e = p; p = DR(p)->next; psize--;
} else if(dirlist_cmp(p,q) <= 0) {
- e = p; p = p->next; psize--;
+ e = p; p = DR(p)->next; psize--;
} else {
- e = q; q = q->next; qsize--;
+ e = q; q = DR(q)->next; qsize--;
}
- if(tail) tail->next = e;
+ if(tail) DW(tail)->next = e;
else list = e;
- e->prev = tail;
+ DW(e)->prev = tail;
tail = e;
}
p = q;
}
- tail->next = NULL;
+ DW(tail)->next = (compll_t)0;
if(nmerges <= 1) {
- if(list->parent)
- list->parent->sub = list;
+ if(DR(list)->parent)
+ DW(DR(list)->parent)->sub = list;
return list;
}
insize *= 2;
@@ -143,109 +144,115 @@ struct dir *dirlist_sort(struct dir *list) {
* - updates the dirlist_(maxs|maxa) values
* - makes sure that the FF_BSEL bits are correct */
void dirlist_fixup() {
- struct dir *t;
+ compll_t t;
/* we're going to determine the selected items from the list itself, so reset this one */
- selected = NULL;
+ selected = (compll_t)0;
- for(t=head; t; t=t->next) {
+ for(t=head; t; t=DR(t)->next) {
/* not visible? not selected! */
- if(ISHIDDEN(t))
- t->flags &= ~FF_BSEL;
- else {
+ if(ISHIDDEN(t)) {
+ if(DR(t)->flags & FF_BSEL)
+ DW(t)->flags &= ~FF_BSEL;
+ } else {
/* visible and selected? make sure only one item is selected */
- if(t->flags & FF_BSEL) {
+ if(DR(t)->flags & FF_BSEL) {
if(!selected)
selected = t;
else
- t->flags &= ~FF_BSEL;
+ DW(t)->flags &= ~FF_BSEL;
}
}
/* update dirlist_(maxs|maxa) */
- if(t->size > dirlist_maxs)
- dirlist_maxs = t->size;
- if(t->asize > dirlist_maxa)
- dirlist_maxa = t->asize;
+ if(DR(t)->size > dirlist_maxs)
+ dirlist_maxs = DR(t)->size;
+ if(DR(t)->asize > dirlist_maxa)
+ dirlist_maxa = DR(t)->asize;
}
/* no selected items found after one pass? select the first visible item */
if(!selected)
- if((selected = dirlist_next(NULL)))
- selected->flags |= FF_BSEL;
+ if((selected = dirlist_next((compll_t)0)))
+ DW(selected)->flags |= FF_BSEL;
}
-void dirlist_open(struct dir *d) {
+void dirlist_open(compll_t d) {
/* set the head of the list */
- head_real = head = d == NULL ? NULL : d->parent == NULL ? d->sub : d->parent->sub;
+ head_real = head = !d ? d : !DR(d)->parent ? DR(d)->sub : DR(DR(d)->parent)->sub;
/* reset internal status */
dirlist_maxs = dirlist_maxa = 0;
/* stop if this is not a directory list we can work with */
- if(head == NULL) {
- dirlist_parent = NULL;
+ if(!head) {
+ dirlist_parent = (compll_t)0;
return;
}
/* sort the dir listing */
head_real = head = dirlist_sort(head);
+ /* allocate reference to parent dir if we don't have one yet */
+ if(!dirlist_parent_alloc) {
+ dirlist_parent_alloc = compll_alloc(SDIRSIZE+2);
+ strcpy(DW(dirlist_parent_alloc)->name, "..");
+ }
+
/* set the reference to the parent dir */
- dirlist_parent_alloc.flags &= ~FF_BSEL;
- if(head->parent->parent) {
- dirlist_parent = &dirlist_parent_alloc;
- strcpy(dirlist_parent->name, "..");
- dirlist_parent->next = head;
- dirlist_parent->parent = head->parent;
- dirlist_parent->sub = head->parent;
+ DW(dirlist_parent_alloc)->flags &= ~FF_BSEL;
+ if(DR(DR(head)->parent)->parent) {
+ dirlist_parent = dirlist_parent_alloc;
+ DW(dirlist_parent)->next = head;
+ DW(dirlist_parent)->parent = DR(head)->parent;
+ DW(dirlist_parent)->sub = DR(head)->parent;
head = dirlist_parent;
} else
- dirlist_parent = NULL;
+ dirlist_parent = (compll_t)0;
dirlist_fixup();
}
-struct dir *dirlist_next(struct dir *d) {
+compll_t dirlist_next(compll_t d) {
if(!head)
- return NULL;
+ return (compll_t)0;
if(!d) {
if(!ISHIDDEN(head))
return head;
else
d = head;
}
- while((d = d->next)) {
+ while((d = DR(d)->next)) {
if(!ISHIDDEN(d))
return d;
}
- return NULL;
+ return (compll_t)0;
}
-struct dir *dirlist_prev(struct dir *d) {
+compll_t dirlist_prev(compll_t d) {
if(!head || !d)
- return NULL;
- while((d = d->prev)) {
+ return (compll_t)0;
+ while((d = DR(d)->prev)) {
if(!ISHIDDEN(d))
return d;
}
if(dirlist_parent)
return dirlist_parent;
- return NULL;
+ return (compll_t)0;
}
-struct dir *dirlist_get(int i) {
- struct dir *t = selected, *d;
+compll_t dirlist_get(int i) {
+ compll_t t = selected, d;
if(!head)
- return NULL;
+ return (compll_t)0;
if(ISHIDDEN(selected)) {
- selected = dirlist_next(NULL);
+ selected = dirlist_next((compll_t)0);
return selected;
}
@@ -275,13 +282,13 @@ struct dir *dirlist_get(int i) {
}
-void dirlist_select(struct dir *d) {
- if(!d || !head || ISHIDDEN(d) || d->parent != head->parent)
+void dirlist_select(compll_t d) {
+ if(!d || !head || ISHIDDEN(d) || DR(d)->parent != DR(head)->parent)
return;
- selected->flags &= ~FF_BSEL;
+ DW(selected)->flags &= ~FF_BSEL;
selected = d;
- selected->flags |= FF_BSEL;
+ DW(selected)->flags |= FF_BSEL;
}
@@ -304,12 +311,12 @@ void dirlist_select(struct dir *d) {
* Regardless of the hint, the returned top will always be chosen such that the
* selected item is visible.
*/
-struct dir *dirlist_top(int hint) {
- struct dir *t;
+compll_t dirlist_top(int hint) {
+ compll_t t;
int i = winrows-3, visible = 0;
if(hint == -2 || hint == -3)
- top = NULL;
+ top = (compll_t)0;
/* check whether the current selected item is within the visible window */
if(top) {
@@ -358,7 +365,7 @@ void dirlist_set_sort(int col, int desc, int df) {
/* sort the list (excluding the parent, which is always on top) */
head_real = dirlist_sort(head_real);
if(dirlist_parent)
- dirlist_parent->next = head_real;
+ DW(dirlist_parent)->next = head_real;
else
head = head_real;
dirlist_top(-3);