Commit cbd7ffcbaac9875a39f6bccf4ce1ddee56e9dc90

Thomas de Grivel 2021-12-29T18:12:45

WIP

diff --git a/Makefile b/Makefile
index 5a43713..57cf963 100644
--- a/Makefile
+++ b/Makefile
@@ -6,11 +6,11 @@ build: libkv kv
 LIBKV_SRC = buffer.c kv_path.c
 LIBKV_O   = buffer.o kv_path.o
 
-KV_SRC = kv.c
-KV_O   = kv.o
+KV_SRC = kv_cli.c
+KV_O   = kv_cli.o libkv.a
 
 CFLAGS ?=
-CFLAGS += -W -Wall -Werror -ansi -pedantic -I.
+CFLAGS += -W -Wall -Werror -std=ansi -pedantic -I.
 
 ifeq ($(DEBUG),)
 CFLAGS += -O2
diff --git a/buffer.c b/buffer.c
index 945fd1a..e090ec1 100644
--- a/buffer.c
+++ b/buffer.c
@@ -21,6 +21,7 @@ int buffer_init (s_buffer *b, FILE *fp, void *state)
   b->size = BUFFER_SIZE;
   b->state = state;
   b->wpos = 0;
+  b->k = NULL;
   return 0;
 }
 
diff --git a/buffer.h b/buffer.h
index fd95a4d..d12bbef 100644
--- a/buffer.h
+++ b/buffer.h
@@ -7,6 +7,8 @@
 #ifndef BUFFER_H
 #define BUFFER_H
 
+#include "kv_path.h"
+
 #ifdef DEBUG
 # define BUFFER_SIZE 64
 #else
@@ -15,12 +17,13 @@
 
 typedef struct buffer
 {
-  char  *chars;
-  FILE  *fp;
-  size_t pos;
-  size_t size;
-  void  *state;
-  size_t wpos;
+  char      *chars;
+  FILE      *fp;
+  s_kv_path *k;
+  size_t     pos;
+  size_t     size;
+  void      *state;
+  size_t     wpos;
 } s_buffer;
 
 int        buffer_init (s_buffer *b, FILE *fp, void *state);
diff --git a/kv.h b/kv.h
index fd703db..db1b829 100644
--- a/kv.h
+++ b/kv.h
@@ -9,4 +9,10 @@
 
 #include "buffer.h"
 
+/* access key path through b->k */
+
+typedef int f_kv (s_buffer *b, const char *v, size_t vsz);
+
+int kv_parse (s_buffer *b, f_kv *f);
+
 #endif
diff --git a/kv_cli.c b/kv_cli.c
new file mode 100644
index 0000000..d50b290
--- /dev/null
+++ b/kv_cli.c
@@ -0,0 +1,62 @@
+/*
+ * kv - key value text file format
+ *
+ * Copyright 2022 Thomas de Grivel
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <kv.h>
+
+typedef struct kv_paths s_kv_paths;
+
+struct kv_paths {
+  s_kv_path  *k;
+  const char *v;
+  size_t      vsz;
+  s_kv_paths *next;
+};
+
+int on_kv (s_buffer *b, const char *v, size_t vsz)
+{
+  (void) b;
+  (void) v;
+  (void) vsz;
+  printf("--- v: %s\n", v);
+  return 0;
+}
+
+int read_file (const char *path, s_kv_paths *keys)
+{
+  FILE *fp = fopen(path, "rb");
+  s_buffer b;
+  if (buffer_init(&b, fp, keys) ||
+      kv_parse(&b, on_kv) ||
+      buffer_close(&b))
+    return -1;
+  return 0;
+}
+
+s_kv_paths *kv_paths_new (s_kv_path *k, s_kv_paths *next)
+{
+  s_kv_paths *keys = calloc(sizeof(s_kv_paths), 1);
+  if (keys) {
+    keys->k = k;
+    keys->next = next;
+  }
+  return keys;
+}
+
+s_kv_paths * read_keys (FILE *fp)
+{
+  (void) fp;
+  return NULL;
+}
+
+int main (int argc, char **argv)
+{
+  s_kv_paths *keys = read_keys(stdin);
+  while (--argc > 0)
+    read_file(*++argv, keys);
+  return 0;
+}
diff --git a/kv_path.c b/kv_path.c
index 63e5ad4..98b085b 100644
--- a/kv_path.c
+++ b/kv_path.c
@@ -7,6 +7,7 @@
 #include <assert.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
 #include "kv_path.h"
 
 void kv_path_init (s_kv_path *p, const char *k, size_t ks,
@@ -48,3 +49,50 @@ size_t kv_path_print (s_kv_path *p, FILE *fp)
   }
   return r;
 }
+
+s_kv_path * kv_path_reverse (s_kv_path *p)
+{
+  s_kv_path *acc = NULL;
+  while (p) {
+    acc = kv_path_new(p->k, p->ks, acc);
+    p = p->parent;
+  }
+  return acc;
+}
+
+void kv_path_delete_all (s_kv_path *p)
+{
+  while (p) {
+    s_kv_path *parent = p->parent;
+    kv_path_delete(p);
+    p = parent;
+  }
+}
+
+size_t min (size_t a, size_t b)
+{
+  if (a < b)
+    return a;
+  return b;
+}
+
+int kv_path_compare (s_kv_path *a, s_kv_path *b)
+{
+  int cmp;
+  a = kv_path_reverse(a);
+  b = kv_path_reverse(b);
+  while (a && b) {
+    if (a == b)
+      return 0;
+    cmp = memcmp(a->k, b->k, min(a->ks, b->ks));
+    if (cmp)
+      return cmp;
+    if (a->ks < b->ks)
+      return -1;
+    if (a->ks > b->ks)
+      return 1;
+    a = a->parent;
+    b = b->parent;
+  }
+  return 0;
+}
diff --git a/kv_path.h b/kv_path.h
index 1895648..065231b 100644
--- a/kv_path.h
+++ b/kv_path.h
@@ -20,5 +20,6 @@ void        kv_path_init (s_kv_path *p, const char *k, size_t ks,
 s_kv_path * kv_path_new (const char *k, size_t ks, s_kv_path *parent);
 void        kv_path_delete (s_kv_path *p);
 size_t      kv_path_print (s_kv_path *p, FILE *fp);
+int         kv_path_compare (s_kv_path *a, s_kv_path *b);
 
 #endif