Radish alpha
H
rad:z3QDZAW2FAfuLvihrhiyDC9fAD8G9
HardenedBSD Package Manager
Radicle
Git
pkg: convert stringlist_t to charv_t
Baptiste Daroussin committed 1 year ago
commit 3c902625b4381f7a75a16c9cbff177535dd1edc7
parent 48c09bd
22 files changed +381 -481
modified libpkg/lua_scripts.c
@@ -1,27 +1,7 @@
/*-
-
 * Copyright (c) 2019 Baptiste Daroussin <bapt@FreeBSD.org>
-
 * All rights reserved.
-
 * 
-
 * Redistribution and use in source and binary forms, with or without
-
 * modification, are permitted provided that the following conditions
-
 * are met:
-
 * 1. Redistributions of source code must retain the above copyright
-
 *    notice, this list of conditions and the following disclaimer
-
 *    in this position and unchanged.
-
 * 2. Redistributions in binary form must reproduce the above copyright
-
 *    notice, this list of conditions and the following disclaimer in the
-
 *    documentation and/or other materials provided with the distribution.
-
 * 
-
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
-
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-
 * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
-
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
 * Copyright (c) 2019-2025 Baptiste Daroussin <bapt@FreeBSD.org>
+
 *
+
 * SPDX-License-Identifier: BSD-2-Clause
 */

#include "pkg_config.h"
@@ -60,7 +40,7 @@ pkg_lua_script_run(struct pkg * const pkg, pkg_lua_script type, bool upgrade)
	int cur_pipe[2];
	char *line = NULL;

-
	if (tll_length(pkg->lua_scripts[type]) == 0)
