static ucl_object_t * new_dynamic_elt (ucl_object_t *arr, const gchar *name, gdouble value) { ucl_object_t *n; n = ucl_object_typed_new (UCL_OBJECT); ucl_object_insert_key (n, ucl_object_fromstring (name), "name", sizeof ("name") - 1, false); ucl_object_insert_key (n, ucl_object_fromdouble (value), "value", sizeof ("value") - 1, false); ucl_array_append (arr, n); return n; }
ucl_object_t * rspamd_log_errorbuf_export (const rspamd_logger_t *logger) { struct rspamd_logger_error_elt *cpy, *cur; ucl_object_t *top = ucl_object_typed_new (UCL_ARRAY); guint i; if (logger->errlog == NULL) { return top; } cpy = g_malloc0_n (logger->errlog->max_elts, sizeof (*cpy) + logger->errlog->elt_len); memcpy (cpy, logger->errlog->elts, logger->errlog->max_elts * (sizeof (*cpy) + logger->errlog->elt_len)); for (i = 0; i < logger->errlog->max_elts; i ++) { cur = (struct rspamd_logger_error_elt *)((guchar *)cpy + i * ((sizeof (*cpy) + logger->errlog->elt_len))); if (cur->completed) { ucl_object_t *obj = ucl_object_typed_new (UCL_OBJECT); ucl_object_insert_key (obj, ucl_object_fromdouble (cur->ts), "ts", 0, false); ucl_object_insert_key (obj, ucl_object_fromint (cur->pid), "pid", 0, false); ucl_object_insert_key (obj, ucl_object_fromstring (g_quark_to_string (cur->ptype)), "type", 0, false); ucl_object_insert_key (obj, ucl_object_fromstring (cur->id), "id", 0, false); ucl_object_insert_key (obj, ucl_object_fromstring (cur->module), "module", 0, false); ucl_object_insert_key (obj, ucl_object_fromstring (cur->message), "message", 0, false); ucl_array_append (top, obj); } } ucl_object_array_sort (top, rspamd_log_errlog_cmp); g_free (cpy); return top; }
static ucl_object_t* new_dynamic_metric (const gchar *metric_name, ucl_object_t *top) { ucl_object_t *metric; metric = ucl_object_typed_new (UCL_OBJECT); ucl_object_insert_key (metric, ucl_object_fromstring (metric_name), "metric", sizeof ("metric") - 1, true); ucl_object_insert_key (metric, ucl_object_typed_new (UCL_ARRAY), "actions", sizeof ("actions") - 1, false); ucl_object_insert_key (metric, ucl_object_typed_new (UCL_ARRAY), "symbols", sizeof ("symbols") - 1, false); ucl_array_append (top, metric); return metric; }
static void rspamd_symbols_cache_counters_cb (gpointer v, gpointer ud) { struct counters_cbdata *cbd = ud; ucl_object_t *obj, *top; struct cache_item *item = v, *parent; top = cbd->top; if (item->type != SYMBOL_TYPE_CALLBACK) { obj = ucl_object_typed_new (UCL_OBJECT); ucl_object_insert_key (obj, ucl_object_fromstring (item->symbol), "symbol", 0, false); if (item->type == SYMBOL_TYPE_VIRTUAL && item->parent != -1) { g_assert (item->parent < (gint)cbd->cache->items_by_id->len); parent = g_ptr_array_index (cbd->cache->items_by_id, item->parent); ucl_object_insert_key (obj, ucl_object_fromdouble (item->weight), "weight", 0, false); ucl_object_insert_key (obj, ucl_object_fromint (item->frequency), "frequency", 0, false); ucl_object_insert_key (obj, ucl_object_fromdouble (parent->avg_time), "time", 0, false); } else { ucl_object_insert_key (obj, ucl_object_fromdouble (item->weight), "weight", 0, false); ucl_object_insert_key (obj, ucl_object_fromint (item->frequency), "frequency", 0, false); ucl_object_insert_key (obj, ucl_object_fromdouble (item->avg_time), "time", 0, false); } ucl_array_append (top, obj); } }
int pkg_ini(const char *path, const char *reposdir, pkg_init_flags flags) { struct ucl_parser *p = NULL; size_t i; const char *val = NULL; const char *buf, *walk, *value, *key, *k; const char *evkey = NULL; const char *nsname = NULL; const char *evpipe = NULL; const ucl_object_t *cur, *object; ucl_object_t *obj = NULL, *o, *ncfg; ucl_object_iter_t it = NULL; struct sbuf *ukey = NULL; bool fatal_errors = false; k = NULL; o = NULL; pkg_get_myarch(myabi, BUFSIZ); pkg_get_myarch_legacy(myabi_legacy, BUFSIZ); if (parsed != false) { pkg_emit_error("pkg_init() must only be called once"); return (EPKG_FATAL); } if (((flags & PKG_INIT_FLAG_USE_IPV4) == PKG_INIT_FLAG_USE_IPV4) && ((flags & PKG_INIT_FLAG_USE_IPV6) == PKG_INIT_FLAG_USE_IPV6)) { pkg_emit_error("Invalid flags for pkg_init()"); return (EPKG_FATAL); } config = ucl_object_typed_new(UCL_OBJECT); for (i = 0; i < c_size; i++) { switch (c[i].type) { case PKG_STRING: obj = ucl_object_fromstring_common( c[i].def != NULL ? c[i].def : "", 0, UCL_STRING_TRIM); ucl_object_insert_key(config, obj, c[i].key, strlen(c[i].key), false); break; case PKG_INT: ucl_object_insert_key(config, ucl_object_fromstring_common(c[i].def, 0, UCL_STRING_PARSE_INT), c[i].key, strlen(c[i].key), false); break; case PKG_BOOL: ucl_object_insert_key(config, ucl_object_fromstring_common(c[i].def, 0, UCL_STRING_PARSE_BOOLEAN), c[i].key, strlen(c[i].key), false); break; case PKG_OBJECT: obj = ucl_object_typed_new(UCL_OBJECT); if (c[i].def != NULL) { walk = buf = c[i].def; while ((buf = strchr(buf, ',')) != NULL) { key = walk; value = walk; while (*value != ',') { if (*value == '=') break; value++; } ucl_object_insert_key(obj, ucl_object_fromstring_common(value + 1, buf - value - 1, UCL_STRING_TRIM), key, value - key, false); buf++; walk = buf; } key = walk; value = walk; while (*value != ',') { if (*value == '=') break; value++; } if (o == NULL) o = ucl_object_typed_new(UCL_OBJECT); ucl_object_insert_key(o, ucl_object_fromstring_common(value + 1, strlen(value + 1), UCL_STRING_TRIM), key, value - key, false); } ucl_object_insert_key(config, obj, c[i].key, strlen(c[i].key), false); break; case PKG_ARRAY: obj = ucl_object_typed_new(UCL_ARRAY); if (c[i].def != NULL) { walk = buf = c[i].def; while ((buf = strchr(buf, ',')) != NULL) { ucl_array_append(obj, ucl_object_fromstring_common(walk, buf - walk, UCL_STRING_TRIM)); buf++; walk = buf; } ucl_array_append(obj, ucl_object_fromstring_common(walk, strlen(walk), UCL_STRING_TRIM)); } ucl_object_insert_key(config, obj, c[i].key, strlen(c[i].key), false); break; } } if (path == NULL) path = PREFIX"/etc/pkg.conf"; p = ucl_parser_new(0); errno = 0; obj = NULL; if (!ucl_parser_add_file(p, path)) { if (errno != ENOENT) pkg_emit_error("Invalid configuration file: %s", ucl_parser_get_error(p)); } else { obj = ucl_parser_get_object(p); } ncfg = NULL; while (obj != NULL && (cur = ucl_iterate_object(obj, &it, true))) { sbuf_init(&ukey); key = ucl_object_key(cur); for (i = 0; key[i] != '\0'; i++) sbuf_putc(ukey, toupper(key[i])); sbuf_finish(ukey); object = ucl_object_find_keyl(config, sbuf_data(ukey), sbuf_len(ukey)); if (strncasecmp(sbuf_data(ukey), "PACKAGESITE", sbuf_len(ukey)) == 0 || strncasecmp(sbuf_data(ukey), "PUBKEY", sbuf_len(ukey)) == 0 || strncasecmp(sbuf_data(ukey), "MIRROR_TYPE", sbuf_len(ukey)) == 0) { pkg_emit_error("%s in pkg.conf is no longer " "supported. Convert to the new repository style." " See pkg.conf(5)", sbuf_data(ukey)); fatal_errors = true; continue; } /* ignore unknown keys */ if (object == NULL) continue; if (object->type != cur->type) { pkg_emit_error("Malformed key %s, ignoring", key); continue; } if (ncfg == NULL) ncfg = ucl_object_typed_new(UCL_OBJECT); ucl_object_insert_key(ncfg, ucl_object_copy(cur), sbuf_data(ukey), sbuf_len(ukey), true); } if (fatal_errors) { ucl_object_unref(ncfg); ucl_parser_free(p); return (EPKG_FATAL); } if (ncfg != NULL) { it = NULL; while (( cur = ucl_iterate_object(ncfg, &it, true))) { key = ucl_object_key(cur); ucl_object_replace_key(config, ucl_object_ref(cur), key, strlen(key), true); } ucl_object_unref(ncfg); } ncfg = NULL; it = NULL; while ((cur = ucl_iterate_object(config, &it, true))) { o = NULL; key = ucl_object_key(cur); val = getenv(key); if (val == NULL) continue; switch (cur->type) { case UCL_STRING: o = ucl_object_fromstring_common(val, 0, UCL_STRING_TRIM); break; case UCL_INT: o = ucl_object_fromstring_common(val, 0, UCL_STRING_PARSE_INT); if (o->type != UCL_INT) { pkg_emit_error("Invalid type for environment " "variable %s, got %s, while expecting an integer", key, val); ucl_object_unref(o); continue; } break; case UCL_BOOLEAN: o = ucl_object_fromstring_common(val, 0, UCL_STRING_PARSE_BOOLEAN); if (o->type != UCL_BOOLEAN) { pkg_emit_error("Invalid type for environment " "variable %s, got %s, while expecting a boolean", key, val); ucl_object_unref(o); continue; } break; case UCL_OBJECT: o = ucl_object_typed_new(UCL_OBJECT); walk = buf = val; while ((buf = strchr(buf, ',')) != NULL) { k = walk; value = walk; while (*value != ',') { if (*value == '=') break; value++; } ucl_object_insert_key(o, ucl_object_fromstring_common(value + 1, buf - value - 1, UCL_STRING_TRIM), k, value - k, false); buf++; walk = buf; } key = walk; value = walk; while (*value != '\0') { if (*value == '=') break; value++; } ucl_object_insert_key(o, ucl_object_fromstring_common(value + 1, strlen(value + 1), UCL_STRING_TRIM), k, value - k, false); break; case UCL_ARRAY: o = ucl_object_typed_new(UCL_ARRAY); walk = buf = val; while ((buf = strchr(buf, ',')) != NULL) { ucl_array_append(o, ucl_object_fromstring_common(walk, buf - walk, UCL_STRING_TRIM)); buf++; walk = buf; } ucl_array_append(o, ucl_object_fromstring_common(walk, strlen(walk), UCL_STRING_TRIM)); break; default: /* ignore other types */ break; } if (o != NULL) { if (ncfg == NULL) ncfg = ucl_object_typed_new(UCL_OBJECT); ucl_object_insert_key(ncfg, o, key, strlen(key), true); } } if (ncfg != NULL) { it = NULL; while (( cur = ucl_iterate_object(ncfg, &it, true))) { key = ucl_object_key(cur); ucl_object_replace_key(config, ucl_object_ref(cur), key, strlen(key), true); } ucl_object_unref(ncfg); } disable_plugins_if_static(); parsed = true; ucl_object_unref(obj); ucl_parser_free(p); if (strcmp(pkg_object_string(pkg_config_get("ABI")), "unknown") == 0) { pkg_emit_error("Unable to determine ABI"); return (EPKG_FATAL); } pkg_debug(1, "%s", "pkg initialized"); /* Start the event pipe */ evpipe = pkg_object_string(pkg_config_get("EVENT_PIPE")); if (evpipe != NULL) connect_evpipe(evpipe); debug_level = pkg_object_int(pkg_config_get("DEBUG_LEVEL")); it = NULL; object = ucl_object_find_key(config, "PKG_ENV"); while ((cur = ucl_iterate_object(object, &it, true))) { evkey = ucl_object_key(cur); pkg_debug(1, "Setting env var: %s", evkey); if (evkey != NULL && evkey[0] != '\0') setenv(evkey, ucl_object_tostring_forced(cur), 1); } /* load the repositories */ load_repositories(reposdir, flags); setenv("HTTP_USER_AGENT", "pkg/"PKGVERSION, 1); /* bypass resolv.conf with specified NAMESERVER if any */ nsname = pkg_object_string(pkg_config_get("NAMESERVER")); if (nsname != NULL) set_nameserver(ucl_object_tostring_forced(o)); return (EPKG_OK); }
bool ucl_parse_csexp (struct ucl_parser *parser) { const unsigned char *p, *end; ucl_object_t *obj; struct ucl_stack *st; uint64_t len = 0, mult = 1; enum { start_parse, read_obrace, read_length, read_value, read_ebrace, parse_err } state = start_parse; assert (parser != NULL); assert (parser->chunks != NULL); assert (parser->chunks->begin != NULL); assert (parser->chunks->remain != 0); p = parser->chunks->begin; end = p + parser->chunks->remain; while (p < end) { switch (state) { case start_parse: /* At this point we expect open brace */ if (*p == '(') { state = read_obrace; } else { ucl_create_err (&parser->err, "bad starting character for " "sexp block: %x", (int)*p); state = parse_err; } break; case read_obrace: st = calloc (1, sizeof (*st)); if (st == NULL) { ucl_create_err (&parser->err, "no memory"); state = parse_err; continue; } st->obj = ucl_object_typed_new (UCL_ARRAY); if (st->obj == NULL) { ucl_create_err (&parser->err, "no memory"); state = parse_err; continue; } if (parser->stack == NULL) { /* We have no stack */ parser->stack = st; if (parser->top_obj == NULL) { parser->top_obj = st->obj; } } else { /* Prepend new element to the stack */ LL_PREPEND (parser->stack, st); } p ++; NEXT_STATE; break; case read_length: if (*p == ':') { if (len == 0) { ucl_create_err (&parser->err, "zero length element"); state = parse_err; continue; } state = read_value; } else if (*p >= '0' && *p <= '9') { len += (*p - '0') * mult; mult *= 10; if (len > UINT32_MAX) { ucl_create_err (&parser->err, "too big length of an " "element"); state = parse_err; continue; } } else { ucl_create_err (&parser->err, "bad length character: %x", (int)*p); state = parse_err; continue; } p ++; break; case read_value: if ((uint64_t)(end - p) > len || len == 0) { ucl_create_err (&parser->err, "invalid length: %llu, %ld " "remain", (long long unsigned)len, (long)(end - p)); state = parse_err; continue; } obj = ucl_object_typed_new (UCL_STRING); obj->value.sv = (const char*)p; obj->len = len; obj->flags |= UCL_OBJECT_BINARY; if (!(parser->flags & UCL_PARSER_ZEROCOPY)) { ucl_copy_value_trash (obj); } ucl_array_append (parser->stack->obj, obj); p += len; NEXT_STATE; break; case read_ebrace: if (parser->stack == NULL) { /* We have an extra end brace */ ucl_create_err (&parser->err, "invalid length: %llu, %ld " "remain", (long long unsigned)len, (long)(end - p)); state = parse_err; continue; } /* Pop the container */ st = parser->stack; parser->stack = st->next; if (parser->stack->obj->type == UCL_ARRAY) { ucl_array_append (parser->stack->obj, st->obj); } else { ucl_create_err (&parser->err, "bad container object, array " "expected"); state = parse_err; continue; } free (st); p++; NEXT_STATE; break; case parse_err: default: return false; } } if (state != read_ebrace) { ucl_create_err (&parser->err, "invalid finishing state: %d", state); return false; } return true; }
int main (int argc, char **argv) { ucl_object_t *obj, *cur, *ar, *ref; const ucl_object_t *found; FILE *out; unsigned char *emitted; const char *fname_out = NULL; int ret = 0; switch (argc) { case 2: fname_out = argv[1]; break; } if (fname_out != NULL) { out = fopen (fname_out, "w"); if (out == NULL) { exit (-errno); } } else { out = stdout; } obj = ucl_object_typed_new (UCL_OBJECT); /* Create some strings */ cur = ucl_object_fromstring_common (" test string ", 0, UCL_STRING_TRIM); ucl_object_insert_key (obj, cur, "key1", 0, false); cur = ucl_object_fromstring_common (" test \nstring\n ", 0, UCL_STRING_TRIM | UCL_STRING_ESCAPE); ucl_object_insert_key (obj, cur, "key2", 0, false); cur = ucl_object_fromstring_common (" test string \n", 0, 0); ucl_object_insert_key (obj, cur, "key3", 0, false); /* Array of numbers */ ar = ucl_object_typed_new (UCL_ARRAY); cur = ucl_object_fromint (10); ucl_array_append (ar, cur); cur = ucl_object_fromdouble (10.1); ucl_array_append (ar, cur); cur = ucl_object_fromdouble (9.999); ucl_array_prepend (ar, cur); /* Removing from an array */ cur = ucl_object_fromdouble (1.0); ucl_array_append (ar, cur); cur = ucl_array_delete (ar, cur); assert (ucl_object_todouble (cur) == 1.0); ucl_object_unref (cur); cur = ucl_object_fromdouble (2.0); ucl_array_append (ar, cur); cur = ucl_array_pop_last (ar); assert (ucl_object_todouble (cur) == 2.0); ucl_object_unref (cur); cur = ucl_object_fromdouble (3.0); ucl_array_prepend (ar, cur); cur = ucl_array_pop_first (ar); assert (ucl_object_todouble (cur) == 3.0); ucl_object_unref (cur); ucl_object_insert_key (obj, ar, "key4", 0, false); cur = ucl_object_frombool (true); /* Ref object to test refcounts */ ref = ucl_object_ref (cur); ucl_object_insert_key (obj, cur, "key4", 0, false); /* Empty strings */ cur = ucl_object_fromstring_common (" ", 0, UCL_STRING_TRIM); ucl_object_insert_key (obj, cur, "key5", 0, false); cur = ucl_object_fromstring_common ("", 0, UCL_STRING_ESCAPE); ucl_object_insert_key (obj, cur, "key6", 0, false); cur = ucl_object_fromstring_common (" \n", 0, UCL_STRING_ESCAPE); ucl_object_insert_key (obj, cur, "key7", 0, false); /* Numbers and booleans */ cur = ucl_object_fromstring_common ("1mb", 0, UCL_STRING_ESCAPE | UCL_STRING_PARSE); ucl_object_insert_key (obj, cur, "key8", 0, false); cur = ucl_object_fromstring_common ("3.14", 0, UCL_STRING_PARSE); ucl_object_insert_key (obj, cur, "key9", 0, false); cur = ucl_object_fromstring_common ("true", 0, UCL_STRING_PARSE); ucl_object_insert_key (obj, cur, "key10", 0, false); cur = ucl_object_fromstring_common (" off ", 0, UCL_STRING_PARSE | UCL_STRING_TRIM); ucl_object_insert_key (obj, cur, "key11", 0, false); cur = ucl_object_fromstring_common ("*****@*****.**", 0, UCL_STRING_PARSE_INT); ucl_object_insert_key (obj, cur, "key12", 0, false); cur = ucl_object_fromstring_common ("#test", 0, UCL_STRING_PARSE_INT); ucl_object_insert_key (obj, cur, "key13", 0, false); cur = ucl_object_frombool (true); ucl_object_insert_key (obj, cur, "k=3", 0, false); /* Try to find using path */ /* Should exist */ found = ucl_lookup_path (obj, "key4.1"); assert (found != NULL && ucl_object_toint (found) == 10); /* . should be ignored */ found = ucl_lookup_path (obj, ".key4.1"); assert (found != NULL && ucl_object_toint (found) == 10); /* moar dots... */ found = ucl_lookup_path (obj, ".key4........1..."); assert (found != NULL && ucl_object_toint (found) == 10); /* No such index */ found = ucl_lookup_path (obj, ".key4.3"); assert (found == NULL); /* No such key */ found = ucl_lookup_path (obj, "key9..key1"); assert (found == NULL); emitted = ucl_object_emit (obj, UCL_EMIT_CONFIG); fprintf (out, "%s\n", emitted); ucl_object_unref (obj); if (emitted != NULL) { free (emitted); } fclose (out); /* Ref should still be accessible */ ref->value.iv = 100500; ucl_object_unref (ref); return ret; }
int main (int argc, char **argv) { ucl_object_t *obj, *cur, *ar, *ar1, *ref, *test_obj, *comments; ucl_object_iter_t it; const ucl_object_t *found, *it_obj, *test; struct ucl_emitter_functions *fn; FILE *out; unsigned char *emitted; const char *fname_out = NULL; struct ucl_parser *parser; int ret = 0; switch (argc) { case 2: fname_out = argv[1]; break; } if (fname_out != NULL) { out = fopen (fname_out, "w"); if (out == NULL) { exit (-errno); } } else { out = stdout; } obj = ucl_object_typed_new (UCL_OBJECT); /* Keys replacing */ cur = ucl_object_fromstring_common ("value1", 0, UCL_STRING_TRIM); ucl_object_insert_key (obj, cur, "key0", 0, false); cur = ucl_object_fromdouble (0.1); assert (ucl_object_replace_key (obj, cur, "key0", 0, false)); /* Create some strings */ cur = ucl_object_fromstring_common (" test string ", 0, UCL_STRING_TRIM); ucl_object_insert_key (obj, cur, "key1", 0, false); cur = ucl_object_fromstring_common (" test \nstring\n\r\n\b\t\f\\\" ", 0, UCL_STRING_TRIM | UCL_STRING_ESCAPE); ucl_object_insert_key (obj, cur, "key2", 0, false); cur = ucl_object_fromstring_common (" test string \n", 0, 0); ucl_object_insert_key (obj, cur, "key3", 0, false); /* Array of numbers */ ar = ucl_object_typed_new (UCL_ARRAY); cur = ucl_object_fromint (10); ucl_array_append (ar, cur); assert (ucl_array_index_of (ar, cur) == 0); cur = ucl_object_fromdouble (10.1); ucl_array_append (ar, cur); assert (ucl_array_index_of (ar, cur) == 1); cur = ucl_object_fromdouble (9.999); ucl_array_prepend (ar, cur); assert (ucl_array_index_of (ar, cur) == 0); ar1 = ucl_object_copy (ar); cur = ucl_object_fromstring ("abc"); ucl_array_prepend (ar1, cur); cur = ucl_object_fromstring ("cde"); ucl_array_prepend (ar1, cur); cur = ucl_object_fromstring ("аАаБаВ"); /* UTF8 */ ucl_array_prepend (ar1, cur); cur = ucl_object_fromstring ("ааБаВ"); /* UTF8 */ ucl_array_prepend (ar1, cur); /* * This is ususally broken or fragile as utf collate is far from perfect cur = ucl_object_fromstring ("баБаВ"); ucl_array_prepend (ar1, cur); cur = ucl_object_fromstring ("ааБаВ"); // hello to @bapt ucl_array_prepend (ar1, cur); */ cur = ucl_object_fromstring ("№"); /* everybody likes emoji in the code */ ucl_array_prepend (ar1, cur); ucl_object_array_sort (ar1, ucl_object_compare_qsort); /* Removing from an array */ cur = ucl_object_fromdouble (1.0); ucl_array_append (ar, cur); cur = ucl_array_delete (ar, cur); assert (ucl_object_todouble (cur) == 1.0); ucl_object_unref (cur); cur = ucl_object_fromdouble (2.0); ucl_array_append (ar, cur); cur = ucl_array_pop_last (ar); assert (ucl_object_todouble (cur) == 2.0); ucl_object_unref (cur); cur = ucl_object_fromdouble (3.0); ucl_array_prepend (ar, cur); cur = ucl_array_pop_first (ar); assert (ucl_object_todouble (cur) == 3.0); ucl_object_unref (cur); ucl_object_insert_key (obj, ar, "key4", 0, false); cur = ucl_object_frombool (true); /* Ref object to test refcounts */ ref = ucl_object_ref (cur); ucl_object_insert_key (obj, cur, "key4", 0, false); /* Empty strings */ cur = ucl_object_fromstring_common (" ", 0, UCL_STRING_TRIM); ucl_object_insert_key (obj, cur, "key5", 0, false); cur = ucl_object_fromstring_common ("", 0, UCL_STRING_ESCAPE); ucl_object_insert_key (obj, cur, "key6", 0, false); cur = ucl_object_fromstring_common (" \n", 0, UCL_STRING_ESCAPE); ucl_object_insert_key (obj, cur, "key7", 0, false); /* Numbers and booleans */ cur = ucl_object_fromstring_common ("1mb", 0, UCL_STRING_ESCAPE | UCL_STRING_PARSE); ucl_object_insert_key (obj, cur, "key8", 0, false); cur = ucl_object_fromstring_common ("3.14", 0, UCL_STRING_PARSE); ucl_object_insert_key (obj, cur, "key9", 0, false); cur = ucl_object_fromstring_common ("true", 0, UCL_STRING_PARSE); ucl_object_insert_key (obj, cur, "key10", 0, false); cur = ucl_object_fromstring_common (" off ", 0, UCL_STRING_PARSE | UCL_STRING_TRIM); ucl_object_insert_key (obj, cur, "key11", 0, false); cur = ucl_object_fromstring_common ("*****@*****.**", 0, UCL_STRING_PARSE_INT); ucl_object_insert_key (obj, cur, "key12", 0, false); cur = ucl_object_fromstring_common ("#test", 0, UCL_STRING_PARSE_INT); ucl_object_insert_key (obj, cur, "key13", 0, false); cur = ucl_object_frombool (true); ucl_object_insert_key (obj, cur, "k=3", 0, false); ucl_object_insert_key (obj, ar1, "key14", 0, false); cur = ucl_object_new_userdata (ud_dtor, ud_emit, NULL); ucl_object_insert_key (obj, cur, "key15", 0, false); /* More tests for keys */ cur = ucl_object_fromlstring ("test", 3); ucl_object_insert_key (obj, cur, "key16", 0, false); test = ucl_object_lookup_any (obj, "key100", "key200", "key300", "key16", NULL); assert (test == cur); test = ucl_object_lookup_len (obj, "key160", 5); assert (test == cur); cur = ucl_object_pop_key (obj, "key16"); assert (test == cur); test = ucl_object_pop_key (obj, "key16"); assert (test == NULL); test = ucl_object_lookup_len (obj, "key160", 5); assert (test == NULL); /* Objects merging tests */ test_obj = ucl_object_new_full (UCL_OBJECT, 2); ucl_object_insert_key (test_obj, cur, "key16", 0, true); ucl_object_merge (obj, test_obj, true); ucl_object_unref (test_obj); /* Array merging test */ test_obj = ucl_object_new_full (UCL_ARRAY, 3); ucl_array_append (test_obj, ucl_object_fromstring ("test")); ucl_array_merge (test_obj, ar1, false); ucl_object_insert_key (obj, test_obj, "key17", 0, true); /* Object deletion */ cur = ucl_object_fromstring ("test"); ucl_object_insert_key (obj, cur, "key18", 0, true); assert (ucl_object_delete_key (obj, "key18")); assert (!ucl_object_delete_key (obj, "key18")); cur = ucl_object_fromlstring ("test", 4); ucl_object_insert_key (obj, cur, "key18\0\0", 7, true); assert (ucl_object_lookup_len (obj, "key18\0\0", 7) == cur); assert (ucl_object_lookup (obj, "key18") == NULL); assert (ucl_object_lookup_len (obj, "key18\0\1", 7) == NULL); assert (ucl_object_delete_keyl (obj, "key18\0\0", 7)); /* Comments */ comments = ucl_object_typed_new (UCL_OBJECT); found = ucl_object_lookup (obj, "key17"); test = ucl_object_lookup (obj, "key16"); ucl_comments_add (comments, found, "# test comment"); assert (ucl_comments_find (comments, found) != NULL); assert (ucl_comments_find (comments, test) == NULL); ucl_comments_move (comments, found, test); assert (ucl_comments_find (comments, found) == NULL); assert (ucl_comments_find (comments, test) != NULL); /* Array replace */ ar1 = ucl_object_typed_new (UCL_ARRAY); cur = ucl_object_fromstring ("test"); cur = ucl_elt_append (cur, ucl_object_fromstring ("test1")); ucl_array_append (ar1, cur); test = ucl_array_replace_index (ar1, ucl_object_fromstring ("test2"), 0); assert (test == cur); /* Try to find using path */ /* Should exist */ found = ucl_object_lookup_path (obj, "key4.1"); assert (found != NULL && ucl_object_toint (found) == 10); /* . should be ignored */ found = ucl_object_lookup_path (obj, ".key4.1"); assert (found != NULL && ucl_object_toint (found) == 10); /* moar dots... */ found = ucl_object_lookup_path (obj, ".key4........1..."); assert (found != NULL && ucl_object_toint (found) == 10); /* No such index */ found = ucl_object_lookup_path (obj, ".key4.3"); assert (found == NULL); /* No such key */ found = ucl_object_lookup_path (obj, "key9..key1"); assert (found == NULL); /* Test iteration */ it = ucl_object_iterate_new (obj); it_obj = ucl_object_iterate_safe (it, true); /* key0 = 0.1 */ assert (ucl_object_type (it_obj) == UCL_FLOAT); it_obj = ucl_object_iterate_safe (it, true); /* key1 = "" */ assert (ucl_object_type (it_obj) == UCL_STRING); it_obj = ucl_object_iterate_safe (it, true); /* key2 = "" */ assert (ucl_object_type (it_obj) == UCL_STRING); it_obj = ucl_object_iterate_safe (it, true); /* key3 = "" */ assert (ucl_object_type (it_obj) == UCL_STRING); it_obj = ucl_object_iterate_safe (it, true); /* key4 = ([float, int, float], boolean) */ ucl_object_iterate_reset (it, it_obj); it_obj = ucl_object_iterate_safe (it, true); assert (ucl_object_type (it_obj) == UCL_FLOAT); it_obj = ucl_object_iterate_safe (it, true); assert (ucl_object_type (it_obj) == UCL_INT); it_obj = ucl_object_iterate_safe (it, true); assert (ucl_object_type (it_obj) == UCL_FLOAT); it_obj = ucl_object_iterate_safe (it, true); assert (ucl_object_type (it_obj) == UCL_BOOLEAN); ucl_object_iterate_free (it); fn = ucl_object_emit_memory_funcs (&emitted); assert (ucl_object_emit_full (obj, UCL_EMIT_CONFIG, fn, comments)); fprintf (out, "%s\n", emitted); ucl_object_emit_funcs_free (fn); ucl_object_unref (obj); ucl_object_unref (comments); parser = ucl_parser_new (UCL_PARSER_NO_IMPLICIT_ARRAYS); if (ucl_parser_add_chunk_full (parser, emitted, strlen (emitted), 3, UCL_DUPLICATE_ERROR, UCL_PARSE_UCL)) { /* Should fail due to duplicate */ assert (0); } else { assert (ucl_parser_get_error (parser) != NULL); ucl_parser_clear_error (parser); ucl_parser_free (parser); parser = ucl_parser_new (0); ucl_parser_add_chunk_full (parser, emitted, strlen (emitted), 3, UCL_DUPLICATE_MERGE, UCL_PARSE_UCL); } assert (ucl_parser_get_column (parser) == 0); assert (ucl_parser_get_linenum (parser) != 0); ucl_parser_clear_error (parser); assert (ucl_parser_get_error_code (parser) == 0); obj = ucl_parser_get_object (parser); ucl_parser_free (parser); ucl_object_free (obj); if (emitted != NULL) { free (emitted); } fclose (out); /* Ref should still be accessible */ ref->value.iv = 100500; ucl_object_unref (ref); return ret; }
static ucl_object_t * _iterate_python (PyObject *obj) { if (obj == Py_None) { return ucl_object_new(); } else if (PyBool_Check (obj)) { return ucl_object_frombool (obj == Py_True); } #if PY_MAJOR_VERSION < 3 else if (PyInt_Check (obj)) { return ucl_object_fromint (PyInt_AsLong (obj)); } #endif else if (PyLong_Check (obj)) { return ucl_object_fromint (PyLong_AsLong (obj)); } else if (PyFloat_Check (obj)) { return ucl_object_fromdouble (PyFloat_AsDouble (obj)); } else if (PyUnicode_Check (obj)) { ucl_object_t *ucl_str; PyObject *str = PyUnicode_AsASCIIString(obj); ucl_str = ucl_object_fromstring (PyBytes_AsString (str)); Py_DECREF(str); return ucl_str; } #if PY_MAJOR_VERSION < 3 else if (PyString_Check (obj)) { return ucl_object_fromstring (PyString_AsString (obj)); } #endif else if (PyDict_Check(obj)) { PyObject *key, *value; Py_ssize_t pos = 0; ucl_object_t *top, *elm; char *keystr = NULL; top = ucl_object_typed_new (UCL_OBJECT); while (PyDict_Next(obj, &pos, &key, &value)) { elm = _iterate_python(value); if (PyUnicode_Check(key)) { PyObject *keyascii = PyUnicode_AsASCIIString(key); keystr = PyBytes_AsString(keyascii); Py_DECREF(keyascii); } #if PY_MAJOR_VERSION < 3 else if (PyString_Check(key)) { keystr = PyString_AsString(key); } #endif else { PyErr_SetString(PyExc_TypeError, "Unknown key type"); return NULL; } ucl_object_insert_key (top, elm, keystr, 0, true); } return top; } else if (PySequence_Check(obj)) { PyObject *value; Py_ssize_t len, pos; ucl_object_t *top, *elm; len = PySequence_Length(obj); top = ucl_object_typed_new (UCL_ARRAY); for (pos = 0; pos < len; pos++) { value = PySequence_GetItem(obj, pos); elm = _iterate_python(value); ucl_array_append(top, elm); } return top; } else { PyErr_SetString(PyExc_TypeError, "Unhandled object type"); return NULL; } return NULL; }
int merge_mode(char *destination_node, char *data) { ucl_object_t *dst_obj = NULL; ucl_object_t *sub_obj = NULL; ucl_object_t *old_obj = NULL; ucl_object_t *tmp_obj = NULL; int success = 0; char *dst_frag; setparser = ucl_parser_new(UCL_PARSER_KEY_LOWERCASE | UCL_PARSER_NO_IMPLICIT_ARRAYS); /* Lookup the destination to write to */ dst_obj = get_parent(destination_node); sub_obj = get_object(destination_node); if (sub_obj == NULL) { fprintf(stderr, "Failed to find destination node: %s\n", destination_node); return false; } if (include_file != NULL) { /* get UCL to add from file */ set_obj = parse_file(setparser, include_file); } else if (data == NULL || strcmp(data, "-") == 0) { /* get UCL to add from stdin */ set_obj = parse_input(setparser, stdin); } else { /* User provided data inline */ set_obj = parse_string(setparser, data); } if (debug > 0) { char *rt = NULL, *dt = NULL, *st = NULL; rt = objtype_as_string(dst_obj); dt = objtype_as_string(sub_obj); st = objtype_as_string(set_obj); fprintf(stderr, "root type: %s, destination type: %s, new type: %s\n", rt, dt, st); if (rt != NULL) free(rt); if (dt != NULL) free(dt); if (st != NULL) free(st); fprintf(stderr, "Merging key %s to root: %s\n", ucl_object_key(sub_obj), ucl_object_key(dst_obj)); } dst_frag = strrchr(destination_node, input_sepchar); if (dst_frag == NULL) { dst_frag = destination_node; } else { dst_frag++; } /* Add it to the object here */ if (sub_obj == dst_obj && *dst_frag != '\0') { /* Sub-object does not exist, create a new one */ success = ucl_object_insert_key(dst_obj, set_obj, dst_frag, 0, true); } else if (ucl_object_type(sub_obj) == UCL_ARRAY && ucl_object_type(set_obj) == UCL_ARRAY) { if (debug > 0) { fprintf(stderr, "Merging array of size %u with array of size %u\n", sub_obj->len, set_obj->len); } success = ucl_array_merge(sub_obj, set_obj, true); } else if (ucl_object_type(sub_obj) == UCL_ARRAY) { if (debug > 0) { fprintf(stderr, "Appending object to array of size %u\n", sub_obj->len); } success = ucl_array_append(sub_obj, ucl_object_ref(set_obj)); } else if (ucl_object_type(sub_obj) == UCL_OBJECT && ucl_object_type(set_obj) == UCL_OBJECT) { if (debug > 0) { fprintf(stderr, "Merging object %s with object %s\n", ucl_object_key(sub_obj), ucl_object_key(set_obj)); } /* XXX not supported: * success = ucl_object_merge(sub_obj, set_obj, false, true); */ /* Old non-recursive way */ /* success = ucl_object_merge(sub_obj, set_obj, false); */ success = merge_recursive(sub_obj, set_obj, false); } else if (ucl_object_type(sub_obj) != UCL_OBJECT && ucl_object_type(sub_obj) != UCL_ARRAY) { /* Create an explicit array */ if (debug > 0) { fprintf(stderr, "Creating an array and appended the new item\n"); } tmp_obj = ucl_object_typed_new(UCL_ARRAY); /* * Reference and Append the original scalar * The additional reference is required because the old object will be * unreferenced as part of the ucl_object_replace_key operation */ ucl_array_append(tmp_obj, ucl_object_ref(sub_obj)); /* Reference and Append the new scalar (unref in cleanup()) */ ucl_array_append(tmp_obj, ucl_object_ref(set_obj)); /* Replace the old object with the newly created one */ if (ucl_object_type(dst_obj) == UCL_ARRAY) { old_obj = ucl_array_replace_index(dst_obj, tmp_obj, ucl_array_index_of(dst_obj, sub_obj)); success = false; if (old_obj != NULL) { ucl_object_unref(old_obj); success = true; } } else { success = ucl_object_replace_key(dst_obj, tmp_obj, ucl_object_key(sub_obj), 0, true); } } else { if (debug > 0) { fprintf(stderr, "Merging object into key %s\n", ucl_object_key(sub_obj)); } success = ucl_object_insert_key_merged(dst_obj, ucl_object_ref(set_obj), ucl_object_key(sub_obj), 0, true); } return success; }