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