+
	if (vec_len(&pkg->lua_scripts[type]) == 0)
		return (EPKG_OK);

	if (!pkg_object_bool(pkg_config_get("RUN_SCRIPTS"))) {
@@ -72,7 +52,8 @@ pkg_lua_script_run(struct pkg * const pkg, pkg_lua_script type, bool upgrade)
	do_reap = procctl(P_PID, mypid, PROC_REAP_ACQUIRE, NULL) == 0;
#endif

-
	tll_foreach(pkg->lua_scripts[type], s) {
+
	vec_foreach(pkg->lua_scripts[type], i) {
+
		char *script = pkg->lua_scripts[type].d[i];
		if (get_socketpair(cur_pipe) == -1) {
			pkg_emit_errno("pkg_lua_script_script", "socketpair");
			goto cleanup;
@@ -115,13 +96,13 @@ pkg_lua_script_run(struct pkg * const pkg, pkg_lua_script type, bool upgrade)
			lua_override_ios(L, true);

			/* parse and set arguments of the line is in the comments */
-
			if (STARTS_WITH(s->item, "-- args: ")) {
+
			if (STARTS_WITH(script, "-- args: ")) {
				char *walk, *begin, *line = NULL;
				int spaces, argc = 0;
				char **args = NULL;

-
				walk = strchr(s->item, '\n');
-
				begin = s->item + strlen("-- args: ");
+
				walk = strchr(script, '\n');
+
				begin = script + strlen("-- args: ");
				line = xstrndup(begin, walk - begin);
				spaces = pkg_utils_count_spaces(line);
				args = xmalloc((spaces + 1)* sizeof(char *));
@@ -132,8 +113,8 @@ pkg_lua_script_run(struct pkg * const pkg, pkg_lua_script type, bool upgrade)
				lua_args_table(L, args, argc);
			}

-
			pkg_debug(3, "Scripts: executing lua\n--- BEGIN ---\n%s\nScripts: --- END ---", s->item);
-
			if (luaL_dostring(L, s->item)) {
+
			pkg_debug(3, "Scripts: executing lua\n--- BEGIN ---\n%s\nScripts: --- END ---", script);
+
			if (luaL_dostring(L, script)) {
				pkg_emit_error("Failed to execute lua script: %s", lua_tostring(L, -1));
				lua_close(L);
				_exit(1);
@@ -183,14 +164,14 @@ cleanup:
}

ucl_object_t *
-
pkg_lua_script_to_ucl(stringlist_t *scripts)
+
pkg_lua_script_to_ucl(charv_t *scripts)
{
	ucl_object_t *array;

	array = ucl_object_typed_new(UCL_ARRAY);
-
	tll_foreach(*scripts, s)
-
		ucl_array_append(array, ucl_object_fromstring_common(s->item,
-
		    strlen(s->item), UCL_STRING_RAW|UCL_STRING_TRIM));
+
	vec_foreach(*scripts, i)
+
		ucl_array_append(array, ucl_object_fromstring_common(scripts->d[i],
+
		    strlen(scripts->d[i]), UCL_STRING_RAW|UCL_STRING_TRIM));

	return (array);
}
@@ -206,7 +187,7 @@ pkg_lua_script_from_ucl(struct pkg *pkg, const ucl_object_t *obj, pkg_lua_script
			pkg_emit_error("lua scripts be strings");
			return (EPKG_FATAL);
		}
-
		tll_push_back(pkg->lua_scripts[type], xstrdup(ucl_object_tostring(cur)));
+
		vec_push(&pkg->lua_scripts[type], xstrdup(ucl_object_tostring(cur)));
	}
	return (EPKG_OK);
}
modified libpkg/pkg.c
@@ -1,5 +1,5 @@
/*-
-
 * Copyright (c) 2011-2024 Baptiste Daroussin <bapt@FreeBSD.org>
+
 * Copyright (c) 2011-2025 Baptiste Daroussin <bapt@FreeBSD.org>
 * Copyright (c) 2011-2012 Julien Laffaye <jlaffaye@FreeBSD.org>
 * Copyright (c) 2012 Bryan Drewery <bryan@shatow.net>
 * Copyright (c) 2013 Matthew Seaman <matthew@FreeBSD.org>
@@ -76,7 +76,7 @@ pkg_free(struct pkg *pkg)
	for (int i = 0; i < PKG_NUM_SCRIPTS; i++)
		xstring_free(pkg->scripts[i]);
	for (int i = 0; i < PKG_NUM_LUA_SCRIPTS; i++)
-
		tll_free_and_free(pkg->lua_scripts[i], free);
+
		vec_free_and_free(&pkg->lua_scripts[i], free);

	pkg_list_free(pkg, PKG_DEPS);
	pkg_list_free(pkg, PKG_RDEPS);
@@ -85,27 +85,27 @@ pkg_free(struct pkg *pkg)
	pkg_list_free(pkg, PKG_OPTIONS);
	pkg_list_free(pkg, PKG_CONFIG_FILES);

-
	tll_free_and_free(pkg->users, free);
+
	vec_free_and_free(&pkg->users, free);
	pkg->flags &= ~PKG_LOAD_USERS;
-
	tll_free_and_free(pkg->groups, free);
+
	vec_free_and_free(&pkg->groups, free);
	pkg->flags &= ~PKG_LOAD_GROUPS;
-
	tll_free_and_free(pkg->shlibs_required, free);
+
	vec_free_and_free(&pkg->shlibs_required, free);
	pkg->flags &= ~PKG_LOAD_SHLIBS_REQUIRED;
-
	tll_free_and_free(pkg->shlibs_provided, free);
+
	vec_free_and_free(&pkg->shlibs_provided, free);
	pkg->flags &= ~PKG_LOAD_SHLIBS_REQUIRED;
-
	tll_free_and_free(pkg->provides, free);
+
	vec_free_and_free(&pkg->provides, free);
	pkg->flags &= ~PKG_LOAD_PROVIDES;
-
	tll_free_and_free(pkg->requires, free);
+
	vec_free_and_free(&pkg->requires, free);
	pkg->flags &= ~PKG_LOAD_REQUIRES;
-
	tll_free_and_free(pkg->categories, free);
+
	vec_free_and_free(&pkg->categories, free);
	pkg->flags &= ~PKG_LOAD_CATEGORIES;
-
	tll_free_and_free(pkg->licenses, free);
+
	vec_free_and_free(&pkg->licenses, free);
	pkg->flags &= ~PKG_LOAD_LICENSES;

	tll_free_and_free(pkg->message, pkg_message_free);
	tll_free_and_free(pkg->annotations, pkg_kv_free);

-
	tll_free_and_free(pkg->dir_to_del, free);
+
	vec_free_and_free(&pkg->dir_to_del, free);

	if (pkg->rootfd != -1)
		close(pkg->rootfd);
@@ -405,45 +405,13 @@ pkg_each(config_files, struct pkg_config_file, config_files);
int
pkg_adduser(struct pkg *pkg, const char *name)
{
-
	assert(pkg != NULL);
-
	assert(name != NULL && name[0] != '\0');
-

-
	tll_foreach(pkg->users, u) {
-
		if (!STREQ(u->item, name))
-
			continue;
-
		if (ctx.developer_mode) {
-
			pkg_emit_error("duplicate user listing: %s, fatal (developer mode)", name);
-
			return (EPKG_FATAL);
-
		}
-
		pkg_emit_error("duplicate user listing: %s, ignoring", name);
-
		return (EPKG_OK);
-
	}
-

-
	tll_push_back(pkg->users, xstrdup(name));
-

-
	return (EPKG_OK);
+
	return (pkg_addstring(&pkg->users, name, "user"));
}

int
pkg_addgroup(struct pkg *pkg, const char *name)
{
-
	assert(pkg != NULL);
-
	assert(name != NULL && name[0] != '\0');
-

-
	tll_foreach(pkg->groups, g) {
-
		if (!STREQ(g->item, name))
-
			continue;
-
		if (ctx.developer_mode) {
-
			pkg_emit_error("duplicate group listing: %s, fatal (developer mode)", name);
-
			return (EPKG_FATAL);
-
		}
-
		pkg_emit_error("duplicate group listing: %s, ignoring", name);
-
		return (EPKG_OK);
-
	}
-

-
	tll_push_back(pkg->groups, xstrdup(name));
-

-
	return (EPKG_OK);
+
	return (pkg_addstring(&pkg->groups, name, "group"));
}

int
@@ -601,14 +569,12 @@ pkg_addconfig_file(struct pkg *pkg, const char *path, const char *content)
}

int
-
pkg_addstring(stringlist_t *list, const char *val, const char *title)
+
pkg_addstring(charv_t *list, const char *val, const char *title)
{
	assert(val != NULL);
	assert(title != NULL);

-
	tll_foreach(*list, v) {
-
		if (!STREQ(v->item, val))
-
			continue;
+
	if (charv_contains(list, val, false)) {
		if (ctx.developer_mode) {
			pkg_emit_error("duplicate %s listing: %s, fatal"
			    " (developer mode)", title, val);
@@ -619,7 +585,7 @@ pkg_addstring(stringlist_t *list, const char *val, const char *title)
		return (EPKG_OK);
	}

-
	tll_push_back(*list, xstrdup(val));
+
	vec_push(list, xstrdup(val));

	return (EPKG_OK);
}
@@ -696,7 +662,7 @@ pkg_add_lua_script(struct pkg *pkg, const char *data, pkg_lua_script type)
	if (type >= PKG_LUA_UNKNOWN)
		return (EPKG_FATAL);

-
	tll_push_back(pkg->lua_scripts[type], xstrdup(data));
+
	vec_push(&pkg->lua_scripts[type], xstrdup(data));

	return (EPKG_OK);
}
@@ -967,14 +933,12 @@ pkg_addshlib_required(struct pkg *pkg, const char *name,
	char *full_name = pkg_shlib_name_with_flags(name, flags);

	/* silently ignore duplicates in case of shlibs */
-
	tll_foreach(pkg->shlibs_required, s) {
-
		if (STREQ(s->item, full_name)) {
-
			free(full_name);
-
			return (EPKG_OK);
-
		}
+
	if (charv_contains(&pkg->shlibs_required, full_name, false)) {
+
		free(full_name);
+
		return (EPKG_OK);
	}

-
	tll_push_back(pkg->shlibs_required, full_name);
+
	vec_push(&pkg->shlibs_required, full_name);

	dbg(3, "added shlib deps for %s on %s", pkg->name, full_name);

@@ -991,14 +955,12 @@ pkg_addshlib_provided(struct pkg *pkg, const char *name,
	char *full_name = pkg_shlib_name_with_flags(name, flags);

	/* silently ignore duplicates in case of shlibs */
-
	tll_foreach(pkg->shlibs_provided, s) {
-
		if (STREQ(s->item, full_name)) {
-
			free(full_name);
-
			return (EPKG_OK);
-
		}
+
	if (charv_contains(&pkg->shlibs_provided, full_name, false)) {
+
		free(full_name);
+
		return (EPKG_OK);
	}

-
	tll_push_back(pkg->shlibs_provided, full_name);
+
	vec_push(&pkg->shlibs_provided, full_name);

	dbg(3, "added shlib provide %s for %s", full_name, pkg->name);

@@ -1035,12 +997,10 @@ pkg_addrequire(struct pkg *pkg, const char *name)
	assert(name != NULL && name[0] != '\0');

	/* silently ignore duplicates in case of conflicts */
-
	tll_foreach(pkg->requires, p) {
-
		if (STREQ(p->item, name))
-
			return (EPKG_OK);
-
	}
+
	if (charv_contains(&pkg->requires, name, false))
+
		return (EPKG_OK);

-
	tll_push_back(pkg->requires, xstrdup(name));
+
	vec_push(&pkg->requires, xstrdup(name));

	return (EPKG_OK);
}
@@ -1052,12 +1012,10 @@ pkg_addprovide(struct pkg *pkg, const char *name)
	assert(name != NULL && name[0] != '\0');

	/* silently ignore duplicates in case of conflicts */
-
	tll_foreach(pkg->provides, p) {
-
		if (STREQ(p->item, name))
-
			return (EPKG_OK);
-
	}
+
	if (charv_contains(&pkg->provides, name, false))
+
		return (EPKG_OK);

-
	tll_push_back(pkg->provides, xstrdup(name));
+
	vec_push(&pkg->provides, xstrdup(name));

	return (EPKG_OK);
}
@@ -1121,17 +1079,17 @@ pkg_list_count(const struct pkg *pkg, pkg_list list)
	case PKG_CONFIG_FILES:
		return (pkghash_count(pkg->config_files_hash));
	case PKG_USERS:
-
		return (tll_length(pkg->users));
+
		return (vec_len(&pkg->users));
	case PKG_GROUPS:
-
		return (tll_length(pkg->groups));
+
		return (vec_len(&pkg->groups));
	case PKG_SHLIBS_REQUIRED:
-
		return (tll_length(pkg->shlibs_required));
+
		return (vec_len(&pkg->shlibs_required));
	case PKG_SHLIBS_PROVIDED:
-
		return (tll_length(pkg->shlibs_provided));
+
		return (vec_len(&pkg->shlibs_provided));
	case PKG_REQUIRES:
-
		return (tll_length(pkg->requires));
+
		return (vec_len(&pkg->requires));
	case PKG_PROVIDES:
-
		return (tll_length(pkg->provides));
+
		return (vec_len(&pkg->provides));
	}

	return (0);
modified libpkg/pkg_abi.c
@@ -1,5 +1,5 @@
/*-
-
 * Copyright (c) 2011-2012 Baptiste Daroussin <bapt@FreeBSD.org>
+
 * Copyright (c) 2011-2025 Baptiste Daroussin <bapt@FreeBSD.org>
 * Copyright (c) 2012-2013 Matthew Seaman <matthew@FreeBSD.org>
 * Copyright (c) 2024 The FreeBSD Foundation
 *
@@ -440,42 +440,43 @@ pkg_arch_to_legacy(const char *arch, char *dest, size_t sz)
}

void
-
pkg_cleanup_shlibs_required(struct pkg *pkg, stringlist_t *internal_provided)
+
pkg_cleanup_shlibs_required(struct pkg *pkg, charv_t *internal_provided)
{
	struct pkg_file *file = NULL;
	const char *lib;

-
	tll_foreach(pkg->shlibs_required, s)
-
	{
-
		if (stringlist_contains(&pkg->shlibs_provided, s->item) ||
-
		    stringlist_contains(internal_provided, s->item)) {
+
	vec_foreach(pkg->shlibs_required, i) {
+
		const char *s = pkg->shlibs_required.d[i];
+
		printf("* %s\n", s);
+
		if (charv_contains(&pkg->shlibs_provided, s, false) ||
+
		    charv_contains(internal_provided, s, false)) {
			pkg_debug(2,
			    "remove %s from required shlibs as the "
			    "package %s provides this library itself",
-
			    s->item, pkg->name);
-
			tll_remove_and_free(pkg->shlibs_required, s, free);
+
			    s, pkg->name);
+
			vec_remove_and_free(&pkg->shlibs_required, i, free);
			continue;
		}
-
		if (match_ucl_lists(s->item,
+
		if (match_ucl_lists(s,
		    pkg_config_get("SHLIB_REQUIRE_IGNORE_GLOB"),
		    pkg_config_get("SHLIB_REQUIRE_IGNORE_REGEX"))) {
			pkg_debug(2,
			    "remove %s from required shlibs for package %s as it "
			    "is matched by SHLIB_REQUIRE_IGNORE_GLOB/REGEX.",
-
			    s->item, pkg->name);
-
			tll_remove_and_free(pkg->shlibs_required, s, free);
+
			    s, pkg->name);
+
			vec_remove_and_free(&pkg->shlibs_required, i, free);
			continue;
		}
		file = NULL;
		while (pkg_files(pkg, &file) == EPKG_OK) {
-
			if ((lib = strstr(file->path, s->item)) != NULL &&
-
			    strlen(lib) == strlen(s->item) && lib[-1] == '/') {
+
			if ((lib = strstr(file->path, s)) != NULL &&
+
			    strlen(lib) == strlen(s) && lib[-1] == '/') {
				pkg_debug(2,
				    "remove %s from required shlibs as "
				    "the package %s provides this file itself",
-
				    s->item, pkg->name);
+
				    s, pkg->name);

-
				tll_remove_and_free(pkg->shlibs_required, s,
+
				vec_remove_and_free(&pkg->shlibs_required, i,
				    free);
				break;
			}
@@ -506,12 +507,12 @@ pkg_analyse_files(struct pkgdb *db __unused, struct pkg *pkg, const char *stage)
		pkg_analyse_close=pkg_analyse_close_elf;
	}

-
	if (tll_length(pkg->shlibs_required) != 0) {
-
		tll_free_and_free(pkg->shlibs_required, free);
+
	if (vec_len(&pkg->shlibs_required) != 0) {
+
		vec_free_and_free(&pkg->shlibs_required, free);
	}

-
	if (tll_length(pkg->shlibs_provided) != 0) {
-
		tll_free_and_free(pkg->shlibs_provided, free);
+
	if (vec_len(&pkg->shlibs_provided) != 0) {
+
		vec_free_and_free(&pkg->shlibs_provided, free);
	}

	ret = pkg_analyse_init(stage);
@@ -527,9 +528,11 @@ pkg_analyse_files(struct pkgdb *db __unused, struct pkg *pkg, const char *stage)
	/* shlibs that are provided by files in the package but not matched by
	   SHLIB_PROVIDE_PATHS_* are still used to filter the shlibs
	   required by the package */
-
	stringlist_t internal_provided = tll_init();
+
	charv_t internal_provided;
+
	vec_init(&internal_provided);
	/* list of shlibs that are in the path to be evaluated for provided but are symlinks */
-
	stringlist_t maybe_provided = tll_init();
+
	charv_t maybe_provided;
+
	vec_init(&maybe_provided);

	while (pkg_files(pkg, &file) == EPKG_OK) {
		struct stat st;
@@ -579,40 +582,40 @@ pkg_analyse_files(struct pkgdb *db __unused, struct pkg *pkg, const char *stage)
				if (S_ISREG(st.st_mode)) {
					pkg_addshlib_provided(pkg, provided, provided_flags);
				} else {
-
					tll_push_back(maybe_provided, pkg_shlib_name_with_flags(provided, provided_flags));
+
					vec_push(&maybe_provided, pkg_shlib_name_with_flags(provided, provided_flags));
				}
			} else {
-
				tll_push_back(internal_provided, pkg_shlib_name_with_flags(provided, provided_flags));
+
				vec_push(&internal_provided, pkg_shlib_name_with_flags(provided, provided_flags));
			}
			free(provided);
		}
	}

-
	tll_foreach(maybe_provided, s) {
-
		tll_foreach(internal_provided, ip) {
-
			if (STREQ(s->item, ip->item)) {
-
				pkg_addshlib_provided(pkg, s->item, PKG_SHLIB_FLAGS_NONE);
-
				tll_remove_and_free(internal_provided, ip, free);
+
	vec_foreach(maybe_provided, i) {
+
		vec_foreach(internal_provided, j) {
+
			if (STREQ(maybe_provided.d[i], internal_provided.d[j])) {
+
				pkg_addshlib_provided(pkg, maybe_provided.d[i], PKG_SHLIB_FLAGS_NONE);
+
				vec_remove_and_free(&internal_provided, j, free);
			}
		}
-
		tll_remove_and_free(maybe_provided, s, free);
+
		vec_remove_and_free(&maybe_provided, i, free);
	}
-
	tll_free(maybe_provided);
+
	vec_free(&maybe_provided);
	/*
	 * Do not depend on libraries that a package provides itself
	 */
	pkg_cleanup_shlibs_required(pkg, &internal_provided);
-
	tll_free_and_free(internal_provided, free);
+
	vec_free_and_free(&internal_provided, free);

-
	tll_foreach(pkg->shlibs_provided, s) {
-
		if (match_ucl_lists(s->item,
+
	vec_foreach(pkg->shlibs_provided, i) {
+
		if (match_ucl_lists(pkg->shlibs_provided.d[i],
		    pkg_config_get("SHLIB_PROVIDE_IGNORE_GLOB"),
		    pkg_config_get("SHLIB_PROVIDE_IGNORE_REGEX"))) {
			pkg_debug(2,
			    "remove %s from provided shlibs for package %s as it "
			    "is matched by SHLIB_PROVIDE_IGNORE_GLOB/REGEX.",
-
			    s->item, pkg->name);
-
			tll_remove_and_free(pkg->shlibs_provided, s, free);
+
			    pkg->shlibs_provided.d[i], pkg->name);
+
			vec_remove_and_free(&pkg->shlibs_provided, i, free);
			continue;
		}
	}
@@ -622,7 +625,7 @@ pkg_analyse_files(struct pkgdb *db __unused, struct pkg *pkg, const char *stage)
	 * drop the provided one
	 */
	if (pkg_kv_get(&pkg->annotations, "no_provide_shlib") != NULL) {
-
		tll_free_and_free(pkg->shlibs_provided, free);
+
		vec_free_and_free(&pkg->shlibs_provided, free);
	}

	if (failures)
modified libpkg/pkg_add.c
@@ -1132,11 +1132,11 @@ scan_local_pkgs(struct pkg_add_db *db, bool fromstdin, struct localhashes *l, co
		}
		vec_foreach(db->localpkgs, i) {
			struct pkg *p = db->localpkgs.d[i];
-
			tll_foreach(p->shlibs_provided, sp) {
-
				pkghash_safe_add(l->shlibs_provides, sp->item, xstrdup(p->repopath), free);
+
			vec_foreach(p->shlibs_provided, j) {
+
				pkghash_safe_add(l->shlibs_provides, p->shlibs_provided.d[j], xstrdup(p->repopath), free);
			}
-
			tll_foreach(p->provides, sp) {
-
				pkghash_safe_add(l->provides, sp->item, xstrdup(p->repopath), free);
+
			vec_foreach(p->provides, j) {
+
				pkghash_safe_add(l->provides, p->provides.d[j], xstrdup(p->repopath), free);
			}
		}
	}
@@ -1264,21 +1264,22 @@ pkg_add_check_pkg_archive(struct pkg_add_db *db, struct pkg *pkg,
		}
	}

-
	tll_foreach(pkg->shlibs_required, s) {
+
	vec_foreach(pkg->shlibs_required, i) {
+
		const char *s = pkg->shlibs_required.d[i];
		if (!db->pkgbase && db->system_shlibs == NULL) {
			int ret;
			ret = scan_system_shlibs(&db->system_shlibs, ctx.pkg_rootdir);
			if (ret == EPKG_NOCOMPAT32)
				db->ignore_compat32 = true;
		}
-
		if (pkghash_get(db->system_shlibs, s->item) != NULL)
+
		if (pkghash_get(db->system_shlibs, s) != NULL)
			continue;
		pkghash_entry *founddep = NULL;
-
		if (pkgdb_is_shlib_provided(db->db, s->item))
+
		if (pkgdb_is_shlib_provided(db->db, s))
			continue;

		if (fromstdin) {
-
			pkg_emit_error("Missing shlib dependency: %s", s->item);
+
			pkg_emit_error("Missing shlib dependency: %s", s);
			if ((flags & PKG_ADD_FORCE_MISSING) == 0)
				goto cleanup;
			continue;
@@ -1287,8 +1288,8 @@ pkg_add_check_pkg_archive(struct pkg_add_db *db, struct pkg *pkg,
			scan_local_pkgs(db, fromstdin, &l, bd, ext);
			scanned = true;
		}
-
		if ((founddep = pkghash_get(l.shlibs_provides, s->item)) == NULL) {
-
			pkg_emit_error("Missing shlib dependency: %s", s->item);
+
		if ((founddep = pkghash_get(l.shlibs_provides, s)) == NULL) {
+
			pkg_emit_error("Missing shlib dependency: %s", s);
			if ((flags & PKG_ADD_FORCE_MISSING) == 0)
				goto cleanup;
			continue;
@@ -1306,13 +1307,14 @@ pkg_add_check_pkg_archive(struct pkg_add_db *db, struct pkg *pkg,
		}
	}

-
	tll_foreach(pkg->requires, s) {
+
	vec_foreach(pkg->requires, i) {
+
		const char *s = pkg->requires.d[i];
		pkghash_entry *founddep = NULL;
-
		if (pkgdb_is_provided(db->db, s->item))
+
		if (pkgdb_is_provided(db->db, s))
			continue;

		if (fromstdin) {
-
			pkg_emit_error("Missing require dependency: %s", s->item);
+
			pkg_emit_error("Missing require dependency: %s", s);
			if ((flags & PKG_ADD_FORCE_MISSING) == 0)
				goto cleanup;
			continue;
@@ -1321,8 +1323,8 @@ pkg_add_check_pkg_archive(struct pkg_add_db *db, struct pkg *pkg,
			scan_local_pkgs(db, fromstdin, &l, bd, ext);
			scanned = true;
		}
-
		if ((founddep = pkghash_get(l.provides, s->item)) == NULL) {
-
			pkg_emit_error("Missing require dependency: %s", s->item);
+
		if ((founddep = pkghash_get(l.provides, s)) == NULL) {
+
			pkg_emit_error("Missing require dependency: %s", s);
			if ((flags & PKG_ADD_FORCE_MISSING) == 0)
				goto cleanup;
			continue;
@@ -1388,7 +1390,7 @@ pkg_add_cleanup_old(struct pkgdb *db, struct pkg *old, struct pkg *new, struct t
					const char *libname;
					libname = strrchr(f->path, '/');
					if (libname != NULL &&
-
					    stringlist_contains(&old->shlibs_provided, libname+1)) {
+
					    charv_contains(&old->shlibs_provided, libname+1, false)) {
						backup_library(db, old, f->path);
					}
				}
modified libpkg/pkg_attributes.c
@@ -1,29 +1,9 @@
/*-
-
 * Copyright (c) 2011-2013 Baptiste Daroussin <bapt@FreeBSD.org>
+
 * Copyright (c) 2011-2025 Baptiste Daroussin <bapt@FreeBSD.org>
 * Copyright (c) 2011-2012 Julien Laffaye <jlaffaye@FreeBSD.org>
 * Copyright (c) 2013 Matthew Seaman <matthew@FreeBSD.org>
-
 * All rights reserved.
 *
-
 * Redistribution and use in source and binary forms, with or without
-
 * modification, are permitted provided that the following conditions
-
 * are met:
-
 * 1. Redistributions of source code must retain the above copyright
-
 *    notice, this list of conditions and the following disclaimer
-
 *    in this position and unchanged.
-
 * 2. Redistributions in binary form must reproduce the above copyright
-
 *    notice, this list of conditions and the following disclaimer in the
-
 *    documentation and/or other materials provided with the distribution.
-
 *
-
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
-
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-
 * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
-
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
 * SPDX-License-Identifier: BSD-2-Clause
 */

#include <assert.h>
@@ -204,13 +184,9 @@ pkg_stringlist_iterator(struct pkg_stringlist *l)
const char *
pkg_stringlist_next(struct pkg_stringlist_iterator *it)
{
-
	if (it->cur == NULL)
-
		it->cur = it->list->head;
-
	else
-
		it->cur = ((__typeof__(it->list->head))it->cur)->next;
-
	if (it->cur == NULL)
+
	if (it->pos >= it->list->len)
		return (NULL);
-
	return (((__typeof__(it->list->head))it->cur)->item);
+
	return (it->list->d[it->pos++]);
}

struct pkg_el *
@@ -356,8 +332,8 @@ pkg_get_element(struct pkg *p, pkg_attr a)
bool
stringlist_contains(stringlist_t *l, const char *name)
{
-
	tll_foreach(*l, e) {
-
		if (STREQ(e->item, name))
+
	tll_foreach(*l, s) {
+
		if (STREQ(s->item, name))
			return (true);
	}
	return (false);
modified libpkg/pkg_checksum.c
@@ -206,7 +206,6 @@ pkg_checksum_generate(struct pkg *pkg, char *dest, size_t destlen,
	struct pkg_option *option = NULL;
	struct pkg_dep *dep = NULL;
	struct pkg_file *f = NULL;
-
	int i;
	bool is_group = false;
	vec_init(&tofree);

@@ -228,20 +227,20 @@ pkg_checksum_generate(struct pkg *pkg, char *dest, size_t destlen,
		LL_APPEND(entries, kv_new(option->key, option->value));
	}

-
	tll_foreach(pkg->shlibs_required, s) {
-
		LL_APPEND(entries, kv_new("required_shlib", s->item));
+
	vec_foreach(pkg->shlibs_required, i) {
+
		LL_APPEND(entries, kv_new("required_shlib", pkg->shlibs_required.d[i]));
	}

-
	tll_foreach(pkg->shlibs_provided, s) {
-
		LL_APPEND(entries, kv_new("provided_shlib", s->item));
+
	vec_foreach(pkg->shlibs_provided, i) {
+
		LL_APPEND(entries, kv_new("provided_shlib", pkg->shlibs_provided.d[i]));
	}

-
	tll_foreach(pkg->users, u) {
-
		LL_APPEND(entries, kv_new("user", u->item));
+
	vec_foreach(pkg->users, i) {
+
		LL_APPEND(entries, kv_new("user", pkg->users.d[i]));
	}

-
	tll_foreach(pkg->groups, g) {
-
		LL_APPEND(entries, kv_new("group", g->item));
+
	vec_foreach(pkg->groups, i) {
+
		LL_APPEND(entries, kv_new("group", pkg->groups.d[i]));
	}

	while (pkg_deps(pkg, &dep) == EPKG_OK) {
@@ -254,12 +253,12 @@ pkg_checksum_generate(struct pkg *pkg, char *dest, size_t destlen,
		}
	}

-
	tll_foreach(pkg->provides, p) {
-
		LL_APPEND(entries, kv_new("provide", p->item));
+
	vec_foreach(pkg->provides, i) {
+
		LL_APPEND(entries, kv_new("provide", pkg->provides.d[i]));
	}

-
	tll_foreach(pkg->requires, r) {
-
		LL_APPEND(entries, kv_new("require", r->item));
+
	vec_foreach(pkg->requires, i) {
+
		LL_APPEND(entries, kv_new("require", pkg->requires.d[i]));
	}

	if (inc_scripts) {
@@ -270,8 +269,8 @@ pkg_checksum_generate(struct pkg *pkg, char *dest, size_t destlen,
			}
		}
		for (int i = 0; i < PKG_NUM_LUA_SCRIPTS; i++) {
-
			tll_foreach(pkg->lua_scripts[i], s)
-
				LL_APPEND(entries, kv_new("lua_script", s->item));
+
			vec_foreach(pkg->lua_scripts[i], j)
+
				LL_APPEND(entries, kv_new("lua_script", pkg->lua_scripts[i].d[j]));
		}
	}

@@ -290,7 +289,7 @@ pkg_checksum_generate(struct pkg *pkg, char *dest, size_t destlen,
	}

	if (checksum_types[type].encfunc) {
-
		i = snprintf(dest, destlen, "%d%c%d%c", PKG_CHECKSUM_CUR_VERSION,
+
		size_t i = snprintf(dest, destlen, "%d%c%d%c", PKG_CHECKSUM_CUR_VERSION,
				PKG_CKSUM_SEPARATOR, type, PKG_CKSUM_SEPARATOR);
		assert(i < destlen);
		checksum_types[type].encfunc(bdigest, blen, dest + i, destlen - i);
modified libpkg/pkg_cudf.c
@@ -136,12 +136,12 @@ cudf_emit_pkg(struct pkg *pkg, int version, FILE *f,
	}

	column = 0;
-
	if (tll_length(pkg->provides) > 0) {
+
	if (vec_len(&pkg->provides) > 0) {
		if (fprintf(f, "provides: ") < 0)
			return (EPKG_FATAL);
-
		tll_foreach(pkg->provides, p) {
-
			if (cudf_print_element(f, p->item,
-
			    column + 1 == tll_length(pkg->provides), &column) < 0) {
+
		vec_foreach(pkg->provides, i) {
+
			if (cudf_print_element(f, pkg->provides.d[i],
+
			    column + 1 == vec_len(&pkg->provides), &column) < 0) {
				return (EPKG_FATAL);
			}
		}
modified libpkg/pkg_delete.c
@@ -167,21 +167,22 @@ pkg_add_dir_to_del(struct pkg *pkg, const char *file, const char *dir)
		path[len] = '\0';
	}

-
	tll_foreach(pkg->dir_to_del, d) {
-
		len2 = strlen(d->item);
-
		if (len2 >= len && strncmp(path, d->item, len) == 0)
+
	vec_foreach(pkg->dir_to_del, i) {
+
		len2 = strlen(pkg->dir_to_del.d[i]);
+
		if (len2 >= len && strncmp(path, pkg->dir_to_del.d[i], len) == 0)
			return;

-
		if (strncmp(path, d->item, len2) == 0) {
+
		if (strncmp(path, pkg->dir_to_del.d[i], len2) == 0) {
			pkg_debug(1, "Replacing in deletion %s with %s",
-
			    d->item, path);
-
			tll_remove_and_free(pkg->dir_to_del, d, free);
-
			break;
+
			    pkg->dir_to_del.d[i], path);
+
			free(pkg->dir_to_del.d[i]);
+
			pkg->dir_to_del.d[i] = xstrdup(path);
+
			return;
		}
	}

	pkg_debug(1, "Adding to deletion %s", path);
-
	tll_push_back(pkg->dir_to_del, xstrdup(path));
+
	vec_push(&pkg->dir_to_del, xstrdup(path));
}

static void
@@ -272,9 +273,8 @@ pkg_effective_rmdir(struct pkgdb *db, struct pkg *pkg)
	char prefix_r[MAXPATHLEN];

	snprintf(prefix_r, sizeof(prefix_r), "%s", pkg->prefix[0] ? pkg->prefix + 1 : "");
-
	tll_foreach(pkg->dir_to_del, d) {
-
		rmdir_p(db, pkg, d->item, prefix_r);
-
		tll_remove_and_free(pkg->dir_to_del, d, free);
+
	vec_foreach(pkg->dir_to_del, i) {
+
		rmdir_p(db, pkg, pkg->dir_to_del.d[i], prefix_r);
	}
}

@@ -408,7 +408,7 @@ pkg_delete_dir(struct pkg *pkg, struct pkg_dir *dir)
	if ((strncmp(prefix_rel, path, len) == 0) && path[len] == '/') {
		pkg_add_dir_to_del(pkg, NULL, path);
	} else {
-
		tll_push_back(pkg->dir_to_del, xstrdup(path));
+
		vec_push(&pkg->dir_to_del, xstrdup(path));
	}
}

modified libpkg/pkg_jobs.c
@@ -562,15 +562,15 @@ pkg_jobs_process_delete_request(struct pkg_jobs *j)
				rc = EPKG_FATAL;
		}

-
		tll_foreach(lp->provides, i) {
-
			if (!delete_process_provides(j, lp, i->item,
+
		vec_foreach(lp->provides, i) {
+
			if (!delete_process_provides(j, lp, lp->provides.d[i],
			    pkgdb_query_provide, pkgdb_query_require,
			    &to_process))
				rc = EPKG_FATAL;
		}

-
		tll_foreach(lp->shlibs_provided, i) {
-
			if (!delete_process_provides(j, lp, i->item,
+
		vec_foreach(lp->shlibs_provided, i) {
+
			if (!delete_process_provides(j, lp, lp->shlibs_provided.d[i],
			    pkgdb_query_shlib_provide,
			    pkgdb_query_shlib_require, &to_process))
				rc = EPKG_FATAL;
@@ -663,8 +663,8 @@ pkg_jobs_test_automatic(struct pkg_jobs *j, struct pkg *p)
			return (false);
	}

-
	tll_foreach(p->provides, i) {
-
		it = pkgdb_query_require(j->db, i->item);
+
	vec_foreach(p->provides, i) {
+
		it = pkgdb_query_require(j->db, p->provides.d[i]);
		if (it == NULL)
			continue;
		npkg = NULL;
@@ -678,8 +678,8 @@ pkg_jobs_test_automatic(struct pkg_jobs *j, struct pkg *p)
		pkgdb_it_free(it);
	}

-
	tll_foreach(p->shlibs_provided, i) {
-
		it = pkgdb_query_shlib_require(j->db, i->item);
+
	vec_foreach(p->shlibs_provided, i) {
+
		it = pkgdb_query_shlib_require(j->db, p->shlibs_provided.d[i]);
		if (it == NULL)
			continue;
		npkg = NULL;
@@ -1180,19 +1180,19 @@ pkg_jobs_need_upgrade(struct pkghash *system_shlibs, struct pkg *rp, struct pkg
	}

	/* Provides */
-
	if (tll_length(rp->provides) != tll_length(lp->provides)) {
+
	if (vec_len(&rp->provides) != vec_len(&lp->provides)) {
		free(rp->reason);
		rp->reason = xstrdup("provides changed");
		return (true);
	}
-
	l1 = xcalloc(tll_length(lp->provides), sizeof (char*));
+
	l1 = xcalloc(vec_len(&lp->provides), sizeof (char*));
	i = 0;
-
	tll_foreach(lp->provides, l) {
-
		l1[i++] = l->item;
+
	vec_foreach(lp->provides, j) {
+
		l1[i++] = lp->provides.d[j];
	}
	i = 0;
-
	tll_foreach(rp->provides, r) {
-
		if (!STREQ(r->item, l1[i])) {
+
	vec_foreach(rp->provides, j) {
+
		if (!STREQ(rp->provides.d[j], l1[i])) {
			free(rp->reason);
			rp->reason = xstrdup("provides changed");
			free(l1);
@@ -1202,19 +1202,19 @@ pkg_jobs_need_upgrade(struct pkghash *system_shlibs, struct pkg *rp, struct pkg
	free(l1);

	/* Requires */
-
	if (tll_length(rp->requires) != tll_length(lp->requires)) {
+
	if (vec_len(&rp->requires) != vec_len(&lp->requires)) {
		free(rp->reason);
		rp->reason = xstrdup("requires changed");
		return (true);
	}
-
	l1 = xcalloc(tll_length(lp->requires), sizeof (char*));
+
	l1 = xcalloc(vec_len(&lp->requires), sizeof (char*));
	i = 0;
-
	tll_foreach(lp->requires, l) {
-
		l1[i++] = l->item;
+
	vec_foreach(lp->requires, j) {
+
		l1[i++] = lp->requires.d[j];
	}
	i = 0;
-
	tll_foreach(rp->requires, r) {
-
		if (!STREQ(r->item, l1[i])) {
+
	vec_foreach(rp->requires, j) {
+
		if (!STREQ(rp->requires.d[j], l1[i])) {
			free(rp->reason);
			rp->reason = xstrdup("requires changed");
			free(l1);
@@ -1224,19 +1224,19 @@ pkg_jobs_need_upgrade(struct pkghash *system_shlibs, struct pkg *rp, struct pkg
	free(l1);

	/* Finish by the shlibs */
-
	if (tll_length(rp->shlibs_provided) != tll_length(lp->shlibs_provided)) {
+
	if (vec_len(&rp->shlibs_provided) != vec_len(&lp->shlibs_provided)) {
		free(rp->reason);
		rp->reason = xstrdup("provided shared library changed");
		return (true);
	}
-
	l1 = xcalloc(tll_length(lp->shlibs_provided), sizeof (char*));
+
	l1 = xcalloc(vec_len(&lp->shlibs_provided), sizeof (char*));
	i = 0;
-
	tll_foreach(lp->shlibs_provided, l) {
-
		l1[i++] = l->item;
+
	vec_foreach(lp->shlibs_provided, j) {
+
		l1[i++] = lp->shlibs_provided.d[j];
	}
	i = 0;
-
	tll_foreach(rp->shlibs_provided, r) {
-
		if (!STREQ(r->item, l1[i])) {
+
	vec_foreach(rp->shlibs_provided, j) {
+
		if (!STREQ(rp->shlibs_provided.d[j], l1[i])) {
			free(rp->reason);
			rp->reason = xstrdup("provided shared library changed");
			free(l1);
@@ -1246,20 +1246,20 @@ pkg_jobs_need_upgrade(struct pkghash *system_shlibs, struct pkg *rp, struct pkg
	}
	free(l1);

-
	size_t cntr = tll_length(rp->shlibs_required);
-
	size_t cntl = tll_length(lp->shlibs_required);
+
	size_t cntr = vec_len(&rp->shlibs_required);
+
	size_t cntl = vec_len(&lp->shlibs_required);
	if (cntr != cntl) {
		if (system_shlibs != NULL) {
		/*
		 * before considering shlibs we need to check if we are running
		 * pkgbase
		 */
-
			tll_foreach(rp->shlibs_required, r) {
-
				if (pkghash_get(system_shlibs, r->item) != NULL)
+
			vec_foreach(rp->shlibs_required, i) {
+
				if (pkghash_get(system_shlibs, rp->shlibs_required.d[i]) != NULL)
					cntr--;
			}
-
			tll_foreach(lp->shlibs_required, l) {
-
				if (pkghash_get(system_shlibs, l->item) != NULL)
+
			vec_foreach(lp->shlibs_required, i) {
+
				if (pkghash_get(system_shlibs, lp->shlibs_required.d[i]) != NULL)
					cntl--;
			}
		}
@@ -1269,18 +1269,18 @@ pkg_jobs_need_upgrade(struct pkghash *system_shlibs, struct pkg *rp, struct pkg
			return (true);
		}
	}
-
	l1 = xcalloc(tll_length(lp->shlibs_required), sizeof (char*));
+
	l1 = xcalloc(vec_len(&lp->shlibs_required), sizeof (char*));
	i = 0;
-
	tll_foreach(lp->shlibs_required, l) {
-
		if (pkghash_get(system_shlibs, l->item) != NULL)
+
	vec_foreach(lp->shlibs_required, j) {
+
		if (pkghash_get(system_shlibs, lp->shlibs_required.d[j]) != NULL)
			continue;
-
		l1[i++] = l->item;
+
		l1[i++] = lp->shlibs_required.d[j];
	}
	i = 0;
-
	tll_foreach(rp->shlibs_required, r) {
-
		if (pkghash_get(system_shlibs, r->item) != NULL)
+
	vec_foreach(rp->shlibs_required, j) {
+
		if (pkghash_get(system_shlibs, rp->shlibs_required.d[j]) != NULL)
			continue;
-
		if (!STREQ(r->item, l1[i])) {
+
		if (!STREQ(rp->shlibs_required.d[j], l1[i])) {
			free(rp->reason);
			rp->reason = xstrdup("required shared library changed");
			free(l1);
modified libpkg/pkg_jobs_universe.c
@@ -472,37 +472,38 @@ pkg_jobs_universe_process_shlibs(struct pkg_jobs_universe *universe,
	struct pkgdb_it *it;
	int rc;

-
	tll_foreach(pkg->shlibs_required, s) {
-
		if (pkghash_get(universe->j->system_shlibs, s->item) != NULL)
+
	vec_foreach(pkg->shlibs_required, i) {
+
		const char *s = pkg->shlibs_required.d[i];
+
		if (pkghash_get(universe->j->system_shlibs, s) != NULL)
			continue;
-
		if (pkghash_get(universe->provides, s->item) != NULL)
+
		if (pkghash_get(universe->provides, s) != NULL)
			continue;

		/* Check for local provides */
-
		it = pkgdb_query_shlib_provide(universe->j->db, s->item);
+
		it = pkgdb_query_shlib_provide(universe->j->db, s);
		if (it != NULL) {
			rc = pkg_jobs_universe_handle_provide(universe, it,
-
			    s->item, true, pkg);
+
			    s, true, pkg);
			pkgdb_it_free(it);

			if (rc != EPKG_OK) {
				dbg(1, "cannot find local packages that provide library %s "
						"required for %s",
-
						s->item, pkg->name);
+
						s, pkg->name);
			}
		}
		/* Not found, search in the repos */
		it = pkgdb_repo_shlib_provide(universe->j->db,
-
			s->item, universe->j->reponames);
+
			s, universe->j->reponames);

		if (it != NULL) {
-
			rc = pkg_jobs_universe_handle_provide(universe, it, s->item, true, pkg);
+
			rc = pkg_jobs_universe_handle_provide(universe, it, s, true, pkg);
			pkgdb_it_free(it);

			if (rc != EPKG_OK) {
				dbg(1, "cannot find remote packages that provide library %s "
						"required for %s",
-
				    s->item, pkg->name);
+
				    s, pkg->name);
			}
		}
	}
@@ -517,35 +518,36 @@ pkg_jobs_universe_process_provides_requires(struct pkg_jobs_universe *universe,
	struct pkgdb_it *it;
	int rc;

-
	tll_foreach(pkg->requires, r) {
-
		if (pkghash_get(universe->provides, r->item) != NULL)
+
	vec_foreach(pkg->requires, i) {
+
		const char *r = pkg->requires.d[i];
+
		if (pkghash_get(universe->provides, r) != NULL)
			continue;

		/* Check for local provides */
-
		it = pkgdb_query_provide(universe->j->db, r->item);
+
		it = pkgdb_query_provide(universe->j->db, r);
		if (it != NULL) {
-
			rc = pkg_jobs_universe_handle_provide(universe, it, r->item, false, pkg);
+
			rc = pkg_jobs_universe_handle_provide(universe, it, r, false, pkg);
			pkgdb_it_free(it);

			if (rc != EPKG_OK) {
				dbg(1, "cannot find local packages that provide %s "
						"required for %s",
-
						r->item, pkg->name);
+
						r, pkg->name);
			}
		}

		/* Not found, search in the repos */
		it = pkgdb_repo_provide(universe->j->db,
-
			r->item, universe->j->reponames);
+
			r, universe->j->reponames);

		if (it != NULL) {
-
			rc = pkg_jobs_universe_handle_provide(universe, it, r->item, false, pkg);
+
			rc = pkg_jobs_universe_handle_provide(universe, it, r, false, pkg);
			pkgdb_it_free(it);

			if (rc != EPKG_OK) {
				dbg(1, "cannot find remote packages that provide %s "
						"required for %s",
-
				    r->item, pkg->name);
+
				    r, pkg->name);
				return (rc);
			}
		}
modified libpkg/pkg_manifest.c
@@ -1,29 +1,9 @@
/*-
-
 * Copyright (c) 2011-2023 Baptiste Daroussin <bapt@FreeBSD.org>
+
 * Copyright (c) 2011-2025 Baptiste Daroussin <bapt@FreeBSD.org>
 * Copyright (c) 2011-2012 Julien Laffaye <jlaffaye@FreeBSD.org>
 * Copyright (c) 2013-2014 Vsevolod Stakhov <vsevolod@FreeBSD.org>
-
 * All rights reserved.
 *
-
 * Redistribution and use in source and binary forms, with or without
-
 * modification, are permitted provided that the following conditions
-
 * are met:
-
 * 1. Redistributions of source code must retain the above copyright
-
 *    notice, this list of conditions and the following disclaimer
-
 *    in this position and unchanged.
-
 * 2. Redistributions in binary form must reproduce the above copyright
-
 *    notice, this list of conditions and the following disclaimer in the
-
 *    documentation and/or other materials provided with the distribution.
-
 *
-
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
-
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-
 * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
-
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
 * SPDX-License-Identifier: BSD-2-Clause
 */

#include <sys/types.h>
@@ -983,10 +963,10 @@ pkg_emit_object(struct pkg *pkg, short flags)

	dbg(4, "Emitting licenses");
	seq = NULL;
-
	tll_foreach(pkg->licenses, l) {
+
	vec_foreach(pkg->licenses, i) {
		if (seq == NULL)
			seq = ucl_object_typed_new(UCL_ARRAY);
-
		ucl_array_append(seq, ucl_object_fromstring(l->item));
+
		ucl_array_append(seq, ucl_object_fromstring(pkg->licenses.d[i]));
	}
	if (seq)
		ucl_object_insert_key(top, seq, "licenses", 8, false);
@@ -1018,50 +998,50 @@ pkg_emit_object(struct pkg *pkg, short flags)

	dbg(4, "Emitting categories");
	seq = NULL;
-
	tll_foreach(pkg->categories, c) {
+
	vec_foreach(pkg->categories, i) {
		if (seq == NULL)
			seq = ucl_object_typed_new(UCL_ARRAY);
-
		ucl_array_append(seq, ucl_object_fromstring(c->item));
+
		ucl_array_append(seq, ucl_object_fromstring(pkg->categories.d[i]));
	}
	if (seq)
		ucl_object_insert_key(top, seq, "categories", 10, false);

	dbg(4, "Emitting users");
	seq = NULL;
-
	tll_foreach(pkg->users, u) {
+
	vec_foreach(pkg->users, i) {
		if (seq == NULL)
			seq = ucl_object_typed_new(UCL_ARRAY);
-
		ucl_array_append(seq, ucl_object_fromstring(u->item));
+
		ucl_array_append(seq, ucl_object_fromstring(pkg->users.d[i]));
	}
	if (seq)
		ucl_object_insert_key(top, seq, "users", 5, false);

	dbg(4, "Emitting groups");
	seq = NULL;
-
	tll_foreach(pkg->groups, g) {
+
	vec_foreach(pkg->groups, i) {
		if (seq == NULL)
			seq = ucl_object_typed_new(UCL_ARRAY);
-
		ucl_array_append(seq, ucl_object_fromstring(g->item));
+
		ucl_array_append(seq, ucl_object_fromstring(pkg->groups.d[i]));
	}
	if (seq)
		ucl_object_insert_key(top, seq, "groups", 6, false);

	dbg(4, "Emitting shibs_required");
	seq = NULL;
-
	tll_foreach(pkg->shlibs_required, s) {
+
	vec_foreach(pkg->shlibs_required, i) {
		if (seq == NULL)
			seq = ucl_object_typed_new(UCL_ARRAY);
-
		ucl_array_append(seq, ucl_object_fromstring(s->item));
+
		ucl_array_append(seq, ucl_object_fromstring(pkg->shlibs_required.d[i]));
	}
	if (seq)
		ucl_object_insert_key(top, seq, "shlibs_required", 15, false);

	dbg(4, "Emitting shlibs_provided");
	seq = NULL;
-
	tll_foreach(pkg->shlibs_provided, s) {
+
	vec_foreach(pkg->shlibs_provided, i) {
		if (seq == NULL)
			seq = ucl_object_typed_new(UCL_ARRAY);
-
		ucl_array_append(seq, ucl_object_fromstring(s->item));
+
		ucl_array_append(seq, ucl_object_fromstring(pkg->shlibs_provided.d[i]));
	}
	if (seq)
		ucl_object_insert_key(top, seq, "shlibs_provided", 15, false);
@@ -1078,20 +1058,20 @@ pkg_emit_object(struct pkg *pkg, short flags)

	dbg(4, "Emitting provides");
	seq = NULL;
-
	tll_foreach(pkg->provides, p) {
+
	vec_foreach(pkg->provides, i) {
		if (seq == NULL)
			seq = ucl_object_typed_new(UCL_ARRAY);
-
		ucl_array_append(seq, ucl_object_fromstring(p->item));
+
		ucl_array_append(seq, ucl_object_fromstring(pkg->provides.d[i]));
	}
	if (seq)
		ucl_object_insert_key(top, seq, "provides", 8, false);

	dbg(4, "Emitting requires");
	seq = NULL;
-
	tll_foreach(pkg->requires, r) {
+
	vec_foreach(pkg->requires, i) {
		if (seq == NULL)
			seq = ucl_object_typed_new(UCL_ARRAY);
-
		ucl_array_append(seq, ucl_object_fromstring(r->item));
+
		ucl_array_append(seq, ucl_object_fromstring(pkg->requires.d[i]));
	}
	if (seq)
		ucl_object_insert_key(top, seq, "requires", 8, false);
@@ -1220,7 +1200,7 @@ pkg_emit_object(struct pkg *pkg, short flags)
		dbg(4, "Emitting lua scripts");
		map = NULL;
		for (i = 0; i < PKG_NUM_LUA_SCRIPTS; i++) {
-
			if (tll_length(pkg->lua_scripts[i]) == 0)
+
			if (vec_len(&pkg->lua_scripts[i]) == 0)
				continue;
			switch(i) {
			case PKG_LUA_PRE_INSTALL:
modified libpkg/pkg_printf.c
@@ -913,7 +913,7 @@ format_shlibs_required(xstring *buf, const void *data, struct percent_esc *p)
	const struct pkg	*pkg = data;

	if (p->flags & (PP_ALTERNATE_FORM1|PP_ALTERNATE_FORM2))
-
		return (list_count(buf, tll_length(pkg->shlibs_required), p));
+
		return (list_count(buf, vec_len(&pkg->shlibs_required), p));
	else {
		int			 count;

@@ -922,13 +922,13 @@ format_shlibs_required(xstring *buf, const void *data, struct percent_esc *p)
		count = 1;
		fflush(p->sep_fmt->fp);
		fflush(p->item_fmt->fp);
-
		tll_foreach(pkg->shlibs_required, r) {
+
		vec_foreach(pkg->shlibs_required, i) {
			if (count > 1)
				iterate_item(buf, pkg, p->sep_fmt->buf,
-
					     r->item, count, PP_B);
+
					     pkg->shlibs_required.d[i], count, PP_B);

			iterate_item(buf, pkg, p->item_fmt->buf,
-
				     r->item, count, PP_B);
+
				     pkg->shlibs_required.d[i], count, PP_B);
			count++;
		}
	}
@@ -960,19 +960,19 @@ format_categories(xstring *buf, const void *data, struct percent_esc *p)
	int			 count = 0;

	if (p->flags & (PP_ALTERNATE_FORM1|PP_ALTERNATE_FORM2)) {
-
		return (list_count(buf, tll_length(pkg->categories), p));
+
		return (list_count(buf, vec_len(&pkg->categories), p));
	} else {
		set_list_defaults(p, "%Cn", ", ");

		count = 1;
		fflush(p->sep_fmt->fp);
		fflush(p->item_fmt->fp);
-
		tll_foreach(pkg->categories, c) {
+
		vec_foreach(pkg->categories, i) {
			if (count > 1)
				iterate_item(buf, pkg, p->sep_fmt->buf,
-
				    c->item, count, PP_C);
+
				    pkg->categories.d[i], count, PP_C);

-
			iterate_item(buf, pkg, p->item_fmt->buf, c->item,
+
			iterate_item(buf, pkg, p->item_fmt->buf, pkg->categories.d[i],
			    count, PP_C);
			count++;
		}
@@ -1175,7 +1175,7 @@ format_groups(xstring *buf, const void *data, struct percent_esc *p)
	const struct pkg	*pkg = data;

	if (p->flags & (PP_ALTERNATE_FORM1|PP_ALTERNATE_FORM2))
-
		return (list_count(buf, tll_length(pkg->groups), p));
+
		return (list_count(buf, vec_len(&pkg->groups), p));
	else {
		int	 count;

@@ -1184,13 +1184,13 @@ format_groups(xstring *buf, const void *data, struct percent_esc *p)
		count = 1;
		fflush(p->sep_fmt->fp);
		fflush(p->item_fmt->fp);
-
		tll_foreach(pkg->groups, g) {
+
		vec_foreach(pkg->groups, i) {
			if (count > 1)
				iterate_item(buf, pkg, p->sep_fmt->buf,
-
					     g->item, count, PP_G);
+
					     pkg->groups.d[i], count, PP_G);

			iterate_item(buf, pkg,p->item_fmt->buf,
-
				     g->item, count, PP_G);
+
				     pkg->groups.d[i], count, PP_G);
			count++;
		}
	}
@@ -1231,19 +1231,19 @@ format_licenses(xstring *buf, const void *data, struct percent_esc *p)
	int			 count = 0;

	if (p->flags & (PP_ALTERNATE_FORM1|PP_ALTERNATE_FORM2)) {
-
		return (list_count(buf, tll_length(pkg->licenses), p));
+
		return (list_count(buf, vec_len(&pkg->licenses), p));
	} else {
		set_list_defaults(p, "%Ln", " %l ");

		count = 1;
		fflush(p->sep_fmt->fp);
		fflush(p->item_fmt->fp);
-
		tll_foreach(pkg->licenses, l) {
+
		vec_foreach(pkg->licenses, i) {
			if (count > 1)
				iterate_item(buf, pkg, p->sep_fmt->buf,
-
				    l->item, count, PP_L);
+
				    pkg->licenses.d[i], count, PP_L);

-
			iterate_item(buf, pkg, p->item_fmt->buf, l->item,
+
			iterate_item(buf, pkg, p->item_fmt->buf, pkg->licenses.d[i],
			    count, PP_L);
			count++;
		}
@@ -1461,7 +1461,7 @@ format_users(xstring *buf, const void *data, struct percent_esc *p)
	const struct pkg	*pkg = data;

	if (p->flags & (PP_ALTERNATE_FORM1|PP_ALTERNATE_FORM2))
-
		return (list_count(buf, tll_length(pkg->users), p));
+
		return (list_count(buf, vec_len(&pkg->users), p));
	else {
		int	 count;

@@ -1470,13 +1470,13 @@ format_users(xstring *buf, const void *data, struct percent_esc *p)
		count = 1;
		fflush(p->sep_fmt->fp);
		fflush(p->item_fmt->fp);
-
		tll_foreach(pkg->users, u) {
+
		vec_foreach(pkg->users, i) {
			if (count > 1)
				iterate_item(buf, pkg, p->sep_fmt->buf,
-
					     u->item, count, PP_U);
+
					     pkg->users.d[i], count, PP_U);

			iterate_item(buf, pkg, p->item_fmt->buf,
-
				     u->item, count, PP_U);
+
				     pkg->users.d[i], count, PP_U);
			count++;
		}
	}
@@ -1527,7 +1527,7 @@ format_required(xstring *buf, const void *data, struct percent_esc *p)
	const struct pkg	*pkg = data;

	if (p->flags & (PP_ALTERNATE_FORM1|PP_ALTERNATE_FORM2))
-
		return (list_count(buf, tll_length(pkg->requires), p));
+
		return (list_count(buf, vec_len(&pkg->requires), p));
	else {
		int	 count;

@@ -1536,13 +1536,13 @@ format_required(xstring *buf, const void *data, struct percent_esc *p)
		count = 1;
		fflush(p->sep_fmt->fp);
		fflush(p->item_fmt->fp);
-
		tll_foreach(pkg->requires, r) {
+
		vec_foreach(pkg->requires, i) {
			if (count > 1)
				iterate_item(buf, pkg, p->sep_fmt->buf,
-
					     r->item, count, PP_Y);
+
					     pkg->requires.d[i], count, PP_Y);

			iterate_item(buf, pkg, p->item_fmt->buf,
-
				     r->item, count, PP_Y);
+
				     pkg->requires.d[i], count, PP_Y);
			count++;
		}
	}
@@ -1584,7 +1584,7 @@ format_shlibs_provided(xstring *buf, const void *data, struct percent_esc *p)
	const struct pkg	*pkg = data;

	if (p->flags & (PP_ALTERNATE_FORM1|PP_ALTERNATE_FORM2))
-
		return (list_count(buf, tll_length(pkg->shlibs_provided), p));
+
		return (list_count(buf, vec_len(&pkg->shlibs_provided), p));
	else {
		int	 count;

@@ -1593,13 +1593,13 @@ format_shlibs_provided(xstring *buf, const void *data, struct percent_esc *p)
		count = 1;
		fflush(p->sep_fmt->fp);
		fflush(p->item_fmt->fp);
-
		tll_foreach(pkg->shlibs_provided, r) {
+
		vec_foreach(pkg->shlibs_provided, i) {
			if (count > 1)
				iterate_item(buf, pkg, p->sep_fmt->buf,
-
					     r->item, count, PP_b);
+
					     pkg->shlibs_provided.d[i], count, PP_b);

			iterate_item(buf, pkg, p->item_fmt->buf,
-
				     r->item, count, PP_b);
+
				     pkg->shlibs_provided.d[i], count, PP_b);
			count++;
		}
	}
@@ -1925,7 +1925,7 @@ format_provided(xstring *buf, const void *data, struct percent_esc *p)
	const struct pkg	*pkg = data;

	if (p->flags & (PP_ALTERNATE_FORM1|PP_ALTERNATE_FORM2))
-
		return (list_count(buf, tll_length(pkg->provides), p));
+
		return (list_count(buf, vec_len(&pkg->provides), p));
	else {
		int	 count;

@@ -1934,13 +1934,13 @@ format_provided(xstring *buf, const void *data, struct percent_esc *p)
		count = 1;
		fflush(p->sep_fmt->fp);
		fflush(p->item_fmt->fp);
-
		tll_foreach(pkg->provides, r) {
+
		vec_foreach(pkg->provides, i) {
			if (count > 1)
				iterate_item(buf, pkg, p->sep_fmt->buf,
-
					     r->item, count, PP_y);
+
					     pkg->provides.d[i], count, PP_y);

			iterate_item(buf, pkg, p->item_fmt->buf,
-
				     r->item, count, PP_y);
+
				     pkg->provides.d[i], count, PP_y);
			count++;
		}
	}
modified libpkg/pkg_solve.c
@@ -308,7 +308,7 @@ pkg_solve_handle_provide (struct pkg_solve_problem *problem,
		pkg = curvar->unit->pkg;

		if (pr->is_shlib) {
-
			libfound = stringlist_contains(&pkg->shlibs_provided, pr->provide);
+
			libfound = charv_contains(&pkg->shlibs_provided, pr->provide, false);
			/* Skip incompatible ABI as well */
			if (libfound && !STREQ(pkg->abi, orig->abi)) {
				dbg(2, "require %s: package %s-%s(%c) provides wrong ABI %s, "
@@ -318,7 +318,7 @@ pkg_solve_handle_provide (struct pkg_solve_problem *problem,
			}
		}
		else {
-
			providefound = stringlist_contains(&pkg->provides, pr->provide);
+
			providefound = charv_contains(&pkg->provides, pr->provide, false);
		}

		if (!providefound && !libfound) {
@@ -721,22 +721,23 @@ pkg_solve_process_universe_variable(struct pkg_solve_problem *problem,
		}

		/* Shlibs */
-
		tll_foreach(pkg->shlibs_required, s) {
+
		vec_foreach(pkg->shlibs_required, i) {
+
			const char *s = pkg->shlibs_required.d[i];
			/* Ignore 32 bit libraries */
-
			if (j->ignore_compat32 && str_ends_with(s->item, ":32"))
+
			if (j->ignore_compat32 && str_ends_with(s, ":32"))
				continue;
-
			if (pkghash_get(j->system_shlibs, s->item) != NULL) {
+
			if (pkghash_get(j->system_shlibs, s) != NULL) {
				/* The shlib is provided by the system */
				continue;
			}
			if (pkg_solve_add_require_rule(problem, cur_var,
-
			    s->item, cur_var->assumed_reponame) != EPKG_OK) {
+
			    s, cur_var->assumed_reponame) != EPKG_OK) {
				continue;
			}
		}
-
		tll_foreach(pkg->requires, r) {
+
		vec_foreach(pkg->requires, i) {
			if (pkg_solve_add_require_rule(problem, cur_var,
-
			    r->item, cur_var->assumed_reponame) != EPKG_OK) {
+
			    pkg->requires.d[i], cur_var->assumed_reponame) != EPKG_OK) {
				continue;
			}
		}
modified libpkg/pkgdb.c
@@ -1,5 +1,5 @@
/*-
-
 * Copyright (c) 2011-2024 Baptiste Daroussin <bapt@FreeBSD.org>
+
 * Copyright (c) 2011-2025 Baptiste Daroussin <bapt@FreeBSD.org>
 * Copyright (c) 2011-2012 Julien Laffaye <jlaffaye@FreeBSD.org>
 * Copyright (c) 2011 Will Andrews <will@FreeBSD.org>
 * Copyright (c) 2011 Philippe Pepiot <phil@philpep.org>
@@ -1833,10 +1833,10 @@ pkgdb_register_pkg(struct pkgdb *db, struct pkg *pkg, int forced,
	 * Insert categories
	 */

-
	tll_foreach(pkg->categories, c) {
-
		ret = run_prstmt(CATEGORY1, c->item);
+
	vec_foreach(pkg->categories, i) {
+
		ret = run_prstmt(CATEGORY1, pkg->categories.d[i]);
		if (ret == SQLITE_DONE)
-
			ret = run_prstmt(CATEGORY2, package_id, c->item);
+
			ret = run_prstmt(CATEGORY2, package_id, pkg->categories.d[i]);
		if (ret != SQLITE_DONE) {
			ERROR_STMT_SQLITE(s, STMT(CATEGORY2));
			goto cleanup;
@@ -1847,11 +1847,11 @@ pkgdb_register_pkg(struct pkgdb *db, struct pkg *pkg, int forced,
	 * Insert licenses
	 */

-
	tll_foreach(pkg->licenses, l) {
-
		if (run_prstmt(LICENSES1, l->item)
+
	vec_foreach(pkg->licenses, i) {
+
		if (run_prstmt(LICENSES1, pkg->licenses.d[i])
		    != SQLITE_DONE
		    ||
-
		    run_prstmt(LICENSES2, package_id, l->item)
+
		    run_prstmt(LICENSES2, package_id, pkg->licenses.d[i])
		    != SQLITE_DONE) {
			ERROR_STMT_SQLITE(s, STMT(LICENSES2));
			goto cleanup;
@@ -1862,11 +1862,11 @@ pkgdb_register_pkg(struct pkgdb *db, struct pkg *pkg, int forced,
	 * Insert users
	 */

-
	tll_foreach(pkg->users, u) {
-
		if (run_prstmt(USERS1, u->item)
+
	vec_foreach(pkg->users, i) {
+
		if (run_prstmt(USERS1, pkg->users.d[i])
		    != SQLITE_DONE
		    ||
-
		    run_prstmt(USERS2, package_id, u->item)
+
		    run_prstmt(USERS2, package_id, pkg->users.d[i])
		    != SQLITE_DONE) {
			ERROR_STMT_SQLITE(s, STMT(USERS2));
			goto cleanup;
@@ -1877,11 +1877,11 @@ pkgdb_register_pkg(struct pkgdb *db, struct pkg *pkg, int forced,
	 * Insert groups
	 */

-
	tll_foreach(pkg->groups, g) {
-
		if (run_prstmt(GROUPS1, g->item)
+
	vec_foreach(pkg->groups, i) {
+
		if (run_prstmt(GROUPS1, pkg->groups.d[i])
		    != SQLITE_DONE
		    ||
-
		    run_prstmt(GROUPS2, package_id, g->item)
+
		    run_prstmt(GROUPS2, package_id, pkg->groups.d[i])
		    != SQLITE_DONE) {
			ERROR_STMT_SQLITE(s, STMT(GROUPS2));
			goto cleanup;
@@ -1986,10 +1986,10 @@ pkgdb_insert_lua_scripts(struct pkg *pkg, int64_t package_id, sqlite3 *s)
	int64_t			 i;

	for (i = 0; i < PKG_NUM_LUA_SCRIPTS; i++) {
-
		tll_foreach(pkg->lua_scripts[i], script) {
-
			if (run_prstmt(LUASCRIPT1, script->item) != SQLITE_DONE
+
		vec_foreach(pkg->lua_scripts[i], j) {
+
			if (run_prstmt(LUASCRIPT1, pkg->lua_scripts[i].d[j]) != SQLITE_DONE
			    ||
-
			    run_prstmt(LUASCRIPT2, script->item, package_id, i) != SQLITE_DONE) {
+
			    run_prstmt(LUASCRIPT2, pkg->lua_scripts[i].d[j], package_id, i) != SQLITE_DONE) {
				ERROR_STMT_SQLITE(s, STMT(LUASCRIPT2));
				return (EPKG_FATAL);
			}
@@ -2001,11 +2001,11 @@ pkgdb_insert_lua_scripts(struct pkg *pkg, int64_t package_id, sqlite3 *s)
int
pkgdb_update_shlibs_required(struct pkg *pkg, int64_t package_id, sqlite3 *s)
{
-
	tll_foreach(pkg->shlibs_required, r) {
-
		if (run_prstmt(SHLIBS1, r->item)
+
	vec_foreach(pkg->shlibs_required, i) {
+
		if (run_prstmt(SHLIBS1, pkg->shlibs_required.d[i])
		    != SQLITE_DONE
		    ||
-
		    run_prstmt(SHLIBS_REQD, package_id, r->item)
+
		    run_prstmt(SHLIBS_REQD, package_id, pkg->shlibs_required.d[i])
		    != SQLITE_DONE) {
			ERROR_STMT_SQLITE(s, STMT(SHLIBS_REQD));
			return (EPKG_FATAL);
@@ -2034,11 +2034,11 @@ pkgdb_update_config_file_content(struct pkg *p, sqlite3 *s)
int
pkgdb_update_shlibs_provided(struct pkg *pkg, int64_t package_id, sqlite3 *s)
{
-
	tll_foreach(pkg->shlibs_provided, r) {
-
		if (run_prstmt(SHLIBS1, r->item)
+
	vec_foreach(pkg->shlibs_provided, i) {
+
		if (run_prstmt(SHLIBS1, pkg->shlibs_provided.d[i])
		    != SQLITE_DONE
		    ||
-
		    run_prstmt(SHLIBS_PROV, package_id, r->item)
+
		    run_prstmt(SHLIBS_PROV, package_id, pkg->shlibs_provided.d[i])
		    != SQLITE_DONE) {
			ERROR_STMT_SQLITE(s, STMT(SHLIBS_PROV));
			return (EPKG_FATAL);
@@ -2051,11 +2051,11 @@ pkgdb_update_shlibs_provided(struct pkg *pkg, int64_t package_id, sqlite3 *s)
int
pkgdb_update_requires(struct pkg *pkg, int64_t package_id, sqlite3 *s)
{
-
	tll_foreach(pkg->requires, r) {
-
		if (run_prstmt(REQUIRE, r->item)
+
	vec_foreach(pkg->requires, i) {
+
		if (run_prstmt(REQUIRE, pkg->requires.d[i])
		    != SQLITE_DONE
		    ||
-
		    run_prstmt(PKG_REQUIRE, package_id, r->item)
+
		    run_prstmt(PKG_REQUIRE, package_id, pkg->requires.d[i])
		    != SQLITE_DONE) {
			ERROR_STMT_SQLITE(s, STMT(PKG_REQUIRE));
			return (EPKG_FATAL);
@@ -2068,11 +2068,11 @@ pkgdb_update_requires(struct pkg *pkg, int64_t package_id, sqlite3 *s)
int
pkgdb_update_provides(struct pkg *pkg, int64_t package_id, sqlite3 *s)
{
-
	tll_foreach(pkg->provides, p) {
-
		if (run_prstmt(PROVIDE, p->item)
+
	vec_foreach(pkg->provides, i) {
+
		if (run_prstmt(PROVIDE, pkg->provides.d[i])
		    != SQLITE_DONE
		    ||
-
		    run_prstmt(PKG_PROVIDE, package_id, p->item)
+
		    run_prstmt(PKG_PROVIDE, package_id, pkg->provides.d[i])
		    != SQLITE_DONE) {
			ERROR_STMT_SQLITE(s, STMT(PKG_PROVIDE));
			return (EPKG_FATAL);
modified libpkg/pkgdb_iterator.c
@@ -1,5 +1,5 @@
/*-
-
 * Copyright (c) 2011-2023 Baptiste Daroussin <bapt@FreeBSD.org>
+
 * Copyright (c) 2011-2025 Baptiste Daroussin <bapt@FreeBSD.org>
 * Copyright (c) 2011-2012 Julien Laffaye <jlaffaye@FreeBSD.org>
 * Copyright (c) 2011 Will Andrews <will@FreeBSD.org>
 * Copyright (c) 2011 Philippe Pepiot <phil@philpep.org>
@@ -10,28 +10,8 @@
 * Copyright (c) 2013-2017 Vsevolod Stakhov <vsevolod@FreeBSD.org>
 * Copyright (c) 2023 Serenity Cyber Security, LLC
 *                    Author: Gleb Popov <arrowd@FreeBSD.org>
-
 * All rights reserved.
 *
-
 * Redistribution and use in source and binary forms, with or without
-
 * modification, are permitted provided that the following conditions
-
 * are met:
-
 * 1. Redistributions of source code must retain the above copyright
-
 *    notice, this list of conditions and the following disclaimer
-
 *    in this position and unchanged.
-
 * 2. Redistributions in binary form must reproduce the above copyright
-
 *    notice, this list of conditions and the following disclaimer in the
-
 *    documentation and/or other materials provided with the distribution.
-
 *
-
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
-
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-
 * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
-
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
 * SPDX-License-Identifier: BSD-2-Clause
 */

#ifdef HAVE_CONFIG_H
@@ -588,7 +568,7 @@ pkgdb_load_group(sqlite3 *sqlite, struct pkg *pkg)
static int
addshlib_required_raw(struct pkg *pkg, const char *name)
{
-
	tll_push_back(pkg->shlibs_required, xstrdup(name));
+
	vec_push(&pkg->shlibs_required, xstrdup(name));
	return (EPKG_OK);
}

@@ -611,7 +591,7 @@ pkgdb_load_shlib_required(sqlite3 *sqlite, struct pkg *pkg)
static int
addshlib_provided_raw(struct pkg *pkg, const char *name)
{
-
	tll_push_back(pkg->shlibs_provided, xstrdup(name));
+
	vec_push(&pkg->shlibs_provided, xstrdup(name));
	return (EPKG_OK);
}

modified libpkg/private/pkg.h
@@ -110,7 +110,7 @@ struct pkg_kvlist {
};

struct pkg_stringlist {
-
	stringlist_t *list;
+
	charv_t *list;
};

struct pkg_kvlist_iterator {
@@ -119,8 +119,8 @@ struct pkg_kvlist_iterator {
};

struct pkg_stringlist_iterator {
-
	stringlist_t *list;
-
	void *cur;
+
	charv_t *list;
+
	size_t pos;
};

struct pkg_ctx {
@@ -180,7 +180,7 @@ struct pkg {
	bool		 vital;
	int64_t		 id;
	xstring		*scripts[PKG_NUM_SCRIPTS];
-
	stringlist_t	 lua_scripts[PKG_NUM_LUA_SCRIPTS];
+
	charv_t	 lua_scripts[PKG_NUM_LUA_SCRIPTS];
	char			*name;
	char			*origin;
	char			*version;
@@ -212,29 +212,29 @@ struct pkg {
	struct pkg_dep		*depends;
	pkghash			*rdepshash;
	struct pkg_dep		*rdepends;
-
	stringlist_t		 categories;
-
	stringlist_t		 licenses;
+
	charv_t		 categories;
+
	charv_t		 licenses;
	pkghash			*filehash;
	struct pkg_file		*files;
	pkghash			*dirhash;
	struct pkg_dir		*dirs;
	pkghash			*optionshash;
	struct pkg_option	*options;
-
	stringlist_t		 users;
-
	stringlist_t		 groups;
-
	stringlist_t		 shlibs_required;
-
	stringlist_t		 shlibs_provided;
+
	charv_t		 users;
+
	charv_t		 groups;
+
	charv_t		 shlibs_required;
+
	charv_t		 shlibs_provided;
	pkghash			*conflictshash;
	struct pkg_conflict	*conflicts;
-
	stringlist_t		 provides;
-
	stringlist_t		 requires;
+
	charv_t		 provides;
+
	charv_t		 requires;
	pkghash			*config_files_hash;
	struct pkg_config_file	*config_files;
	kvlist_t		 annotations;
	unsigned			flags;
	int		rootfd;
	char		rootpath[MAXPATHLEN];
-
	stringlist_t	dir_to_del;
+
	charv_t	dir_to_del;
	pkg_t		 type;
	struct pkg_repo		*repo;
};
@@ -662,7 +662,7 @@ int pkg_start_stop_rc_scripts(struct pkg *, pkg_rc_attr attr);

int pkg_script_run(struct pkg *, pkg_script type, bool upgrade, bool noexec);
int pkg_lua_script_run(struct pkg *, pkg_lua_script type, bool upgrade);
-
ucl_object_t *pkg_lua_script_to_ucl(stringlist_t *);
+
ucl_object_t *pkg_lua_script_to_ucl(charv_t *);
int pkg_script_run_child(int pid, int *pstat, int inputfd, const char* script_name);

int pkg_open2(struct pkg **p, struct archive **a, struct archive_entry **ae,
@@ -789,7 +789,7 @@ int pkg_adddir(struct pkg *pkg, const char *path, bool check_duplicates);
int pkg_adddir_attr(struct pkg *pkg, const char *path, const char *uname,
    const char *gname, mode_t perm, u_long fflags, bool check_duplicates);

-
int pkg_addstring(stringlist_t *s, const char *value, const char *title);
+
int pkg_addstring(charv_t *s, const char *value, const char *title);
int pkg_kv_add(kvlist_t *kv, const char *key, const char *value, const char *title);
const char *pkg_kv_get(const kvlist_t *kv, const char *key);
int pkg_adduser(struct pkg *pkg, const char *name);
@@ -864,6 +864,6 @@ char * expand_plist_variables(const char *in, kvlist_t *vars);

int scan_system_shlibs(pkghash **system_shlibs, const char *rootdir);
void pkg_lists_sort(struct pkg *p);
-
void pkg_cleanup_shlibs_required(struct pkg *pkg, stringlist_t *internal_provided);
+
void pkg_cleanup_shlibs_required(struct pkg *pkg, charv_t *internal_provided);

#endif
modified libpkg/private/utils.h
@@ -119,6 +119,7 @@ void append_random_suffix(char *buf, int buflen, int suffixlen);
char *json_escape(const char *str);
const char *get_http_auth(void);
bool c_charv_contains(c_charv_t *, const char *, bool);
+
bool charv_contains(charv_t *, const char *, bool);
bool str_ends_with(const char *str, const char *end);

#endif
modified libpkg/repo/binary/update.c
@@ -1,6 +1,6 @@
/*
 * Copyright (c) 2014, Vsevolod Stakhov
-
 * Copyright (c) 2012-2024 Baptiste Daroussin <bapt@FreeBSD.org>
+
 * Copyright (c) 2012-2025 Baptiste Daroussin <bapt@FreeBSD.org>
 * Copyright (c) 2012 Julien Laffaye <jlaffaye@FreeBSD.org>
 * Copyright (c) 2024 Serenity Cyber Security, LLC
 *                    Author: Gleb Popov <arrowd@FreeBSD.org>
@@ -181,22 +181,22 @@ try_again:
		}
	}

-
	tll_foreach(pkg->categories, c) {
-
		ret = pkg_repo_binary_run_prstatement(CAT1, c->item);
+
	vec_foreach(pkg->categories, i) {
+
		const char *s = pkg->categories.d[i];
+
		ret = pkg_repo_binary_run_prstatement(CAT1, s);
		if (ret == SQLITE_DONE)
-
			ret = pkg_repo_binary_run_prstatement(CAT2, package_id,
-
			    c->item);
+
			ret = pkg_repo_binary_run_prstatement(CAT2, package_id, s);
		if (ret != SQLITE_DONE) {
			ERROR_SQLITE(sqlite, pkg_repo_binary_sql_prstatement(CAT2));
			return (EPKG_FATAL);
		}
	}

-
	tll_foreach(pkg->licenses, l) {
-
		ret = pkg_repo_binary_run_prstatement(LIC1, l->item);
+
	vec_foreach(pkg->licenses, i) {
+
		const char *s = pkg->licenses.d[i];
+
		ret = pkg_repo_binary_run_prstatement(LIC1, s);
		if (ret == SQLITE_DONE)
-
			ret = pkg_repo_binary_run_prstatement(LIC2, package_id,
-
			    l->item);
+
			ret = pkg_repo_binary_run_prstatement(LIC2, package_id, s);
		if (ret != SQLITE_DONE) {
			ERROR_SQLITE(sqlite, pkg_repo_binary_sql_prstatement(LIC2));
			return (EPKG_FATAL);
@@ -215,44 +215,44 @@ try_again:
		}
	}

-
	tll_foreach(pkg->shlibs_required, s) {
-
		ret = pkg_repo_binary_run_prstatement(SHLIB1, s->item);
+
	vec_foreach(pkg->shlibs_required, i) {
+
		const char *s = pkg->shlibs_required.d[i];
+
		ret = pkg_repo_binary_run_prstatement(SHLIB1, s);
		if (ret == SQLITE_DONE)
-
			ret = pkg_repo_binary_run_prstatement(SHLIB_REQD, package_id,
-
			    s->item);
+
			ret = pkg_repo_binary_run_prstatement(SHLIB_REQD, package_id, s);
		if (ret != SQLITE_DONE) {
			ERROR_SQLITE(sqlite, pkg_repo_binary_sql_prstatement(SHLIB_REQD));
			return (EPKG_FATAL);
		}
	}

-
	tll_foreach(pkg->shlibs_provided, s) {
-
		ret = pkg_repo_binary_run_prstatement(SHLIB1, s->item);
+
	vec_foreach(pkg->shlibs_provided, i) {
+
		const char *s = pkg->shlibs_provided.d[i];
+
		ret = pkg_repo_binary_run_prstatement(SHLIB1, s);
		if (ret == SQLITE_DONE)
-
			ret = pkg_repo_binary_run_prstatement(SHLIB_PROV, package_id,
-
			    s->item);
+
			ret = pkg_repo_binary_run_prstatement(SHLIB_PROV, package_id, s);
		if (ret != SQLITE_DONE) {
			ERROR_SQLITE(sqlite, pkg_repo_binary_sql_prstatement(SHLIB_PROV));
			return (EPKG_FATAL);
		}
	}

-
	tll_foreach(pkg->provides, p) {
-
		ret = pkg_repo_binary_run_prstatement(PROVIDE, p->item);
+
	vec_foreach(pkg->provides, i) {
+
		const char *s = pkg->provides.d[i];
+
		ret = pkg_repo_binary_run_prstatement(PROVIDE, s);
		if (ret == SQLITE_DONE)
-
			ret = pkg_repo_binary_run_prstatement(PROVIDES, package_id,
-
			    p->item);
+
			ret = pkg_repo_binary_run_prstatement(PROVIDES, package_id, s);
		if (ret != SQLITE_DONE) {
			ERROR_SQLITE(sqlite, pkg_repo_binary_sql_prstatement(PROVIDES));
			return (EPKG_FATAL);
		}
	}

-
	tll_foreach(pkg->requires, r) {
-
		ret = pkg_repo_binary_run_prstatement(REQUIRE, r->item);
+
	vec_foreach(pkg->requires, i) {
+
		const char *s = pkg->requires.d[i];
+
		ret = pkg_repo_binary_run_prstatement(REQUIRE, s);
		if (ret == SQLITE_DONE)
-
			ret = pkg_repo_binary_run_prstatement(REQUIRES, package_id,
-
			    r->item);
+
			ret = pkg_repo_binary_run_prstatement(REQUIRES, package_id, s);
		if (ret != SQLITE_DONE) {
			ERROR_SQLITE(sqlite, pkg_repo_binary_sql_prstatement(REQUIRES));
			return (EPKG_FATAL);
modified libpkg/utils.c
@@ -1074,6 +1074,22 @@ get_http_auth(void)
}

bool
+
charv_contains(charv_t *v, const char *el, bool casesensitive)
+
{
+
	vec_foreach(*v, i) {
+
		if (casesensitive) {
+
			if (STREQ(v->d[i], el))
+
				return (true);
+
		} else {
+
			if (STRIEQ(v->d[i], el)) {
+
				return (true);
+
			}
+
		}
+
	}
+
	return (false);
+
}
+

+
bool
c_charv_contains(c_charv_t *v, const char *el, bool casesensitive)
{
	vec_foreach(*v, i) {
modified tests/lib/pkg_add_dir_to_del.c
@@ -38,26 +38,26 @@ ATF_TC_BODY(pkg_add_dir_to_del, tc)
	ATF_REQUIRE_EQ(EPKG_OK, pkg_new(&p, PKG_FILE));
	pkg_set(p, PKG_ATTR_PREFIX, "/usr/local");

-
	ATF_REQUIRE_EQ(tll_length(p->dir_to_del), 0);
+
	ATF_REQUIRE_EQ(vec_len(&p->dir_to_del), 0);

	pkg_add_dir_to_del(p, "/usr/local/plop/bla", NULL);

-
	ATF_REQUIRE_STREQ(tll_back(p->dir_to_del), "/usr/local/plop/");
+
	ATF_REQUIRE_STREQ(vec_last(&p->dir_to_del), "/usr/local/plop/");

	pkg_add_dir_to_del(p, NULL, "/usr/local/plop");

-
	ATF_REQUIRE_EQ(tll_length(p->dir_to_del), 1);
+
	ATF_REQUIRE_EQ(vec_len(&p->dir_to_del), 1);

	pkg_add_dir_to_del(p, NULL, "/var/run/yeah");

-
	ATF_REQUIRE_STREQ(tll_back(p->dir_to_del), "/var/run/yeah/");
+
	ATF_REQUIRE_STREQ(vec_last(&p->dir_to_del), "/var/run/yeah/");

	pkg_free(p);
}

ATF_TP_ADD_TCS(tp)
{
-
	ATF_TP_ADD_TC(tp, pkg_add_dir_to_del); 
+
	ATF_TP_ADD_TC(tp, pkg_add_dir_to_del);

	return (atf_no_error());
}
modified tests/lib/pkg_elf.c
@@ -59,13 +59,13 @@ ATF_TC_BODY(analyse_elf, tc)
	ATF_REQUIRE_EQ(EPKG_OK, pkg_new(&p, PKG_INSTALLED));
	ATF_REQUIRE(p != NULL);

-
	ATF_REQUIRE_EQ(tll_length(p->shlibs_required), 0);
+
	ATF_REQUIRE_EQ(vec_len(&p->shlibs_required), 0);
	ATF_REQUIRE_EQ(pkg_analyse_elf(false, p, binpath, &provided, &provided_flags), EPKG_OK);
-
	ATF_REQUIRE_EQ(tll_length(p->shlibs_provided), 0);
+
	ATF_REQUIRE_EQ(vec_len(&p->shlibs_provided), 0);
	ATF_REQUIRE_STREQ(provided, "libtestfbsd.so.1");
	ATF_REQUIRE_EQ(provided_flags, PKG_SHLIB_FLAGS_NONE);
-
	ATF_REQUIRE_EQ(tll_length(p->shlibs_required), 1);
-
	ATF_REQUIRE_STREQ(tll_front(p->shlibs_required), "libc.so.7");
+
	ATF_REQUIRE_EQ(vec_len(&p->shlibs_required), 1);
+
	ATF_REQUIRE_STREQ(vec_first(&p->shlibs_required), "libc.so.7");
	free(provided);
	free(binpath);

@@ -73,10 +73,10 @@ ATF_TC_BODY(analyse_elf, tc)
	provided_flags = PKG_SHLIB_FLAGS_NONE;
	xasprintf(&binpath, "%s/Makefile", atf_tc_get_config_var(tc, "srcdir"));
	ATF_REQUIRE_EQ(pkg_analyse_elf(false, p, binpath, &provided, &provided_flags), EPKG_END);
-
	ATF_REQUIRE_EQ(tll_length(p->shlibs_provided), 0);
+
	ATF_REQUIRE_EQ(vec_len(&p->shlibs_provided), 0);
	ATF_REQUIRE_EQ(provided, NULL);
	ATF_REQUIRE_EQ(provided_flags, PKG_SHLIB_FLAGS_NONE);
-
	ATF_REQUIRE_EQ(tll_length(p->shlibs_required), 1);
+
	ATF_REQUIRE_EQ(vec_len(&p->shlibs_required), 1);
	free(provided);
	free(binpath);

@@ -84,12 +84,12 @@ ATF_TC_BODY(analyse_elf, tc)
	provided_flags = PKG_SHLIB_FLAGS_NONE;
	xasprintf(&binpath, "%s/frontend/libtest2fbsd.so.1", atf_tc_get_config_var(tc, "srcdir"));
	ATF_REQUIRE_EQ(pkg_analyse_elf(false, p, binpath, &provided, &provided_flags), EPKG_OK);
-
	ATF_REQUIRE_EQ(tll_length(p->shlibs_provided), 0);
+
	ATF_REQUIRE_EQ(vec_len(&p->shlibs_provided), 0);
	ATF_REQUIRE_STREQ(provided, "libtest2fbsd.so.1");
	ATF_REQUIRE_EQ(provided_flags, PKG_SHLIB_FLAGS_NONE);
-
	ATF_REQUIRE_EQ(tll_length(p->shlibs_required), 2);
-
	ATF_REQUIRE_STREQ(tll_front(p->shlibs_required), "libc.so.7");
-
	ATF_REQUIRE_STREQ(tll_back(p->shlibs_required), "libfoo.so.1");
+
	ATF_REQUIRE_EQ(vec_len(&p->shlibs_required), 2);
+
	ATF_REQUIRE_STREQ(vec_first(&p->shlibs_required), "libc.so.7");
+
	ATF_REQUIRE_STREQ(vec_last(&p->shlibs_required), "libfoo.so.1");
	free(provided);
	free(binpath);

modified tests/lib/shlibs.c
@@ -13,22 +13,23 @@ ATF_TC_WITHOUT_HEAD(cleanup_shlibs_required);
ATF_TC_BODY(cleanup_shlibs_required, tc)
{
	struct pkg *p;
-
	stringlist_t internal_provided = tll_init();
+
	charv_t internal_provided;
+
	vec_init(&internal_provided);

	ATF_REQUIRE_EQ(pkg_new(&p, PKG_FILE), EPKG_OK);
	ATF_REQUIRE(p != NULL);
-
	tll_push_back(p->shlibs_required, xstrdup("lib1.so:32"));
-
	tll_push_back(p->shlibs_required, xstrdup("lib1.so"));
-
	tll_push_back(p->shlibs_required, xstrdup("libA.so"));
-
	tll_push_back(p->shlibs_required, xstrdup("libA.so:32"));
+
	vec_push(&p->shlibs_required, xstrdup("lib1.so:32"));
+
	vec_push(&p->shlibs_required, xstrdup("lib1.so"));
+
	vec_push(&p->shlibs_required, xstrdup("libA.so"));
+
	vec_push(&p->shlibs_required, xstrdup("libA.so:32"));
	pkg_cleanup_shlibs_required(p, &internal_provided);
-
	ATF_REQUIRE_EQ(tll_length(p->shlibs_required), 4);
-
	tll_push_back(p->shlibs_provided, "lib1.so");
+
	ATF_REQUIRE_EQ(vec_len(&p->shlibs_required), 4);
+
	vec_push(&p->shlibs_provided, "lib1.so");
	pkg_cleanup_shlibs_required(p, &internal_provided);
-
	ATF_REQUIRE_EQ(tll_length(p->shlibs_required), 3);
-
	tll_push_back(internal_provided, "lib1.so:32");
+
	ATF_REQUIRE_EQ(vec_len(&p->shlibs_required), 3);
+
	vec_push(&internal_provided, "lib1.so:32");
	pkg_cleanup_shlibs_required(p, &internal_provided);
-
	ATF_REQUIRE_EQ(tll_length(p->shlibs_required), 2);
+
	ATF_REQUIRE_EQ_MSG(vec_len(&p->shlibs_required), 2, "expecint 2 got %zu", vec_len(&p->shlibs_required));
}

ATF_TP_ADD_TCS(tp)