static void test_clone(void) { jd_var dst = JD_INIT, src = JD_INIT, ref = JD_INIT; jd_var json = JD_INIT; jd_set_string(&json, "{\"a\":[1,2,3],\"b\":3.14,\"c\":\"foo\"}"); jd_from_json(&ref, &json); jd_clone(&src, &ref, 1); jd_clone(&dst, &src, 0); /* shallow */ jdt_is(&dst, &src, "clone matches"); jd_assign(jd_lv(&dst, "$.d.0.capsule.source"), &json); jdt_is(&ref, &src, "source unchanged"); jd_assign(jd_lv(&dst, "$.a.3"), &json); jdt_is(jd_rv(&src, "$.a.3"), &json, "deep item changed"); jd_clone(&src, &ref, 1); jd_clone(&dst, &src, 1); /* deep */ jdt_is(&dst, &src, "clone matches"); jd_assign(jd_lv(&dst, "$.d.0.capsule.source"), &json); jdt_is(&ref, &src, "source unchanged"); jd_assign(jd_lv(&dst, "$.a.3"), &json); jdt_is(&ref, &src, "source unchanged again"); jd_release(&dst); jd_release(&src); jd_release(&ref); jd_release(&json); }
static void test_retain_release(void) { int i; jd_var h = JD_INIT, s = JD_INIT; jd_set_string(&s, "Hello, World"); jd_assign(jd_lv(&h, "$.hello"), &s); jd_release(&s); is(s.type, VOID, "release -> type == void"); for (i = 0; i < 10; i++) jd_release(&s); /* make sure it's a nop */ jdt_is_json(&h, "{\"hello\":\"Hello, World\"}", "data matches"); jd_release(&h); }
static int grep_filter(jd_var *out, jd_var *cl, jd_var *in) { int ok = 0; JD_SCOPE { JD_VAR(rv); jd_eval(cl, rv, in); ok = jd_test(rv); if (ok) jd_assign(out, in); } return ok; }
size_t jd_array_remove(jd_array *jda, int idx, size_t count, jd_var *slot) { unsigned ix = check_idx_open(jda, idx); size_t avail = jd_array_count(jda) - ix; if (count > avail) count = avail; if (slot) { unsigned i; for (i = 0; i < count; i++) jd_assign(slot++, ELT(jda, ix + i)); } release(jda, ix, count); memmove(ELT(jda, ix), ELT(jda, ix + count), (avail - count) * sizeof(jd_var)); jda->s.used -= count * sizeof(jd_var); return count; }
int jdt_throws(void (*func)(void *), void *ctx, const char *want, const char *msg, ...) { va_list ap; int rc = 0; scope { JD_VAR(caught); JD_SV(vwant, want); try { func(ctx); } catch(e) { jd_assign(caught, e); } va_start(ap, msg); rc = _is(jd_get_ks(caught, "message", 0), vwant, msg, ap); va_end(ap); } return rc; }
static jd_var *path_iter(jd_var *iter, jd_var *data) { jd_var *slot = jd_push(jd_set_array(jd_context(jd_set_closure(iter, path_iter_f)), 2), 2); jd_assign(slot++, data); jd_set_string(jd_push(jd_set_array(slot++, 1000), 1), "$"); return iter; }
jd_var *jd__closure_clone(jd_var *out, jd_closure *jdc, int deep) { jd_set_closure(out, jdc->f); if (deep) jd_clone(jd_context(out), &jdc->ctx, 1); else jd_assign(jd_context(out), &jdc->ctx); return out; }
static filter *filter__clone(filter *f) { filter *nf = jd_alloc(sizeof(filter)); *nf = *f; jd_assign(&nf->config, &f->config); return nf; }