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);
}