Radish alpha
H
rad:z3QDZAW2FAfuLvihrhiyDC9fAD8G9
HardenedBSD Package Manager
Radicle
Git
Convert struct pkg to mostly be a ucl_object_t and chase libucl changes
Baptiste Daroussin committed 12 years ago
commit 3a72e6bd854bebd10d6f08497e4dea821fcca807
parent 05452d0
22 files changed +443 -378
modified libpkg/pkg.c
@@ -40,7 +40,7 @@
#include "private/pkg.h"
#include "private/utils.h"

-
static struct _fields {
+
/*static struct _fields {
	const char *human_desc;
	int type;
	int optional;
@@ -63,7 +63,7 @@ static struct _fields {
	[PKG_REPOURL] = {"repourl", PKG_REMOTE, 1},
	[PKG_DIGEST] = {"manifestdigest", PKG_REMOTE|PKG_INSTALLED, 1},
	[PKG_REASON] = {"reason", PKG_REMOTE, 1}
-
};
+
};*/

int
pkg_new(struct pkg **pkg, pkg_t type)
@@ -73,11 +73,8 @@ pkg_new(struct pkg **pkg, pkg_t type)
		return EPKG_FATAL;
	}

-
	(*pkg)->automatic = false;
-
	(*pkg)->locked = false;
-
	(*pkg)->direct = false;
+
	(*pkg)->fields = ucl_object_typed_new(UCL_OBJECT);
	(*pkg)->type = type;
-
	(*pkg)->licenselogic = LICENSE_SINGLE;

	return (EPKG_OK);
}
@@ -90,21 +87,11 @@ pkg_reset(struct pkg *pkg, pkg_t type)
	if (pkg == NULL)
		return;

-
	for (i = 0; i < PKG_NUM_FIELDS; i++)
-
		sbuf_reset(pkg->fields[i]);
+
	ucl_object_unref(pkg->fields);
+
	pkg->fields = ucl_object_typed_new(UCL_OBJECT);

	for (i = 0; i < PKG_NUM_SCRIPTS; i++)
		sbuf_reset(pkg->scripts[i]);
-

-
	pkg->flatsize = 0;
-
	pkg->old_flatsize = 0;
-
	pkg->pkgsize = 0;
-
	pkg->time = 0;
-
	pkg->flags = 0;
-
	pkg->automatic = false;
-
	pkg->locked = false;
-
	pkg->licenselogic = LICENSE_SINGLE;
-

	pkg_list_free(pkg, PKG_LICENSES);
	pkg_list_free(pkg, PKG_CATEGORIES);
	pkg_list_free(pkg, PKG_DEPS);
@@ -118,7 +105,6 @@ pkg_reset(struct pkg *pkg, pkg_t type)
	pkg_list_free(pkg, PKG_SHLIBS_PROVIDED);
	pkg_list_free(pkg, PKG_ANNOTATIONS);

-
	pkg->rowid = 0;
	pkg->type = type;
}

@@ -128,8 +114,7 @@ pkg_free(struct pkg *pkg)
	if (pkg == NULL)
		return;

-
	for (int i = 0; i < PKG_NUM_FIELDS; i++)
-
		sbuf_free(pkg->fields[i]);
+
	ucl_object_unref(pkg->fields);

	for (int i = 0; i < PKG_NUM_SCRIPTS; i++)
		sbuf_free(pkg->scripts[i]);
@@ -161,25 +146,11 @@ pkg_type(const struct pkg * restrict pkg)
int
pkg_is_valid(const struct pkg * restrict pkg)
{
-
	int i;
-

	if (pkg->type == 0) {
		pkg_emit_error("package type undefined");
		return (EPKG_FATAL);
	}

-
	/* Ensure that required fields are set. */
-
	for (i = 0; i < PKG_NUM_FIELDS; i++) {
-
		if ((fields[i].type & pkg->type) == 0 ||
-
		    fields[i].optional ||
-
		    (pkg->fields[i] != NULL &&
-
		    sbuf_len(pkg->fields[i]) > 0))
-
			continue;
-
		pkg_emit_error("package field incomplete: %s",
-
		    fields[i].human_desc);
-
		return (EPKG_FATAL);
-
	}
-

	return (EPKG_OK);
}

