From 575d873efeaac8e1cc9069c6ff05519dcfaf71ab Mon Sep 17 00:00:00 2001 From: night0721 Date: Sat, 30 Mar 2024 03:39:02 +0000 Subject: [PATCH] make icons show in dir content via hash table dynamically --- Makefile | 2 +- ccc.c | 43 +++++++++++++---- config.h | 2 + file.c | 4 +- icons.c | 137 +++++++++++++++++++++++-------------------------------- icons.h | 19 ++++---- 6 files changed, 108 insertions(+), 99 deletions(-) diff --git a/Makefile b/Makefile index 8686316..4eeec43 100644 --- a/Makefile +++ b/Makefile @@ -14,7 +14,7 @@ MANDIR = $(PREFIX)/share/man/man1 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) -SRC = ccc.c util.c file.c +SRC = ccc.c util.c file.c icons.c $(TARGET): $(SRC) $(CC) $(SRC) -o $@ $(CFLAGS) $(LDFLAGS) diff --git a/ccc.c b/ccc.c index 2905eeb..5a7a898 100644 --- a/ccc.c +++ b/ccc.c @@ -13,9 +13,10 @@ #include #include -#include "file.h" -#include "util.h" #include "config.h" +#include "file.h" +#include "icons.h" +#include "util.h" /* functions' definitions */ void show_help(); @@ -105,6 +106,7 @@ int main(int argc, char** argv) /* init files and marked arrays */ files = arraylist_init(100); marked = arraylist_init(100); + hashtable_init(); cwd = memalloc(PATH_MAX * sizeof(char)); if (argc == 2) { @@ -533,13 +535,38 @@ void add_file_stat(char *filepath, int ftype) if (stat(filepath, &file_stat) == -1) { /* can't be triggered? */ if (errno == EACCES) - arraylist_add(files, filepath, "", "", "", 8, false, false); + arraylist_add(files, filepath, NULL, NULL, NULL, 8, false, false); } /* get file type and color, 4 chars for the type and icon */ char *type = memalloc(4 * sizeof(char)); - wchar_t *icon = memalloc(2 * sizeof(wchar_t)); - wcsncpy(icon, L"", 2); + wchar_t *icon_str = memalloc(2 * sizeof(wchar_t)); + + filepath[strlen(filepath)] = '\0'; + /* find last / in path */ + char *f_bname = strrchr(filepath, '/'); + char *ext = NULL; + if (f_bname != NULL) { + /* shift 1 to get basename */ + f_bname += 1; + /* handle file without extension */ + ext = strrchr(f_bname, '.'); + if (ext != NULL) { + ext += 1; + } else { + ext = f_bname; + } + } + if (ext != NULL) { + icon *ext_icon = hashtable_search(ext); + if (ext_icon == NULL) + wcsncpy(icon_str, L"", 2); + else + wcsncpy(icon_str, ext_icon->icon, 2); + } else { + wcsncpy(icon_str, L"0", 2); + } + int color; if (S_ISDIR(file_stat.st_mode)) { @@ -571,7 +598,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, 8, true, force); + arraylist_add(marked, filepath, NULL, type, icon_str, 8, true, force); /* free type and return without allocating more stuff */ free(type); return; @@ -612,14 +639,14 @@ void add_file_stat(char *filepath, int ftype) char *total_stat = memalloc(37 * sizeof(char)); snprintf(total_stat, 37, "%s %s %-8s", mode_str, time, size); - arraylist_add(files, filepath, total_stat, type, icon, color, false, false); + arraylist_add(files, filepath, total_stat, type, icon_str, color, false, false); free(time); free(size); free(total_stat); free(type); free(mode_str); - free(icon); + free(icon_str); } /* diff --git a/config.h b/config.h index 9f9dd7d..52032bc 100644 --- a/config.h +++ b/config.h @@ -1,3 +1,5 @@ +#include "icons.h" + /* Settings */ #define PH 1 /* panel height */ #define JUMP_NUM 14 /* how long ctrl + u/d jump are */ diff --git a/file.c b/file.c index 1ab9b61..50afab1 100644 --- a/file.c +++ b/file.c @@ -26,8 +26,8 @@ void arraylist_free(ArrayList *list) free(list->items[i].path); if (list->items[i].stats != NULL) free(list->items[i].stats); - /*if (list->items[i].icon != NULL) - free(list->items[i].icon);*/ + if (list->items[i].icon != NULL) + free(list->items[i].icon); } free(list->items); diff --git a/icons.c b/icons.c index 4b995ed..59f0638 100644 --- a/icons.c +++ b/icons.c @@ -2,14 +2,10 @@ #include #include #include +#include -#define MAX_NAME 30 -#define TABLE_SIZE 20 - -typedef struct { - char name[MAX_NAME]; - char *icon; -} icon; +#include "icons.h" +#include "util.h" icon *hash_table[TABLE_SIZE]; @@ -24,18 +20,43 @@ unsigned int hash(char *name) hash_value = (hash_value * name[i]) % TABLE_SIZE; } + printf("Name: %s | Hash Value: %d\n", name, hash_value); return hash_value; } -void init_hash_table() +void hashtable_init() { - int i = 0; - - for (; i < TABLE_SIZE; i++) + for (int i = 0; i < TABLE_SIZE; i++) hash_table[i] = NULL; + + icon *c = memalloc(sizeof(icon)); + strcpy(c->name, "c"); + c->icon = L""; + + icon *h = memalloc(sizeof(icon)); + strcpy(h->name, "h"); + h->icon = L""; + + icon *cpp = memalloc(sizeof(icon)); + strcpy(cpp->name, "cpp"); + cpp->icon = L""; + + icon *hpp = memalloc(sizeof(icon)); + strcpy(hpp->name, "hpp"); + hpp->icon = L"󰰀"; + + icon *md = memalloc(sizeof(icon)); + strcpy(md->name, "md"); + md->icon = L""; + + hashtable_add(c); + hashtable_add(h); + hashtable_add(cpp); + hashtable_add(hpp); + hashtable_add(md); } -void print_table() +void hashtable_print() { int i = 0; @@ -43,88 +64,44 @@ void print_table() if (hash_table[i] == NULL) { printf("%i. ---\n", i); } else { - printf("%i. %s %s\n", i, hash_table[i]->name, hash_table[i]->icon); + printf("%i. | Name %s | Icon %ls\n", i, hash_table[i]->name, hash_table[i]->icon); } } } /* Gets hashed name and tries to store the icon struct in that place */ -bool add_icon(icon *p) +bool hashtable_add(icon *p) { if (p == NULL) return false; int index = hash(p->name); - int i = 0, try; - - try = (i + index) % TABLE_SIZE; - if (hash_table[try] == NULL) { - hash_table[try] = p; - return true; + int initial_index = index; + /* linear probing until an empty slot is found */ + while (hash_table[index] != NULL) { + index = (index + 1) % TABLE_SIZE; /* move to next item */ + /* the hash table is full as no available index back to initial index, cannot fit new item */ + if (index == initial_index) return false; } - return false; + hash_table[index] = p; + return true; } /* Rehashes the name and then looks in this spot, if found returns icon */ -icon *icon_search(char *name) +icon *hashtable_search(char *name) { - int index = hash(name), i = 0; - - // this handles icons with the same hash values - // or use linked lists in structs - // for (; i < TABLE_SIZE; i++) { - // int try = (index + i) % TABLE_SIZE; - // - // for (; i < TABLE_SIZE; i++) { - // try = (i + index) % TABLE_SIZE; - // - // if (hash_table[try] == NULL) - // return false; - // - // if (strncmp(hash_table[try]->name, name, TABLE_SIZE) == 0) - // return hash_table[try]; - // } - // - // return false; - // } - // - // return NULL; - - if (hash_table[index] == NULL) - return false; - - if (strncmp(hash_table[index]->name, name, MAX_NAME) == 0) - return hash_table[index]; - + int index = hash(name); + int initial_index = index; + + /* Linear probing until an empty slot or the desired item is found */ + while (hash_table[index] != NULL) { + if (strncmp(hash_table[index]->name, name, MAX_NAME) == 0) + return hash_table[index]; + + index = (index + 1) % TABLE_SIZE; /* Move to the next slot */ + /* back to same item */ + if (index == initial_index) break; + } + return NULL; } - -int main(void) -{ - init_hash_table(); - - /* name reference name icon */ - icon c = { .name="c", .icon="" }; - icon h = { .name="h", .icon="" }; - icon cpp = { .name="cpp", .icon="" }; - icon hpp = { .name="hpp", .icon="󰰀" }; - icon md = { .name="md", .icon="" }; - - add_icon(&c); - add_icon(&h); - add_icon(&cpp); - add_icon(&hpp); - add_icon(&md); - - print_table(); - - icon *tmp = icon_search("hpp"); - - if (tmp == NULL) - printf("null\n"); - - printf("%s", tmp->icon); - - return 0; -} - diff --git a/icons.h b/icons.h index 2de349f..db87223 100644 --- a/icons.h +++ b/icons.h @@ -1,18 +1,21 @@ -#ifndef FILE_H_ -#define FILE_H_ +#ifndef ICONS_H_ +#define ICONS_H_ + +#include +#include #define MAX_NAME 30 -#define TABLE_SIZE 20 +#define TABLE_SIZE 50 typedef struct { char name[MAX_NAME]; - char icon[4]; + wchar_t *icon; } icon; unsigned int hash(char *name); -void init_hash_table(); -void print_table(); -bool add_icon(icon *p); -icon *icon_search(char *name); +void hashtable_init(); +void hashtable_print(); +bool hashtable_add(icon *p); +icon *hashtable_search(char *name); #endif