コード例 #1
0
ファイル: locfile.c プロジェクト: DanielXLee/jq
void locfile_locate(struct locfile* l, location loc, const char* fmt, ...) {
  va_list fmtargs;
  va_start(fmtargs, fmt);
  int startline;
  int offset;

  if (loc.start != -1) {
    startline = locfile_get_line(l, loc.start);
    offset = l->linemap[startline];
  }

  jv m1 = jv_string_vfmt(fmt, fmtargs);
  if (!jv_is_valid(m1)) {
    jq_report_error(l->jq, m1);
    return;
  }
  if (loc.start == -1) {
    jq_report_error(l->jq, jv_string_fmt("jq: error: %s\n<unknown location>", jv_string_value(m1)));
    jv_free(m1);
    return;
  }
  jv m2 = jv_string_fmt("%s\n%.*s%*s", jv_string_value(m1),
                        locfile_line_length(l, startline), l->data + offset,
                        loc.start - offset, "");
  jv_free(m1);
  jq_report_error(l->jq, m2);
  return;
}
コード例 #2
0
ファイル: builtin.c プロジェクト: amscanne/jq
static int string_cmp(const void* pa, const void* pb){
  const jv* a = pa;
  const jv* b = pb;
  int lena = jv_string_length(jv_copy(*a));
  int lenb = jv_string_length(jv_copy(*b));
  int minlen = lena < lenb ? lena : lenb;
  int r = memcmp(jv_string_value(*a), jv_string_value(*b), minlen);
  if (r == 0) r = lena - lenb;
  return r;
}
コード例 #3
0
ファイル: jq_test.c プロジェクト: AndrewO/jq
static void test_err_cb(void *data, jv e) {
  struct err_data *err_data = data;
  if (jv_get_kind(e) != JV_KIND_STRING)
    e = jv_dump_string(e, JV_PRINT_INVALID);
  if (!strncmp(jv_string_value(e), "jq: error", sizeof("jq: error") - 1))
    snprintf(err_data->buf, sizeof(err_data->buf), "%s", jv_string_value(e));
  if (strchr(err_data->buf, '\n'))
    *(strchr(err_data->buf, '\n')) = '\0';
  jv_free(e);
}
コード例 #4
0
ファイル: locfile.c プロジェクト: 4honor/jq
void locfile_locate(struct locfile* l, location loc, const char* fmt, ...) {
  jq_err_cb cb;
  void *cb_data;
  va_list fmtargs;
  va_start(fmtargs, fmt);
  int startline;
  int offset;

  if (loc.start != -1) {
    startline = locfile_get_line(l, loc.start);
    offset = l->linemap[startline];
  }

  jq_get_error_cb(l->jq, &cb, &cb_data);

  jv m1 = jv_string_vfmt(fmt, fmtargs);
  if (!jv_is_valid(m1)) {
    jv_free(m1);
    goto enomem;
  }
  jv m2;
  if (loc.start == -1) {
    m2 = jv_string_fmt("%s\n<unknown location>", jv_string_value(m1));
    if (cb)
      cb(cb_data, m2);
    else
      fprintf(stderr, "%s", jv_string_value(m2));
    jv_free(m1);
    jv_free(m2);
    return;
  }
  m2 = jv_string_fmt("%s\n%.*s%*s", jv_string_value(m1),
                     locfile_line_length(l, startline), l->data + offset,
                     loc.start - offset, "");
  jv_free(m1);
  if (!jv_is_valid(m2)) {
    jv_free(m2);
    goto enomem;
  }
  if (cb)
    cb(cb_data, m2);
  else
    fprintf(stderr, "%s", jv_string_value(m2));
  jv_free(m2);
  return;

enomem:
  if (cb != NULL)
    cb(cb_data, jv_invalid());
  else if (errno == ENOMEM || errno == 0)
    fprintf(stderr, "Error formatting jq compilation error: %s", strerror(errno ? errno : ENOMEM));
  else
    fprintf(stderr, "Error formatting jq compilation error: %s", strerror(errno));
  return;
}
コード例 #5
0
ファイル: jq.c プロジェクト: Gasol/php-ext-jq
static void
php_jq_filter(zval **return_value, jq_state *jq, jv json, int flags TSRMLS_DC)
{
    jv result;

    jq_start(jq, jv_copy(json), 0);

    if (jv_is_valid(result = jq_next(jq))) {
        int multiple = 0;
        while (1) {
            zval *zv;

            ALLOC_INIT_ZVAL(zv);

            if (flags == JQ_OPT_RAW) {
                if (jv_get_kind(result) == JV_KIND_STRING) {
                    ZVAL_STRING(zv, jv_string_value(result), 1);
                } else {
                    jv dump = jv_dump_string(result, 0);
                    if (jv_is_valid(dump)) {
                        ZVAL_STRING(zv, jv_string_value(dump), 1);
                    }
                    jv_free(dump);
                }
            } else {
                php_jv_dump(&zv, result TSRMLS_CC);
            }

            if (!jv_is_valid(result = jq_next(jq))) {
                if (multiple) {
                    zend_hash_next_index_insert(Z_ARRVAL_PP(return_value),
                                                &zv, sizeof(zv), NULL);
                } else {
                    ZVAL_ZVAL(*return_value, zv, 1, 1);
                }
                break;
            }

            if (!multiple) {
                multiple = 1;
                array_init(*return_value);
            }

            zend_hash_next_index_insert(Z_ARRVAL_PP(return_value),
                                        &zv, sizeof(zv), NULL);
        }
    } else {
        jv_free(result);
        if (PHP_JQ_G(display_errors)) {
            PHP_JQ_ERR(E_WARNING, "filter parse error");
        }
        ZVAL_BOOL(*return_value, 0);
    }
}
コード例 #6
0
ファイル: bytecode.c プロジェクト: 40a/jq
void dump_operation(struct bytecode* bc, uint16_t* codeptr) {
  int pc = codeptr - bc->code;
  printf("%04d ", pc);
  const struct opcode_description* op = opcode_describe(bc->code[pc++]);
  printf("%s", op->name);
  if (op->length > 1) {
    uint16_t imm = bc->code[pc++];
    if (op->op == CALL_JQ || op->op == TAIL_CALL_JQ) {
      for (int i=0; i<imm+1; i++) {
        uint16_t level = bc->code[pc++];
        uint16_t idx = bc->code[pc++];
        jv name;
        if (idx & ARG_NEWCLOSURE) {
          idx &= ~ARG_NEWCLOSURE;
          name = jv_object_get(jv_copy(getlevel(bc,level)->subfunctions[idx]->debuginfo),
                               jv_string("name"));
        } else {
          name = jv_array_get(jv_object_get(jv_copy(getlevel(bc,level)->debuginfo),
                                            jv_string("params")), idx);
        }
        printf(" %s:%d",
               jv_string_value(name),
               idx);
        jv_free(name);
        if (level) {
          printf("^%d", level);
        }
      }
    } else if (op->op == CALL_BUILTIN) {
      int func = bc->code[pc++];
      jv name = jv_array_get(jv_copy(bc->globals->cfunc_names), func);
      printf(" %s", jv_string_value(name));
      jv_free(name);
    } else if (op->flags & OP_HAS_BRANCH) {
      printf(" %04d", pc + imm);
    } else if (op->flags & OP_HAS_CONSTANT) {
      printf(" ");
      jv_dump(jv_array_get(jv_copy(bc->constants), imm), 0);
    } else if (op->flags & OP_HAS_VARIABLE) {
      uint16_t v = bc->code[pc++];
      jv name = jv_array_get(jv_object_get(jv_copy(getlevel(bc,imm)->debuginfo), jv_string("locals")), v);
      printf(" $%s:%d",
             jv_string_value(name),
             v);
      jv_free(name);
      if (imm) {
        printf("^%d", imm);
      }
    } else {
      printf(" %d", imm);
    }
  }
}
コード例 #7
0
ファイル: builtin.c プロジェクト: no2key/jq
static jv f_startswith(jv a, jv b) {
  int alen = jv_string_length_bytes(jv_copy(a));
  int blen = jv_string_length_bytes(jv_copy(b));
  jv ret;

  if (blen <= alen && memcmp(jv_string_value(a), jv_string_value(b), blen) == 0)
    ret = jv_true();
  else
    ret = jv_false();
  jv_free(a);
  jv_free(b);
  return ret;
}
コード例 #8
0
ファイル: builtin.c プロジェクト: jezdikm/jq
static jv f_startswith(jq_state *jq, jv a, jv b) {
  if (jv_get_kind(a) != JV_KIND_STRING || jv_get_kind(b) != JV_KIND_STRING)
    return jv_invalid_with_msg(jv_string("startswith() requires string inputs"));
  int alen = jv_string_length_bytes(jv_copy(a));
  int blen = jv_string_length_bytes(jv_copy(b));
  jv ret;

  if (blen <= alen && memcmp(jv_string_value(a), jv_string_value(b), blen) == 0)
    ret = jv_true();
  else
    ret = jv_false();
  jv_free(a);
  jv_free(b);
  return ret;
}
コード例 #9
0
ファイル: main.c プロジェクト: 4honor/jq
static int process(jq_state *jq, jv value, int flags) {
  int ret = 14; // No valid results && -e -> exit(4)
  jq_start(jq, value, flags);
  jv result;
  while (jv_is_valid(result = jq_next(jq))) {
    if ((options & RAW_OUTPUT) && jv_get_kind(result) == JV_KIND_STRING) {
      fwrite(jv_string_value(result), 1, jv_string_length_bytes(jv_copy(result)), stdout);
      ret = 0;
      jv_free(result);
    } else {
      int dumpopts;
      /* Disable colour by default on Windows builds as Windows
         terminals tend not to display it correctly */
#ifdef WIN32
      dumpopts = 0;
#else
      dumpopts = isatty(fileno(stdout)) ? JV_PRINT_COLOUR : 0;
#endif
      if (options & SORTED_OUTPUT) dumpopts |= JV_PRINT_SORTED;
      if (!(options & COMPACT_OUTPUT)) dumpopts |= JV_PRINT_PRETTY;
      if (options & ASCII_OUTPUT) dumpopts |= JV_PRINT_ASCII;
      if (options & COLOUR_OUTPUT) dumpopts |= JV_PRINT_COLOUR;
      if (options & NO_COLOUR_OUTPUT) dumpopts &= ~JV_PRINT_COLOUR;
      if (jv_get_kind(result) == JV_KIND_FALSE || jv_get_kind(result) == JV_KIND_NULL)
        ret = 11;
      else
        ret = 0;
      jv_dump(result, dumpopts);
    }
    if (!(options & RAW_NO_LF))
        printf("\n");
    if (options & UNBUFFERED_OUTPUT)
      fflush(stdout);
  }
  if (jv_invalid_has_msg(jv_copy(result))) {
    // Uncaught jq exception
    jv msg = jv_invalid_get_msg(jv_copy(result));
    if (jv_get_kind(msg) == JV_KIND_STRING) {
      fprintf(stderr, "jq: error: %s\n", jv_string_value(msg));
    } else {
      msg = jv_dump_string(msg, 0);
      fprintf(stderr, "jq: error (not a string): %s\n", jv_string_value(msg));
    }
    jv_free(msg);
  }
  jv_free(result);
  return ret;
}
コード例 #10
0
ファイル: execute.c プロジェクト: anandankm/jq
struct bytecode* jq_compile_args(const char* str, jv args) {
  assert(jv_get_kind(args) == JV_KIND_ARRAY);
  struct locfile locations;
  locfile_init(&locations, str, strlen(str));
  block program;
  struct bytecode* bc = 0;
  int nerrors = jq_parse(&locations, &program);
  if (nerrors == 0) {
    for (int i=0; i<jv_array_length(jv_copy(args)); i++) {
      jv arg = jv_array_get(jv_copy(args), i);
      jv name = jv_object_get(jv_copy(arg), jv_string("name"));
      jv value = jv_object_get(arg, jv_string("value"));
      program = gen_var_binding(gen_const(value), jv_string_value(name), program);
      jv_free(name);
    }
    jv_free(args);
    program = builtins_bind(program);
    nerrors = block_compile(program, &locations, &bc);
  }
  if (nerrors) {
    fprintf(stderr, "%d compile %s\n", nerrors, nerrors > 1 ? "errors" : "error");
  }
  locfile_free(&locations);
  return bc;
}
コード例 #11
0
ファイル: main.c プロジェクト: RavikumarTulugu/antkorp
static void process(jv value, int flags) {
  jq_state *jq = NULL;
  jq_init(bc, value, &jq, flags);
  jv result;
  while (jv_is_valid(result = jq_next(jq))) {
    if ((options & RAW_OUTPUT) && jv_get_kind(result) == JV_KIND_STRING) {
      fwrite(jv_string_value(result), 1, jv_string_length_bytes(jv_copy(result)), stdout);
      jv_free(result);
    } else {
      int dumpopts;
      /* Disable colour by default on Windows builds as Windows
         terminals tend not to display it correctly */
#ifdef WIN32
      dumpopts = 0;
#else
      dumpopts = isatty(fileno(stdout)) ? JV_PRINT_COLOUR : 0;
#endif
      if (!(options & COMPACT_OUTPUT)) dumpopts |= JV_PRINT_PRETTY;
      if (options & ASCII_OUTPUT) dumpopts |= JV_PRINT_ASCII;
      if (options & COLOUR_OUTPUT) dumpopts |= JV_PRINT_COLOUR;
      if (options & NO_COLOUR_OUTPUT) dumpopts &= ~JV_PRINT_COLOUR;
      jv_dump(result, dumpopts);
    }
    printf("\n");
  }
  jv_free(result);
  jq_teardown(&jq);
}
コード例 #12
0
ファイル: builtin.c プロジェクト: no2key/jq
static jv f_endswith(jv a, jv b) {
  const char *astr = jv_string_value(a);
  const char *bstr = jv_string_value(b);
  size_t alen = jv_string_length_bytes(jv_copy(a));
  size_t blen = jv_string_length_bytes(jv_copy(b));
  jv ret;;

  if (alen < blen ||
     memcmp(astr + (alen - blen), bstr, blen) != 0)
    ret = jv_false();
  else
    ret = jv_true();
  jv_free(a);
  jv_free(b);
  return ret;
}
コード例 #13
0
ファイル: execute.c プロジェクト: anandankm/jq
void print_error(jv value) {
  assert(!jv_is_valid(value));
  jv msg = jv_invalid_get_msg(value);
  if (jv_get_kind(msg) == JV_KIND_STRING) {
    fprintf(stderr, "jq: error: %s\n", jv_string_value(msg));
  }
  jv_free(msg);
}
コード例 #14
0
ファイル: builtin.c プロジェクト: jezdikm/jq
static jv f_endswith(jq_state *jq, jv a, jv b) {
  if (jv_get_kind(a) != JV_KIND_STRING || jv_get_kind(b) != JV_KIND_STRING)
    return jv_invalid_with_msg(jv_string("endswith() requires string inputs"));
  const char *astr = jv_string_value(a);
  const char *bstr = jv_string_value(b);
  size_t alen = jv_string_length_bytes(jv_copy(a));
  size_t blen = jv_string_length_bytes(jv_copy(b));
  jv ret;;

  if (alen < blen ||
     memcmp(astr + (alen - blen), bstr, blen) != 0)
    ret = jv_false();
  else
    ret = jv_true();
  jv_free(a);
  jv_free(b);
  return ret;
}
コード例 #15
0
ファイル: execute.c プロジェクト: Gasol/php-ext-jq
static void print_error(jq_state *jq, jv value) {
  assert(!jv_is_valid(value));
  jv msg = jv_invalid_get_msg(value);
  jv msg2;
  if (jv_get_kind(msg) == JV_KIND_STRING)
    msg2 = jv_string_fmt("jq: error: %s", jv_string_value(msg));
  else
    msg2 = jv_string_fmt("jq: error: <unknown>");
  jv_free(msg);

  if (jq->err_cb)
    jq->err_cb(jq->err_cb_data, msg2);
  else if (jv_get_kind(msg2) == JV_KIND_STRING)
    fprintf(stderr, "%s\n", jv_string_value(msg2));
  else
    fprintf(stderr, "jq: error: %s\n", strerror(ENOMEM));
  jv_free(msg2);
}
コード例 #16
0
ファイル: builtin.c プロジェクト: no2key/jq
static jv f_rtrimstr(jv input, jv right) {
  if (jv_get_kind(f_endswith(jv_copy(input), jv_copy(right))) == JV_KIND_TRUE) {
    jv res = jv_string_sized(jv_string_value(input),
                             jv_string_length_bytes(jv_copy(input)) - jv_string_length_bytes(right));
    jv_free(input);
    return res;
  }
  jv_free(right);
  return input;
}
コード例 #17
0
ファイル: main.c プロジェクト: abetusk/jq
static int process_extra_opt(jq_state *jq, jv value, int flags, int dumpopts, jv_extra_opt *extra_opt) {
  int ret = 14; // No valid results && -e -> exit(4)
  jq_start(jq, value, flags);
  jv result;
  while (jv_is_valid(result = jq_next(jq))) {
    if ((options & RAW_OUTPUT) && jv_get_kind(result) == JV_KIND_STRING) {
      fwrite(jv_string_value(result), 1, jv_string_length_bytes(jv_copy(result)), stdout);
      ret = 0;
      jv_free(result);
    } else {
      if (jv_get_kind(result) == JV_KIND_FALSE || jv_get_kind(result) == JV_KIND_NULL)
        ret = 11;
      else
        ret = 0;
      if (options & SEQ)
        priv_fwrite("\036", 1, stdout, dumpopts & JV_PRINT_ISATTY);
      jv_dump_extra_opt(result, dumpopts, extra_opt);
    }
    if (!(options & RAW_NO_LF))
      priv_fwrite("\n", 1, stdout, dumpopts & JV_PRINT_ISATTY);
    if (options & UNBUFFERED_OUTPUT)
      fflush(stdout);
  }
  if (jv_invalid_has_msg(jv_copy(result))) {
    // Uncaught jq exception
    jv msg = jv_invalid_get_msg(jv_copy(result));
    jv input_pos = jq_util_input_get_position(jq);
    if (jv_get_kind(msg) == JV_KIND_STRING) {
      fprintf(stderr, "jq: error (at %s): %s\n",
              jv_string_value(input_pos), jv_string_value(msg));
    } else {
      msg = jv_dump_string(msg, 0);
      fprintf(stderr, "jq: error (at %s) (not a string): %s\n",
              jv_string_value(input_pos), jv_string_value(msg));
    }
    ret = 5;
    jv_free(input_pos);
    jv_free(msg);
  }
  jv_free(result);
  return ret;
}
コード例 #18
0
ファイル: execute.c プロジェクト: Gasol/php-ext-jq
int jq_compile_args(jq_state *jq, const char* str, jv args) {
  jv_nomem_handler(jq->nomem_handler, jq->nomem_handler_data);
  assert(jv_get_kind(args) == JV_KIND_ARRAY);
  struct locfile locations;
  locfile_init(&locations, jq, str, strlen(str));
  block program;
  jq_reset(jq);
  if (jq->bc) {
    bytecode_free(jq->bc);
    jq->bc = 0;
  }
  int nerrors = jq_parse(&locations, &program);
  if (nerrors == 0) {
    int i;
    for (i=0; i<jv_array_length(jv_copy(args)); i++) {
      jv arg = jv_array_get(jv_copy(args), i);
      jv name = jv_object_get(jv_copy(arg), jv_string("name"));
      jv value = jv_object_get(arg, jv_string("value"));
      program = gen_var_binding(gen_const(value), jv_string_value(name), program);
      jv_free(name);
    }
    nerrors = builtins_bind(jq, &program);
    if (nerrors == 0) {
      nerrors = block_compile(program, &locations, &jq->bc);
    }
  }
  jv_free(args);
  if (nerrors) {
    jv s = jv_string_fmt("%d compile %s", nerrors,
                         nerrors > 1 ? "errors" : "error");
    if (jq->err_cb != NULL)
      jq->err_cb(jq->err_cb_data, s);
    else if (!jv_is_valid(s))
      fprintf(stderr, "Error formatting jq compilation errors: %s\n", strerror(errno));
    else
      fprintf(stderr, "%s\n", jv_string_value(s));
    jv_free(s);
  }
  locfile_free(&locations);
  return jq->bc != NULL;
}
コード例 #19
0
ファイル: jq.c プロジェクト: Gasol/php-ext-jq
static void
php_jq_err_cb(void *data, jv err)
{
    TSRMLS_FETCH();
    if (jv_is_valid(err) && PHP_JQ_G(display_errors)) {
        jv dump = jv_dump_string(jv_copy(err), 0);
        if (jv_is_valid(dump)) {
            PHP_JQ_ERR(E_WARNING, jv_string_value(dump));
        }
        jv_free(dump);
    }
}
コード例 #20
0
ファイル: bytecode.c プロジェクト: 40a/jq
void dump_disassembly(int indent, struct bytecode* bc) {
  if (bc->nclosures > 0) {
    printf("%*s[params: ", indent, "");
    jv params = jv_object_get(jv_copy(bc->debuginfo), jv_string("params"));
    for (int i=0; i<bc->nclosures; i++) {
      if (i) printf(", ");
      jv name = jv_array_get(jv_copy(params), i);
      printf("%s", jv_string_value(name));
      jv_free(name);
    }
    jv_free(params);
    printf("]\n");
  }
  dump_code(indent, bc);
  for (int i=0; i<bc->nsubfunctions; i++) {
    struct bytecode* subfn = bc->subfunctions[i];
    jv name = jv_object_get(jv_copy(subfn->debuginfo), jv_string("name"));
    printf("%*s%s:%d:\n", indent, "", jv_string_value(name), i);
    jv_free(name);
    dump_disassembly(indent+2, subfn);
  }
}
コード例 #21
0
ファイル: builtin.c プロジェクト: amscanne/jq
static void f_tonumber(jv input[], jv output[]) {
  if (jv_get_kind(input[0]) == JV_KIND_NUMBER) {
    output[0] = input[0];
  } else if (jv_get_kind(input[0]) == JV_KIND_STRING) {
    jv parsed = jv_parse(jv_string_value(input[0]));
    if (!jv_is_valid(parsed)) {
      jv_free(input[0]);
      output[0] = parsed;
    } else if (jv_get_kind(parsed) != JV_KIND_NUMBER) {
      output[0] = jv_invalid_with_msg(jv_string_fmt("'%s' is not a number",
                                                    jv_string_value(input[0])));
      jv_free(input[0]);
    } else {
      jv_free(input[0]);
      output[0] = parsed;
    }
  } else {
    output[0] = jv_invalid_with_msg(jv_string_fmt("Cannot parse %s as a number",
                                                  jv_kind_name(jv_get_kind(input[0]))));
    jv_free(input[0]);
    return;
  }
}
コード例 #22
0
ファイル: builtin.c プロジェクト: no2key/jq
static jv f_ltrimstr(jv input, jv left) {
  if (jv_get_kind(f_startswith(jv_copy(input), jv_copy(left))) != JV_KIND_TRUE) {
    jv_free(left);
    return input;
  }
  /*
   * FIXME It'd be better to share the suffix with the original input --
   * that we could do, we just can't share prefixes.
   */
  int prefixlen = jv_string_length_bytes(left);
  jv res = jv_string_sized(jv_string_value(input) + prefixlen,
                           jv_string_length_bytes(jv_copy(input)) - prefixlen);
  jv_free(input);
  return res;
}
コード例 #23
0
ファイル: main.c プロジェクト: ShayanZafar/jq
static void process(jv value) {
  jq_init(bc, value);
  jv result;
  while (jv_is_valid(result = jq_next())) {
    if ((options & RAW_OUTPUT) && jv_get_kind(result) == JV_KIND_STRING) {
      fwrite(jv_string_value(result), 1, jv_string_length(jv_copy(result)), stdout);
    } else {
      int dumpopts = 0;
      if (!(options & COMPACT_OUTPUT)) dumpopts |= JV_PRINT_PRETTY;
      if (options & ASCII_OUTPUT) dumpopts |= JV_PRINT_ASCII;
      jv_dump(result, dumpopts);
    }
    printf("\n");
  }
  jv_free(result);
  jq_teardown();
}
コード例 #24
0
ファイル: main.c プロジェクト: phihag/jq
static int process(jq_state *jq, jv value, int flags) {
  int ret = 0;
  jq_start(jq, value, flags);
  jv result;
  while (jv_is_valid(result = jq_next(jq))) {
    if ((options & RAW_OUTPUT) && jv_get_kind(result) == JV_KIND_STRING) {
      fwrite(jv_string_value(result), 1, jv_string_length_bytes(jv_copy(result)), stdout);
      if (jv_get_kind(result) == JV_KIND_FALSE)
        ret = 10;
      else if (jv_get_kind(result) == JV_KIND_NULL)
        ret = 11;
      else
        ret = 0;
      jv_free(result);
    } else {
      int dumpopts;
      /* Disable colour by default on Windows builds as Windows
         terminals tend not to display it correctly */
#ifdef WIN32
      dumpopts = 0;
#else
      dumpopts = isatty(fileno(stdout)) ? JV_PRINT_COLOUR : 0;
#endif
      if (options & SORTED_OUTPUT) dumpopts |= JV_PRINT_SORTED;
      if (!(options & COMPACT_OUTPUT)) dumpopts |= JV_PRINT_PRETTY;
      if (options & ASCII_OUTPUT) dumpopts |= JV_PRINT_ASCII;
      if (options & COLOUR_OUTPUT) dumpopts |= JV_PRINT_COLOUR;
      if (options & NO_COLOUR_OUTPUT) dumpopts &= ~JV_PRINT_COLOUR;
      if (options & UNBUFFERED_OUTPUT) dumpopts |= JV_PRINT_UNBUFFERED;
      if (jv_get_kind(result) == JV_KIND_FALSE)
        ret = 10;
      else if (jv_get_kind(result) == JV_KIND_NULL)
        ret = 11;
      else
        ret = 0;
      jv_dump(result, dumpopts);
    }
    printf("\n");
  }
  jv_free(result);
  return ret;
}
コード例 #25
0
ファイル: jqr.cpp プロジェクト: davharris/jqr
// when is this called >1 time?
std::vector<std::string> jqr_process(jq_state_ptr state, jv value) {
  std::vector<std::string> ret;
  jq_start(state.get(), value, 0);

  jv result = jq_next(state.get());

  while (jv_is_valid(result)) {
    jv dumped = jv_dump_string(result, 0);
    // A lot of unnecessary copying here (char* to string to R - read
    // how one is *meant* to do this).
    const char *str = jv_string_value(dumped);
    std::string str_cpp(str);
    ret.push_back(str_cpp);

    result = jq_next(state.get());
  }

  jv_free(result);
  return ret;
}
コード例 #26
0
ファイル: jqr.cpp プロジェクト: davharris/jqr
std::vector<std::string> jqr_parse(jq_state_ptr state, jv_parser_ptr parser) {
  jv value = jv_parser_next(parser.get());
  std::vector<std::string> ret;

  // This loop is not dealt with properly yet; will just take last.
  while (jv_is_valid(value)) {
    ret = jqr_process(state, value);
    value = jv_parser_next(parser.get());
  }

  if (jv_invalid_has_msg(jv_copy(value))) {
    jv msg = jv_invalid_get_msg(value);
    const char * msg_str = jv_string_value(msg);
    jv_free(msg);
    jv_free(value);
    Rcpp::stop(msg_str);
  } else {
    jv_free(value);
  }
  return ret;
}
コード例 #27
0
ファイル: jv_parse.c プロジェクト: dfkoh/jq
jv jv_parse_sized(const char* string, int length) {
  struct jv_parser parser;
  parser_init(&parser);
  jv_parser_set_buf(&parser, string, length, 0);
  jv value = jv_parser_next(&parser);
  if (jv_is_valid(value)) {
    jv next = jv_parser_next(&parser);
    if (jv_is_valid(next)) {
      // multiple JSON values, we only wanted one
      jv_free(value);
      jv_free(next);
      value = jv_invalid_with_msg(jv_string("Unexpected extra JSON values"));
    } else if (jv_invalid_has_msg(jv_copy(next))) {
      // parser error after the first JSON value
      jv_free(value);
      value = next;
    } else {
      // a single valid JSON value
      jv_free(next);
    }
  } else if (jv_invalid_has_msg(jv_copy(value))) {
    // parse error, we'll return it
  } else {
    // no value at all
    jv_free(value);
    value = jv_invalid_with_msg(jv_string("Expected JSON value"));
  }
  parser_free(&parser);

  if (!jv_is_valid(value) && jv_invalid_has_msg(jv_copy(value))) {
    jv msg = jv_invalid_get_msg(value);
    value = jv_invalid_with_msg(jv_string_fmt("%s (while parsing '%s')",
                                              jv_string_value(msg),
                                              string));
    jv_free(msg);
  }
  return value;
}
コード例 #28
0
ファイル: jv_aux.c プロジェクト: 4honor/jq
jv jv_get(jv t, jv k) {
  jv v;
  if (jv_get_kind(t) == JV_KIND_OBJECT && jv_get_kind(k) == JV_KIND_STRING) {
    v = jv_object_get(t, k);
    if (!jv_is_valid(v)) {
      jv_free(v);
      v = jv_null();
    }
  } else if (jv_get_kind(t) == JV_KIND_ARRAY && jv_get_kind(k) == JV_KIND_NUMBER) {
    if(jv_is_integer(k)){
      int idx = (int)jv_number_value(k);
      if (idx < 0)
        idx += jv_array_length(jv_copy(t));
      v = jv_array_get(t, idx);
      if (!jv_is_valid(v)) {
        jv_free(v);
        v = jv_null();
      }
    } else {
      jv_free(t);
      jv_free(k);
      v = jv_null();
    }
  } else if (jv_get_kind(t) == JV_KIND_ARRAY && jv_get_kind(k) == JV_KIND_OBJECT) {
    int start, end;
    if (parse_slice(t, k, &start, &end)) {
      v = jv_array_slice(t, start, end);
    } else {
      v = jv_invalid_with_msg(jv_string_fmt("Start and end indices of an array slice must be numbers"));
      jv_free(t);
    }
  } else if (jv_get_kind(t) == JV_KIND_STRING && jv_get_kind(k) == JV_KIND_OBJECT) {
    int start, end;
    if (parse_slice(t, k, &start, &end)) {
      v = jv_string_slice(t, start, end);
    } else {
      v = jv_invalid_with_msg(jv_string_fmt("Start and end indices of an string slice must be numbers"));
      jv_free(t);
    }
  } else if (jv_get_kind(t) == JV_KIND_STRING && jv_get_kind(k) == JV_KIND_STRING) {
    v = jv_string_indexes(t, k);
  } else if (jv_get_kind(t) == JV_KIND_ARRAY && jv_get_kind(k) == JV_KIND_ARRAY) {
    v = jv_array_indexes(t, k);
  } else if (jv_get_kind(t) == JV_KIND_NULL && 
             (jv_get_kind(k) == JV_KIND_STRING || 
              jv_get_kind(k) == JV_KIND_NUMBER || 
              jv_get_kind(k) == JV_KIND_OBJECT)) {
    jv_free(t);
    jv_free(k);
    v = jv_null();
  } else {
    /*
     * If k is a short string it's probably from a jq .foo expression or
     * similar, in which case putting it in the invalid msg may help the
     * user.  The length 30 is arbitrary.
     */
    if (jv_get_kind(k) == JV_KIND_STRING && jv_string_length_bytes(jv_copy(k)) < 30) {
      v = jv_invalid_with_msg(jv_string_fmt("Cannot index %s with string \"%s\"",
                                            jv_kind_name(jv_get_kind(t)),
                                            jv_string_value(k)));
    } else {
      v = jv_invalid_with_msg(jv_string_fmt("Cannot index %s with %s",
                                            jv_kind_name(jv_get_kind(t)),
                                            jv_kind_name(jv_get_kind(k))));
    }
    jv_free(t);
    jv_free(k);
  }
  return v;
}
コード例 #29
0
ファイル: jq_test.c プロジェクト: AndrewO/jq
static void run_jq_tests(jv lib_dirs, FILE *testdata) {
  char prog[4096];
  char buf[4096];
  struct err_data err_msg;
  int tests = 0, passed = 0, invalid = 0;
  unsigned int lineno = 0;
  int must_fail = 0;
  int check_msg = 0;
  jq_state *jq = NULL;

  jq = jq_init();
  assert(jq);
  if (jv_get_kind(lib_dirs) == JV_KIND_NULL)
    lib_dirs = jv_array();
  jq_set_attr(jq, jv_string("JQ_LIBRARY_PATH"), lib_dirs);

  while (1) {
    if (!fgets(prog, sizeof(prog), testdata)) break;
    lineno++;
    if (skipline(prog)) continue;
    if (checkfail(prog)) {
      must_fail = 1;
      check_msg = checkerrormsg(prog);
      jq_set_error_cb(jq, test_err_cb, &err_msg);
      continue;
    }
    if (prog[strlen(prog)-1] == '\n') prog[strlen(prog)-1] = 0;
    printf("Testing '%s' at line number %u\n", prog, lineno);
    int pass = 1;
    tests++;
    int compiled = jq_compile(jq, prog);

    if (must_fail) {
      jq_set_error_cb(jq, NULL, NULL);
      must_fail = 0;
      check_msg = 0;
      if (!fgets(buf, sizeof(buf), testdata)) { invalid++; break; }
      lineno++;
      if (buf[strlen(buf)-1] == '\n') buf[strlen(buf)-1] = 0;
      if (compiled) {
        printf("*** Test program compiled that should not have at line %u: %s\n", lineno, prog);
        invalid++; continue;
      }
      if (check_msg && strcmp(buf, err_msg.buf) != 0) {
        printf("*** Erroneous test program failed with wrong message (%s) at line %u: %s\n", err_msg.buf, lineno, prog);
        invalid++;
      } else {
        passed++;
      }
      continue;
    }

    if (!compiled) {
      printf("*** Test program failed to compile at line %u: %s\n", lineno, prog);
      invalid++;
      // skip past test data
      while (fgets(buf, sizeof(buf), testdata)) {
        lineno++;
        if (buf[0] == '\n' || (buf[0] == '\r' && buf[1] == '\n'))
          break;
      }
      continue;
    }
    printf("Disassembly:\n");
    jq_dump_disassembly(jq, 2);
    printf("\n");
    if (!fgets(buf, sizeof(buf), testdata)) { invalid++; break; }
    lineno++;
    jv input = jv_parse(buf);
    if (!jv_is_valid(input)){ invalid++; continue; }
    jq_start(jq, input, JQ_DEBUG_TRACE);

    while (fgets(buf, sizeof(buf), testdata)) {
      lineno++;
      if (skipline(buf)) break;
      jv expected = jv_parse(buf);
      if (!jv_is_valid(expected)){ invalid++; continue; }
      jv actual = jq_next(jq);
      if (!jv_is_valid(actual)) {
        jv_free(actual);
        printf("*** Insufficient results for test at line number %u: %s\n", lineno, prog);
        pass = 0;
        break;
      } else if (!jv_equal(jv_copy(expected), jv_copy(actual))) {
        printf("*** Expected ");
        jv_dump(jv_copy(expected), 0);
        printf(", but got ");
        jv_dump(jv_copy(actual), 0);
        printf(" for test at line number %u: %s\n", lineno, prog);
        pass = 0;
      }
      jv as_string = jv_dump_string(jv_copy(expected), rand() & ~(JV_PRINT_COLOUR|JV_PRINT_REFCOUNT));
      jv reparsed = jv_parse_sized(jv_string_value(as_string), jv_string_length_bytes(jv_copy(as_string)));
      assert(jv_equal(jv_copy(expected), jv_copy(reparsed)));
      jv_free(as_string);
      jv_free(reparsed);
      jv_free(expected);
      jv_free(actual);
    }
    if (pass) {
      jv extra = jq_next(jq);
      if (jv_is_valid(extra)) {
        printf("*** Superfluous result: ");
        jv_dump(extra, 0);
        printf(" for test at line number %u, %s\n", lineno, prog);
        pass = 0;
      } else {
        jv_free(extra);
      }
    }
    passed+=pass;
  }
  jq_teardown(&jq);
  printf("%d of %d tests passed (%d malformed)\n", passed,tests,invalid);
  if (passed != tests) exit(1);
}
コード例 #30
0
ファイル: jq_test.c プロジェクト: AndrewO/jq
static void jv_test() {
  /// JSON parser regression tests
  {
    jv v = jv_parse("{\"a':\"12\"}");
    assert(jv_get_kind(v) == JV_KIND_INVALID);
    v = jv_invalid_get_msg(v);
    assert(strcmp(jv_string_value(v), "Expected separator between values at line 1, column 9 (while parsing '{\"a':\"12\"}')") == 0);
    jv_free(v);
  }
  /// Arrays and numbers
  {
    jv a = jv_array();
    assert(jv_get_kind(a) == JV_KIND_ARRAY);
    assert(jv_array_length(jv_copy(a)) == 0);
    assert(jv_array_length(jv_copy(a)) == 0);
  
    a = jv_array_append(a, jv_number(42));
    assert(jv_array_length(jv_copy(a)) == 1);
    assert(jv_number_value(jv_array_get(jv_copy(a), 0)) == 42);

    jv a2 = jv_array_append(jv_array(), jv_number(42));
    assert(jv_equal(jv_copy(a), jv_copy(a)));
    assert(jv_equal(jv_copy(a2), jv_copy(a2)));
    assert(jv_equal(jv_copy(a), jv_copy(a2)));
    assert(jv_equal(jv_copy(a2), jv_copy(a)));
    jv_free(a2);

    a2 = jv_array_append(jv_array(), jv_number(19));
    assert(!jv_equal(jv_copy(a), jv_copy(a2)));
    assert(!jv_equal(jv_copy(a2), jv_copy(a)));
    jv_free(a2);


    assert(jv_get_refcnt(a) == 1);
    a = jv_array_append(a, jv_copy(a));
    assert(jv_get_refcnt(a) == 1);

    assert(jv_array_length(jv_copy(a)) == 2);
    assert(jv_number_value(jv_array_get(jv_copy(a), 0)) == 42);

    for (int i=0; i<10; i++) {
      jv subarray = jv_array_get(jv_copy(a), 1);
      assert(jv_get_kind(subarray) == JV_KIND_ARRAY);
      assert(jv_array_length(jv_copy(subarray)) == 1);
      assert(jv_number_value(jv_array_get(jv_copy(subarray), 0)) == 42);
      jv_free(subarray);
    }


    jv subarray = jv_array_get(jv_copy(a), 1);
    assert(jv_get_kind(subarray) == JV_KIND_ARRAY);
    assert(jv_array_length(jv_copy(subarray)) == 1);
    assert(jv_number_value(jv_array_get(jv_copy(subarray), 0)) == 42);

    jv sub2 = jv_copy(subarray);
    sub2 = jv_array_append(sub2, jv_number(19));

    assert(jv_get_kind(sub2) == JV_KIND_ARRAY);
    assert(jv_array_length(jv_copy(sub2)) == 2);
    assert(jv_number_value(jv_array_get(jv_copy(sub2), 0)) == 42);
    assert(jv_number_value(jv_array_get(jv_copy(sub2), 1)) == 19);

    assert(jv_get_kind(subarray) == JV_KIND_ARRAY);
    assert(jv_array_length(jv_copy(subarray)) == 1);
    assert(jv_number_value(jv_array_get(jv_copy(subarray), 0)) == 42);

    jv_free(subarray);

    void* before = sub2.u.ptr;
    sub2 = jv_array_append(sub2, jv_number(200));
    void* after = sub2.u.ptr;
    assert(before == after);
    jv_free(sub2);

    jv a3 = jv_array_append(jv_copy(a), jv_number(19));
    assert(jv_array_length(jv_copy(a3)) == 3);
    assert(jv_number_value(jv_array_get(jv_copy(a3), 0)) == 42);
    assert(jv_array_length(jv_array_get(jv_copy(a3), 1)) == 1);
    assert(jv_number_value(jv_array_get(jv_copy(a3), 2)) == 19);
    jv_free(a3);


    jv a4 = jv_array();
    a4 = jv_array_append(a4, jv_number(1));
    a4 = jv_array_append(a4, jv_number(2));
    jv a5 = jv_copy(a4);
    a4 = jv_array_append(a4, jv_number(3));
    a4 = jv_array_slice(a4, 0, 1);
    assert(jv_array_length(jv_copy(a4)) == 1);
    a4 = jv_array_append(a4, jv_number(4));
    assert(jv_array_length(jv_copy(a4)) == 2);
    assert(jv_array_length(jv_copy(a5)) == 2);
    jv_free(a4);
    jv_free(a5);


    assert(jv_array_length(jv_copy(a)) == 2);
    assert(jv_number_value(jv_array_get(jv_copy(a), 0)) == 42);
    assert(jv_array_length(jv_array_get(jv_copy(a), 1)) == 1);


    jv_dump(jv_copy(a), 0); printf("\n");
    jv_free(a);
  }


  /// Strings
  {
    assert(jv_equal(jv_string("foo"), jv_string_sized("foo", 3)));
    char nasty[] = "foo\0";
    jv shortstr = jv_string(nasty), longstr = jv_string_sized(nasty, sizeof(nasty));
    assert(jv_string_length_bytes(jv_copy(shortstr)) == (int)strlen(nasty));
    assert(jv_string_length_bytes(jv_copy(longstr)) == (int)sizeof(nasty));
    jv_free(shortstr);
    jv_free(longstr);

  
    char a1s[] = "hello", a2s[] = "hello", bs[] = "goodbye";
    jv a1 = jv_string(a1s), a2 = jv_string(a2s), b = jv_string(bs);
    assert(jv_equal(jv_copy(a1), jv_copy(a2)));
    assert(jv_equal(jv_copy(a2), jv_copy(a1)));
    assert(!jv_equal(jv_copy(a1), jv_copy(b)));
    
    assert(jv_string_hash(jv_copy(a1)) == jv_string_hash(jv_copy(a1)));
    assert(jv_string_hash(jv_copy(a1)) == jv_string_hash(jv_copy(a2)));
    assert(jv_string_hash(jv_copy(b)) != jv_string_hash(jv_copy(a1)));
    jv_free(a1);
    jv_free(a2);
    jv_free(b);

    assert(jv_equal(jv_string("hello42!"), jv_string_fmt("hello%d%s", 42, "!")));
    char big[20000];
    for (int i=0; i<(int)sizeof(big); i++) big[i] = 'a';
    big[sizeof(big)-1] = 0;
    jv str = jv_string_fmt("%s", big);
    assert(jv_string_length_bytes(jv_copy(str)) == sizeof(big) - 1);
    assert(!strcmp(big, jv_string_value(str)));
    jv_free(str);
  }

  /// Objects
  {
    jv o1 = jv_object();
    o1 = jv_object_set(o1, jv_string("foo"), jv_number(42));
    o1 = jv_object_set(o1, jv_string("bar"), jv_number(24));
    assert(jv_number_value(jv_object_get(jv_copy(o1), jv_string("foo"))) == 42);
    assert(jv_number_value(jv_object_get(jv_copy(o1), jv_string("bar"))) == 24);

    jv o2 = jv_object_set(jv_copy(o1), jv_string("foo"), jv_number(420));
    o2 = jv_object_set(o2, jv_string("bar"), jv_number(240));
    assert(jv_number_value(jv_object_get(jv_copy(o1), jv_string("foo"))) == 42);
    assert(jv_number_value(jv_object_get(jv_copy(o1), jv_string("bar"))) == 24);
    assert(jv_number_value(jv_object_get(jv_copy(o2), jv_string("foo"))) == 420);
    jv_free(o1);
    assert(jv_number_value(jv_object_get(jv_copy(o2), jv_string("bar"))) == 240);

    jv_dump(jv_copy(o2), 0); printf("\n");

    jv_free(o2);
  }

  /// Compile errors
  {
    jq_state *jq = jq_init();
    jq_compile_args(jq, "}", jv_array());
    jq_teardown(&jq);
  }
}