@@ -187,38 +158,37 @@ static int
pkg_vget(const struct pkg * restrict pkg, va_list ap)
{
	int attr;
+
	const ucl_object_t *obj;

	while ((attr = va_arg(ap, int)) > 0) {
-
		if (attr < PKG_NUM_FIELDS) {
-
			const char **var = va_arg(ap, const char **);
-
			*var = (pkg->fields[attr] != NULL) ?
-
			    sbuf_get(pkg->fields[attr]) : NULL;
-
			continue;
+

+
		if (attr >= PKG_NUM_FIELDS || attr <= 0) {
+
			pkg_emit_error("Bad argument on pkg_get");
+
			return (EPKG_FATAL);
		}
-
		switch (attr) {
-
		case PKG_FLATSIZE:
-
			*va_arg(ap, int64_t *) = pkg->flatsize;
-
			break;
-
		case PKG_OLD_FLATSIZE:
-
			*va_arg(ap, int64_t *) = pkg->old_flatsize;
-
			break;
-
		case PKG_PKGSIZE:
-
			*va_arg(ap, int64_t *) = pkg->pkgsize;
-
			break;
-
		case PKG_LICENSE_LOGIC:
-
			*va_arg(ap, lic_t *) = pkg->licenselogic;
-
			break;
-
		case PKG_AUTOMATIC:
-
			*va_arg(ap, bool *) = pkg->automatic;
-
			break;
-
		case PKG_LOCKED:
-
			*va_arg(ap, bool *) = pkg->locked;
+

+
		obj = ucl_object_find_key(pkg->fields, pkg_keys[attr].name);
+
		switch (pkg_keys[attr].type) {
+
		case UCL_STRING:
+
			if (obj == NULL) {
+
				*va_arg(ap, const char **) = NULL;
+
				break;
+
			}
+
			*va_arg(ap, const char **) = ucl_object_tostring_forced(obj);
			break;
-
		case PKG_TIME:
-
			*va_arg(ap, int64_t *) = pkg->time;
+
		case UCL_BOOLEAN:
+
			if (obj == NULL) {
+
				*va_arg(ap, bool *) = false;
+
				break;
+
			}
+
			*va_arg(ap, bool *) = ucl_object_toboolean(obj);
			break;
-
		case PKG_ROWID:
-
			*va_arg(ap, int64_t *) = pkg->rowid;
+
		case UCL_INT:
+
			if (obj == NULL) {
+
				*va_arg(ap, int64_t *) = 0;
+
				break;
+
			}
+
			*va_arg(ap, int64_t *) = ucl_object_toint(obj);
			break;
		default:
			va_arg(ap, void *); /* ignore */
@@ -244,73 +214,64 @@ pkg_get2(const struct pkg * restrict pkg, ...)
	return (ret);
}

-
static void
-
pkg_set_repourl(struct pkg *pkg, const char *str)
-
{
-
	struct pkg_repo *r;
-

-
	r = pkg_repo_find_ident(str);
-
	if (r != NULL)
-
		pkg_set(pkg, PKG_REPOURL, pkg_repo_url(r));
-
}
-

static int
pkg_vset(struct pkg *pkg, va_list ap)
{
	int attr;
+
	struct pkg_repo *r;
+
	char *buf = NULL;
+
	const char *data;
+
	const char *str;
+


	while ((attr = va_arg(ap, int)) > 0) {
-
		if (attr < PKG_NUM_FIELDS) {
-
			struct sbuf **sbuf;
-
			const char *str = va_arg(ap, const char *);
+
		if (attr >= PKG_NUM_FIELDS || attr <= 0) {
+
			pkg_emit_error("Bad argument on pkg_get");
+
			return (EPKG_FATAL);
+
		}
+

+
		switch (pkg_keys[attr].type) {
+
		case UCL_STRING:
+
			str = va_arg(ap, const char *);
+
			data = str;

-
			if (str == NULL) {
-
				pkg->fields[attr] = NULL;
-
				continue;
+
			if (attr == PKG_MTREE && !STARTS_WITH(str, "#mtree")) {
+
				asprintf(&buf, "#mtree\n%s", str);
+
				data = buf;
			}

-
			sbuf = &pkg->fields[attr];
+
			if (attr == PKG_REPOURL) {
+
				r = pkg_repo_find_ident(str);
+
				if (r == NULL)
+
					break;
+
				data = pkg_repo_url(r);
+
			}

-
			if (attr == PKG_MTREE && !STARTS_WITH(str, "#mtree")) {
-
				sbuf_set(sbuf, "#mtree\n");
-
				sbuf_cat(*sbuf, str);
-
				sbuf_finish(*sbuf);
-
				continue;
+
			if (!ucl_object_replace_key(pkg->fields,
+
			    ucl_object_fromstring_common(data, strlen(data), 0),
+
			    pkg_keys[attr].name, strlen(pkg_keys[attr].name), false)) {
+
				if (buf != NULL)
+
					free(buf);
+
				return (EPKG_FATAL);
			}

-
			if (attr == PKG_REPOURL)
-
				pkg_set_repourl(pkg, str);
+
			if (buf != NULL)
+
				free(buf);

-
			sbuf_set(sbuf, str);
-
			continue;
-
		}
-
		switch (attr) {
-
		case PKG_AUTOMATIC:
-
			pkg->automatic = (int)va_arg(ap, int64_t);
-
			break;
-
		case PKG_LOCKED:
-
			pkg->locked = (bool)va_arg(ap, int64_t);
			break;
-
		case PKG_LICENSE_LOGIC:
-
			pkg->licenselogic = (lic_t)va_arg(ap, int64_t);
-
			break;
-
		case PKG_FLATSIZE:
-
			pkg->flatsize = va_arg(ap, int64_t);
-
			break;
-
		case PKG_OLD_FLATSIZE:
-
			pkg->old_flatsize = va_arg(ap, int64_t);
-
			break;
-
		case PKG_PKGSIZE:
-
			pkg->pkgsize = va_arg(ap, int64_t);
-
			break;
-
		case PKG_TIME:
-
			pkg->time = va_arg(ap, int64_t);
+
		case UCL_BOOLEAN:
+
			if (!ucl_object_replace_key(pkg->fields,
+
			    ucl_object_frombool((bool)va_arg(ap, int64_t)),
+
			    pkg_keys[attr].name, strlen(pkg_keys[attr].name), false))
+
				return (EPKG_FATAL);
			break;
-
		case PKG_ROWID:
-
			pkg->rowid = va_arg(ap, int64_t);
+
		case UCL_INT:
+
			if (!ucl_object_replace_key(pkg->fields,
+
			    ucl_object_fromint(va_arg(ap, int64_t)),
+
			    pkg_keys[attr].name, strlen(pkg_keys[attr].name), false))
+
				return (EPKG_FATAL);
			break;
		default:
-
			/* XXX emit an error? */
			(void) va_arg(ap, void *);
			break;
		}
@@ -467,19 +428,12 @@ pkg_provides(const struct pkg *pkg, struct pkg_provide **c)
int
pkg_addlicense(struct pkg *pkg, const char *name)
{
-
	pkg_object *o = NULL;
+
	const pkg_object *o;
+
	pkg_object *l;
	pkg_iter iter = NULL;

	assert(pkg != NULL);
	assert(name != NULL && name[0] != '\0');
-
	const char *pkgname;
-

-
	if (pkg->licenselogic == LICENSE_SINGLE && UCL_COUNT(pkg->licenses) != 0) {
-
		pkg_get(pkg, PKG_NAME, &pkgname);
-
		pkg_emit_error("%s have a single license which is already set",
-
		    pkgname);
-
		return (EPKG_FATAL);
-
	}

	while ((o = pkg_object_iterate(pkg->licenses, &iter))) {
		if (strcmp(pkg_object_string(o), name) == 0) {
@@ -493,8 +447,10 @@ pkg_addlicense(struct pkg *pkg, const char *name)
		}
	}

-
	o = ucl_object_fromstring_common(name, strlen(name), 0);
-
	pkg->licenses = ucl_array_append(pkg->licenses, o);
+
	l = ucl_object_fromstring_common(name, strlen(name), 0);
+
	if (pkg->licenses == NULL)
+
		pkg->licenses = ucl_object_typed_new(UCL_ARRAY);
+
	ucl_array_append(pkg->licenses, l);

	return (EPKG_OK);
}
@@ -691,7 +647,8 @@ pkg_addfile_attr(struct pkg *pkg, const char *path, const char *sha256, const ch
int
pkg_addcategory(struct pkg *pkg, const char *name)
{
-
	pkg_object *o = NULL;
+
	const pkg_object *o;
+
	pkg_object *c;
	pkg_iter iter = NULL;

	assert(pkg != NULL);
@@ -709,8 +666,10 @@ pkg_addcategory(struct pkg *pkg, const char *name)
		}
	}

-
	o = ucl_object_fromstring_common(name, strlen(name), 0);
-
	pkg->categories = ucl_array_append(pkg->categories, o);
+
	c = ucl_object_fromstring_common(name, strlen(name), 0);
+
	if (pkg->categories == NULL)
+
		pkg->categories = ucl_object_typed_new(UCL_ARRAY);
+
	ucl_array_append(pkg->categories, c);

	return (EPKG_OK);
}
@@ -1065,7 +1024,8 @@ pkg_addprovide(struct pkg *pkg, const char *name)
int
pkg_addannotation(struct pkg *pkg, const char *tag, const char *value)
{
-
	ucl_object_t *an;
+
	const ucl_object_t *an;
+
	ucl_object_t *o;

	assert(pkg != NULL);
	assert(tag != NULL);
@@ -1085,14 +1045,15 @@ pkg_addannotation(struct pkg *pkg, const char *tag, const char *value)
			return (EPKG_OK);
		}
	}
-
	an = ucl_object_fromstring_common(value, strlen(value), 0);
-
	pkg->annotations = ucl_object_insert_key(pkg->annotations,
-
	    an, tag, strlen(tag), true);
+
	o = ucl_object_fromstring_common(value, strlen(value), 0);
+
	if (pkg->annotations == NULL)
+
		pkg->annotations = ucl_object_typed_new(UCL_OBJECT);
+
	ucl_object_insert_key(pkg->annotations, o, tag, strlen(tag), true);

	return (EPKG_OK);
}

-
pkg_object *
+
const pkg_object *
pkg_licenses(const struct pkg *pkg)
{
	assert (pkg != NULL);
@@ -1100,7 +1061,7 @@ pkg_licenses(const struct pkg *pkg)
	return (pkg->licenses);
}

-
pkg_object *
+
const pkg_object *
pkg_categories(const struct pkg *pkg)
{
	assert (pkg != NULL);
@@ -1108,7 +1069,7 @@ pkg_categories(const struct pkg *pkg)
	return (pkg->categories);
}

-
pkg_object *
+
const pkg_object *
pkg_annotations(const struct pkg *pkg)
{
	assert(pkg != NULL);
@@ -1116,7 +1077,7 @@ pkg_annotations(const struct pkg *pkg)
	return (pkg->annotations);
}

-
pkg_object *
+
const pkg_object *
pkg_annotation_lookup(const struct pkg *pkg, const char *tag)
{
	assert(pkg != NULL);
@@ -1292,17 +1253,17 @@ int
pkg_open2(struct pkg **pkg_p, struct archive **a, struct archive_entry **ae,
    const char *path, struct pkg_manifest_key *keys, int flags, int fd)
{
-
	struct pkg	 *pkg;
-
	pkg_error_t	  retcode = EPKG_OK;
-
	int		  ret;
-
	const char	 *fpath;
-
	bool		  manifest = false;
-
	const void	 *buf;
-
	size_t		  size;
-
	off_t		  offset = 0;
-
	struct sbuf	**sbuf;
-
	int		  i, r;
-
	bool		  read_from_stdin = 0;
+
	struct pkg	*pkg;
+
	pkg_error_t	 retcode = EPKG_OK;
+
	int		 ret;
+
	const char	*fpath;
+
	bool		 manifest = false;
+
	const void	*buf;
+
	size_t		 size;
+
	off_t		 offset = 0;
+
	struct sbuf	*sbuf;
+
	int		 i, r;
+
	bool		 read_from_stdin = 0;

	struct {
		const char *name;
@@ -1392,13 +1353,12 @@ pkg_open2(struct pkg **pkg_p, struct archive **a, struct archive_entry **ae,

		for (i = 0; files[i].name != NULL; i++) {
			if (strcmp(fpath, files[i].name) == 0) {
-
				sbuf = &pkg->fields[files[i].attr];
-
				sbuf_init(sbuf);
+
				sbuf = sbuf_new_auto();
				offset = 0;
				for (;;) {
					if ((r = archive_read_data_block(*a, &buf,
							&size, &offset)) == 0) {
-
						sbuf_bcat(*sbuf, buf, size);
+
						sbuf_bcat(sbuf, buf, size);
					}
					else {
						if (r == ARCHIVE_FATAL) {
@@ -1412,7 +1372,9 @@ pkg_open2(struct pkg **pkg_p, struct archive **a, struct archive_entry **ae,
							break;
					}
				}
-
				sbuf_finish(*sbuf);
+
				sbuf_finish(sbuf);
+
				pkg_set(pkg, PKG_MTREE, sbuf_data(sbuf));
+
				sbuf_delete(sbuf);
			}
		}
	}
@@ -1454,7 +1416,7 @@ pkg_copy_tree(struct pkg *pkg, const char *src, const char *dest)
	char dpath[MAXPATHLEN];
	const char *prefix;
	char *mtree;
-
	pkg_object *o;
+
	const pkg_object *o;

	o = pkg_config_get("DISABLE_MTREE");
	if (o && !pkg_object_bool(o)) {
@@ -1606,9 +1568,13 @@ pkg_has_message(struct pkg *p)
bool
pkg_is_locked(const struct pkg * restrict p)
{
+
	bool ret;
+

	assert(p != NULL);

-
	return (p->locked);
+
	pkg_get(p, PKG_LOCKED, &ret);
+

+
	return (ret);
}

bool
modified libpkg/pkg.h.in
@@ -238,15 +238,15 @@ typedef enum {
	PKG_REPOURL,
	PKG_DIGEST,
	PKG_REASON,
-
	PKG_NUM_FIELDS, 	/* end of fields */
-
	PKG_FLATSIZE = 64U,
+
	PKG_FLATSIZE,
	PKG_OLD_FLATSIZE,
	PKG_PKGSIZE,
	PKG_LICENSE_LOGIC,
	PKG_AUTOMATIC,
	PKG_LOCKED,
	PKG_ROWID,
-
	PKG_TIME
+
	PKG_TIME,
+
	PKG_NUM_FIELDS, 	/* end of fields */
} pkg_attr;

typedef enum {
@@ -580,8 +580,8 @@ int pkg_files(const struct pkg *, struct pkg_file **file);
 */
int pkg_dirs(const struct pkg *pkg, struct pkg_dir **dir);

-
pkg_object *pkg_categories(const struct pkg *pkg);
-
pkg_object *pkg_licenses(const struct pkg *pkg);
+
const pkg_object *pkg_categories(const struct pkg *pkg);
+
const pkg_object *pkg_licenses(const struct pkg *pkg);

/**
 * Iterates over the users of the package.
@@ -637,8 +637,8 @@ int pkg_provides(const struct pkg *pkg, struct pkg_provide **provide);
 * @param note must be set to NULL for the first call.
 * @return An error code
 */
-
pkg_object *pkg_annotation_lookup(const struct pkg *p, const char *tag);
-
pkg_object *pkg_annotations(const struct pkg *p);
+
const pkg_object *pkg_annotation_lookup(const struct pkg *p, const char *tag);
+
const pkg_object *pkg_annotations(const struct pkg *p);

/**
 * Iterate over all of the files within the package pkg, ensuring the
@@ -1282,7 +1282,7 @@ const char *pkg_plugin_get(struct pkg_plugin *p, pkg_plugin_key key);
void *pkg_plugin_func(struct pkg_plugin *p, const char *func);

int pkg_plugin_conf_add(struct pkg_plugin *p, pkg_object_t type, const char *key, const char *def);
-
pkg_object *pkg_plugin_conf(struct pkg_plugin *p);
+
const pkg_object *pkg_plugin_conf(struct pkg_plugin *p);

int pkg_plugin_parse(struct pkg_plugin *p);
void pkg_plugin_errno(struct pkg_plugin *p, const char *func, const char *arg);
@@ -1300,17 +1300,17 @@ int pkg_plugin_hook_register(struct pkg_plugin *p, pkg_plugin_hook_t hook, pkg_p
 * Get the value of a configuration key
 */

-
pkg_object *pkg_conf(void);
-
pkg_object *pkg_config_get(const char *);
-
pkg_object_t pkg_object_type(pkg_object *);
-
int64_t pkg_object_int(pkg_object *o);
-
bool pkg_object_bool(pkg_object *o);
-
const char *pkg_object_string(pkg_object *o);
+
const pkg_object *pkg_conf(void);
+
const pkg_object *pkg_config_get(const char *);
+
pkg_object_t pkg_object_type(const pkg_object *);
+
int64_t pkg_object_int(const pkg_object *o);
+
bool pkg_object_bool(const pkg_object *o);
+
const char *pkg_object_string(const pkg_object *o);
void pkg_object_free(pkg_object *o);
-
const char *pkg_object_key(pkg_object *);
-
pkg_object *pkg_object_iterate(pkg_object *, pkg_iter *);
-
unsigned pkg_object_count(pkg_object *);
-
const char *pkg_object_dump(pkg_object *o);
+
const char *pkg_object_key(const pkg_object *);
+
const pkg_object *pkg_object_iterate(const pkg_object *, pkg_iter *);
+
unsigned pkg_object_count(const pkg_object *);
+
const char *pkg_object_dump(const pkg_object *o);
const char *pkg_config_dump(void);

/**
modified libpkg/pkg_config.c
@@ -349,7 +349,7 @@ pkg_initialized(void)
	return (parsed);
}

-
pkg_object *
+
const pkg_object *
pkg_config_get(const char *key) {
	return (ucl_object_find_key(config, key));
}
@@ -369,7 +369,7 @@ disable_plugins_if_static(void)

	/* if dlh is NULL then we are in static binary */
	if (dlh == NULL)
-
		config = ucl_object_replace_key(config, ucl_object_frombool(false), "ENABLE_PLUGINS", 14, false);
+
		ucl_object_replace_key(config, ucl_object_frombool(false), "ENABLE_PLUGINS", 14, false);
	else
		dlclose(dlh);

@@ -377,9 +377,10 @@ disable_plugins_if_static(void)
}

static void
-
add_repo(ucl_object_t *obj, struct pkg_repo *r, const char *rname)
+
add_repo(const ucl_object_t *obj, struct pkg_repo *r, const char *rname)
{
-
	ucl_object_t *cur, *tmp = NULL;
+
	const ucl_object_t *cur;
+
	ucl_object_t *tmp = NULL;
	ucl_object_iter_t it = NULL;
	bool enable = true;
	const char *url = NULL, *pubkey = NULL, *mirror_type = NULL;
@@ -494,9 +495,9 @@ add_repo(ucl_object_t *obj, struct pkg_repo *r, const char *rname)
}

static void
-
walk_repo_obj(ucl_object_t *obj, const char *file)
+
walk_repo_obj(const ucl_object_t *obj, const char *file)
{
-
	ucl_object_t *cur;
+
	const ucl_object_t *cur;
	ucl_object_iter_t it = NULL;
	struct pkg_repo *r;
	const char *key;
@@ -595,7 +596,7 @@ load_repo_files(const char *repodir)
static void
load_repositories(const char *repodir)
{
-
	pkg_object *reposlist, *cur;
+
	const pkg_object *reposlist, *cur;
	pkg_iter it = NULL;

	if (repodir != NULL) {
@@ -642,7 +643,8 @@ pkg_init(const char *path, const char *reposdir)
	const char *evkey = NULL;
	const char *nsname = NULL;
	const char *evpipe = NULL;
-
	ucl_object_t *obj = NULL, *cur, *o, *ncfg;
+
	const ucl_object_t *cur, *object;
+
	ucl_object_t *obj = NULL, *o, *ncfg;
	ucl_object_iter_t it = NULL;
	struct sbuf *ukey = NULL;

@@ -652,29 +654,29 @@ pkg_init(const char *path, const char *reposdir)
		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);
-
			config = ucl_object_insert_key(config, obj,
+
			ucl_object_insert_key(config, obj,
			    c[i].key, strlen(c[i].key), false);
			break;
		case PKG_INT:
-
			config = ucl_object_insert_key(config,
+
			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:
-
			config = ucl_object_insert_key(config,
+
			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 = NULL;
-
			if (c[i].def == NULL) {
-
				obj = ucl_object_typed_new(UCL_OBJECT);
-
			} else {
+
			obj = ucl_object_typed_new(UCL_OBJECT);
+
			if (c[i].def != NULL) {
				walk = buf = c[i].def;
				while ((buf = strchr(buf, ',')) != NULL) {
					key = walk;
@@ -684,7 +686,7 @@ pkg_init(const char *path, const char *reposdir)
							break;
						value++;
					}
-
					obj = ucl_object_insert_key(obj,
+
					ucl_object_insert_key(obj,
					    ucl_object_fromstring_common(value + 1, buf - value - 1, UCL_STRING_TRIM),
					    key, value - key, false);
					buf++;
@@ -697,29 +699,29 @@ pkg_init(const char *path, const char *reposdir)
						break;
					value++;
				}
-
				o = ucl_object_insert_key(o,
+
				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);
+
				    key, value - key, false);
			}
-
			config = ucl_object_insert_key(config, obj,
+
			ucl_object_insert_key(config, obj,
			    c[i].key, strlen(c[i].key), false);
			break;
		case PKG_ARRAY:
-
			obj = NULL;
-
			if (c[i].def == NULL) {
-
				obj = ucl_object_typed_new(UCL_ARRAY);
-
			} else {
+
			obj = ucl_object_typed_new(UCL_ARRAY);
+
			if (c[i].def != NULL) {
				walk = buf = c[i].def;
				while ((buf = strchr(buf, ',')) != NULL) {
-
					obj = ucl_array_append(obj,
+
					ucl_array_append(obj,
					    ucl_object_fromstring_common(walk, buf - walk, UCL_STRING_TRIM));
					buf++;
					walk = buf;
				}
-
				obj = ucl_array_append(obj,
+
				ucl_array_append(obj,
				    ucl_object_fromstring_common(walk, strlen(walk), UCL_STRING_TRIM));
			}
-
			config = ucl_object_insert_key(config, obj,
+
			ucl_object_insert_key(config, obj,
			    c[i].key, strlen(c[i].key), false);
			break;
		}
@@ -747,24 +749,26 @@ pkg_init(const char *path, const char *reposdir)
		for (i = 0; key[i] != '\0'; i++)
			sbuf_putc(ukey, toupper(key[i]));
		sbuf_done(ukey);
-
		o = ucl_object_find_keyl(config, sbuf_data(ukey), sbuf_len(ukey));
+
		object = ucl_object_find_keyl(config, sbuf_data(ukey), sbuf_len(ukey));
		/* ignore unknown keys */
-
		if (o == NULL)
+
		if (object == NULL)
			continue;

-
		if (o->type != cur->type) {
+
		if (object->type != cur->type) {
			pkg_emit_error("Malformed key %s, ignoring", key);
			continue;
		}

-
		ncfg = ucl_object_insert_key(ncfg, ucl_object_ref(cur), key, strlen(key), false);
+
		if (ncfg == NULL)
+
			ncfg = ucl_object_typed_new(UCL_OBJECT);
+
		ucl_object_insert_key(ncfg, ucl_object_ref(cur), key, strlen(key), false);
	}

	if (ncfg != NULL) {
		it = NULL;
		while (( cur = ucl_iterate_object(ncfg, &it, true))) {
			key = ucl_object_key(cur);
-
			config = ucl_object_replace_key(config, ucl_object_ref(cur), key, strlen(key), false);
+
			ucl_object_replace_key(config, ucl_object_ref(cur), key, strlen(key), false);
		}
		ucl_object_unref(ncfg);
	}
@@ -802,6 +806,7 @@ pkg_init(const char *path, const char *reposdir)
			}
			break;
		case UCL_OBJECT:
+
			o = ucl_object_typed_new(UCL_OBJECT);
			walk = buf = val;
			while ((buf = strchr(buf, ',')) != NULL) {
				k = walk;
@@ -811,7 +816,7 @@ pkg_init(const char *path, const char *reposdir)
						break;
					value++;
				}
-
				o = ucl_object_insert_key(o,
+
				ucl_object_insert_key(o,
				    ucl_object_fromstring_common(value + 1, buf - value - 1, UCL_STRING_TRIM),
				    k, value - k, false);
				buf++;
@@ -824,34 +829,38 @@ pkg_init(const char *path, const char *reposdir)
					break;
				value++;
			}
-
			o = ucl_object_insert_key(o,
+
			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) {
-
				o = ucl_array_append(o,
+
				ucl_array_append(o,
				    ucl_object_fromstring_common(walk, buf - walk, UCL_STRING_TRIM));
				buf++;
				walk = buf;
			}
-
			o = ucl_array_append(o,
+
			ucl_array_append(o,
			    ucl_object_fromstring_common(walk, strlen(walk), UCL_STRING_TRIM));
			break;
		default:
			/* ignore other types */
			break;
		}
-
		if (o != NULL)
-
			ncfg = ucl_object_insert_key(ncfg, o, key, strlen(key), true);
+
		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);
-
			config = ucl_object_replace_key(config, ucl_object_ref(cur), key, strlen(key), false);
+
			ucl_object_replace_key(config, ucl_object_ref(cur), key, strlen(key), false);
		}
		ucl_object_unref(ncfg);
	}
@@ -870,7 +879,7 @@ pkg_init(const char *path, const char *reposdir)
		connect_evpipe(evpipe);

	it = NULL;
-
	o = ucl_object_find_key(config, "PKG_ENV");
+
	object = ucl_object_find_key(config, "PKG_ENV");
	while ((cur = ucl_iterate_object(o, &it, true))) {
		evkey = ucl_object_key(cur);
		if (evkey != NULL && evkey[0] != '\0')
modified libpkg/pkg_create.c
@@ -54,7 +54,7 @@ pkg_create_from_dir(struct pkg *pkg, const char *root,
	struct stat	 st;
	char		 sha256[SHA256_DIGEST_LENGTH * 2 + 1];
	int64_t		 flatsize = 0;
-
	ucl_object_t	*obj;
+
	const ucl_object_t	*obj;

	if (pkg_is_valid(pkg) != EPKG_OK) {
		pkg_emit_error("the package is not valid");
modified libpkg/pkg_delete.c
@@ -144,7 +144,7 @@ pkg_delete_files(struct pkg *pkg, unsigned force)

	while (pkg_files(pkg, &file) == EPKG_OK) {
		const char *sum = pkg_file_cksum(file);
-
		ucl_object_t *obj;
+
		const ucl_object_t *obj;

		if (file->keep == 1)
			continue;
@@ -179,9 +179,9 @@ pkg_delete_files(struct pkg *pkg, unsigned force)
int
pkg_delete_dirs(__unused struct pkgdb *db, struct pkg *pkg, bool force)
{
-
	struct pkg_dir	*dir = NULL;
-
	ucl_object_t *obj;
-
	char		fpath[MAXPATHLEN];
+
	struct pkg_dir		*dir = NULL;
+
	const ucl_object_t 	*obj;
+
	char			 fpath[MAXPATHLEN];

	while (pkg_dirs(pkg, &dir) == EPKG_OK) {
		if (dir->keep == 1)
modified libpkg/pkg_jobs.c
@@ -836,11 +836,13 @@ pkg_jobs_test_automatic(struct pkg_jobs *j, struct pkg *p)
	struct pkg_job_universe_item *unit;
	struct pkg *npkg;
	bool ret = true;
+
	bool automatic;

	while (pkg_rdeps(p, &d) == EPKG_OK && ret) {
		HASH_FIND_STR(j->universe, pkg_dep_get(d, PKG_DEP_ORIGIN), unit);
		if (unit != NULL) {
-
			if (!unit->pkg->automatic) {
+
			pkg_get(unit->pkg, PKG_AUTOMATIC, &automatic);
+
			if (!automatic) {
				return (false);
			}
			npkg = unit->pkg;
@@ -848,9 +850,10 @@ pkg_jobs_test_automatic(struct pkg_jobs *j, struct pkg *p)
		else {
			npkg = get_local_pkg(j, pkg_dep_get(d, PKG_DEP_ORIGIN),
					PKG_LOAD_BASIC|PKG_LOAD_RDEPS);
+
			pkg_get(npkg, PKG_AUTOMATIC, &automatic);
			if (npkg == NULL)
				return (false);
-
			if (!npkg->automatic) {
+
			if (!automatic) {
				pkg_free(npkg);
				return (false);
			}
@@ -1233,7 +1236,7 @@ static bool
newer_than_local_pkg(struct pkg_jobs *j, struct pkg *rp, bool force)
{
	char *origin, *newversion, *oldversion, *reponame;
-
	ucl_object_t *an;
+
	const ucl_object_t *an;
	int64_t oldsize;
	struct pkg *lp;
	bool automatic;
@@ -1846,7 +1849,7 @@ pkg_jobs_handle_install(struct pkg_solved *ps, struct pkg_jobs *j, bool handle_r
{
	struct pkg *new, *old;
	const char *pkgorigin, *oldversion = NULL;
-
	ucl_object_t *an;
+
	const ucl_object_t *an;
	char path[MAXPATHLEN], *target;
	bool automatic = false;
	int flags = 0;
modified libpkg/pkg_manifest.c
@@ -60,13 +60,13 @@
#define PKG_CONFLICTS		-17
#define PKG_PROVIDES		-18

-
static int pkg_string(struct pkg *, ucl_object_t *, int);
-
static int pkg_obj(struct pkg *, ucl_object_t *, int);
-
static int pkg_array(struct pkg *, ucl_object_t *, int);
-
static int pkg_int(struct pkg *, ucl_object_t *, int);
-
static int pkg_set_deps_from_object(struct pkg *, ucl_object_t *);
-
static int pkg_set_files_from_object(struct pkg *, ucl_object_t *);
-
static int pkg_set_dirs_from_object(struct pkg *, ucl_object_t *);
+
static int pkg_string(struct pkg *, const ucl_object_t *, int);
+
static int pkg_obj(struct pkg *, const ucl_object_t *, int);
+
static int pkg_array(struct pkg *, const ucl_object_t *, int);
+
static int pkg_int(struct pkg *, const ucl_object_t *, int);
+
static int pkg_set_deps_from_object(struct pkg *, const ucl_object_t *);
+
static int pkg_set_files_from_object(struct pkg *, const ucl_object_t *);
+
static int pkg_set_dirs_from_object(struct pkg *, const ucl_object_t *);

/*
 * Keep sorted
@@ -75,7 +75,7 @@ static struct manifest_key {
	const char *key;
	int type;
	enum ucl_type valid_type;
-
	int (*parse_data)(struct pkg *, ucl_object_t *, int);
+
	int (*parse_data)(struct pkg *, const ucl_object_t *, int);
} manifest_keys[] = {
	{ "annotations",         PKG_ANNOTATIONS,         UCL_OBJECT, pkg_obj},
	{ "arch",                PKG_ARCH,                UCL_STRING, pkg_string},
@@ -119,7 +119,7 @@ static struct manifest_key {

struct dataparser {
	enum ucl_type type;
-
	int (*parse_data)(struct pkg *, ucl_object_t *, int);
+
	int (*parse_data)(struct pkg *, const ucl_object_t *, int);
	UT_hash_handle hh;
};

@@ -262,10 +262,12 @@ script_type_str(const char *str)
}

static int
-
pkg_string(struct pkg *pkg, ucl_object_t *obj, int attr)
+
pkg_string(struct pkg *pkg, const ucl_object_t *obj, int attr)
{
	int ret = EPKG_OK;
	const char *str;
+
	struct sbuf *buf = NULL;
+

	str = ucl_object_tostring_forced(obj);

	switch (attr)
@@ -285,10 +287,14 @@ pkg_string(struct pkg *pkg, ucl_object_t *obj, int attr)
		}
		break;
	default:
-
		if (attr == PKG_DESC)
-
			ret = urldecode(str, &pkg->fields[attr]);
-
		else
-
			ret = pkg_set(pkg, attr, str);
+
		if (attr == PKG_DESC) {
+
			urldecode(str, &buf);
+
			sbuf_finish(buf);
+
			str = sbuf_data(buf);
+
		}
+
		ret = pkg_set(pkg, attr, str);
+
		if (buf != NULL)
+
			sbuf_delete(buf);
		break;
	}

@@ -296,15 +302,15 @@ pkg_string(struct pkg *pkg, ucl_object_t *obj, int attr)
}

static int
-
pkg_int(struct pkg *pkg, ucl_object_t *obj, int attr)
+
pkg_int(struct pkg *pkg, const ucl_object_t *obj, int attr)
{
	return (pkg_set(pkg, attr, ucl_object_toint(obj)));
}

static int
-
pkg_array(struct pkg *pkg, ucl_object_t *obj, int attr)
+
pkg_array(struct pkg *pkg, const ucl_object_t *obj, int attr)
{
-
	ucl_object_t *cur;
+
	const ucl_object_t *cur;
	ucl_object_iter_t it = NULL;

	pkg_debug(3, "%s", "Manifest: parsing array");
@@ -377,10 +383,10 @@ pkg_array(struct pkg *pkg, ucl_object_t *obj, int attr)
}

static int
-
pkg_obj(struct pkg *pkg, ucl_object_t *obj, int attr)
+
pkg_obj(struct pkg *pkg, const ucl_object_t *obj, int attr)
{
	struct sbuf *tmp = NULL;
-
	ucl_object_t *cur;
+
	const ucl_object_t *cur;
	ucl_object_iter_t it = NULL;
	pkg_script script_type;
	const char *key, *buf;
@@ -503,9 +509,9 @@ pkg_obj(struct pkg *pkg, ucl_object_t *obj, int attr)
}

static int
-
pkg_set_files_from_object(struct pkg *pkg, ucl_object_t *obj)
+
pkg_set_files_from_object(struct pkg *pkg, const ucl_object_t *obj)
{
-
	ucl_object_t *cur;
+
	const ucl_object_t *cur;
	ucl_object_iter_t it = NULL;
	const char *sum = NULL;
	const char *uname = NULL;
@@ -550,9 +556,9 @@ pkg_set_files_from_object(struct pkg *pkg, ucl_object_t *obj)
}

static int
-
pkg_set_dirs_from_object(struct pkg *pkg, ucl_object_t *obj)
+
pkg_set_dirs_from_object(struct pkg *pkg, const ucl_object_t *obj)
{
-
	ucl_object_t *cur;
+
	const ucl_object_t *cur;
	ucl_object_iter_t it = NULL;
	const char *uname = NULL;
	const char *gname = NULL;
@@ -596,9 +602,9 @@ pkg_set_dirs_from_object(struct pkg *pkg, ucl_object_t *obj)
}

static int
-
pkg_set_deps_from_object(struct pkg *pkg, ucl_object_t *obj)
+
pkg_set_deps_from_object(struct pkg *pkg, const ucl_object_t *obj)
{
-
	ucl_object_t *cur, *self;
+
	const ucl_object_t *cur, *self;
	ucl_object_iter_t it = NULL, it2;
	const char *origin = NULL;
	const char *version = NULL;
@@ -642,7 +648,7 @@ pkg_set_deps_from_object(struct pkg *pkg, ucl_object_t *obj)
static int
parse_manifest(struct pkg *pkg, struct pkg_manifest_key *keys, ucl_object_t *obj)
{
-
	ucl_object_t *cur;
+
	const ucl_object_t *cur;
	ucl_object_iter_t it = NULL;
	struct pkg_manifest_key *selected_key;
	struct dataparser *dp;
@@ -670,7 +676,8 @@ int
pkg_parse_manifest(struct pkg *pkg, char *buf, size_t len, struct pkg_manifest_key *keys)
{
	struct ucl_parser *p = NULL;
-
	ucl_object_t *obj = NULL, *cur;
+
	const ucl_object_t *cur;
+
	ucl_object_t *obj = NULL;
	ucl_object_iter_t it = NULL;
	int rc;
	struct pkg_manifest_key *sk;
@@ -732,7 +739,8 @@ int
pkg_parse_manifest_file(struct pkg *pkg, const char *file, struct pkg_manifest_key *keys)
{
	struct ucl_parser *p = NULL;
-
	ucl_object_t *obj = NULL, *cur;
+
	const ucl_object_t *cur;
+
	ucl_object_t *obj = NULL;
	ucl_object_iter_t it = NULL;
	int rc;
	bool fallback = false;
@@ -806,17 +814,20 @@ pkg_emit_filelist(struct pkg *pkg, FILE *f)
	struct sbuf *b = NULL;

	pkg_get(pkg, PKG_NAME, &name, PKG_ORIGIN, &origin, PKG_VERSION, &version);
-
	obj = ucl_object_insert_key(obj, ucl_object_fromstring(origin), "origin", 6, false);
-
	obj = ucl_object_insert_key(obj, ucl_object_fromstring(name), "name", 4, false);
-
	obj = ucl_object_insert_key(obj, ucl_object_fromstring(version), "version", 7, false);
+
	obj = ucl_object_typed_new(UCL_OBJECT);
+
	ucl_object_insert_key(obj, ucl_object_fromstring(origin), "origin", 6, false);
+
	ucl_object_insert_key(obj, ucl_object_fromstring(name), "name", 4, false);
+
	ucl_object_insert_key(obj, ucl_object_fromstring(version), "version", 7, false);

	seq = NULL;
	while (pkg_files(pkg, &file) == EPKG_OK) {
		urlencode(pkg_file_path(file), &b);
-
		seq = ucl_array_append(seq, ucl_object_fromlstring(sbuf_data(b), sbuf_len(b)));
+
		if (seq == NULL)
+
			seq = ucl_object_typed_new(UCL_ARRAY);
+
		ucl_array_append(seq, ucl_object_fromlstring(sbuf_data(b), sbuf_len(b)));
	}
	if (seq != NULL)
-
		obj = ucl_object_insert_key(obj, seq, "files", 5, false);
+
		ucl_object_insert_key(obj, seq, "files", 5, false);

	ucl_object_emit_file(obj, UCL_EMIT_JSON_COMPACT, f);

@@ -849,7 +860,7 @@ emit_manifest(struct pkg *pkg, struct sbuf **out, short flags)
	lic_t licenselogic;
	int64_t flatsize, pkgsize;
	ucl_object_t *map, *seq, *submap;
-
	ucl_object_t *top = NULL;
+
	ucl_object_t *top = ucl_object_typed_new(UCL_OBJECT);

	pkg_get(pkg, PKG_NAME, &name, PKG_ORIGIN, &pkgorigin,
	    PKG_COMMENT, &comment, PKG_ARCH, &pkgarch, PKG_WWW, &www,
@@ -861,130 +872,152 @@ emit_manifest(struct pkg *pkg, struct sbuf **out, short flags)

	pkg_debug(4, "Emitting basic metadata");
	if (name)
-
		top = ucl_object_insert_key(top, ucl_object_fromstring(name), "name", 4, false);
+
		ucl_object_insert_key(top, ucl_object_fromstring(name), "name", 4, false);
	if (pkgorigin)
-
		top = ucl_object_insert_key(top, ucl_object_fromstring(pkgorigin), "origin", 6, false);
+
		ucl_object_insert_key(top, ucl_object_fromstring(pkgorigin), "origin", 6, false);
	if (version)
-
		top = ucl_object_insert_key(top, ucl_object_fromstring(version), "version", 7, false);
+
		ucl_object_insert_key(top, ucl_object_fromstring(version), "version", 7, false);
	if (comment)
-
		top = ucl_object_insert_key(top, ucl_object_fromstring_common(comment, 0, UCL_STRING_TRIM), "comment", 7, false);
+
		ucl_object_insert_key(top, ucl_object_fromstring_common(comment, 0, UCL_STRING_TRIM), "comment", 7, false);
	if (pkgarch)
-
		top = ucl_object_insert_key(top, ucl_object_fromstring(pkgarch), "arch", 4, false);
+
		ucl_object_insert_key(top, ucl_object_fromstring(pkgarch), "arch", 4, false);
	if (pkgmaintainer)
-
		top = ucl_object_insert_key(top, ucl_object_fromstring(pkgmaintainer), "maintainer", 10, false);
+
		ucl_object_insert_key(top, ucl_object_fromstring(pkgmaintainer), "maintainer", 10, false);
	if (prefix)
-
		top = ucl_object_insert_key(top, ucl_object_fromstring(prefix), "prefix", 6, false);
+
		ucl_object_insert_key(top, ucl_object_fromstring(prefix), "prefix", 6, false);
	if (www)
-
		top = ucl_object_insert_key(top, ucl_object_fromstring(www), "www", 3, false);
+
		ucl_object_insert_key(top, ucl_object_fromstring(www), "www", 3, false);
	if (repopath)
-
		top = ucl_object_insert_key(top, ucl_object_fromstring(repopath), "path", 4, false);
+
		ucl_object_insert_key(top, ucl_object_fromstring(repopath), "path", 4, false);
	if (pkgsum)
-
		top = ucl_object_insert_key(top, ucl_object_fromstring(pkgsum), "sum", 3, false);
+
		ucl_object_insert_key(top, ucl_object_fromstring(pkgsum), "sum", 3, false);

	switch (licenselogic) {
	case LICENSE_SINGLE:
-
		top = ucl_object_insert_key(top, ucl_object_fromlstring("single", 6), "licenselogic", 12, false);
+
		ucl_object_insert_key(top, ucl_object_fromlstring("single", 6), "licenselogic", 12, false);
		break;
	case LICENSE_AND:
-
		top = ucl_object_insert_key(top, ucl_object_fromlstring("and", 3), "licenselogic", 12, false);
+
		ucl_object_insert_key(top, ucl_object_fromlstring("and", 3), "licenselogic", 12, false);
		break;
	case LICENSE_OR:
-
		top = ucl_object_insert_key(top, ucl_object_fromlstring("or", 2), "licenselogic", 12, false);
+
		ucl_object_insert_key(top, ucl_object_fromlstring("or", 2), "licenselogic", 12, false);
		break;
	}

	pkg_debug(4, "Emitting licenses");
	if (pkg->licenses != NULL)
-
		top = ucl_object_insert_key(top,
+
		ucl_object_insert_key(top,
		    ucl_object_ref(pkg->licenses), "licenses", 8, false);

-
	top = ucl_object_insert_key(top, ucl_object_fromint(flatsize), "flatsize", 8, false);
+
	ucl_object_insert_key(top, ucl_object_fromint(flatsize), "flatsize", 8, false);
	if (pkgsize > 0)
-
		top = ucl_object_insert_key(top, ucl_object_fromint(pkgsize), "pkgsize", 7, false);
+
		ucl_object_insert_key(top, ucl_object_fromint(pkgsize), "pkgsize", 7, false);

	urlencode(desc, &tmpsbuf);
-
	top = ucl_object_insert_key(top,
+
	ucl_object_insert_key(top,
	    ucl_object_fromstring_common(sbuf_data(tmpsbuf), sbuf_len(tmpsbuf), UCL_STRING_TRIM),
	    "desc", 4, false);

	pkg_debug(4, "Emitting deps");
	map = NULL;
	while (pkg_deps(pkg, &dep) == EPKG_OK) {
-
		submap = NULL;
-
		submap = ucl_object_insert_key(submap, ucl_object_fromstring(pkg_dep_origin(dep)), "origin", 6, false);
-
		submap = ucl_object_insert_key(submap, ucl_object_fromstring(pkg_dep_version(dep)), "version", 7, false);
-
		map = ucl_object_insert_key(map, submap, pkg_dep_name(dep), 0, false);
+
		submap = ucl_object_typed_new(UCL_OBJECT);
+
		ucl_object_insert_key(submap, ucl_object_fromstring(pkg_dep_origin(dep)), "origin", 6, false);
+
		ucl_object_insert_key(submap, ucl_object_fromstring(pkg_dep_version(dep)), "version", 7, false);
+
		if (map == NULL)
+
			map = ucl_object_typed_new(UCL_OBJECT);
+
		ucl_object_insert_key(map, submap, pkg_dep_name(dep), 0, false);
	}
	if (map)
-
		top = ucl_object_insert_key(top, map, "deps", 4, false);
+
		ucl_object_insert_key(top, map, "deps", 4, false);

	pkg_debug(4, "Emitting categories");
	if (pkg->categories != NULL)
-
		top = ucl_object_insert_key(top,
+
		ucl_object_insert_key(top,
		    ucl_object_ref(pkg->categories), "categories", 10, false);

	pkg_debug(4, "Emitting users");
	seq = NULL;
-
	while (pkg_users(pkg, &user) == EPKG_OK)
-
		seq = ucl_array_append(seq, ucl_object_fromstring(pkg_user_name(user)));
+
	while (pkg_users(pkg, &user) == EPKG_OK) {
+
		if (seq == NULL)
+
			seq = ucl_object_typed_new(UCL_ARRAY);
+
		ucl_array_append(seq, ucl_object_fromstring(pkg_user_name(user)));
+
	}
	if (seq)
-
		top = ucl_object_insert_key(top, seq, "users", 5, false);
+
		ucl_object_insert_key(top, seq, "users", 5, false);

	pkg_debug(4, "Emitting groups");
	seq = NULL;
-
	while (pkg_groups(pkg, &group) == EPKG_OK) 
-
		seq = ucl_array_append(seq, ucl_object_fromstring(pkg_group_name(group)));
+
	while (pkg_groups(pkg, &group) == EPKG_OK) {
+
		if (seq == NULL)
+
			seq = ucl_object_typed_new(UCL_ARRAY);
+
		ucl_array_append(seq, ucl_object_fromstring(pkg_group_name(group)));
+
	}
	if (seq)
-
		top = ucl_object_insert_key(top, seq, "groups", 6, false);
+
		ucl_object_insert_key(top, seq, "groups", 6, false);

	pkg_debug(4, "Emitting required");
	seq = NULL;
-
	while (pkg_shlibs_required(pkg, &shlib) == EPKG_OK)
-
		seq = ucl_array_append(seq, ucl_object_fromstring(pkg_shlib_name(shlib)));
+
	while (pkg_shlibs_required(pkg, &shlib) == EPKG_OK) {
+
		if (seq == NULL)
+
			seq = ucl_object_typed_new(UCL_ARRAY);
+
		ucl_array_append(seq, ucl_object_fromstring(pkg_shlib_name(shlib)));
+
	}
	if (seq)
-
		top = ucl_object_insert_key(top, seq, "shlibs_required", 15, false);
+
		ucl_object_insert_key(top, seq, "shlibs_required", 15, false);

	pkg_debug(4, "Emitting shlibs_provided");
	seq = NULL;
-
	while (pkg_shlibs_provided(pkg, &shlib) == EPKG_OK)
-
		seq = ucl_array_append(seq, ucl_object_fromstring(pkg_shlib_name(shlib)));
+
	while (pkg_shlibs_provided(pkg, &shlib) == EPKG_OK) {
+
		if (seq == NULL)
+
			seq = ucl_object_typed_new(UCL_ARRAY);
+
		ucl_array_append(seq, ucl_object_fromstring(pkg_shlib_name(shlib)));
+
	}
	if (seq)
-
		top = ucl_object_insert_key(top, seq, "shlibs_provided", 15, false);
+
		ucl_object_insert_key(top, seq, "shlibs_provided", 15, false);

	pkg_debug(4, "Emitting conflicts");
	map = NULL;
-
	while (pkg_conflicts(pkg, &conflict) == EPKG_OK)
-
		map = ucl_object_insert_key(map,
+
	while (pkg_conflicts(pkg, &conflict) == EPKG_OK) {
+
		if (map == NULL)
+
			map = ucl_object_typed_new(UCL_OBJECT);
+
		ucl_object_insert_key(map,
		    ucl_object_fromstring(pkg_option_value(option)),
		    pkg_conflict_origin(conflict), 0, false);
+
	}
	if (map)
-
		top = ucl_object_insert_key(top, map, "conflicts", 9, false);
+
		ucl_object_insert_key(top, map, "conflicts", 9, false);

	pkg_debug(4, "Emitting provides");
	map = NULL;
-
	while (pkg_provides(pkg, &provide) == EPKG_OK)
-
		map = ucl_object_insert_key(map,
+
	while (pkg_provides(pkg, &provide) == EPKG_OK) {
+
		if (map == NULL)
+
			map = ucl_object_typed_new(UCL_OBJECT);
+
		ucl_object_insert_key(map,
		    ucl_object_fromstring(pkg_option_value(option)),
		    pkg_provide_name(provide), 0, false);
+
	}
	if (map)
-
		top = ucl_object_insert_key(top, map, "provides", 8, false);
+
		ucl_object_insert_key(top, map, "provides", 8, false);

	pkg_debug(4, "Emitting options");
	map = NULL;
	while (pkg_options(pkg, &option) == EPKG_OK) {
		pkg_debug(2, "Emiting option: %s", pkg_option_value(option));
-
		map = ucl_object_insert_key(map,
+
		if (map == NULL)
+
			map = ucl_object_typed_new(UCL_OBJECT);
+
		ucl_object_insert_key(map,
		    ucl_object_fromstring(pkg_option_value(option)),
		    pkg_option_opt(option), 0, false);
	}
	if (map)
-
		top = ucl_object_insert_key(top, map, "options", 7, false);
+
		ucl_object_insert_key(top, map, "options", 7, false);

	if (pkg->annotations != NULL) {
		/* Remove internal only annotations */
		ucl_object_delete_keyl(pkg->annotations, "repository", 10);
		ucl_object_delete_keyl(pkg->annotations, "relocated", 9);
-
		top = ucl_object_insert_key(top,
+
		ucl_object_insert_key(top,
		    ucl_object_ref(pkg->annotations), "annotations", 11, false);
	}

@@ -999,12 +1032,14 @@ emit_manifest(struct pkg *pkg, struct sbuf **out, short flags)
					pkg_sum = "-";

				urlencode(pkg_file_path(file), &tmpsbuf);
-
				map = ucl_object_insert_key(map,
+
				if (map == NULL)
+
					map = ucl_object_typed_new(UCL_OBJECT);
+
				ucl_object_insert_key(map,
				    ucl_object_fromstring(pkg_sum),
				    sbuf_data(tmpsbuf), sbuf_len(tmpsbuf), true);
			}
			if (map)
-
				top = ucl_object_insert_key(top, map, "files", 5, false);
+
				ucl_object_insert_key(top, map, "files", 5, false);

			pkg_debug(4, "Emitting directories");
			map = NULL;
@@ -1013,12 +1048,14 @@ emit_manifest(struct pkg *pkg, struct sbuf **out, short flags)
				/* For now append y/n to stay compatible with libyaml version 
				 * obj_append_boolean(map, sbuf_get(tmpsbuf), pkg_dir_try(dir));
				 */
-
				map = ucl_object_insert_key(map,
+
				if (map == NULL)
+
					map = ucl_object_typed_new(UCL_OBJECT);
+
				ucl_object_insert_key(map,
				    ucl_object_fromstring(pkg_dir_try(dir) ? "y" : "n"),
				    sbuf_data(tmpsbuf), sbuf_len(tmpsbuf), true);
			}
			if (map)
-
				top = ucl_object_insert_key(top, map, "directories", 11, false);
+
				ucl_object_insert_key(top, map, "directories", 11, false);
		}

		pkg_debug(4, "Emitting scripts");
@@ -1057,19 +1094,21 @@ emit_manifest(struct pkg *pkg, struct sbuf **out, short flags)
				break;
			}
			urlencode(pkg_script_get(pkg, i), &tmpsbuf);
-
			map = ucl_object_insert_key(map,
+
			if (map == NULL)
+
				map = ucl_object_typed_new(UCL_OBJECT);
+
			ucl_object_insert_key(map,
			    ucl_object_fromstring_common(sbuf_data(tmpsbuf),
			        sbuf_len(tmpsbuf), UCL_STRING_TRIM),
			    script_types, 0, true);
		}
		if (map)
-
			top = ucl_object_insert_key(top, map, "scripts", 7, false);
+
			ucl_object_insert_key(top, map, "scripts", 7, false);
	}

	pkg_debug(4, "Emitting message");
	if (message != NULL && *message != '\0') {
		urlencode(message, &tmpsbuf);
-
		top = ucl_object_insert_key(top,
+
		ucl_object_insert_key(top,
		    ucl_object_fromstring_common(sbuf_data(tmpsbuf), sbuf_len(tmpsbuf), UCL_STRING_TRIM),
		    "message", 7, false);
	}
modified libpkg/pkg_object.c
@@ -30,7 +30,7 @@
#include "private/pkg.h"

const char *
-
pkg_object_dump(pkg_object *o)
+
pkg_object_dump(const pkg_object *o)
{
	if (o == NULL)
		return ("");
@@ -45,7 +45,7 @@ pkg_object_free(pkg_object *o)
}

const char *
-
pkg_object_key(pkg_object *o)
+
pkg_object_key(const pkg_object *o)
{
	if (o == NULL)
		return (NULL);
@@ -53,8 +53,8 @@ pkg_object_key(pkg_object *o)
	return (ucl_object_key(o));
}

-
pkg_object *
-
pkg_object_iterate(pkg_object *o, pkg_iter *it)
+
const pkg_object *
+
pkg_object_iterate(const pkg_object *o, pkg_iter *it)
{
	if (o == NULL)
		return (NULL);
@@ -63,7 +63,7 @@ pkg_object_iterate(pkg_object *o, pkg_iter *it)
}

pkg_object_t
-
pkg_object_type(pkg_object *o)
+
pkg_object_type(const pkg_object *o)
{

	if (o == NULL)
@@ -87,7 +87,7 @@ pkg_object_type(pkg_object *o)
}

bool
-
pkg_object_bool(pkg_object *o)
+
pkg_object_bool(const pkg_object *o)
{
	assert(o->type == UCL_BOOLEAN);

@@ -95,7 +95,7 @@ pkg_object_bool(pkg_object *o)
}

const char *
-
pkg_object_string(pkg_object *o)
+
pkg_object_string(const pkg_object *o)
{
	const char *ret;

@@ -110,7 +110,7 @@ pkg_object_string(pkg_object *o)
}

int64_t
-
pkg_object_int(pkg_object *o)
+
pkg_object_int(const pkg_object *o)
{
	assert(o->type == UCL_INT);

@@ -118,7 +118,7 @@ pkg_object_int(pkg_object *o)
}

unsigned
-
pkg_object_count(pkg_object *o)
+
pkg_object_count(const pkg_object *o)
{
	return (UCL_COUNT(o));
}
modified libpkg/pkg_ports.c
@@ -703,10 +703,10 @@ keyword_free(struct keyword *k)
}

static int
-
parse_actions(ucl_object_t *o, struct plist *p,
+
parse_actions(const ucl_object_t *o, struct plist *p,
    char *line, struct file_attr *a)
{
-
	ucl_object_t *cur;
+
	const ucl_object_t *cur;
	ucl_object_iter_t it = NULL;
	int i;

@@ -723,8 +723,8 @@ parse_actions(ucl_object_t *o, struct plist *p,
}

static void
-
parse_attributes(ucl_object_t *o, struct file_attr **a) {
-
	ucl_object_t *cur;
+
parse_attributes(const ucl_object_t *o, struct file_attr **a) {
+
	const ucl_object_t *cur;
	ucl_object_iter_t it = NULL;
	const char *key;

@@ -763,7 +763,7 @@ parse_attributes(ucl_object_t *o, struct file_attr **a) {
static int
apply_keyword_file(ucl_object_t *obj, struct plist *p, char *line, struct file_attr *attr)
{
-
	ucl_object_t *o;
+
	const ucl_object_t *o;
	char *cmd;

	if ((o = ucl_object_find_key(obj,  "attributes")))
modified libpkg/pkg_printf.c
@@ -839,9 +839,9 @@ format_annotations(struct sbuf *sbuf, const void *data, struct percent_esc *p)
	if (p->flags & (PP_ALTERNATE_FORM1|PP_ALTERNATE_FORM2))
		return (list_count(sbuf, pkg_list_count(pkg, PKG_ANNOTATIONS), p));
	else {
-
		pkg_object	*note;
-
		pkg_iter	it = NULL;
-
		int		 count;
+
		const pkg_object	*note;
+
		pkg_iter		it = NULL;
+
		int			 count;

		set_list_defaults(p, "%An: %Av\n", "");

@@ -940,9 +940,9 @@ format_categories(struct sbuf *sbuf, const void *data, struct percent_esc *p)
		return (list_count(sbuf, pkg_list_count(pkg, PKG_CATEGORIES),
				   p));
	else {
-
		pkg_object	*cat;
-
		pkg_iter	 it = NULL;
-
		int		 count;
+
		const pkg_object	*cat;
+
		pkg_iter		 it = NULL;
+
		int			 count;

		set_list_defaults(p, "%Cn", ", ");

@@ -1253,8 +1253,8 @@ format_licenses(struct sbuf *sbuf, const void *data, struct percent_esc *p)
		return (list_count(sbuf, pkg_object_count(pkg_licenses(pkg)),
				   p));
	else {
-
		pkg_object	*lic;
-
		pkg_iter	 iter = NULL;
+
		const pkg_object	*lic;
+
		pkg_iter		 iter = NULL;
		int			 count;

		set_list_defaults(p, "%Ln", " %l ");
modified libpkg/pkg_repo.c
@@ -550,7 +550,7 @@ pkg_repo_fetch_meta(struct pkg_repo *repo, time_t *t)
static struct fingerprint *
pkg_repo_parse_fingerprint(ucl_object_t *obj)
{
-
	ucl_object_t *cur;
+
	const ucl_object_t *cur;
	ucl_object_iter_t it = NULL;
	const char *function = NULL, *fp = NULL;
	hash_t fct = HASH_UNKNOWN;
modified libpkg/pkg_repo_meta.c
@@ -116,7 +116,7 @@ pkg_repo_meta_open_schema_v1()
static int
pkg_repo_meta_parse(ucl_object_t *top, struct pkg_repo_meta **target, int version)
{
-
	ucl_object_t *obj;
+
	const ucl_object_t *obj;
	struct pkg_repo_meta *meta;

	meta = calloc(1, sizeof(*meta));
@@ -167,7 +167,7 @@ if (meta == NULL) {
	pkg_emit_errno("pkg_repo_meta_parse", "malloc failed for pkg_repo_meta");
	return (EPKG_FATAL);
}
-
	ucl_object_t *obj;
+
	const ucl_object_t *obj;

	if ((obj = ucl_object_find_key(top, "version")) != NULL) {
		if (obj->type == UCL_INT) {
modified libpkg/pkg_status.c
@@ -43,14 +43,14 @@ static bool is_exec_at_localbase(const char *progname);
pkg_status_t
pkg_status(int *count)
{
-
	pkg_object	*o;
-
	const char	*progname;
-
	char		 dbpath[MAXPATHLEN];
-
	int		 numpkgs = 0;
-
	sqlite3		*db = NULL;
-
	sqlite3_stmt	*stmt = NULL;
-
	const char      *sql = "SELECT COUNT(*) FROM packages";
-
	bool		 dbsuccess;
+
	const pkg_object	*o;
+
	const char		*progname;
+
	char			 dbpath[MAXPATHLEN];
+
	int			 numpkgs = 0;
+
	sqlite3			*db = NULL;
+
	sqlite3_stmt		*stmt = NULL;
+
	const char		*sql = "SELECT COUNT(*) FROM packages";
+
	bool			 dbsuccess;

	/* Is this executable called pkg, or does pkg exist at
	   $LOCALBASE/sbin/pkg.  Ditto: pkg-static. Portability:
modified libpkg/pkgdb.c
@@ -132,6 +132,7 @@ load_val(sqlite3 *db, struct pkg *pkg, const char *sql, unsigned flags,
{
	sqlite3_stmt	*stmt;
	int		 ret;
+
	int64_t		 rowid;

	assert(db != NULL && pkg != NULL);

@@ -144,7 +145,8 @@ load_val(sqlite3 *db, struct pkg *pkg, const char *sql, unsigned flags,
		return (EPKG_FATAL);
	}

-
	sqlite3_bind_int64(stmt, 1, pkg->rowid);
+
	pkg_get(pkg, PKG_ROWID, &rowid);
+
	sqlite3_bind_int64(stmt, 1, rowid);

	while ((ret = sqlite3_step(stmt)) == SQLITE_ROW) {
		pkg_adddata(pkg, sqlite3_column_text(stmt, 0));
@@ -170,6 +172,7 @@ load_tag_val(sqlite3 *db, struct pkg *pkg, const char *sql, unsigned flags,
{
	sqlite3_stmt	*stmt;
	int		 ret;
+
	int64_t		 rowid;

	assert(db != NULL && pkg != NULL);

@@ -182,7 +185,8 @@ load_tag_val(sqlite3 *db, struct pkg *pkg, const char *sql, unsigned flags,
		return (EPKG_FATAL);
	}

-
	sqlite3_bind_int64(stmt, 1, pkg->rowid);
+
	pkg_get(pkg, PKG_ROWID, &rowid);
+
	sqlite3_bind_int64(stmt, 1, rowid);

	while ((ret = sqlite3_step(stmt)) == SQLITE_ROW) {
		pkg_addtagval(pkg, sqlite3_column_text(stmt, 0),
@@ -964,9 +968,9 @@ database_access(unsigned mode, const char* dbdir, const char *dbname)
int
pkgdb_access(unsigned mode, unsigned database)
{
-
	pkg_object	*o;
-
	const char	*dbdir;
-
	int		 retval = EPKG_OK;
+
	const pkg_object	*o;
+
	const char		*dbdir;
+
	int			 retval = EPKG_OK;

	/*
	 * This will return one of:
@@ -1689,6 +1693,7 @@ pkgdb_load_deps(struct pkgdb *db, struct pkg *pkg)
{
	sqlite3_stmt	*stmt = NULL;
	int		 ret = EPKG_OK;
+
	int64_t		 rowid;
	char		 sql[BUFSIZ];
	const char	*reponame = NULL;
	const char	*mainsql = ""
@@ -1722,7 +1727,8 @@ pkgdb_load_deps(struct pkgdb *db, struct pkg *pkg)
		return (EPKG_FATAL);
	}

-
	sqlite3_bind_int64(stmt, 1, pkg->rowid);
+
	pkg_get(pkg, PKG_ROWID, &rowid);
+
	sqlite3_bind_int64(stmt, 1, rowid);

	while ((ret = sqlite3_step(stmt)) == SQLITE_ROW) {
		pkg_adddep(pkg, sqlite3_column_text(stmt, 0),
@@ -1808,6 +1814,7 @@ pkgdb_load_files(struct pkgdb *db, struct pkg *pkg)
{
	sqlite3_stmt	*stmt = NULL;
	int		 ret;
+
	int64_t		 rowid;
	const char	 sql[] = ""
		"SELECT path, sha256 "
		"FROM files "
@@ -1826,7 +1833,8 @@ pkgdb_load_files(struct pkgdb *db, struct pkg *pkg)
		return (EPKG_FATAL);
	}

-
	sqlite3_bind_int64(stmt, 1, pkg->rowid);
+
	pkg_get(pkg, PKG_ROWID, &rowid);
+
	sqlite3_bind_int64(stmt, 1, rowid);

	while ((ret = sqlite3_step(stmt)) == SQLITE_ROW) {
		pkg_addfile(pkg, sqlite3_column_text(stmt, 0),
@@ -1855,6 +1863,7 @@ pkgdb_load_dirs(struct pkgdb *db, struct pkg *pkg)
		"ORDER by path DESC";
	sqlite3_stmt	*stmt;
	int		 ret;
+
	int64_t		 rowid;

	assert(db != NULL && pkg != NULL);
	assert(pkg->type == PKG_INSTALLED);
@@ -1868,7 +1877,8 @@ pkgdb_load_dirs(struct pkgdb *db, struct pkg *pkg)
		return (EPKG_FATAL);
	}

-
	sqlite3_bind_int64(stmt, 1, pkg->rowid);
+
	pkg_get(pkg, PKG_ROWID, &rowid);
+
	sqlite3_bind_int64(stmt, 1, rowid);

	while ((ret = sqlite3_step(stmt)) == SQLITE_ROW) {
		pkg_adddir(pkg, sqlite3_column_text(stmt, 0),
@@ -2080,6 +2090,7 @@ pkgdb_load_scripts(struct pkgdb *db, struct pkg *pkg)
{
	sqlite3_stmt	*stmt = NULL;
	int		 ret;
+
	int64_t		 rowid;
	const char	 sql[] = ""
		"SELECT script, type "
		"FROM pkg_script JOIN script USING(script_id) "
@@ -2097,7 +2108,8 @@ pkgdb_load_scripts(struct pkgdb *db, struct pkg *pkg)
		return (EPKG_FATAL);
	}

-
	sqlite3_bind_int64(stmt, 1, pkg->rowid);
+
	pkg_get(pkg, PKG_ROWID, &rowid);
+
	sqlite3_bind_int64(stmt, 1, rowid);

	while ((ret = sqlite3_step(stmt)) == SQLITE_ROW) {
		pkg_addscript(pkg, sqlite3_column_text(stmt, 0),
@@ -2585,7 +2597,7 @@ pkgdb_register_pkg(struct pkgdb *db, struct pkg *pkg, int complete, int forced)
	struct pkg_group	*group = NULL;
	struct pkg_conflict	*conflict = NULL;
	struct pkgdb_it		*it = NULL;
-
	pkg_object		*obj;
+
	const pkg_object	*obj;
	pkg_iter		 iter;

	sqlite3			*s;
@@ -2970,8 +2982,8 @@ pkgdb_update_provides(struct pkg *pkg, int64_t package_id, sqlite3 *s)
int
pkgdb_insert_annotations(struct pkg *pkg, int64_t package_id, sqlite3 *s)
{
-
	pkg_object	*note;
-
	pkg_iter	 it = NULL;
+
	const pkg_object	*note;
+
	pkg_iter		 it = NULL;

	while ((note = pkg_object_iterate(pkg->annotations, &it))) {
		if (run_prstmt(ANNOTATE1, pkg_object_key(note))
modified libpkg/pkgdb_repo.c
@@ -474,7 +474,7 @@ pkgdb_repo_add_package(struct pkg *pkg, const char *pkg_path,
	struct pkg_dep		*dep      = NULL;
	struct pkg_option	*option   = NULL;
	struct pkg_shlib	*shlib    = NULL;
-
	pkg_object		*obj;
+
	const pkg_object	*obj;
	pkg_iter		 it;
	int64_t			 package_id;

modified libpkg/plugins.c
@@ -200,7 +200,9 @@ pkg_plugin_conf_add(struct pkg_plugin *p, pkg_object_t type, const char *key,
					break;
				value++;
			}
-
			o = ucl_object_insert_key(o,
+
			if (o == NULL)
+
				o = ucl_object_typed_new(UCL_OBJECT);
+
			ucl_object_insert_key(o,
			    ucl_object_fromstring_common(value + 1, buf - value - 1, UCL_STRING_TRIM),
			    k, value - k, false);
			buf++;
@@ -213,19 +215,25 @@ pkg_plugin_conf_add(struct pkg_plugin *p, pkg_object_t type, const char *key,
				break;
			value++;
		}
-
		o = ucl_object_insert_key(o,
+
		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),
		    k, value - k, false);
		break;
	case PKG_ARRAY:
		walk = buf = def;
		while ((buf = strchr(buf, ',')) != NULL) {
-
			o = ucl_array_append(o,
+
			if (o == NULL)
+
				o = ucl_object_typed_new(UCL_ARRAY);
+
			ucl_array_append(o,
					ucl_object_fromstring_common(walk, buf - walk, UCL_STRING_TRIM));
			buf++;
			walk = buf;
		}
-
		o = ucl_array_append(o,
+
		if (o == NULL)
+
			o = ucl_object_typed_new(UCL_ARRAY);
+
		ucl_array_append(o,
				ucl_object_fromstring_common(walk, strlen(walk), UCL_STRING_TRIM));
		break;
	default:
@@ -233,7 +241,7 @@ pkg_plugin_conf_add(struct pkg_plugin *p, pkg_object_t type, const char *key,
	}

	if (o != NULL)
-
		p->conf = ucl_object_replace_key(p->conf, o, key, strlen(key), false);
+
		ucl_object_replace_key(p->conf, o, key, strlen(key), false);

	return (EPKG_OK);
}
@@ -257,7 +265,7 @@ pkg_plugins_init(void)
{
	struct pkg_plugin *p = NULL;
	char pluginfile[MAXPATHLEN];
-
	ucl_object_t *obj, *cur;
+
	const ucl_object_t *obj, *cur;
	ucl_object_iter_t it = NULL;
	const char *plugdir;
	bool plug_enabled = false;
@@ -316,7 +324,8 @@ pkg_plugin_parse(struct pkg_plugin *p)
	const char *path;
	const char *plugname;
	struct ucl_parser *pr;
-
	ucl_object_t *obj, *cur, *o;
+
	const ucl_object_t *cur, *o;
+
	ucl_object_t *obj;
	ucl_object_iter_t it = NULL;
	const char *key;

@@ -352,10 +361,8 @@ pkg_plugin_parse(struct pkg_plugin *p)
			continue;
		}

-
		o = ucl_object_pop_key(p->conf, key);
-
		if (o != NULL)
-
			ucl_object_unref(o);
-
		p->conf = ucl_object_insert_key(p->conf, cur, key, strlen(key), false);
+
		ucl_object_delete_key(p->conf, key);
+
		ucl_object_insert_key(p->conf, ucl_object_ref(cur), key, strlen(key), false);
	}

	p->parsed = true;
@@ -389,7 +396,7 @@ pkg_plugins_shutdown(void)
	return;
}

-
pkg_object *
+
const pkg_object *
pkg_plugin_conf(struct pkg_plugin *p)
{
	return (p->conf);
modified libpkg/private/pkg.h
@@ -109,13 +109,8 @@
extern int eventpipe;

struct pkg {
-
	struct sbuf	*fields[PKG_NUM_FIELDS];
+
	ucl_object_t	*fields;
	bool		 direct;
-
	bool		 automatic;
-
	bool		 locked;
-
	int64_t		 flatsize;
-
	int64_t		 old_flatsize;
-
	int64_t		 pkgsize;
	struct sbuf	*scripts[PKG_NUM_SCRIPTS];
	ucl_object_t		*licenses;
	ucl_object_t		*categories;
@@ -132,9 +127,6 @@ struct pkg {
	struct pkg_conflict *conflicts;
	struct pkg_provide	*provides;
	unsigned       	 flags;
-
	int64_t		 rowid;
-
	int64_t		 time;
-
	lic_t		 licenselogic;
	pkg_t		 type;
	UT_hash_handle	 hh;
	struct pkg	*next;
@@ -357,6 +349,38 @@ int pkg_delete(struct pkg *pkg, struct pkgdb *db, unsigned flags);
#define PKG_DELETE_NOSCRIPT (1<<2)
#define PKG_DELETE_CONFLICT (1<<3)

+
static struct pkg_key {
+
	const char *name;
+
	int type;
+
} pkg_keys [] = {
+
	[PKG_ORIGIN] = { "origin", UCL_STRING },
+
	[PKG_NAME] = { "name", UCL_STRING },
+
	[PKG_VERSION] = { "version", UCL_STRING },
+
	[PKG_COMMENT] = { "comment", UCL_STRING },
+
	[PKG_DESC] = { "desc", UCL_STRING },
+
	[PKG_MTREE] = { "mtree", UCL_STRING },
+
	[PKG_MESSAGE] = { "message", UCL_STRING },
+
	[PKG_ARCH] = { "arch", UCL_STRING },
+
	[PKG_MAINTAINER] = { "maintainer", UCL_STRING },
+
	[PKG_WWW] = { "www", UCL_STRING },
+
	[PKG_PREFIX] = { "prefix", UCL_STRING },
+
	[PKG_REPOPATH] = { "repopath", UCL_STRING },
+
	[PKG_CKSUM] = { "sum", UCL_STRING },
+
	[PKG_OLD_VERSION] = { "old_version", UCL_STRING },
+
	[PKG_REPONAME] = { "reponame", UCL_STRING },
+
	[PKG_REPOURL] = { "repourl", UCL_STRING },
+
	[PKG_DIGEST] = { "digest", UCL_STRING },
+
	[PKG_REASON] = { "reason", UCL_STRING },
+
	[PKG_FLATSIZE] = { "flatsize", UCL_INT },
+
	[PKG_OLD_FLATSIZE] = { "old_flatsize", UCL_INT },
+
	[PKG_PKGSIZE] = { "pkgsize", UCL_INT },
+
	[PKG_LICENSE_LOGIC] = { "licenselogic", UCL_INT },
+
	[PKG_AUTOMATIC] = { "automatic", UCL_BOOLEAN },
+
	[PKG_LOCKED] = { "locked", UCL_BOOLEAN },
+
	[PKG_ROWID] = { "rowid", UCL_INT },
+
	[PKG_TIME] = { "time", UCL_INT },
+
};
+

int pkg_fetch_file_to_fd(struct pkg_repo *repo, const char *url,
		int dest, time_t *t);
int pkg_repo_fetch_package(struct pkg *pkg);
modified libpkg/utils.c
@@ -519,7 +519,9 @@ yaml_sequence_to_object(ucl_object_t *obj, yaml_document_t *doc, yaml_node_t *no
			/* Should not happen */
			break;
		}
-
		obj = ucl_array_append(obj, sub);
+
		if (obj == NULL)
+
			obj = ucl_object_typed_new(UCL_ARRAY);
+
		ucl_array_append(obj, sub);
		++item;
	}

@@ -555,8 +557,11 @@ yaml_mapping_to_object(ucl_object_t *obj, yaml_document_t *doc, yaml_node_t *nod
			/* Should not happen */
			break;
		}
-
		if (sub != NULL)
-
			obj = ucl_object_insert_key(obj, sub, key->data.scalar.value, key->data.scalar.length, true);
+
		if (sub != NULL) {
+
			if (obj == NULL)
+
				obj = ucl_object_typed_new(UCL_OBJECT);
+
			ucl_object_insert_key(obj, sub, key->data.scalar.value, key->data.scalar.length, true);
+
		}
		++pair;
	}

modified src/config.c
@@ -45,7 +45,7 @@ usage_config(void)
int
exec_config(int argc, char **argv)
{
-
	pkg_object *conf, *o;
+
	const pkg_object *conf, *o;
	pkg_iter it = NULL;
	const char *buf;
	char *key;
modified src/main.c
@@ -270,7 +270,7 @@ exec_help(int argc, char **argv)
static void
show_plugin_info(void)
{
-
	pkg_object		*conf;
+
	const pkg_object	*conf;
	struct pkg_plugin	*p = NULL;

	while (pkg_plugins(&p) == EPKG_OK) {
@@ -481,7 +481,7 @@ main(int argc, char **argv)
	struct plugcmd *c;
	const char *conffile = NULL;
	const char *reposdir = NULL;
-
	pkg_object *alias, *cur;
+
	const pkg_object *alias, *cur;
	pkg_iter it = NULL;
	const char *alias_value;
	char **newargv, *arg, *args;
modified src/query.c
@@ -75,7 +75,7 @@ static struct query_flags accepted_query_flags[] = {
};

static void
-
format_str(struct pkg *pkg, struct sbuf *dest, const char *qstr, void *data)
+
format_str(struct pkg *pkg, struct sbuf *dest, const char *qstr, const void *data)
{
	bool automatic;
	bool locked;
@@ -335,7 +335,7 @@ print_query(struct pkg *pkg, char *qstr, char multiline)
	struct pkg_user		*user   = NULL;
	struct pkg_group	*group  = NULL;
	struct pkg_shlib	*shlib  = NULL;
-
	pkg_object		*o;
+
	const pkg_object	*o;
	pkg_iter		 it;

	switch (multiline) {
modified src/rquery.c
@@ -84,7 +84,7 @@ print_index(struct pkg *pkg)
#ifndef PORTSDIR
#define PORTSDIR "/usr/ports"
#endif
-
	pkg_object *obj = NULL;
+
	const pkg_object *obj = NULL;
	pkg_iter iter = NULL;

	pkg_printf("%n-%v|" PORTSDIR "/%o|%p|%c|" PORTSDIR "/%o/pkg-descr|%m|",