diff --git a/Makefile b/Makefile
index 57cf963..ef62a7b 100644
--- a/Makefile
+++ b/Makefile
@@ -3,14 +3,14 @@ all: build
build: libkv kv
-LIBKV_SRC = buffer.c kv_path.c
-LIBKV_O = buffer.o kv_path.o
+LIBKV_SRC = buffer.c kv.c kv_path.c
+LIBKV_O = buffer.o kv.o kv_path.o
KV_SRC = kv_cli.c
KV_O = kv_cli.o libkv.a
CFLAGS ?=
-CFLAGS += -W -Wall -Werror -std=ansi -pedantic -I.
+CFLAGS += -W -Wall -Werror -std=c89 -pedantic -I.
ifeq ($(DEBUG),)
CFLAGS += -O2
diff --git a/README.md b/README.md
index b83dc22..16ec4ee 100644
--- a/README.md
+++ b/README.md
@@ -22,9 +22,11 @@ K3 = V3 : """ .*? """
K4 = V4 : "<<" D \s .*? D
-K5 = V5 : M2
+ V5 : M2
- K = V : K1 | K2 | K3 | K4 | K5
+ K : K1 | K2 | K3 | K4
+
+ V : V1 | V2 | V3 | V4 | V5
```
diff --git a/buffer.c b/buffer.c
index e090ec1..5d93d3a 100644
--- a/buffer.c
+++ b/buffer.c
@@ -16,7 +16,9 @@ int buffer_init (s_buffer *b, FILE *fp, void *state)
b->chars = calloc(BUFFER_SIZE, 1);
if (!b->chars)
return -1;
+ b->col = 0;
b->fp = fp;
+ b->line = 0;
b->pos = 0;
b->size = BUFFER_SIZE;
b->state = state;
@@ -59,7 +61,9 @@ int buffer_fill (s_buffer *b)
return -1;
assert(b->wpos < b->size);
r = fread(b->chars + b->wpos, 1, b->size - b->wpos, b->fp);
- if (r <= 0)
+ if (r < 0)
+ return -2;
+ if (r == 0)
return -1;
b->wpos += r;
return 0;
@@ -68,9 +72,11 @@ int buffer_fill (s_buffer *b)
int buffer_peek (s_buffer *b)
{
assert(b);
- if (b->pos == b->wpos &&
- buffer_fill(b))
- return -1;
+ if (b->pos == b->wpos) {
+ int r = buffer_fill(b);
+ if (r < 0)
+ return r;
+ }
assert(b->pos < b->wpos);
return b->chars[b->pos];
}
diff --git a/buffer.h b/buffer.h
index d12bbef..7566d23 100644
--- a/buffer.h
+++ b/buffer.h
@@ -18,8 +18,10 @@
typedef struct buffer
{
char *chars;
+ size_t col;
FILE *fp;
s_kv_path *k;
+ size_t line;
size_t pos;
size_t size;
void *state;
diff --git a/kv.c b/kv.c
index 9d67a5e..2531d1c 100644
--- a/kv.c
+++ b/kv.c
@@ -4,33 +4,67 @@
* Copyright 2022 Thomas de Grivel
*/
-#include <stdio.h>
-#include <kv.h>
+#include <assert.h>
+#include "kv.h"
-int on_kv (s_buffer *b, const char *v, size_t vsz)
+int kv_is_space (int c)
{
- (void) b;
- (void) v;
- (void) vsz;
- printf("--- v: %s\n", v);
+ switch (c) {
+ case ' ':
+ case '\n':
+ case '\r':
+ case '\t':
+ case '\v':
+ return 1;
+ default:
+ return 0;
+ }
return 0;
}
-int read_file (const char *path)
+int kv_sp (s_buffer *b)
{
- FILE *fp = fopen(path, "rb");
- s_buffer b;
- if (buffer_init(&b, fp, NULL) ||
- kv_parse(&b, on_kv) ||
- buffer_close(&b))
- return -1;
+ int c = buffer_peek(b);
+ while (kv_is_space(c)) {
+ buffer_read(b);
+ c = buffer_peek(b);
+ }
return 0;
}
+
+int kv_m2 (s_buffer *b, f_kv *f)
+{
+ int c;
+ size_t pos;
+ assert(b);
+ pos = b->pos;
+ c = buffer_read(b);
+ while (kv_sp(c))
+ c = buffer_read(b);
+ if (c == '{') {
+ kv_m1(b, f);
+ c = buffer_read(b);
+ if (c == '}') {
+
+ return 0;
+}
-int main (int argc, char **argv)
+int kv_parse (s_buffer *b, f_kv *f)
{
- while (--argc > 0)
- read_file(*++argv);
- return 0;
+ int c;
+ assert(b);
+ kv_sp(b);
+ c = buffer_peek(b);
+ if (c < 0) {
+ if (c == -1)
+ return 0;
+ return -1;
+ } else if (kv_m2(b, f) || kv_m1(b, f)) {
+ c = buffer_read(b);
+ if (c == -1)
+ return 0;
+ return -1;
+ }
+ return -1;
}
diff --git a/kv_path.h b/kv_path.h
index 065231b..19b345d 100644
--- a/kv_path.h
+++ b/kv_path.h
@@ -7,6 +7,9 @@
#ifndef KV_PATH_H
#define KV_PATH_H
+#include <stdio.h>
+#include <sys/types.h>
+
typedef struct kv_path s_kv_path;
struct kv_path {