Merge pull request #19 from piotr-marendowski/feature

Feature
This commit is contained in:
Piotr Marendowski 2024-03-20 20:53:29 +00:00 committed by GitHub
commit 1b202d5df1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 233 additions and 311 deletions

View file

@ -12,7 +12,7 @@ MANDIR = $(PREFIX)/share/man/man1
# Flags # Flags
LDFLAGS = $(shell pkg-config --libs ncurses) LDFLAGS = $(shell pkg-config --libs ncurses)
CFLAGS = -O3 -pipe -s -std=c99 -pedantic -Wall $(shell pkg-config --cflags ncurses) CFLAGS = -O3 -march=native -mtune=native -pipe -s -std=c99 -pedantic -Wall $(shell pkg-config --cflags ncurses)
SRC = ccc.c util.c file.c SRC = ccc.c util.c file.c

View file

@ -49,30 +49,37 @@ $ sudo make install
## Usage ## Usage
``` ```
h: go to parent dir
j: scroll down j: scroll down
k: scroll up k: scroll up
h: go to parent dir
l: go to child dir l: go to child dir
left: go to parent dir
down: scroll down down: scroll down
up: scroll up up: scroll up
left: go to parent dir
right: go to child dir right: go to child dir
enter: go to child dir/open file enter: go to child dir/open file
backspace: go to parent dir backspace: go to parent dir
g: go to top gg: go to top
G: go to bottom G: go to bottom
t: go to trash ctrl+u: jump up
~: go to home ctrl+d: jump down
t: go to trash dir
~: go to home dir
-: go to previous dir
z: refresh current dir z: refresh current dir
A: show directory disk usage/block size
space: mark file space: mark file
a: mark all files in directory a: mark all files in directory
q: exit ?: show help
q: exit with last dir written to file
ctrl+c exit without writing last dir
``` ```
## License ## License

176
ccc.c
View file

