Cからjqを使う

jqのheadでlibjqが切り出されていたので、main.cを参考にしてCから呼び出してみた。

#include <stdio.h>
#include <string.h>
#include <jq.h>

static void process(jq_state *jq, jv value, int flags) {
  jq_start(jq, value, flags);
  jv result;

  while (jv_is_valid(result = jq_next(jq))) {
    jv dumped = jv_dump_string(result, 0);
    const char *str = jv_string_value(dumped);
    printf("%s\n", str);
  }

  jv_free(result);
}

int main() {
  jq_state *jq;
  int jq_flags = 0;

  jq = jq_init();

  if (jq == NULL) {
    perror("malloc");
    return 1;
  }

  char *program = ".[]";
  int compiled = jq_compile(jq, program);

  if (!compiled) {
    return 1;
  }

  struct jv_parser* parser = jv_parser_new();
  char buf[] = "[{\"FOO\":100},{\"BAR\":200}]";

  jv_parser_set_buf(parser, buf, strlen(buf), 0);

  jv value;

  while (jv_is_valid((value = jv_parser_next(parser)))) {
    process(jq, value, jq_flags);
  }

  if (jv_invalid_has_msg(jv_copy(value))) {
    jv msg = jv_invalid_get_msg(value);
    fprintf(stderr, "parse error: %s\n", jv_string_value(msg));
    jv_free(msg);
  } else {
    jv_free(value);
  }

  jv_parser_free(parser);
  jq_teardown(&jq);

  return 0;
}


~/work$ gcc -ljq test.c -o test
~/work$ ./test
{"FOO":100}
{"BAR":200}
~/work$

コンパイルエラー時にjq_teardownを呼び出さなくてよいのかが、若干気になる。