commit de30cfb2c07a1461d37c2b7caef2d0a721e2b011
Author: Raniconduh <clagv.randomgames@gmail.com>
Date: Sat Jan 29 21:10:38 2022 +0000
diff --git a/include/hash.h b/include/hash.h
new file mode 100644
index 0000000..ca6b571
--- /dev/null
+++ b/include/hash.h
@@ -00 +129 @@
+#ifndef _HASH_H
+#define _HASH_H
+
+#include <stdint.h>
+
+
+typedef struct BucketData {
+ struct BucketData * next;
+ char * key;
+ void (*value)(void *);
+} bucket_data;
+
+typedef struct Bucket {
+ uint32_t hash;
+ bucket_data * data;
+} bucket;
+
+typedef struct Map {
+ uint32_t length;
+ bucket ** arr; // list of pointers to buckets
+} map;
+
+
+map * map_new(size_t n);
+void map_insert(map *, char *, void (*)(void *));
+void map_nuke(map *);
+void (*map_index(map *, char *))(void *);
+
+#endif /* _HASH_H */
diff --git a/include/var.h b/include/var.h
new file mode 100644
index 0000000..a35dcd4
--- /dev/null
+++ b/include/var.h
@@ -00 +110 @@
+#ifndef _VAR_H
+#define _VAR_H
+
+#include <stdbool.h>
+
+void var_init(void);
+bool var_set(char *, void *);
+void terminate_var(void);
+
+#endif /* _VAR_H */
diff --git a/src/commands.c b/src/commands.c
index 259242e..316a3fa 100644
--- a/src/commands.c
+++ b/src/commands.c
@@ -86 +87 @@
#include "io.h"
#include "dir.h"
+#include "var.h"
#include "opts.h"
#include "commands.h"
@@ -14215 +1438 @@ void run_cmd(char * cmd) {
void set(char * v) {
- if (!strcmp(v, "color")) {
- color = true;
- set_color();
- }
-#if ICONS
- else if (!strcmp(v, "icons")) show_icons = true;
-#endif
- else if (!strcmp(v, "long")) p_long = true;
- else {
+ bool tmp = true;
+ if (!var_set(v, &tmp)) {
printw("Unknown variable (%s)", v);
refresh();
napms(500);
@@ -15915 +1538 @@ void set(char * v) {
void unset(char * v) {
- if (!strcmp(v, COLOR_VAR)) {
- color = false;
- set_color();
- }
-#if ICONS
- else if (!strcmp(v, ICONS_VAR)) show_icons = false;
-#endif
- else if (!strcmp(v, LONG_VAR)) p_long = false;
- else {
+ bool tmp = false;
+ if (!var_set(v, &tmp)) {
printw("Unknown variable (%s)", v);
refresh();
napms(500);
diff --git a/src/hash.c b/src/hash.c
new file mode 100644
index 0000000..95f71e8
--- /dev/null
+++ b/src/hash.c
@@ -00 +1128 @@
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "hash.h"
+
+
+// jenkins one at a time hash
+static uint32_t map_hashs(char * s) {
+ uint32_t hash;
+ char * i;
+ for(hash = 0, i = s; *i; i++)
+ {
+ hash += *i;
+ hash += (hash << 10);
+ hash ^= (hash >> 6);
+ }
+ hash += (hash << 3);
+ hash ^= (hash >> 11);
+ hash += (hash << 15);
+ return hash;
+}
+
+
+static bucket_data * map_new_data(void) {
+ bucket_data * a = malloc(sizeof(bucket_data));
+
+ a->next = NULL;
+ a->key = NULL;
+ a->value = NULL;
+
+ return a;
+}
+
+
+static bucket * map_new_bucket(void) {
+ bucket * a = malloc(sizeof(bucket));
+
+ a->hash = 0;
+ a->data = NULL;
+
+ return a;
+}
+
+
+map * map_new(size_t n) {
+ map * m = malloc(sizeof(map));
+
+ m->arr = malloc(sizeof(bucket *) * (n + 1));
+ m->length = n;
+
+ // initialize array
+ for (size_t i = 0; i < n; i++) {
+ m->arr[i] = NULL;
+ }
+
+ return m;
+}
+
+
+void map_insert(map * m, char * k, void (*v)(void *)) {
+ long klen = strlen(k);
+ uint32_t khash = map_hashs(k);
+
+ // hash already exists, add to bucket
+ if (m->length > 0 && m->arr[khash % m->length]) {
+ bucket_data * d = map_new_data();
+
+ d->key = malloc(klen);
+ strcpy(d->key, k);
+
+ d->value = v;
+
+ // replace top node with new node
+ d->next = m->arr[khash % m->length]->data;
+ m->arr[khash % m->length]->data = d;
+ return;
+ }
+
+ // need to create new bucket
+ bucket_data * d = map_new_data();
+
+ d->key = malloc(klen);
+ strcpy(d->key, k);
+ d->value = v;
+
+ bucket * b = map_new_bucket();
+
+ b->hash = khash;
+ b->data = d;
+
+ m->arr[khash % m->length] = b;
+
+ return;
+}
+
+
+void map_nuke(map * m) {
+ // loop over array
+ for (size_t i = 0; i < m->length; i++) {
+ if (!m->arr[i]) continue;
+ // first free linked list
+ for (bucket_data * p = m->arr[i]->data; p;) {
+ bucket_data * tmp = p->next;
+ free(p);
+ p = tmp;
+ }
+ // then free bucket
+ free(m->arr[i]);
+ }
+ // free array
+ free(m->arr);
+ // finally free map itself
+ free(m);
+}
+
+
+void (*map_index(map * m, char * k))(void *) {
+ uint32_t khash = map_hashs(k);
+ bucket_data * p;
+ // if hash exists ...
+ if (m->arr[khash % m->length])
+ // ... then search bucket for key
+ for (p = m->arr[khash % m->length]->data; p; p = p->next)
+ if (!strcmp(p->key, k)) return p->value;
+ return NULL;
+}
diff --git a/src/main.c b/src/main.c
index 3207fde..8a94b24 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1111 +1114 @@
#include "main.h"
#include "opts.h"
#include "dir.h"
+#include "var.h"
#include "io.h"
static size_t first_f, last_f, cursor;
int main(int argc, char ** argv) {
+ var_init();
+
if (!check_config()) create_config();
else read_config();
terminate_opts();
@@ -3726 +3757 @@ int main(int argc, char ** argv) {
done:
free_dir_entries();
free(dir_entries);
+ terminate_var();
terminate_curses();
if (print_path) puts(cwd);
diff --git a/src/opts.c b/src/opts.c
index 7352459..8844be1 100644
--- a/src/opts.c
+++ b/src/opts.c
@@ -66 +67 @@
#include <ctype.h>
#include "opts.h"
+#include "var.h"
#define CFG_FNAME "config"
@@ -1179 +1187 @@ void read_config(void) {
bool bool_val = false;
if (!strcmp(val, "true")) bool_val = true;
- if (!strcmp(var, ICONS_VAR)) show_icons = bool_val;
- else if (!strcmp(var, COLOR_VAR)) color = bool_val;
- else if (!strcmp(var, LONG_VAR)) p_long = bool_val;
+ var_set(var, &bool_val);
}
fclose(fp);
diff --git a/src/var.c b/src/var.c
new file mode 100644
index 0000000..fb3b2a1
--- /dev/null
+++ b/src/var.c
@@ -00 +148 @@
+#include <stdbool.h>
+
+#include "hash.h"
+#include "opts.h"
+#include "io.h"
+
+
+static map * var_map = NULL;
+
+
+// void * p -> bool p
+static void set_icons(void * p) {
+ show_icons = *(bool*)p;
+}
+
+
+static void set_color_f(void * p) {
+ color = *(bool*)p;
+ set_color();
+}
+
+
+static void set_long(void * p) {
+ p_long = *(bool*)p;
+}
+
+
+void var_init(void) {
+ var_map = map_new(4);
+
+ map_insert(var_map, ICONS_VAR, set_icons);
+ map_insert(var_map, COLOR_VAR, set_color_f);
+ map_insert(var_map, LONG_VAR, set_long);
+}
+
+
+bool var_set(char * k, void * p) {
+ void (*set_func)(void *) = map_index(var_map, k);
+ if (!set_func) return false;
+
+ set_func(p);
+ return true;
+}
+
+
+void terminate_var(void) {
+ map_nuke(var_map);
+}