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