Commit 22119e26b425731158afb7d3a1fd30d3feda6779

Thomas de Grivel 2022-01-02T11:43:22

wip

diff --git a/Makefile b/Makefile
index 412f538..3002572 100644
--- a/Makefile
+++ b/Makefile
@@ -3,11 +3,20 @@ all: build
 
 build: libkv kv
 
-LIBKV_SRC = buffer.c kv_chars.c kv_parse.c kv_path.c kv_quote.c
-LIBKV_O   = buffer.o kv_chars.o kv_parse.o kv_path.o kv_quote.o
+LIBKV_SRC = \
+	buffer.c \
+	kv_chars.c \
+	kv_parse.c \
+	kv_path.c \
+	kv_quote.c \
+	rope.c
 
-KV_SRC = kv_cli.c
-KV_O   = kv_cli.o libkv.a
+LIBKV_O = ${LIBKV_SRC:.c=.o}
+
+KV_SRC = \
+	kv.c
+
+KV_O = kv.o libkv.a
 
 CFLAGS ?=
 CFLAGS += -W -Wall -Werror -std=c89 -pedantic -I.
diff --git a/kv.h b/kv.h
index 8adac98..c140df9 100644
--- a/kv.h
+++ b/kv.h
@@ -22,10 +22,10 @@ int kv_is_reserved_char (int c);
 int kv_is_space (int c);
 
 /* quote */
-int kv_contains_triple_double_quotes (const char *str, size_t str_size);
-int kv_quote_triple_double_quotes (char **str, size_t *str_size);
 int kv_contains_reserved_char (const char *str, size_t str_size);
+int kv_contains_triple_double_quotes (const char *str, size_t str_size);
 int kv_needs_quoting (const char *str, size_t str_size);
 int kv_quote (char **str, size_t *str_size);
+int kv_quote_triple_double_quotes (char **str, size_t *str_size);
 
 #endif
diff --git a/kv_quote.c b/kv_quote.c
index 02fda65..350080b 100644
--- a/kv_quote.c
+++ b/kv_quote.c
@@ -9,10 +9,22 @@
 #include <string.h>
 #include "kv.h"
 
