diff --git external/libucl/include/ucl.h external/libucl/include/ucl.h index 2bafb4d..b585be3 100644 --- external/libucl/include/ucl.h +++ external/libucl/include/ucl.h @@ -306,6 +306,19 @@ ucl_object_t* ucl_object_insert_key (ucl_object_t *top, ucl_object_t *elt, const char *key, size_t keylen, bool copy_key) UCL_WARN_UNUSED_RESULT; /** + * Insert a object 'elt' to the hash 'top' and associate it with key 'key', if the specified key exist, + * try to merge its content + * @param top destination object (will be created automatically if top is NULL) + * @param elt element to insert (must NOT be NULL) + * @param key key to associate with this object (either const or preallocated) + * @param keylen length of the key (or 0 for NULL terminated keys) + * @param copy_key make an internal copy of key + * @return new value of top object + */ +ucl_object_t* ucl_object_insert_key_merged (ucl_object_t *top, ucl_object_t *elt, + const char *key, size_t keylen, bool copy_key) UCL_WARN_UNUSED_RESULT; + +/** * Append an element to the array object * @param top destination object (will be created automatically if top is NULL) * @param eltelement to append (must NOT be NULL) diff --git external/libucl/src/ucl_emitter.c external/libucl/src/ucl_emitter.c index 2973f1d..c7d14dc 100644 --- external/libucl/src/ucl_emitter.c +++ external/libucl/src/ucl_emitter.c @@ -537,7 +537,7 @@ ucl_elt_array_write_yaml (ucl_object_t *obj, UT_string *buf, unsigned int tabs, ucl_add_tabs (buf, tabs, false); } - utstring_append_len (buf, ": [\n", 4); + utstring_append_len (buf, "[\n", 2); while (cur) { ucl_elt_write_yaml (cur, buf, tabs + 1, true, false, false); utstring_append_len (buf, ",\n", 2); diff --git external/libucl/src/ucl_hash.c external/libucl/src/ucl_hash.c index a2d0470..d644da4 100644 --- external/libucl/src/ucl_hash.c +++ external/libucl/src/ucl_hash.c @@ -66,7 +66,7 @@ ucl_hash_iterate (ucl_hash_t *hashlin, ucl_hash_iter_t *iter) ucl_hash_node_t *elt = *iter; if (elt == NULL) { - if (hashlin->buckets == NULL) { + if (hashlin == NULL || hashlin->buckets == NULL) { return NULL; } elt = hashlin->buckets; @@ -103,3 +103,15 @@ ucl_hash_search (ucl_hash_t* hashlin, const char *key, unsigned keylen) } return NULL; } + +void +ucl_hash_delete (ucl_hash_t* hashlin, ucl_object_t *obj) +{ + ucl_hash_node_t *found; + + HASH_FIND (hh, hashlin->buckets, obj->key, obj->keylen, found); + + if (found) { + HASH_DELETE (hh, hashlin->buckets, found); + } +} diff --git external/libucl/src/ucl_hash.h external/libucl/src/ucl_hash.h index 8c19382..5c9b851 100644 --- external/libucl/src/ucl_hash.h +++ external/libucl/src/ucl_hash.h @@ -65,6 +65,11 @@ void ucl_hash_destroy (ucl_hash_t* hashlin, ucl_hash_free_func *func); void ucl_hash_insert (ucl_hash_t* hashlin, ucl_object_t *obj, const char *key, unsigned keylen); /** + * Delete an element from the the hashtable. + */ +void ucl_hash_delete (ucl_hash_t* hashlin, ucl_object_t *obj); + +/** * Searches an element in the hashtable. */ ucl_object_t* ucl_hash_search (ucl_hash_t* hashlin, const char *key, unsigned keylen); diff --git external/libucl/src/ucl_util.c external/libucl/src/ucl_util.c index 6f235ae..422b2ea 100644 --- external/libucl/src/ucl_util.c +++ external/libucl/src/ucl_util.c @@ -62,7 +62,7 @@ ucl_object_free_internal (ucl_object_t *obj, bool allow_rec) } else if (obj->type == UCL_OBJECT) { if (obj->value.ov != NULL) { - ucl_hash_destroy (obj->value.ov, (ucl_hash_free_func *)ucl_obj_free); + ucl_hash_destroy (obj->value.ov, (ucl_hash_free_func *)ucl_object_unref); } } tmp = obj->next; @@ -858,11 +858,12 @@ ucl_object_fromstring_common (const char *str, size_t len, enum ucl_string_flags return obj; } -ucl_object_t * -ucl_object_insert_key (ucl_object_t *top, ucl_object_t *elt, - const char *key, size_t keylen, bool copy_key) +static ucl_object_t * +ucl_object_insert_key_common (ucl_object_t *top, ucl_object_t *elt, + const char *key, size_t keylen, bool copy_key, bool merge) { - ucl_object_t *found; + ucl_object_t *found, *cur; + ucl_object_iter_t it = NULL; const char *p; if (elt == NULL || key == NULL) { @@ -892,22 +893,62 @@ ucl_object_insert_key (ucl_object_t *top, ucl_object_t *elt, elt->key = key; elt->keylen = keylen; + if (copy_key) { + ucl_copy_key_trash (elt); + } + found = ucl_hash_search_obj (top->value.ov, elt); if (!found) { top->value.ov = ucl_hash_insert_object (top->value.ov, elt); + DL_APPEND (found, elt); } - - DL_APPEND (found, elt); - - if (copy_key) { - ucl_copy_key_trash (elt); + else if (!merge) { + DL_APPEND (found, elt); + } + else { + if (found->type != UCL_OBJECT && elt->type == UCL_OBJECT) { + /* Insert old elt to new one */ + elt = ucl_object_insert_key_common (elt, found, found->key, found->keylen, copy_key, false); + ucl_hash_delete (top->value.ov, found); + top->value.ov = ucl_hash_insert_object (top->value.ov, elt); + } + else if (found->type == UCL_OBJECT && elt->type != UCL_OBJECT) { + /* Insert new to old */ + found = ucl_object_insert_key_common (found, elt, elt->key, elt->keylen, copy_key, false); + } + else if (found->type == UCL_OBJECT && elt->type == UCL_OBJECT) { + /* Mix two hashes */ + while ((cur = ucl_iterate_object (elt, &it, true)) != NULL) { + ucl_object_ref (cur); + found = ucl_object_insert_key_common (found, cur, cur->key, cur->keylen, copy_key, false); + } + ucl_object_unref (elt); + } + else { + /* Just make a list of scalars */ + DL_APPEND (found, elt); + } } return top; } ucl_object_t * +ucl_object_insert_key (ucl_object_t *top, ucl_object_t *elt, + const char *key, size_t keylen, bool copy_key) +{ + return ucl_object_insert_key_common (top, elt, key, keylen, copy_key, false); +} + +ucl_object_t * +ucl_object_insert_key_merged (ucl_object_t *top, ucl_object_t *elt, + const char *key, size_t keylen, bool copy_key) +{ + return ucl_object_insert_key_common (top, elt, key, keylen, copy_key, true); +} + +ucl_object_t * ucl_obj_get_keyl (ucl_object_t *obj, const char *key, size_t klen) { ucl_object_t *ret, srch; diff --git libpkg/pkg_manifest.c libpkg/pkg_manifest.c index af07cc4..72f7f98 100644 --- libpkg/pkg_manifest.c +++ libpkg/pkg_manifest.c @@ -981,7 +981,8 @@ emit_manifest(struct pkg *pkg, char **out, short flags) } urlencode(pkg_script_get(pkg, i), &tmpsbuf); map = ucl_object_insert_key(map, - ucl_object_fromlstring(sbuf_data(tmpsbuf), sbuf_len(tmpsbuf)), + ucl_object_fromstring_common(sbuf_data(tmpsbuf), + sbuf_len(tmpsbuf), UCL_STRING_TRIM), script_types, 0, true); } obj = ucl_object_insert_key(top, map, "scripts", 7, false); @@ -991,7 +992,7 @@ emit_manifest(struct pkg *pkg, char **out, short flags) if (message != NULL && *message != '\0') { urlencode(message, &tmpsbuf); obj = ucl_object_insert_key(top, - ucl_object_fromlstring(sbuf_data(tmpsbuf), sbuf_len(tmpsbuf)), + ucl_object_fromstring_common(sbuf_data(tmpsbuf), sbuf_len(tmpsbuf), UCL_STRING_TRIM), "message", 7, false); } diff --git libpkg/pkgdb.c libpkg/pkgdb.c index b68c794..5b74878 100644 --- libpkg/pkgdb.c +++ libpkg/pkgdb.c @@ -639,7 +639,6 @@ pkgdb_init(sqlite3 *sdb) "CREATE INDEX deporigini on deps(origin);" "CREATE INDEX pkg_script_package_id ON pkg_script(package_id);" - "CREATE INDEX options_package_id ON options (package_id);" "CREATE INDEX deps_package_id ON deps (package_id);" "CREATE INDEX files_package_id ON files (package_id);" "CREATE INDEX pkg_directories_package_id ON pkg_directories (package_id);" diff --git pkg/Makefile pkg/Makefile index 187e92a..e7b8e54 100644 --- pkg/Makefile +++ pkg/Makefile @@ -150,24 +150,24 @@ fix-xrefs: .include -${PROG}: ${PROGNAME}-static +${PROG}: ${PROG}-static LDFLAGS_STATIC:= -static ${LDFLAGS} LDFLAGS+= -Wl,-rpath=/usr/lib:${PREFIX}/lib -${PROGNAME}-static: ${OBJS} +${PROG}-static: ${OBJS} ${CC} -static ${CFLAGS} ${LDFLAGS_STATIC} -o ${.TARGET} ${OBJS} ${LDADD} ${LDADD_STATIC} -realinstall: ${PROGNAME}-static-install +realinstall: ${PROG}-static-install -${PROGNAME}-static-install: +${PROG}-static-install: ${INSTALL} ${STRIP} -o ${BINOWN} -g ${BINGRP} -m ${BINMODE} \ - ${_INSTALLFLAGS} ${PROG}-static ${DESTDIR}${BINDIR}/${PROGNAME}-static + ${_INSTALLFLAGS} ${PROG}-static ${DESTDIR}${BINDIR}/${PROG}-static depend: staticdepend .ORDER: ${DEPENDFILE} staticdepend staticdepend: .if defined(DPADD_STATIC) && !empty(DPADD_STATIC) - echo ${PROGNAME}-static: ${DPADD_STATIC} >> ${DEPENDFILE} + echo ${PROG}-static: ${DPADD_STATIC} >> ${DEPENDFILE} .endif