Commit 543019593c2515a7a79819bd4bb470e705b41852

Thomas de Grivel 2022-01-03T11:06:25

wip quoting

diff --git a/buffer.c b/buffer.c
index 6aaaee3..84fed94 100644
--- a/buffer.c
+++ b/buffer.c
@@ -12,15 +12,15 @@
 #include <string.h>
 #include "buffer.h"
 
-int buffer_init (s_buffer *b, const char *file_path, FILE *fp, void *state)
+int buffer_init (s_buffer *b, void *state)
 {
   assert(b);
   b->chars = calloc(BUFFER_SIZE, 1);
   if (!b->chars)
     return -1;
   b->col = 0;
-  b->file_path = file_path;
-  b->fp = fp;
+  b->file_path = NULL;
+  b->fp = NULL;
   b->line = 0;
   b->pos = 0;
   b->size = BUFFER_SIZE;
@@ -30,16 +30,53 @@ int buffer_init (s_buffer *b, const char *file_path, FILE *fp, void *state)
   return 0;
 }
 
-s_buffer * buffer_new (const char *file_path, FILE *fp, void *state)
+s_buffer * buffer_new (void *state)
 {
   s_buffer *b = calloc(1, sizeof(s_buffer));
   if (!b)
     return NULL;
-  if (buffer_init(b, file_path, fp, state))
+  if (buffer_init(b, state))
     return NULL;
   return b;
 }
 
+int buffer_open (s_buffer *b, const char *file_path)
+{
+  FILE *fp;
+  assert(b);
+  assert(file_path);
+  fp = fopen(file_path, "rb");
+  if (!fp)
+    return -1;
+  if (b->fp)
+    fclose(b->fp);
+  b->fp = fp;
+  b->file_path = file_path;
+  return 0;
+}
+
+int buffer_close (s_buffer *b)
+{
+  assert(b);
+  if (b->fp) {
+    fclose(b->fp);
+    b->fp = NULL;
+    b->file_path = NULL;
+  }
+  return 0;
+}
+
+int buffer_fp (s_buffer *b, FILE *fp, const char *file_path)
+{
+  assert(b);
+  if (b->fp) {
+    fclose(b->fp);
+    b->fp = fp;
+    b->file_path = file_path;
+  }
+  return 0;
+}
+
 int buffer_resize (s_buffer *b, size_t new_size)
 {
   void *ptr;
@@ -130,11 +167,10 @@ int buffer_flush (s_buffer *b)
   return 0;
 }
 
-int buffer_close (s_buffer *b)
+int buffer_destroy (s_buffer *b)
 {
   if (!b)
     return 0;
-  fclose(b->fp);
   free(b->chars);
   b->chars = NULL;
   b->pos = 0;
@@ -146,7 +182,7 @@ int buffer_close (s_buffer *b)
 
 int buffer_delete (s_buffer *b)
 {
-  if (buffer_close(b))
+  if (buffer_destroy(b))
     return -1;
   free(b);
   return 0;
diff --git a/buffer.h b/buffer.h
index a87f36b..9c2db70 100644
--- a/buffer.h
+++ b/buffer.h
@@ -29,9 +29,11 @@ typedef struct buffer
   size_t      wpos;
 } s_buffer;
 
-int        buffer_init (s_buffer *b, const char *file_path, FILE *fp,
-                        void *state);
-s_buffer * buffer_new (const char *file_path, FILE *fp, void *state);
+int        buffer_init (s_buffer *b, void *state);
+s_buffer * buffer_new (void *state);
+int        buffer_open (s_buffer *b, const char *file_path);
+int        buffer_close (s_buffer *b);
+int        buffer_fp (s_buffer *b, FILE *fp, const char *file_path);
 int        buffer_resize (s_buffer *b, size_t new_size);
 int        buffer_fill (s_buffer *b);
 int        buffer_peek (s_buffer *b);
@@ -39,7 +41,7 @@ int        buffer_peek_n (s_buffer *b, size_t n);
 int        buffer_read (s_buffer *b);
 int        buffer_read_n (s_buffer *b, size_t n);
 int        buffer_flush (s_buffer *b);
-int        buffer_close (s_buffer *b);
+int        buffer_destroy (s_buffer *b);
 int        buffer_delete (s_buffer *b);
 void       buffer_err (s_buffer *b, const char *fmt, ...);
 int        buffer_eat (s_buffer *b, const char *str);
diff --git a/kv.c b/kv.c
index 55d2a25..7d8189d 100644
--- a/kv.c
+++ b/kv.c
@@ -4,8 +4,11 @@
  * Copyright 2022 Thomas de Grivel
 */
 
+#include <assert.h>
+#include <err.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
 #include <kv.h>
 
 typedef struct kv_paths s_kv_paths;
@@ -28,9 +31,9 @@ int on_kv (s_buffer *b, const char *v, size_t vsz)
 
 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) ||
+  if (buffer_init(&b, keys) ||
+      buffer_open(&b, path) ||
       kv_parse(&b, on_kv) ||
       buffer_close(&b))
     return -1;
@@ -53,10 +56,75 @@ s_kv_paths * read_keys (FILE *fp)
   return NULL;
 }
 
-int main (int argc, char **argv)
+int get (int argc, char **argv)
 {
   s_kv_paths *keys = read_keys(stdin);
-  while (--argc > 0)
-    read_file(*++argv, keys);
-  return 0;
+  int r = 0;
+  while (argc--)
+    if (read_file(*argv++, keys))
+      r++;
+  return r;
+}
+
+int quote (int argc, char **argv)
+{
+  s_buffer in;
+  char    *q;
+  size_t   q_size;
+  int      r;
+  if (buffer_init(&in, NULL))
+    return -1;
+  while (argc--) {
+    if (!strcmp(*argv, "-")) {
+      if (buffer_fp(&in, stdin, "stdin"))
+        err(1, "stdin");
+    }
+    else
+      if (buffer_open(&in, *argv))
+        err(1, "%s", *argv);
+    while (!(r = buffer_fill(&in)))
+      ;
+    if (r != -1)
+      err(1, "%s", in.file_path);
+    argv++;
+  }
+  q = in.chars;
+  q_size = in.wpos;
+  if (!(r = kv_quote(&q, &q_size)) &&
+      fwrite(q, q_size, 1, stdout) != 1)
+    err(1, "stdout");
+  return r;
+}
+
+int usage (const char *argv0)
+{
+  printf("Usage: %s OP [FILE ...]\n"
+         "OP can be one of :\n"
+         "  -q | --quote    Quote files.\n"
+         "  -g | --get      Get keys passed on stdin in files.\n",
+         argv0);
+  return 1;
+}
+
+int main (int argc, char **argv)
+{
+  const char *argv0;
+  assert(argc > 0);
+  assert(argv);
+  argv0 = *argv;
+  argc--;
+  argv++;
+  if (argc) {
+    if (!strcmp(*argv, "-q") || !strcmp(*argv, "--quote")) {
+      argc--;
+      argv++;
+      return quote(argc, argv);
+    }
+    if (!strcmp(*argv, "-g") || !strcmp(*argv, "--get")) {
+      argc--;
+      argv++;
+      return get(argc, argv);
+    }
+  }
+  return usage(argv0);
 }