-int kv_contains_triple_double_quotes (const char *str, size_t str_size)
+int kv_check_delimiter (const char *delim)
+{
+  assert(delim);
+  return kv_contains_reserved_char(delim, strlen(delim));
+}
+
+int kv_contains_delimiter (const char *str, size_t str_size,
+                           const char *delim)
 {
+  size_t dsz;
+  assert(str);
+  assert(delim);
+  dsz = strlen(delim);
   while (str_size >= 4) {
-    if (str[0] == '\n' && str[1] == '"' && str[2] == '"' && str[3] == '"')
+    if (str[0] == '\n' && str[1] == '"' && str[2] == '"' &&
+        str[3] == '"')
       return 1;
     str++;
     str_size--;
@@ -20,28 +32,22 @@ int kv_contains_triple_double_quotes (const char *str, size_t str_size)
   return 0;
 }
 
-int kv_quote_triple_double_quotes (char **str, size_t *str_size)
+int kv_contains_reserved_char (const char *str, size_t str_size)
 {
-  char *e;
-  char *s;
-  if (kv_contains_triple_double_quotes(*str, *str_size))
-    return 1;
-  s = calloc(*str_size + 9, 1);
-  if (!s)
-    return -1;
-  s[0] = '"'; s[1] = '"'; s[2] = '"'; s[3] = '\n';
-  memcpy(s + 4, *str, *str_size);
-  e = s + 4 + *str_size;
-  e[0] = '\n'; e[1] = '"'; e[2] = '"'; e[3] = '"'; e[4] = 0;
-  *str = e;
-  *str_size = *str_size + 8;
+  while (str_size) {
+    if (kv_is_reserved_char(str[0]))
+      return 1;
+    str++;
+    str_size--;
+  }
   return 0;
 }
 
-int kv_contains_reserved_char (const char *str, size_t str_size)
+int kv_contains_triple_double_quotes (const char *str, size_t str_size)
 {
-  while (str_size) {
-    if (kv_is_reserved_char(str[0]))
+  while (str_size >= 4) {
+    if (str[0] == '\n' && str[1] == '"' && str[2] == '"' &&
+        str[3] == '"')
       return 1;
     str++;
     str_size--;
@@ -57,16 +63,75 @@ int kv_needs_quoting (const char *str, size_t str_size)
   return 1;
 }
 
+const char *delims[] = {
+  "END",
+  "---",
+  "___",
+  "===",
+  "***",
+  "+++",
+  "!!!",
+  "###",
+  "-END-",
+  "_END_",
+  "=END=",
+  "*END*",
+  "+END+",
+  "!END!",
+  "#END#",
+  NULL
+};
+  
 int kv_quote (char **str, size_t *str_size)
 {
-  int r;
+  int    r;
+  char  *str_delim;
+  size_t str_delim_size;
+  char  *str_triple;
+  size_t str_triple_size;
   assert(str);
   assert(*str);
   assert(str_size);
   if (!kv_needs_quoting(*str, *str_size))
     return 0;
-  r = kv_quote_triple_double_quotes(str, str_size);
+  str_triple = *str;
+  str_triple_size = *str_size;
+  r = kv_quote_triple_double_quotes(&str_triple, &str_triple_size);
+  if (r <= 0)
+    return r;
+  str_delim = *str;
+  str_delim_size = *str_size;
+  r = kv_quote_delim(&str_delim, &str_delim_size, "END");
   if (r <= 0)
     return r;
+  if (r) {
+                      return r;
+                    if (r) {
+                      r = kv_quote_delim(&str_delim, &str_delim_size, "#END#");
+                      if (r <= 0)
+                        return r;
+                      if (r) {
+                        r = kv_quote_delim(&str_delim, &str_delim_size, "+EOF+");
+                        if (r <= 0)
+                          return r;
+                        
   return -1;
 }
+
+int kv_quote_triple_double_quotes (char **str, size_t *str_size)
+{
+  char *e;
+  char *s;
+  if (kv_contains_triple_double_quotes(*str, *str_size))
+    return 1;
+  s = calloc(*str_size + 9, 1);
+  if (!s)
+    return -1;
+  s[0] = '"'; s[1] = '"'; s[2] = '"'; s[3] = '\n';
+  memcpy(s + 4, *str, *str_size);
+  e = s + 4 + *str_size;
+  e[0] = '\n'; e[1] = '"'; e[2] = '"'; e[3] = '"'; e[4] = 0;
+  *str = e;
+  *str_size = *str_size + 8;
+  return 0;
+}
diff --git a/rope.c b/rope.c
new file mode 100644
index 0000000..de474f0
--- /dev/null
+++ b/rope.c
@@ -0,0 +1,40 @@
+/*
+ * kv - key value text file format
+ *
+ * Copyright 2022 Thomas de Grivel
+*/
+
+#include <assert.h>
+#include "rope.h"
+
+void rope_init (s_rope *r, char *str, size_t size, s_rope *next)
+{
+  assert(r);
+  r->str = str;
+  r->size = size;
+  r->next = next;
+}
+
+s_rope * rope_new (char *str, size_t size, s_rope *next)
+{
+  s_rope *r = calloc(sizeof(s_rope), 1);
+  if (r)
+    rope_init(r, str, size, next);
+  return r;
+}
+
+void rope_delete (s_rope *r)
+{
+  r->str = NULL;
+  r->next = NULL;
+  free(r);
+}
+
+void rope_delete_all (s_rope *r)
+{
+  while (r) {
+    s_rope *t = r;
+    r = r->next;
+    rope_delete(t);
+  }
+}
diff --git a/rope.h b/rope.h
new file mode 100644
index 0000000..41faafc
--- /dev/null
+++ b/rope.h
@@ -0,0 +1,23 @@
+/*
+ * kv - key value text file format
+ *
+ * Copyright 2022 Thomas de Grivel
+*/
+
+#ifndef ROPE_H
+#define ROPE_H
+
+typedef struct rope s_rope;
+
+struct rope {
+  char   *str;
+  size_t  size;
+  s_rope *next;
+};
+
+void     rope_init (s_rope *r, char *str, size_t size, s_rope *next);
+s_rope * rope_new (char *str, size_t size, s_rope *next);
+void     rope_delete (s_rope *r);
+void     rope_delete_all (s_rope *r);
+
+#endif