diff --git a/kv.c b/kv.c
new file mode 100644
index 0000000..55d2a25
--- /dev/null
+++ b/kv.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, path, 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.h b/kv.h
index c140df9..ce11756 100644
--- a/kv.h
+++ b/kv.h
@@ -26,6 +26,8 @@ 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_delim (char **str, size_t *str_size, const char *delim);
+int kv_quote_double_quotes (char **str, size_t *str_size);
int kv_quote_triple_double_quotes (char **str, size_t *str_size);
#endif
diff --git a/kv_cli.c b/kv_cli.c
deleted file mode 100644
index 55d2a25..0000000
--- a/kv_cli.c
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * 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, path, 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_quote.c b/kv_quote.c
index 350080b..b78c847 100644
--- a/kv_quote.c
+++ b/kv_quote.c
@@ -9,6 +9,25 @@
#include <string.h>
#include "kv.h"
+const char *g_delims[] = {
+ "END",
+ "---",
+ "___",
+ "===",
+ "***",
+ "+++",
+ "!!!",
+ "###",
+ "-END-",
+ "_END_",
+ "=END=",
+ "*END*",
+ "+END+",
+ "!END!",
+ "#END#",
+ NULL
+};
+
int kv_check_delimiter (const char *delim)
{
assert(delim);
@@ -63,61 +82,86 @@ 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;
- char *str_delim;
- size_t str_delim_size;
- char *str_triple;
- size_t str_triple_size;
+ const char **delim;
+ int delim_r;
+ char *delim_str;
+ size_t delim_str_size;
+ int double_r;
+ char *double_str;
+ size_t double_str_size;
+ int triple_r;
+ char *triple_str;
+ size_t triple_str_size;
assert(str);
assert(*str);
assert(str_size);
if (!kv_needs_quoting(*str, *str_size))
return 0;
- 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;
-
+ double_str = *str;
+ double_str_size = *str_size;
+ double_r = kv_quote_double_quotes(&double_str, &double_str_size);
+ if (double_r <= 0)
+ return double_r;
+ triple_str = *str;
+ triple_str_size = *str_size;
+ triple_r = kv_quote_triple_double_quotes(&triple_str, &triple_str_size);
+ if (triple_r <= 0)
+ return triple_r;
+ delim_str = *str;
+ delim_str_size = *str_size;
+ delim = &g_delims[0];
+ delim_r = kv_quote_delim(&delim_str, &delim_str_size, *delim);
+ delim++;
+ while (*delim && delim_r > 0) {
+ delim_r = kv_quote_delim(&delim_str, &delim_str_size, *delim);
+ delim++;
+ }
+ if (delim_r <= 0)
+ return delim_r;
+
return -1;
}
+size_t kv_count_reserved_chars (const char *str, size_t str_size)
+{
+ size_t c = 0;
+ while (str_size--)
+ if (kv_is_reserved_char(*str++))
+ c++;
+ return c;
+}
+
+int kv_quote_double_quotes (char **str, size_t *str_size)
+{
+ size_t i = 0;
+ size_t o = 0;
+ size_t res;
+ char *s;
+ assert(str);
+ assert(str_size);
+ res = kv_count_reserved_chars(*str, *str_size);
+ s = calloc(*str_size + res + 3, 1);
+ if (!s)
+ return -1;
+ s[0] = '"';
+ while (i < *str_size) {
+ int c = (*str)[i];
+ if (kv_is_reserved_char(c))
+ s[o++] = '\\';
+ if (c == 0)
+ s[o++] = '0';
+ else
+ s[o++] = c;
+ }
+ assert(o == *str_size + res + 2);
+ s[o] = 0;
+ *str = s;
+ *str_size = o;
+ return 0;
+}
+
int kv_quote_triple_double_quotes (char **str, size_t *str_size)
{
char *e;
diff --git a/rope.c b/rope.c
index de474f0..2f715a1 100644
--- a/rope.c
+++ b/rope.c
@@ -5,6 +5,7 @@
*/
#include <assert.h>
+#include <stdlib.h>
#include "rope.h"
void rope_init (s_rope *r, char *str, size_t size, s_rope *next)