diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/include/keytab.h | 23 | ||||
-rw-r--r-- | src/keytab.c | 89 | ||||
-rw-r--r-- | src/main.c | 19 |
3 files changed, 128 insertions, 3 deletions
diff --git a/src/include/keytab.h b/src/include/keytab.h index e69de29..f3b8910 100644 --- a/src/include/keytab.h +++ b/src/include/keytab.h @@ -0,0 +1,23 @@ +#ifndef KEYTAB_H +#define KEYTAB_H + +#define TABLEN 1024 + +union value { + char *str; + double num; + unsigned int b : 1; +}; + +struct keytab { + char *key; + int flag; + union value v; +}; + +int *getkeys(struct keytab *tab); +struct keytab getkey(struct keytab *tab, char *key); +void setkey(struct keytab *tab, char *pair); +void delkey(struct keytab *tab, char *key); + +#endif diff --git a/src/keytab.c b/src/keytab.c index e69de29..8d929dc 100644 --- a/src/keytab.c +++ b/src/keytab.c @@ -0,0 +1,89 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <ctype.h> + +#include "include/keytab.h" + +static int hash(char *key); + +int *getkeys(struct keytab *tab) +{ + int len = 2; + int *indexes = calloc(len, sizeof(int)); + for (int i = 0, j = 0; i < TABLEN; ++i) { + if (j >= len) { + indexes = realloc(indexes, ++len * sizeof(int)); + indexes[len - 1] = 0; + } + if (tab[i].key) + indexes[j++] = i; + } + return indexes; +} + +struct keytab getkey(struct keytab *tab, char *key) +{ + int idx = hash(key); + if (tab[idx].key == NULL) + return (struct keytab) { .key = NULL, .v = 0 }; + + while (strcmp(tab[idx].key, key) && idx < TABLEN) + idx++; + if (idx >= TABLEN) + return (struct keytab) { .key = NULL, .v = 0 }; + return tab[idx]; +} + +void setkey(struct keytab *tab, char *pair) +{ + char *tmp = calloc(strlen(pair) + 1, sizeof(char)); + strcpy(tmp, pair); + char *tok = strtok(pair, ":"); + if (!strcmp(tmp, tok)) { + fprintf(stderr, "Invalid key-value pair: %s\n", tmp); + free(tmp); + return; + } + free(tmp); + + char *key = calloc(strlen(tok) + 1, sizeof(char)); + strcpy(key, tok); + + tok = strtok(NULL, ":"); + union value v; + int flag; + if (isdigit(*tok)) { + flag = 1; + v.num = atof(tok); + } else if (!strcmp(tok, "true") || !strcmp(tok, "false")) { + flag = 2; + v.b = !strcmp(tok, "true"); + } else { + flag = 3; + v.str = calloc(strlen(tok) + 1, sizeof(char)); + strcpy(v.str, tok); + } + + int idx = hash(key); + while (tab[idx].key != NULL && strcmp(tab[idx].key, key) && idx < TABLEN) + idx++; + if (idx >= TABLEN) { + fprintf(stderr, "No more room in table\n"); + return; + } + if (!tab[idx].key) + tab[idx].key = key; + else + free(key); + tab[idx].v = v; + tab[idx].flag = flag; +} + +int hash(char *key) +{ + unsigned long h = 5381; + for (int i = 0; i < strlen(key); ++i) + h = ((h << 5) + h) + key[i]; + return h % TABLEN; +} @@ -4,9 +4,11 @@ #include "include/fileops.h" #include "include/parser.h" +#include "include/keytab.h" int main(int argc, char **argv) { + struct keytab tab[TABLEN] = {{ NULL, 0, { 0 } }}; if (argc != 2) exit(1); char *filename = argv[1]; @@ -20,13 +22,11 @@ int main(int argc, char **argv) for (int i = 0; i < blen; ++i) { switch (bytes[i].type) { case BEGIN: - printf("BEGIN\n"); break; case END: - printf("END\n"); break; case PAIR: - printf("PAIR: %s\n", bytes[i].value); + setkey(tab, bytes[i].value); free(bytes[i].value); break; case ERROR: @@ -35,6 +35,19 @@ int main(int argc, char **argv) } } + int *indexes = getkeys(tab); + for (int i = 0; indexes[i] != 0; ++i) { + printf("%s: ", tab[indexes[i]].key); + if (tab[indexes[i]].flag == 1) { + printf("%.2lf\n", tab[indexes[i]].v.num); + } else if (tab[indexes[i]].flag == 2) { + printf("%d\n", tab[indexes[i]].v.b); + } else if (tab[indexes[i]].flag == 3) { + printf("%s\n", tab[indexes[i]].v.str); + } + free(tab[indexes[i]].key); + } + free(indexes); free(bytes); exit(0); } |