Thumbnail

rani/cscroll.git

Clone URL: https://git.buni.party/rani/cscroll.git

commit de30cfb2c07a1461d37c2b7caef2d0a721e2b011 Author: Raniconduh <clagv.randomgames@gmail.com> Date: Sat Jan 29 21:10:38 2022 +0000 moved setting cscroll variables into a hash map 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); +}