@ -16,11 +16,13 @@
#include "config.h" #include "config.h"
/* functions' definitions */ /* functions' definitions */
void show_help();
void start_ccc();
void change_dir(const char *buf, int selection); void change_dir(const char *buf, int selection);
int mkdir_p(const char *destdir); int mkdir_p(const char *destdir);
void populate_files(const char *path, int ftype); void populate_files(const char *path, int ftype);
int get_directory_size(const char *fpath, const struct stat *sb, int typeflag, struct FTW *ftwbuf); int get_directory_size(const char *fpath, const struct stat *sb, int typeflag, struct FTW *ftwbuf);
long add_file_stat(char *filepath, int ftype); void add_file_stat(char *filepath, int ftype);
void highlight_current_line(); void highlight_current_line();
void show_file_content(); void show_file_content();
void edit_file(); void edit_file();
@ -33,8 +35,13 @@ void draw_border_title(WINDOW *window, bool active);
unsigned int focus = 0; unsigned int focus = 0;
long current_selection = 0; long current_selection = 0;
bool dirs_size = DIRS_SIZE; bool dirs_size = DIRS_SIZE;
bool show_hidden = SHOW_HIDDEN;
bool file_details = SHOW_DETAILS;
char *cwd; char *cwd;
char *p_cwd; /* previous cwd */
int half_width; int half_width;
ArrayList *files;
ArrayList *marked;
WINDOW *directory_border; WINDOW *directory_border;
WINDOW *directory_content; WINDOW *directory_content;
WINDOW *preview_border; WINDOW *preview_border;
@ -80,15 +87,14 @@ int main(int argc, char** argv)
init_pair(7, COLOR_CYAN, -1); /* MARKED FILES */ init_pair(7, COLOR_CYAN, -1); /* MARKED FILES */
init_pair(8, COLOR_WHITE, -1); /* REG */ init_pair(8, COLOR_WHITE, -1); /* REG */
half_width = COLS / 2; /* init files and marked arrays */
init_windows(); files = arraylist_init(100);
refresh(); marked = arraylist_init(100);
cwd = memalloc(PATH_MAX * sizeof(char)); cwd = memalloc(PATH_MAX * sizeof(char));
p_cwd = memalloc(PATH_MAX * sizeof(char));
getcwd(cwd, PATH_MAX); getcwd(cwd, PATH_MAX);
start_ccc();
populate_files(cwd, 0);
highlight_current_line();
int ch, ch2; int ch, ch2;
while (1) { while (1) {
@ -118,6 +124,7 @@ int main(int argc, char** argv)
case LEFT: case LEFT:
case 'h':; case 'h':;
/* get parent directory */ /* get parent directory */
strcpy(p_cwd, cwd);
char *last_slash = strrchr(cwd, '/'); char *last_slash = strrchr(cwd, '/');
if (last_slash != NULL) { if (last_slash != NULL) {
*last_slash = '\0'; *last_slash = '\0';
@ -129,15 +136,14 @@ int main(int argc, char** argv)
case ENTER: case ENTER:
case RIGHT: case RIGHT:
case 'l':; case 'l':;
file *file = get_file(current_selection); strcpy(p_cwd, cwd);
if (file != NULL) { file c_file = files->items[current_selection];
/* check if it is directory or a regular file */ /* check if it is directory or a regular file */
if (strncmp(file->type, "DIR", 3) == 0) { if (strncmp(c_file.type, "DIR", 3) == 0) {
/* change cwd to directory */ /* change cwd to directory */
change_dir(file->path, 0); change_dir(c_file.path, 0);
} else if (strncmp(file->type, "REG", 3) == 0) { } else if (strncmp(c_file.type, "REG", 3) == 0) {
edit_file(); edit_file();
}
} }
break; break;
@ -162,10 +168,10 @@ int main(int argc, char** argv)
/* jump down (ctrl d) */ /* jump down (ctrl d) */
case CTRLD: case CTRLD:
if ((current_selection + JUMP_NUM) < (files_len() - 1)) if ((current_selection + JUMP_NUM) < (files->length - 1))
current_selection += JUMP_NUM; current_selection += JUMP_NUM;
else else
current_selection = (files_len() - 1); current_selection = (files->length - 1);
highlight_current_line(); highlight_current_line();
break; break;
@ -173,7 +179,7 @@ int main(int argc, char** argv)
/* go down by j or down arrow */ /* go down by j or down arrow */
case DOWN: case DOWN:
case 'j': case 'j':
if (current_selection < (files_len() - 1)) if (current_selection < (files->length - 1))
current_selection++; current_selection++;
highlight_current_line(); highlight_current_line();
@ -181,7 +187,7 @@ int main(int argc, char** argv)
/* jump to the bottom */ /* jump to the bottom */
case 'G': case 'G':
current_selection = (files_len() - 1); current_selection = (files->length - 1);
highlight_current_line(); highlight_current_line();
break; break;
@ -234,14 +240,33 @@ int main(int argc, char** argv)
/* show directories' sizes */ /* show directories' sizes */
case 'A': case 'A':
dirs_size = !dirs_size; dirs_size = !dirs_size;
clear_files(); change_dir(cwd, 0);
populate_files(cwd, 0);
highlight_current_line();
break; break;
/* go to previous dir */
case '-':
change_dir(p_cwd, 0);
break;
/* show help */
case '?':
show_help();
break;
/* toggle hidden files */
case '.':
show_hidden = !show_hidden;
change_dir(cwd, 0);
break;
/* toggle file details */
case 'i':
file_details = !file_details;
change_dir(cwd, 0);
/* mark one file */ /* mark one file */
case SPACE: case SPACE:
add_file_stat(get_filepath(current_selection), 1); add_file_stat(files->items[current_selection].path, 1);
highlight_current_line(); highlight_current_line();
break; break;
@ -254,35 +279,35 @@ int main(int argc, char** argv)
/* mark actions: */ /* mark actions: */
/* delete */ /* delete */
case 'd':; case 'd':;
if (marked_len()) { if (marked->length) {
; ;
} }
break; break;
/* move */ /* move */
case 'm':; case 'm':;
if (marked_len()) { if (marked->length) {
; ;
} }
break; break;
/* copy */ /* copy */
case 'c':; case 'c':;
if (marked_len()) { if (marked->length) {
; ;
} }
break; break;
/* symbolic link */ /* symbolic link */
case 's':; case 's':;
if (marked_len()) { if (marked->length) {
; ;
} }
break; break;
/* bulk rename */ /* bulk rename */
case 'b':; case 'b':;
if (marked_len()) { if (marked->length) {
; ;
} }
break; break;
@ -298,29 +323,54 @@ int main(int argc, char** argv)
delwin(preview_content); delwin(preview_content);
delwin(panel); delwin(panel);
endwin(); endwin();
half_width = COLS / 2; start_ccc();
init_windows();
refresh();
populate_files(cwd, 0);
highlight_current_line();
break; break;
default: default:
break; break;
} }
} }
clear_files(); arraylist_free(files);
clear_marked(); arraylist_free(marked);
endwin(); endwin();
return 0; return 0;
} }
void show_help()
{
wclear(directory_content);
wclear(preview_content);
wprintw(directory_content,"h: go to parent dir\nj: scroll down\nk: scroll up\nl: go to child dir\n\nleft: go to parent dir\ndown: scroll down\nup: scroll up\nright: go to child dir\n\nenter: go to child dir/open file\nbackspace: go to parent dir\n\ngg: go to top\nG: go to bottom\n\nctrl+u: jump up\nctrl+d: jump down\n\nt: go to trash dir\n~: go to home dir\n-: go to previous dir\nz: refresh current dir\n\nA: show directory disk usage/block size\nspace: mark file\na: mark all files in directory\n\n?: show help\nq: exit with last dir written to file\nctrl+c exit without writing last dir");
wpprintw("Visit https://github.com/piotr-marendowski/ccc or use 'man ccc' for help");
wrefresh(directory_content);
wrefresh(preview_content);
}
void start_ccc()
{
half_width = COLS / 2;
init_windows();
refresh();
populate_files(cwd, 0);
highlight_current_line();
}
/* /*
* Change directory in window with selection * Change directory in window with selection
*/ */
void change_dir(const char *buf, int selection) void change_dir(const char *buf, int selection)
{ {
strcpy(cwd, buf); char *buf_dup;
clear_files(); if (buf == p_cwd) {
buf_dup = strdup(p_cwd);
if (buf_dup == NULL) {
return;
}
} else {
buf_dup = (char *) buf;
}
strcpy(cwd, buf_dup);
arraylist_free(files);
files = arraylist_init(100);
populate_files(cwd, 0); populate_files(cwd, 0);
current_selection = selection; current_selection = selection;
highlight_current_line(); highlight_current_line();
@ -398,8 +448,8 @@ void populate_files(const char *path, int ftype)
filename[0] = '\0'; filename[0] = '\0';
strcat(filename, ep->d_name); strcat(filename, ep->d_name);
/* can't be strncmp as that would filter out the dotfiles */ /* use strncmp to filter out dotfiles */
if (strcmp(filename, ".") && strcmp(filename, "..")) { if ((show_hidden && strncmp(filename, ".", 1) && strncmp(filename, "..", 2)) || (!show_hidden && strcmp(filename, ".") && strcmp(filename, ".."))) {
/* construct full file path */ /* construct full file path */
filename[0] = '\0'; filename[0] = '\0';
strcat(filename, cwd); strcat(filename, cwd);
@ -428,13 +478,13 @@ int get_directory_size(const char *fpath, const struct stat *sb, int typeflag, s
* Add that file into list * Add that file into list
* ftype: normal file = 0, normal marked = 1, marking ALL = 2 * ftype: normal file = 0, normal marked = 1, marking ALL = 2
*/ */
long add_file_stat(char *filepath, int ftype) void add_file_stat(char *filepath, int ftype)
{ {
struct stat file_stat; struct stat file_stat;
if (stat(filepath, &file_stat) == -1) { if (stat(filepath, &file_stat) == -1) {
/* can't be triggered? */ /* can't be triggered? */
if (errno == EACCES) if (errno == EACCES)
return add_file(filepath, "", "", 8); arraylist_add(files, filepath, "", "", 8, false, false);
} }
/* get file type and color, 4 chars for the type */ /* get file type and color, 4 chars for the type */
@ -469,14 +519,10 @@ long add_file_stat(char *filepath, int ftype)
if (ftype == 1 || ftype == 2) { if (ftype == 1 || ftype == 2) {
/* force if user is marking all files */ /* force if user is marking all files */
bool force = ftype == 2 ? true : false; bool force = ftype == 2 ? true : false;
long index = add_marked(filepath, type, force); arraylist_add(marked, filepath, NULL, type, 8, true, force);
/* free type and return without allocating more stuff */ /* free type and return without allocating more stuff */
free(type); free(type);
if (index != -1) { return;
return index; /* just marked */
} else {
return -1; /* already marked */
}
} }
/* get last modified time */ /* get last modified time */
@ -511,13 +557,12 @@ long add_file_stat(char *filepath, int ftype)
snprintf(total_stat, 45, "%-18s %-8s", time, size); snprintf(total_stat, 45, "%-18s %-8s", time, size);
total_stat[strlen(total_stat)] = '\0'; total_stat[strlen(total_stat)] = '\0';
long index = add_file(filepath, total_stat, type, color); arraylist_add(files, filepath, total_stat, type, color, false, false);
free(time); free(time);
free(size); free(size);
free(total_stat); free(total_stat);
free(type); free(type);
return index;
} }
@ -533,7 +578,7 @@ void highlight_current_line()
} }
/* calculate range of files to show */ /* calculate range of files to show */
long range = files_len(); long range = files->length;
/* not highlight if no files in directory */ /* not highlight if no files in directory */
if (range == 0) { if (range == 0) {
#if DRAW_PREVIEW #if DRAW_PREVIEW
@ -560,24 +605,24 @@ void highlight_current_line()
wclear(panel); wclear(panel);
/* check for marked files */ /* check for marked files */
long num_marked = marked_len(); long num_marked = marked->length;
if (num_marked > 0) { if (num_marked > 0) {
/* Determine length of formatted string */ /* Determine length of formatted string */
int m_len = snprintf(NULL, 0, "[%ld] selected", num_marked); int m_len = snprintf(NULL, 0, "[%ld] selected", num_marked);
char *selected = memalloc((m_len + 1) * sizeof(char)); char *selected = memalloc((m_len + 1) * sizeof(char));
snprintf(selected, m_len + 1, "[%ld] selected", num_marked); snprintf(selected, m_len + 1, "[%ld] selected", num_marked);
wprintw(panel, "(%ld/%ld) %s %s", current_selection + 1, files_len(), selected, cwd); wprintw(panel, "(%ld/%ld) %s %s", current_selection + 1, files->length, selected, cwd);
} else { } else {
wprintw(panel, "(%ld/%ld) %s", current_selection + 1, files_len(), cwd); wprintw(panel, "(%ld/%ld) %s", current_selection + 1, files->length, cwd);
} }
} }
/* print the actual filename and stats */ /* print the actual filename and stats */
char *line = get_line(i); char *line = get_line(files, i, file_details);
int color = get_color(i); int color = files->items[i].color;
/* check is file marked for action */ /* check is file marked for action */
bool marked = in_marked(get_filepath(i)); bool is_marked = arraylist_includes(marked, files->items[i].path);
if (marked) { if (is_marked) {
/* show file is selected */ /* show file is selected */
wattron(directory_content, COLOR_PAIR(7)); wattron(directory_content, COLOR_PAIR(7));
} else { } else {
@ -590,7 +635,7 @@ void highlight_current_line()
else else
mvwprintw(directory_content, i, 0, "%s", line); mvwprintw(directory_content, i, 0, "%s", line);
if (marked) { if (is_marked) {
wattroff(directory_content, COLOR_PAIR(7)); wattroff(directory_content, COLOR_PAIR(7));
} else { } else {
wattroff(directory_content, COLOR_PAIR(color)); wattroff(directory_content, COLOR_PAIR(color));
@ -616,14 +661,14 @@ void highlight_current_line()
void show_file_content() void show_file_content()
{ {
wclear(preview_content); wclear(preview_content);
file *current_file = get_file((long) current_selection); file current_file = files->items[current_selection];
if (strncmp(current_file->type, "DIR", 3) == 0) if (strncmp(current_file.type, "DIR", 3) == 0)
return; return;
FILE *file = fopen(current_file->path, "r"); FILE *file = fopen(current_file.path, "r");
if (file == NULL) { if (file == NULL) {
mvwprintw(preview_content, 0, 0, "Unable to read %s", current_file->path); mvwprintw(preview_content, 0, 0, "Unable to read %s", current_file.path);
return; return;
} }
#if DRAW_BORDERS #if DRAW_BORDERS
@ -673,7 +718,7 @@ void edit_file()
def_prog_mode(); /* save the tty modes */ def_prog_mode(); /* save the tty modes */
endwin(); /* end curses mode temporarily */ endwin(); /* end curses mode temporarily */
char *filename = get_filepath(current_selection); char *filename = files->items[current_selection].path;
int length = strlen(editor) + strlen(filename) + 2; /* one for space one for null */ int length = strlen(editor) + strlen(filename) + 2; /* one for space one for null */
char command[length]; char command[length];
@ -685,7 +730,8 @@ void edit_file()
} }
} }
int write_last_d() { int write_last_d()
{
#ifdef LAST_D #ifdef LAST_D
char *last_d = memalloc(PATH_MAX * sizeof(char)); char *last_d = memalloc(PATH_MAX * sizeof(char));
strcpy(last_d, LAST_D); strcpy(last_d, LAST_D);

View file

@ -8,6 +8,8 @@
#define DRAW_BORDERS true /* Draw borders around windows? */ #define DRAW_BORDERS true /* Draw borders around windows? */
#define DRAW_PREVIEW true /* Draw file preview? */ #define DRAW_PREVIEW true /* Draw file preview? */
#define SHOW_HIDDEN true /* show hidden files/dotfiles in preview */
#define SHOW_DETAILS true /* show file details */
/* set width offset for windows: /* set width offset for windows:
+-------------%-------------+ +-------------%-------------+

316
file.c
View file

@ -5,274 +5,142 @@
#include "util.h" #include "util.h"
/* files in a link list data structure */
typedef struct file { typedef struct file {
char *path; char *path;
char *stats; char *stats;
char *type; char *type;
int color; int color;
struct file *next;
} file; } file;
file *files = NULL; typedef struct ArrayList {
file *marked = NULL; size_t length;
size_t capacity;
file *items;
} ArrayList;
/* ArrayList *arraylist_init(size_t capacity)
* Get length of files linked list
*/
long files_len()
{ {
file *current = files; ArrayList *list = memalloc(sizeof(ArrayList));
int count = 0; list->length = 0;
while (current != NULL) { list->capacity = capacity;
count++; list->items = memalloc(capacity * sizeof(file));
current = current->next; return list;
}
return count;
} }
/* void arraylist_free(ArrayList *list)
* Get length of marked files
*/
long marked_len()
{ {
file *current = marked; for (size_t i = 0; i < list->length; i++) {
int count = 0; if (list->items[i].type != NULL)
while (current != NULL) { free(list->items[i].type);
count++; if (list->items[i].path != NULL)
current = current->next; free(list->items[i].path);
if (list->items[i].stats != NULL)
free(list->items[i].stats);
} }
return count; free(list->items);
list->length = 0;
} }
void free_file(file *toremove) bool arraylist_includes(ArrayList *list, char *path)
{ {
if (toremove->type != NULL) for (int i = 0; i < list->length; i++) {
free(toremove->type); if (strcmp(list->items[i].path, path) == 0) {
if (toremove->path != NULL) return true;
free(toremove->path); }
if (toremove->stats != NULL) }
free(toremove->stats); return false;
free(toremove);
} }
void clear_files() void arraylist_remove(ArrayList *list, long index)
{ {
file *tmp; if (index >= list->length) {
while (files != NULL) {
tmp = files;
files = files->next;
free_file(tmp);
}
}
void clear_marked()
{
file *tmp;
while (marked != NULL) {
tmp = marked;
files = marked->next;
free_file(tmp);
}
}
long add_file(char *filepath, char *stats, char *type, int color)
{
file *current = files;
file *new_file = memalloc(sizeof(file));
char *buf = strdup(filepath);
char *buf2 = strdup(stats);
char *buf3 = strdup(type);
int buf4 = color;
if (buf == NULL || buf2 == NULL || buf3 == NULL)
perror("ccc");
new_file->path = buf;
new_file->stats = buf2;
new_file->type = buf3;
new_file->color = buf4;
new_file->next = NULL;
if (current == NULL) {
files = new_file;
return 0;
}
long index = 1;
while (current->next != NULL) {
current = current->next;
index++;
}
current->next = new_file;
return index;
}
void remove_marked(file *marked_file)
{
/* If the head node itself is marked for removal */
if (marked == marked_file) {
marked = marked->next;
free_file(marked_file);
return; return;
} }
/* Search for the marked file node in the list */ free(list->items[index].path);
file* temp = marked; free(list->items[index].stats);
while (temp != NULL && temp->next != marked_file) { free(list->items[index].type);
temp = temp->next;
for (long i = index; i < list->length - 1; i++) {
list->items[i] = list->items[i + 1];
} }
/* If the marked file node is found, remove it from the list */ list->length--;
if (temp != NULL) {
temp->next = marked_file->next;
free_file(marked_file);
}
} }
/* /*
* force will not remove duplicate marked files, instead it just skip adding * force will not remove duplicate marked files, instead it just skip adding
*/ */
long add_marked(char *filepath, char *type, bool force) void arraylist_add(ArrayList *list, char *filepath, char *stats, char *type, int color, bool marked, bool force)
{ {
file *current = marked; char *filepath_cp = NULL;
file *new_file = memalloc(sizeof(file)); char *stats_cp = NULL;
char *buf = strdup(filepath); char *type_cp = NULL;
char *buf2 = strdup(type); if (filepath != NULL) {
if (buf == NULL || buf2 == NULL) { filepath_cp = strdup(filepath);
perror("ccc"); if (filepath_cp == NULL) {
perror("ccc");
}
} }
new_file->path = buf; if (stats != NULL) {
new_file->type = buf2; stats_cp = strdup(stats);
new_file->stats = NULL; if (stats_cp == NULL) {
new_file->color = 0; perror("ccc");
new_file->next = NULL; }
if (current == NULL) {
marked = new_file;
return 0;
} }
if (type != NULL) {
long index = 1; type_cp = strdup(type);
while (current->next != NULL) { if (type_cp == NULL) {
if (strcmp(current->path, new_file->path) == 0) { perror("ccc");
if (force) { }
return index; }
} else {
remove_marked(current); /* path, stats, type, color */
free_file(new_file); file new_file = { filepath_cp, stats_cp, type_cp, color };
return -1;
if (list->capacity != list->length) {
if (marked) {
for (int i = 0; i < list->length; i++) {
if (strcmp(list->items[i].path, new_file.path) == 0) {
if (!force) {
arraylist_remove(list, i);
}
return;
}
} }
} }
current = current->next; list->items[list->length] = new_file;
index++;
}
if (strcmp(current->path, new_file->path) == 0){
if (force) {
return 0;
} else {
remove_marked(current);
free_file(new_file);
return -1;
}
}
current->next = new_file;
return index;
}
file *get_marked(long index)
{
file *current = marked;
if (index == 0) {
return current;
}
if (index > files_len()) {
return NULL;
}
for (long i = 0; i < index; i++) {
current = current->next;
}
return current;
}
bool in_marked(char *path)
{
file *tmp = marked;
if (tmp == NULL)
return false;
while (tmp != NULL) {
if (strcmp(path, tmp->path) == 0) {
return true;
}
tmp = tmp->next;
}
return false;
}
file *get_file(long index)
{
file *current = files;
if (index == 0) {
return current;
}
if (index > files_len()) {
return NULL;
}
for (long i = 0; i < index; i++) {
current = current->next;
}
return current;
}
char *get_filepath(long index)
{
file *file = get_file(index);
if (file != NULL) {
char *name = strdup(file->path);
if (!name) {
perror("ccc");
}
return name;
} else { } else {
return NULL; int new_cap = list->capacity * 2;
} file *new_items = memalloc(new_cap * sizeof(file));
} file *old_items = list->items;
list->capacity = new_cap;
int get_color(long index) list->items = new_items;
{ for (int i = 0; i < list->length; i++) {
file *file = get_file(index); new_items[i] = old_items[i];
if (file != NULL) {
int color = file->color;
if (!color) {
perror("ccc");
} }
return color; free(old_items);
} else { list->items[list->length] = new_file;
return 8; /* white */
} }
list->length++;
} }
/* /*
* Construct a formatted line for display * Construct a formatted line for display
*/ */
char *get_line(long index) char *get_line(ArrayList *list, long index, bool detail)
{ {
file *file = get_file(index); file file = list->items[index];
if (file != NULL) { char *name = strdup(file.path);
char *name = strdup(file->path); char *stats = strdup(file.stats);
char *stats = strdup(file->stats); size_t length = strlen(name) + strlen(stats) + 2; /* one for space and one for null */
size_t length = strlen(name) + strlen(stats) + 2; /* one for space and one for null */ char *line = memalloc(length * sizeof(char));
char *line = memalloc(length * sizeof(char));
name = basename(name); name = basename(name);
if (name == NULL || stats == NULL) if (name == NULL || stats == NULL)
perror("ccc"); perror("ccc");
snprintf(line, length, "%s %s", stats, name); snprintf(line, length, "%s %s", stats, name);
return line; return line;
} else {
return NULL;
}
} }

29
file.h
View file

@ -1,27 +1,26 @@
#ifndef FILE_H_ #ifndef FILE_H_
#define FILE_H_ #define FILE_H_
#include <stdio.h>
typedef struct file { typedef struct file {
char *path; char *path;
char *stats; char *stats;
char *type; char *type;
int color; int color;
struct file *next;
} file; } file;
long files_len(); typedef struct ArrayList {
long marked_len(); size_t length;
void free_file(file *toremove); size_t capacity;
void clear_files(); file *items;
void clear_marked(); } ArrayList;
long add_file(char *filepath, char *stats, char *type, int color);
void remove_marked(file *marked_file); ArrayList *arraylist_init(size_t capacity);
long add_marked(char *filepath, char *type, bool force); void arraylist_free(ArrayList *list);
file *get_marked(long index); bool arraylist_includes(ArrayList *list, char *path);
bool in_marked(char *path); void arraylist_remove(ArrayList *list, long index);
file *get_file(long index); void arraylist_add(ArrayList *list, char *filepath, char *stats, char *type, int color, bool marked, bool force);
char *get_filepath(long index); char *get_line(ArrayList *list, long index, bool detail);
int get_color(long index);
char *get_line(long index);
#endif #endif