From 56ac48e5967efb8bc55d715a9b7037366263ee8e Mon Sep 17 00:00:00 2001 From: Piotr Marendowski Date: Sun, 31 Mar 2024 22:44:05 +0200 Subject: [PATCH] Separate filename and path into two parts, changes all over --- Makefile | 2 +- ccc.c | 84 ++++++++++++++++++++++++++++++++++---------------------- config.h | 2 +- file.c | 50 +++++++++++++++++++++------------ file.h | 5 ++-- 5 files changed, 88 insertions(+), 55 deletions(-) diff --git a/Makefile b/Makefile index ce65e35..74cae7e 100644 --- a/Makefile +++ b/Makefile @@ -12,7 +12,7 @@ MANDIR = $(PREFIX)/share/man/man1 # Flags LDFLAGS = $(shell pkg-config --libs ncursesw) -CFLAGS = -O3 -march=native -mtune=native -pipe -s -std=c99 -pedantic -Wall -D_DEFAULT_SOURCE -D_XOPEN_SOURCE=600 $(shell pkg-config --cflags ncursesw) +CFLAGS = -O3 -march=native -mtune=native -pipe -s -g -std=c99 -pedantic -Wall -D_DEFAULT_SOURCE -D_XOPEN_SOURCE=600 $(shell pkg-config --cflags ncursesw) SRC = ccc.c util.c file.c icons.c diff --git a/ccc.c b/ccc.c index 8e2c875..c4e1e8f 100644 --- a/ccc.c +++ b/ccc.c @@ -26,7 +26,7 @@ void change_dir(const char *buf, int selection, int ftype); void mkdir_p(const char *destdir); void populate_files(const char *path, int ftype); int get_directory_size(const char *fpath, const struct stat *sb, int typeflag, struct FTW *ftwbuf); -void add_file_stat(char *filepath, int ftype); +void add_file_stat(char *filename, char *path, int ftype); char *get_file_mode(mode_t mode); void highlight_current_line(); void show_file_content(); @@ -125,7 +125,6 @@ int main(int argc, char** argv) die("ccc: Terminal size needs to be at least 80x24\n"); } ch = getch(); - /* printf("%d ",ch); */ switch (ch) { /* quit */ case 'q': @@ -281,7 +280,7 @@ int main(int argc, char** argv) /* mark one file */ case SPACE: - add_file_stat(files->items[current_selection].path, 1); + add_file_stat(files->items[current_selection].filename, files->items[current_selection].path, 1); highlight_current_line(); break; @@ -292,39 +291,49 @@ int main(int argc, char** argv) /* mark actions: */ /* delete */ - case 'd':; + case 'd': if (marked->length) { char *trash_dir = check_trash_dir(); if (trash_dir != NULL) { - ; - /* do your magic here */ + int i = 0; + while (i < marked->length) { + printf("%s", marked->items->path); + if (rename(marked->items->path, trash_dir) == 0) { + printf("file deleted"); + } else { + perror("error moving file"); + } + i++; + } + } else { + wpprintw("implement hard delete"); } } break; /* move */ - case 'm':; + case 'm': if (marked->length) { ; } break; /* copy */ - case 'c':; + case 'c': if (marked->length) { ; } break; /* symbolic link */ - case 's':; + case 's': if (marked->length) { ; } break; /* bulk rename */ - case 'b':; + case 'b': if (marked->length) { ; } @@ -370,7 +379,9 @@ void start_ccc() init_windows(); } -/* Checks if trash directory is set and returns it */ +/* + * Checks if the trash directory is set and returns it + */ char *check_trash_dir() { char *path = memalloc(PATH_MAX * sizeof(char)); @@ -401,7 +412,7 @@ char *check_trash_dir() /* if has access to trash_dir */ if (access(path, F_OK) != 0) { - /* create the directory with 755 perm if it doesn't exit */ + /* create the directory with 755 permissions if it doesn't exist */ mkdir_p(path); } } @@ -481,7 +492,6 @@ void mkdir_p(const char *destdir) /* * Read the provided directory and add all files in directory to linked list * ftype: normal files = 0, marked = 1, marking ALL = 2 - * ep->d_name -> filename */ void populate_files(const char *path, int ftype) { @@ -493,22 +503,24 @@ void populate_files(const char *path, int ftype) wclear(directory_content); while ((ep = readdir(dp)) != NULL) { - char *filename = memalloc(PATH_MAX * sizeof(char)); - /* make filename be basename of selected item just to pass check */ + char *path = memalloc(PATH_MAX * sizeof(char)); + char *filename = memalloc(FILENAME_MAX * sizeof(char)); + /* copy filename */ filename[0] = '\0'; strcat(filename, ep->d_name); /* use strncmp to filter out dotfiles */ if ((!show_hidden && strncmp(filename, ".", 1) && strncmp(filename, "..", 2)) || (show_hidden && strcmp(filename, ".") && strcmp(filename, ".."))) { /* construct full file path */ - filename[0] = '\0'; - strcat(filename, cwd); - strcat(filename, "/"); - strcat(filename, ep->d_name); /* add filename */ + path[0] = '\0'; + strcat(path, cwd); + strcat(path, "/"); + strcat(path, filename); /* add filename */ - add_file_stat(filename, ftype); + add_file_stat(path, filename, ftype); } free(filename); + free(path); } closedir(dp); wrefresh(directory_content); @@ -529,13 +541,14 @@ int get_directory_size(const char *fpath, const struct stat *sb, int typeflag, s * Add that file into list * ftype: normal file = 0, normal marked = 1, marked ALL = 2 */ -void add_file_stat(char *filepath, int ftype) +void add_file_stat(char *filename, char *path, int ftype) { struct stat file_stat; - if (stat(filepath, &file_stat) == -1) { + char *filename_and_path = strcat(path, filename); + if (stat(filename_and_path, &file_stat) == -1) { /* can't be triggered? */ if (errno == EACCES) - arraylist_add(files, filepath, NULL, NULL, NULL, 8, false, false); + arraylist_add(files, filename, path, NULL, NULL, NULL, 8, false, false); } /* get file type and color, 4 chars for the type and icon */ @@ -545,9 +558,9 @@ void add_file_stat(char *filepath, int ftype) char *type = memalloc(type_size); wchar_t *icon_str = memalloc(icon_size); - filepath[strlen(filepath)] = '\0'; + filename[strlen(filename)] = '\0'; /* find last / in path by finding basename */ - char *f_bname = strrchr(filepath, '/'); + char *f_bname = filename; char *ext = NULL; if (f_bname != NULL) { /* shift 1 to get basename */ @@ -560,6 +573,7 @@ void add_file_stat(char *filepath, int ftype) ext = f_bname; } } + /* add file extension */ if (ext != NULL) { icon *ext_icon = hashtable_search(ext); if (ext_icon == NULL) @@ -575,6 +589,7 @@ void add_file_stat(char *filepath, int ftype) if (S_ISDIR(file_stat.st_mode)) { strncpy(type, "DIR", 4); /* directory type */ color = 5; /* blue color */ + wcsncpy(icon_str, L"󰉋", 2); } else if (S_ISREG(file_stat.st_mode)) { strncpy(type, "REG", 4); /* regular file */ color = 8; /* white color */ @@ -601,7 +616,7 @@ void add_file_stat(char *filepath, int ftype) if (ftype == 1 || ftype == 2) { /* force if user is marking all files */ bool force = ftype == 2 ? true : false; - arraylist_add(marked, filepath, NULL, type, icon_str, 8, true, force); + arraylist_add(marked, filename, path, NULL, type, icon_str, 8, true, force); /* free type and return without allocating more stuff */ free(type); return; @@ -621,11 +636,12 @@ void add_file_stat(char *filepath, int ftype) if (S_ISDIR(file_stat.st_mode)) { /* at most 15 fd opened */ total_dir_size = 0; - nftw(filepath, &get_directory_size, 15, FTW_PHYS); + nftw(filename_and_path, &get_directory_size, 15, FTW_PHYS); bytes = total_dir_size; } } - /* 4 before decimal + 1 dot + DECIMAL_PLACES (after decimal) + unit length(1 for K, 3 for KiB, taking units[1] as B never changes)+ 1 space + 1 null */ + /* 4 before decimal + 1 dot + DECIMAL_PLACES (after decimal) + + unit length (1 for K, 3 for KiB, taking units[1] as B never changes) + 1 space + 1 null */ int size_size = 4 + 1 + DECIMAL_PLACES + strlen(units[1]) + 1 + 1; char *size = memalloc(size_size * sizeof(char)); int unit = 0; @@ -647,7 +663,7 @@ void add_file_stat(char *filepath, int ftype) char *total_stat = memalloc(stat_size); snprintf(total_stat, stat_size, "%s %s %-*s", mode_str, time, size_size, size); - arraylist_add(files, filepath, total_stat, type, icon_str, color, false, false); + arraylist_add(files, filename, path, total_stat, type, icon_str, color, false, false); free(time); free(size); @@ -734,7 +750,7 @@ void highlight_current_line() char *line = get_line(files, i, file_details); int color = files->items[i].color; /* check is file marked for action */ - bool is_marked = arraylist_includes(marked, files->items[i].path); + bool is_marked = arraylist_includes(marked, files->items[i].filename, files->items[i].path); if (is_marked) { /* show file is selected */ wattron(directory_content, COLOR_PAIR(7)); @@ -776,15 +792,17 @@ void highlight_current_line() */ void show_file_content() { - wclear(preview_content); file current_file = files->items[current_selection]; + char *filename_and_path = strcat(current_file.path, current_file.filename); if (strncmp(current_file.type, "DIR", 3) == 0) return; - FILE *file = fopen(current_file.path, "r"); + wclear(preview_content); + + FILE *file = fopen(filename_and_path, "r"); if (file == NULL) { - mvwprintw(preview_content, 0, 0, "Unable to read %s", current_file.path); + mvwprintw(preview_content, 0, 0, "Unable to read %s", filename_and_path); return; } diff --git a/config.h b/config.h index 949b0b7..1c45bb7 100644 --- a/config.h +++ b/config.h @@ -5,7 +5,7 @@ #define DECIMAL_PLACES 1 /* how many decimal places show size with */ /* Size units */ -const char* units[] = {"B", "K", "M", "G", "T", "P"}; +static const char* units[] = {"B", "K", "M", "G", "T", "P"}; /* Set width offset for windows: +-------------%-------------+ diff --git a/file.c b/file.c index 2c7487a..f497af1 100644 --- a/file.c +++ b/file.c @@ -20,10 +20,12 @@ ArrayList *arraylist_init(size_t capacity) void arraylist_free(ArrayList *list) { for (size_t i = 0; i < list->length; i++) { - if (list->items[i].type != NULL) - free(list->items[i].type); + if (list->items[i].path != NULL) + free(list->items[i].filename); if (list->items[i].path != NULL) free(list->items[i].path); + if (list->items[i].type != NULL) + free(list->items[i].type); if (list->items[i].stats != NULL) free(list->items[i].stats); if (list->items[i].icon != NULL) @@ -34,10 +36,15 @@ void arraylist_free(ArrayList *list) list->length = 0; } -bool arraylist_includes(ArrayList *list, char *path) +/* + * Check if the file is in the arraylist + */ +bool arraylist_includes(ArrayList *list, char* filename, char *path) { + char *current_whole_path = strcat(path, filename); for (int i = 0; i < list->length; i++) { - if (strcmp(list->items[i].path, path) == 0) { + char *list_whole_path = strcat(list->items[i].path, list->items[i].filename); + if (strcmp(list_whole_path, current_whole_path) == 0) { return true; } } @@ -50,6 +57,7 @@ void arraylist_remove(ArrayList *list, long index) if (index >= list->length) return; + free(list->items[index].filename); free(list->items[index].path); free(list->items[index].stats); free(list->items[index].type); @@ -64,41 +72,49 @@ void arraylist_remove(ArrayList *list, long index) /* * Force will not remove duplicate marked files, instead it just skip adding */ -void arraylist_add(ArrayList *list, char *filepath, char *stats, char *type, wchar_t *icon, int color, bool marked, bool force) +void arraylist_add(ArrayList *list, char *filename, char *path, char *stats, char *type, wchar_t *icon, int color, bool marked, bool force) { - char *filepath_cp = NULL; + char *filename_cp = NULL; + char *path_cp = NULL; char *stats_cp = NULL; char *type_cp = NULL; wchar_t *icon_cp = NULL; - if (filepath != NULL) { - filepath_cp = strdup(filepath); - if (filepath_cp == NULL) - perror("ccc"); + if (filename_cp != NULL) { + filename_cp = strdup(filename_cp); + if (filename_cp == NULL) + perror("can't add filename to arraylist"); + } + if (path_cp != NULL) { + path_cp = strdup(path_cp); + if (path_cp == NULL) + perror("can't add path to arraylist"); } if (stats != NULL) { stats_cp = strdup(stats); if (stats_cp == NULL) - perror("ccc"); + perror("can't add stats to arraylist"); } if (type != NULL) { type_cp = strdup(type); if (type_cp == NULL) - perror("ccc"); + perror("can't add type to arraylist"); } if (icon != NULL) { icon_cp = wcsdup(icon); if (icon_cp == NULL) - perror("ccc"); + perror("can't add icon to arraylist"); } - /* path, stats, type, icon, color */ - file new_file = { filepath_cp, stats_cp, type_cp, icon_cp, color }; + /* filename, path, stats, type, icon, color */ + file new_file = { filename_cp, path_cp, stats_cp, type_cp, icon_cp, color }; 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) { + char *list_whole_path = strcat(list->items[i].path, list->items[i].filename); + char *current_whole_path = strcat(new_file.path, new_file.filename); + if (strcmp(list_whole_path, current_whole_path) == 0) { if (!force) arraylist_remove(list, i); return; @@ -147,9 +163,7 @@ char *get_line(ArrayList *list, long index, bool detail) length = strlen(name) + 6; /* 4 for icon, 1 for space and 1 for null */ } char *line = memalloc(length * sizeof(char)); - - if (detail) { snprintf(line, length, "%s %ls %s", stats, icon, name); } else { diff --git a/file.h b/file.h index 49f72fc..4ec33dd 100644 --- a/file.h +++ b/file.h @@ -5,6 +5,7 @@ typedef struct file { char *path; + char *filename; char *stats; char *type; wchar_t *icon; @@ -19,9 +20,9 @@ typedef struct ArrayList { ArrayList *arraylist_init(size_t capacity); void arraylist_free(ArrayList *list); -bool arraylist_includes(ArrayList *list, char *path); +bool arraylist_includes(ArrayList *list, char* filename, char *path); void arraylist_remove(ArrayList *list, long index); -void arraylist_add(ArrayList *list, char *filepath, char *stats, char *type, wchar_t *icon, int color, bool marked, bool force); +void arraylist_add(ArrayList *list, char *filename, char *path, char *stats, char *type, wchar_t *icon, int color, bool marked, bool force); char *get_line(ArrayList *list, long index, bool detail); #endif