kmx.io/kv/kv_parse.c

Branch

Thomas de Grivel fd3f14c08 2022-01-02T10:32:18
kv wip
/*
 * kv - key value text file format
 *
 * Copyright 2022 Thomas de Grivel
*/

#include <assert.h>
#include <stdlib.h>
#include "kv.h"

void kv_parse_sp (s_buffer *b)
{
  int c = buffer_peek(b);
  while (kv_is_space(c)) {
    buffer_read(b);
    c = buffer_peek(b);
  }
}

int kv_parse_k (s_buffer *b, char **k, size_t *ksz)
{
  (void) b;
  (void) k;
  (void) ksz;
  return 0;
}

int kv_parse_v (s_buffer *b, char **v, size_t *vsz, f_kv *f)
{
  (void) b;
  (void) v;
  (void) vsz;
  (void) f;
  return 0;
}

int kv_parse_m1 (s_buffer *b, f_kv *f)
{
  char  *k = NULL;
  size_t ksz = 0;
  size_t pos;
  int    r;
  char  *v = NULL;
  size_t vsz = 0;
  assert(b);
  pos = b->pos;
  kv_parse_sp(b);
  r = kv_parse_k(b, &k, &ksz);
  if (r < 0)
    return r;
  if (r) {
    kv_parse_sp(b);
    r = buffer_eat(b, ":");
    if (r < 0)
      goto error;
    kv_parse_sp(b);
    r = kv_parse_v(b, &v, &vsz, f);
    if (r < 0)
      goto error;
    if (r) {
      if (f) {
        b->k = kv_path_new(k, ksz, b->k);
        if (!b->k)
          exit(1);
        r = f(b, v, vsz);
        if (r < 0) {
          buffer_err(b, "event callback returned %d", r);
          r = -5;
          goto error_kv;
        }
      }
      kv_parse_sp(b);
      if (buffer_peek(b) == ',') {
        buffer_read(b);
        kv_parse_sp(b);
      }
      free(k);
      k = NULL;
      free(v);
      v = NULL;
      return 1;
    }
    free(k);
    k = NULL;
  }
  b->pos = pos;
  return 0;
error_kv:
  free(v);
error:
  free(k);
  return r;
}

int kv_parse_m2 (s_buffer *b, f_kv *f)
{
  size_t pos;
  int r;
  assert(b);
  pos = b->pos;
  kv_parse_sp(b);
  if (buffer_peek(b) == '{') {
    buffer_read(b);
    kv_parse_m1(b, f);
    r = buffer_eat(b, "}");
    if (r < 0)
      return r;
    return 1;
  }
  b->pos = pos;
  return 0;
}

int kv_parse (s_buffer *b, f_kv *f)
{
  int c;
  int r;
  assert(b);
  kv_parse_sp(b);
  c = buffer_peek(b);
  if (c < 0) {
    if (c == -1)
      return 0;
    return c;
  }
  r = kv_parse_m2(b, f);
  if (r < 0)
    return r;
  if (r) {
    c = buffer_read(b);
    if (c == -1)
      return 0;
    buffer_err(b, "expected EOF");
    return -2;
  }
  r = kv_parse_m1(b, f);
  if (r < 0)
    return r;
  if (r) {
    c = buffer_read(b);
    if (c == -1)
      return 0;
    buffer_err(b, "expected EOF");
    return -2;
  }
  return -2;
}
Download