summaryrefslogtreecommitdiffstats
path: root/lib/dpkg/t
diff options
context:
space:
mode:
Diffstat (limited to 'lib/dpkg/t')
-rw-r--r--lib/dpkg/t/Makefile.am82
-rw-r--r--lib/dpkg/t/Makefile.in1304
-rw-r--r--lib/dpkg/t/b-fsys-hash.c81
-rw-r--r--lib/dpkg/t/b-pkg-hash.c65
-rw-r--r--lib/dpkg/t/c-tarextract.c151
-rw-r--r--lib/dpkg/t/c-treewalk.c132
-rw-r--r--lib/dpkg/t/c-trigdeferred.c96
-rw-r--r--lib/dpkg/t/t-ar.c61
-rw-r--r--lib/dpkg/t/t-arch.c225
-rw-r--r--lib/dpkg/t/t-buffer.c82
-rw-r--r--lib/dpkg/t/t-c-ctype.c106
-rw-r--r--lib/dpkg/t/t-command.c224
-rw-r--r--lib/dpkg/t/t-deb-version.c90
-rw-r--r--lib/dpkg/t/t-ehandle.c128
-rw-r--r--lib/dpkg/t/t-error.c87
-rw-r--r--lib/dpkg/t/t-file.c98
-rw-r--r--lib/dpkg/t/t-fsys-dir.c71
-rw-r--r--lib/dpkg/t/t-fsys-hash.c108
-rw-r--r--lib/dpkg/t/t-headers-cpp.cc82
-rw-r--r--lib/dpkg/t/t-macros.c45
-rw-r--r--lib/dpkg/t/t-mod-db.c57
-rw-r--r--lib/dpkg/t/t-namevalue.c48
-rw-r--r--lib/dpkg/t/t-pager.c75
-rw-r--r--lib/dpkg/t/t-path.c181
-rw-r--r--lib/dpkg/t/t-pkg-format.c141
-rw-r--r--lib/dpkg/t/t-pkg-hash.c178
-rw-r--r--lib/dpkg/t/t-pkg-list.c90
-rw-r--r--lib/dpkg/t/t-pkg-queue.c116
-rw-r--r--lib/dpkg/t/t-pkg-show.c61
-rw-r--r--lib/dpkg/t/t-pkginfo.c153
-rw-r--r--lib/dpkg/t/t-progname.c53
-rw-r--r--lib/dpkg/t/t-string.c281
-rw-r--r--lib/dpkg/t/t-subproc.c100
-rw-r--r--lib/dpkg/t/t-tar.c148
-rwxr-xr-xlib/dpkg/t/t-tarextract.t165
-rw-r--r--lib/dpkg/t/t-test-skip.c31
-rw-r--r--lib/dpkg/t/t-test.c66
-rwxr-xr-xlib/dpkg/t/t-treewalk.t160
-rwxr-xr-xlib/dpkg/t/t-trigdeferred.t123
-rw-r--r--lib/dpkg/t/t-trigger.c49
-rw-r--r--lib/dpkg/t/t-varbuf.c414
-rw-r--r--lib/dpkg/t/t-version.c308
42 files changed, 6316 insertions, 0 deletions
diff --git a/lib/dpkg/t/Makefile.am b/lib/dpkg/t/Makefile.am
new file mode 100644
index 0000000..c845aaf
--- /dev/null
+++ b/lib/dpkg/t/Makefile.am
@@ -0,0 +1,82 @@
+## Process this file with automake to produce Makefile.in
+
+AM_CPPFLAGS = \
+ -DADMINDIR=\"$(admindir)\" \
+ -idirafter $(top_srcdir)/lib/compat \
+ -I$(top_builddir) \
+ -I$(top_srcdir)/lib
+LDADD = \
+ $(top_builddir)/lib/dpkg/libdpkg.la \
+ $(LIBINTL)
+
+EXTRA_DIST = \
+ $(test_scripts) \
+ $(nil)
+
+TEST_ENV_VARS = \
+ DPKG_PROGTAR=$(TAR) \
+ $(nil)
+
+t_headers_cpp_SOURCES = t-headers-cpp.cc
+
+# The tests are sorted in order of increasing complexity.
+test_programs = \
+ t-test \
+ t-test-skip \
+ t-macros \
+ t-headers-cpp \
+ t-c-ctype \
+ t-namevalue \
+ t-ehandle \
+ t-error \
+ t-string \
+ t-file \
+ t-buffer \
+ t-path \
+ t-progname \
+ t-subproc \
+ t-command \
+ t-pager \
+ t-varbuf \
+ t-ar \
+ t-tar \
+ t-deb-version \
+ t-arch \
+ t-version \
+ t-pkginfo \
+ t-pkg-list \
+ t-pkg-queue \
+ t-pkg-hash \
+ t-pkg-show \
+ t-pkg-format \
+ t-fsys-dir \
+ t-fsys-hash \
+ t-trigger \
+ t-mod-db \
+ $(nil)
+
+test_scripts = \
+ t-tarextract.t \
+ t-treewalk.t \
+ t-trigdeferred.t \
+ $(nil)
+
+BENCHMARK_LDADD_FLAGS = -lrt $(LDADD)
+
+b_fsys_hash_LDADD = $(BENCHMARK_LDADD_FLAGS)
+b_pkg_hash_LDADD = $(BENCHMARK_LDADD_FLAGS)
+
+check_PROGRAMS = \
+ $(test_programs) \
+ b-fsys-hash \
+ b-pkg-hash \
+ c-tarextract \
+ c-treewalk \
+ c-trigdeferred \
+ $(nil)
+
+test_tmpdir = t.tmp
+
+include $(top_srcdir)/check.am
+
+clean-local: check-clean
diff --git a/lib/dpkg/t/Makefile.in b/lib/dpkg/t/Makefile.in
new file mode 100644
index 0000000..f9e99d6
--- /dev/null
+++ b/lib/dpkg/t/Makefile.in
@@ -0,0 +1,1304 @@
+# Makefile.in generated by automake 1.16.3 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2020 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+# Variables to be defined:
+#
+# TEST_VERBOSE - set to 0 (default) or 1 to control test suite verbosity
+# TEST_PARALLEL - set to 1 (default) or N to control the parallel jobs
+# TEST_ENV_VARS - environment variables to be set for the test suite
+# TEST_COVERAGE - set to the perl module in charge of getting test coverage
+# test_tmpdir - test suite temporary directory
+# test_scripts - list of test case scripts
+# test_programs - list of test case programs
+# test_data - list of test data files
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+check_PROGRAMS = $(am__EXEEXT_1) b-fsys-hash$(EXEEXT) \
+ b-pkg-hash$(EXEEXT) c-tarextract$(EXEEXT) c-treewalk$(EXEEXT) \
+ c-trigdeferred$(EXEEXT)
+subdir = lib/dpkg/t
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/dpkg-arch.m4 \
+ $(top_srcdir)/m4/dpkg-build.m4 \
+ $(top_srcdir)/m4/dpkg-compiler.m4 \
+ $(top_srcdir)/m4/dpkg-coverage.m4 \
+ $(top_srcdir)/m4/dpkg-funcs.m4 $(top_srcdir)/m4/dpkg-libs.m4 \
+ $(top_srcdir)/m4/dpkg-linker.m4 $(top_srcdir)/m4/dpkg-progs.m4 \
+ $(top_srcdir)/m4/dpkg-types.m4 \
+ $(top_srcdir)/m4/dpkg-unicode.m4 $(top_srcdir)/m4/gettext.m4 \
+ $(top_srcdir)/m4/host-cpu-c-abi.m4 $(top_srcdir)/m4/iconv.m4 \
+ $(top_srcdir)/m4/intlmacosx.m4 $(top_srcdir)/m4/lib-ld.m4 \
+ $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \
+ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/nls.m4 \
+ $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \
+ $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__EXEEXT_1 = t-test$(EXEEXT) t-test-skip$(EXEEXT) t-macros$(EXEEXT) \
+ t-headers-cpp$(EXEEXT) t-c-ctype$(EXEEXT) t-namevalue$(EXEEXT) \
+ t-ehandle$(EXEEXT) t-error$(EXEEXT) t-string$(EXEEXT) \
+ t-file$(EXEEXT) t-buffer$(EXEEXT) t-path$(EXEEXT) \
+ t-progname$(EXEEXT) t-subproc$(EXEEXT) t-command$(EXEEXT) \
+ t-pager$(EXEEXT) t-varbuf$(EXEEXT) t-ar$(EXEEXT) \
+ t-tar$(EXEEXT) t-deb-version$(EXEEXT) t-arch$(EXEEXT) \
+ t-version$(EXEEXT) t-pkginfo$(EXEEXT) t-pkg-list$(EXEEXT) \
+ t-pkg-queue$(EXEEXT) t-pkg-hash$(EXEEXT) t-pkg-show$(EXEEXT) \
+ t-pkg-format$(EXEEXT) t-fsys-dir$(EXEEXT) t-fsys-hash$(EXEEXT) \
+ t-trigger$(EXEEXT) t-mod-db$(EXEEXT)
+b_fsys_hash_SOURCES = b-fsys-hash.c
+b_fsys_hash_OBJECTS = b-fsys-hash.$(OBJEXT)
+am__DEPENDENCIES_1 =
+am__DEPENDENCIES_2 = $(top_builddir)/lib/dpkg/libdpkg.la \
+ $(am__DEPENDENCIES_1)
+am__DEPENDENCIES_3 = $(am__DEPENDENCIES_2)
+b_fsys_hash_DEPENDENCIES = $(am__DEPENDENCIES_3)
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+b_pkg_hash_SOURCES = b-pkg-hash.c
+b_pkg_hash_OBJECTS = b-pkg-hash.$(OBJEXT)
+b_pkg_hash_DEPENDENCIES = $(am__DEPENDENCIES_3)
+c_tarextract_SOURCES = c-tarextract.c
+c_tarextract_OBJECTS = c-tarextract.$(OBJEXT)
+c_tarextract_LDADD = $(LDADD)
+c_tarextract_DEPENDENCIES = $(top_builddir)/lib/dpkg/libdpkg.la \
+ $(am__DEPENDENCIES_1)
+c_treewalk_SOURCES = c-treewalk.c
+c_treewalk_OBJECTS = c-treewalk.$(OBJEXT)
+c_treewalk_LDADD = $(LDADD)
+c_treewalk_DEPENDENCIES = $(top_builddir)/lib/dpkg/libdpkg.la \
+ $(am__DEPENDENCIES_1)
+c_trigdeferred_SOURCES = c-trigdeferred.c
+c_trigdeferred_OBJECTS = c-trigdeferred.$(OBJEXT)
+c_trigdeferred_LDADD = $(LDADD)
+c_trigdeferred_DEPENDENCIES = $(top_builddir)/lib/dpkg/libdpkg.la \
+ $(am__DEPENDENCIES_1)
+t_ar_SOURCES = t-ar.c
+t_ar_OBJECTS = t-ar.$(OBJEXT)
+t_ar_LDADD = $(LDADD)
+t_ar_DEPENDENCIES = $(top_builddir)/lib/dpkg/libdpkg.la \
+ $(am__DEPENDENCIES_1)
+t_arch_SOURCES = t-arch.c
+t_arch_OBJECTS = t-arch.$(OBJEXT)
+t_arch_LDADD = $(LDADD)
+t_arch_DEPENDENCIES = $(top_builddir)/lib/dpkg/libdpkg.la \
+ $(am__DEPENDENCIES_1)
+t_buffer_SOURCES = t-buffer.c
+t_buffer_OBJECTS = t-buffer.$(OBJEXT)
+t_buffer_LDADD = $(LDADD)
+t_buffer_DEPENDENCIES = $(top_builddir)/lib/dpkg/libdpkg.la \
+ $(am__DEPENDENCIES_1)
+t_c_ctype_SOURCES = t-c-ctype.c
+t_c_ctype_OBJECTS = t-c-ctype.$(OBJEXT)
+t_c_ctype_LDADD = $(LDADD)
+t_c_ctype_DEPENDENCIES = $(top_builddir)/lib/dpkg/libdpkg.la \
+ $(am__DEPENDENCIES_1)
+t_command_SOURCES = t-command.c
+t_command_OBJECTS = t-command.$(OBJEXT)
+t_command_LDADD = $(LDADD)
+t_command_DEPENDENCIES = $(top_builddir)/lib/dpkg/libdpkg.la \
+ $(am__DEPENDENCIES_1)
+t_deb_version_SOURCES = t-deb-version.c
+t_deb_version_OBJECTS = t-deb-version.$(OBJEXT)
+t_deb_version_LDADD = $(LDADD)
+t_deb_version_DEPENDENCIES = $(top_builddir)/lib/dpkg/libdpkg.la \
+ $(am__DEPENDENCIES_1)
+t_ehandle_SOURCES = t-ehandle.c
+t_ehandle_OBJECTS = t-ehandle.$(OBJEXT)
+t_ehandle_LDADD = $(LDADD)
+t_ehandle_DEPENDENCIES = $(top_builddir)/lib/dpkg/libdpkg.la \
+ $(am__DEPENDENCIES_1)
+t_error_SOURCES = t-error.c
+t_error_OBJECTS = t-error.$(OBJEXT)
+t_error_LDADD = $(LDADD)
+t_error_DEPENDENCIES = $(top_builddir)/lib/dpkg/libdpkg.la \
+ $(am__DEPENDENCIES_1)
+t_file_SOURCES = t-file.c
+t_file_OBJECTS = t-file.$(OBJEXT)
+t_file_LDADD = $(LDADD)
+t_file_DEPENDENCIES = $(top_builddir)/lib/dpkg/libdpkg.la \
+ $(am__DEPENDENCIES_1)
+t_fsys_dir_SOURCES = t-fsys-dir.c
+t_fsys_dir_OBJECTS = t-fsys-dir.$(OBJEXT)
+t_fsys_dir_LDADD = $(LDADD)
+t_fsys_dir_DEPENDENCIES = $(top_builddir)/lib/dpkg/libdpkg.la \
+ $(am__DEPENDENCIES_1)
+t_fsys_hash_SOURCES = t-fsys-hash.c
+t_fsys_hash_OBJECTS = t-fsys-hash.$(OBJEXT)
+t_fsys_hash_LDADD = $(LDADD)
+t_fsys_hash_DEPENDENCIES = $(top_builddir)/lib/dpkg/libdpkg.la \
+ $(am__DEPENDENCIES_1)
+am_t_headers_cpp_OBJECTS = t-headers-cpp.$(OBJEXT)
+t_headers_cpp_OBJECTS = $(am_t_headers_cpp_OBJECTS)
+t_headers_cpp_LDADD = $(LDADD)
+t_headers_cpp_DEPENDENCIES = $(top_builddir)/lib/dpkg/libdpkg.la \
+ $(am__DEPENDENCIES_1)
+t_macros_SOURCES = t-macros.c
+t_macros_OBJECTS = t-macros.$(OBJEXT)
+t_macros_LDADD = $(LDADD)
+t_macros_DEPENDENCIES = $(top_builddir)/lib/dpkg/libdpkg.la \
+ $(am__DEPENDENCIES_1)
+t_mod_db_SOURCES = t-mod-db.c
+t_mod_db_OBJECTS = t-mod-db.$(OBJEXT)
+t_mod_db_LDADD = $(LDADD)
+t_mod_db_DEPENDENCIES = $(top_builddir)/lib/dpkg/libdpkg.la \
+ $(am__DEPENDENCIES_1)
+t_namevalue_SOURCES = t-namevalue.c
+t_namevalue_OBJECTS = t-namevalue.$(OBJEXT)
+t_namevalue_LDADD = $(LDADD)
+t_namevalue_DEPENDENCIES = $(top_builddir)/lib/dpkg/libdpkg.la \
+ $(am__DEPENDENCIES_1)
+t_pager_SOURCES = t-pager.c
+t_pager_OBJECTS = t-pager.$(OBJEXT)
+t_pager_LDADD = $(LDADD)
+t_pager_DEPENDENCIES = $(top_builddir)/lib/dpkg/libdpkg.la \
+ $(am__DEPENDENCIES_1)
+t_path_SOURCES = t-path.c
+t_path_OBJECTS = t-path.$(OBJEXT)
+t_path_LDADD = $(LDADD)
+t_path_DEPENDENCIES = $(top_builddir)/lib/dpkg/libdpkg.la \
+ $(am__DEPENDENCIES_1)
+t_pkg_format_SOURCES = t-pkg-format.c
+t_pkg_format_OBJECTS = t-pkg-format.$(OBJEXT)
+t_pkg_format_LDADD = $(LDADD)
+t_pkg_format_DEPENDENCIES = $(top_builddir)/lib/dpkg/libdpkg.la \
+ $(am__DEPENDENCIES_1)
+t_pkg_hash_SOURCES = t-pkg-hash.c
+t_pkg_hash_OBJECTS = t-pkg-hash.$(OBJEXT)
+t_pkg_hash_LDADD = $(LDADD)
+t_pkg_hash_DEPENDENCIES = $(top_builddir)/lib/dpkg/libdpkg.la \
+ $(am__DEPENDENCIES_1)
+t_pkg_list_SOURCES = t-pkg-list.c
+t_pkg_list_OBJECTS = t-pkg-list.$(OBJEXT)
+t_pkg_list_LDADD = $(LDADD)
+t_pkg_list_DEPENDENCIES = $(top_builddir)/lib/dpkg/libdpkg.la \
+ $(am__DEPENDENCIES_1)
+t_pkg_queue_SOURCES = t-pkg-queue.c
+t_pkg_queue_OBJECTS = t-pkg-queue.$(OBJEXT)
+t_pkg_queue_LDADD = $(LDADD)
+t_pkg_queue_DEPENDENCIES = $(top_builddir)/lib/dpkg/libdpkg.la \
+ $(am__DEPENDENCIES_1)
+t_pkg_show_SOURCES = t-pkg-show.c
+t_pkg_show_OBJECTS = t-pkg-show.$(OBJEXT)
+t_pkg_show_LDADD = $(LDADD)
+t_pkg_show_DEPENDENCIES = $(top_builddir)/lib/dpkg/libdpkg.la \
+ $(am__DEPENDENCIES_1)
+t_pkginfo_SOURCES = t-pkginfo.c
+t_pkginfo_OBJECTS = t-pkginfo.$(OBJEXT)
+t_pkginfo_LDADD = $(LDADD)
+t_pkginfo_DEPENDENCIES = $(top_builddir)/lib/dpkg/libdpkg.la \
+ $(am__DEPENDENCIES_1)
+t_progname_SOURCES = t-progname.c
+t_progname_OBJECTS = t-progname.$(OBJEXT)
+t_progname_LDADD = $(LDADD)
+t_progname_DEPENDENCIES = $(top_builddir)/lib/dpkg/libdpkg.la \
+ $(am__DEPENDENCIES_1)
+t_string_SOURCES = t-string.c
+t_string_OBJECTS = t-string.$(OBJEXT)
+t_string_LDADD = $(LDADD)
+t_string_DEPENDENCIES = $(top_builddir)/lib/dpkg/libdpkg.la \
+ $(am__DEPENDENCIES_1)
+t_subproc_SOURCES = t-subproc.c
+t_subproc_OBJECTS = t-subproc.$(OBJEXT)
+t_subproc_LDADD = $(LDADD)
+t_subproc_DEPENDENCIES = $(top_builddir)/lib/dpkg/libdpkg.la \
+ $(am__DEPENDENCIES_1)
+t_tar_SOURCES = t-tar.c
+t_tar_OBJECTS = t-tar.$(OBJEXT)
+t_tar_LDADD = $(LDADD)
+t_tar_DEPENDENCIES = $(top_builddir)/lib/dpkg/libdpkg.la \
+ $(am__DEPENDENCIES_1)
+t_test_SOURCES = t-test.c
+t_test_OBJECTS = t-test.$(OBJEXT)
+t_test_LDADD = $(LDADD)
+t_test_DEPENDENCIES = $(top_builddir)/lib/dpkg/libdpkg.la \
+ $(am__DEPENDENCIES_1)
+t_test_skip_SOURCES = t-test-skip.c
+t_test_skip_OBJECTS = t-test-skip.$(OBJEXT)
+t_test_skip_LDADD = $(LDADD)
+t_test_skip_DEPENDENCIES = $(top_builddir)/lib/dpkg/libdpkg.la \
+ $(am__DEPENDENCIES_1)
+t_trigger_SOURCES = t-trigger.c
+t_trigger_OBJECTS = t-trigger.$(OBJEXT)
+t_trigger_LDADD = $(LDADD)
+t_trigger_DEPENDENCIES = $(top_builddir)/lib/dpkg/libdpkg.la \
+ $(am__DEPENDENCIES_1)
+t_varbuf_SOURCES = t-varbuf.c
+t_varbuf_OBJECTS = t-varbuf.$(OBJEXT)
+t_varbuf_LDADD = $(LDADD)
+t_varbuf_DEPENDENCIES = $(top_builddir)/lib/dpkg/libdpkg.la \
+ $(am__DEPENDENCIES_1)
+t_version_SOURCES = t-version.c
+t_version_OBJECTS = t-version.$(OBJEXT)
+t_version_LDADD = $(LDADD)
+t_version_DEPENDENCIES = $(top_builddir)/lib/dpkg/libdpkg.la \
+ $(am__DEPENDENCIES_1)
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+DEFAULT_INCLUDES =
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__maybe_remake_depfiles = depfiles
+am__depfiles_remade = ./$(DEPDIR)/b-fsys-hash.Po \
+ ./$(DEPDIR)/b-pkg-hash.Po ./$(DEPDIR)/c-tarextract.Po \
+ ./$(DEPDIR)/c-treewalk.Po ./$(DEPDIR)/c-trigdeferred.Po \
+ ./$(DEPDIR)/t-ar.Po ./$(DEPDIR)/t-arch.Po \
+ ./$(DEPDIR)/t-buffer.Po ./$(DEPDIR)/t-c-ctype.Po \
+ ./$(DEPDIR)/t-command.Po ./$(DEPDIR)/t-deb-version.Po \
+ ./$(DEPDIR)/t-ehandle.Po ./$(DEPDIR)/t-error.Po \
+ ./$(DEPDIR)/t-file.Po ./$(DEPDIR)/t-fsys-dir.Po \
+ ./$(DEPDIR)/t-fsys-hash.Po ./$(DEPDIR)/t-headers-cpp.Po \
+ ./$(DEPDIR)/t-macros.Po ./$(DEPDIR)/t-mod-db.Po \
+ ./$(DEPDIR)/t-namevalue.Po ./$(DEPDIR)/t-pager.Po \
+ ./$(DEPDIR)/t-path.Po ./$(DEPDIR)/t-pkg-format.Po \
+ ./$(DEPDIR)/t-pkg-hash.Po ./$(DEPDIR)/t-pkg-list.Po \
+ ./$(DEPDIR)/t-pkg-queue.Po ./$(DEPDIR)/t-pkg-show.Po \
+ ./$(DEPDIR)/t-pkginfo.Po ./$(DEPDIR)/t-progname.Po \
+ ./$(DEPDIR)/t-string.Po ./$(DEPDIR)/t-subproc.Po \
+ ./$(DEPDIR)/t-tar.Po ./$(DEPDIR)/t-test-skip.Po \
+ ./$(DEPDIR)/t-test.Po ./$(DEPDIR)/t-trigger.Po \
+ ./$(DEPDIR)/t-varbuf.Po ./$(DEPDIR)/t-version.Po
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
+CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CXXFLAGS) $(CXXFLAGS)
+AM_V_CXX = $(am__v_CXX_@AM_V@)
+am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@)
+am__v_CXX_0 = @echo " CXX " $@;
+am__v_CXX_1 =
+CXXLD = $(CXX)
+CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
+ $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CXXLD = $(am__v_CXXLD_@AM_V@)
+am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@)
+am__v_CXXLD_0 = @echo " CXXLD " $@;
+am__v_CXXLD_1 =
+SOURCES = b-fsys-hash.c b-pkg-hash.c c-tarextract.c c-treewalk.c \
+ c-trigdeferred.c t-ar.c t-arch.c t-buffer.c t-c-ctype.c \
+ t-command.c t-deb-version.c t-ehandle.c t-error.c t-file.c \
+ t-fsys-dir.c t-fsys-hash.c $(t_headers_cpp_SOURCES) t-macros.c \
+ t-mod-db.c t-namevalue.c t-pager.c t-path.c t-pkg-format.c \
+ t-pkg-hash.c t-pkg-list.c t-pkg-queue.c t-pkg-show.c \
+ t-pkginfo.c t-progname.c t-string.c t-subproc.c t-tar.c \
+ t-test.c t-test-skip.c t-trigger.c t-varbuf.c t-version.c
+DIST_SOURCES = b-fsys-hash.c b-pkg-hash.c c-tarextract.c c-treewalk.c \
+ c-trigdeferred.c t-ar.c t-arch.c t-buffer.c t-c-ctype.c \
+ t-command.c t-deb-version.c t-ehandle.c t-error.c t-file.c \
+ t-fsys-dir.c t-fsys-hash.c $(t_headers_cpp_SOURCES) t-macros.c \
+ t-mod-db.c t-namevalue.c t-pager.c t-path.c t-pkg-format.c \
+ t-pkg-hash.c t-pkg-list.c t-pkg-queue.c t-pkg-show.c \
+ t-pkginfo.c t-progname.c t-string.c t-subproc.c t-tar.c \
+ t-test.c t-test-skip.c t-trigger.c t-varbuf.c t-version.c
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__DIST_COMMON = $(srcdir)/Makefile.in \
+ $(top_srcdir)/build-aux/depcomp $(top_srcdir)/check.am
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOM4TE = @AUTOM4TE@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BUILD_DEVEL_DOCS = @BUILD_DEVEL_DOCS@
+BZ2_LIBS = @BZ2_LIBS@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CURSES_LIBS = @CURSES_LIBS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DOXYGEN = @DOXYGEN@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GCOV = @GCOV@
+GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
+GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
+GREP = @GREP@
+HAVE_DOT = @HAVE_DOT@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INTLLIBS = @INTLLIBS@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+KVM_LIBS = @KVM_LIBS@
+LCOV = @LCOV@
+LCOV_GENHTML = @LCOV_GENHTML@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+LZMA_LIBS = @LZMA_LIBS@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MD_LIBS = @MD_LIBS@
+MKDIR_P = @MKDIR_P@
+MSGFMT = @MSGFMT@
+MSGMERGE = @MSGMERGE@
+MSGMERGE_FOR_MSGFMT_OPTION = @MSGMERGE_FOR_MSGFMT_OPTION@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_BUG_WEB = @PACKAGE_BUG_WEB@
+PACKAGE_COPYRIGHT_HOLDER = @PACKAGE_COPYRIGHT_HOLDER@
+PACKAGE_CPAN_NAME = @PACKAGE_CPAN_NAME@
+PACKAGE_DIST_IS_RELEASE = @PACKAGE_DIST_IS_RELEASE@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_RELEASE_DATE = @PACKAGE_RELEASE_DATE@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VCS_TYPE = @PACKAGE_VCS_TYPE@
+PACKAGE_VCS_URL = @PACKAGE_VCS_URL@
+PACKAGE_VCS_WEB = @PACKAGE_VCS_WEB@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATCH = @PATCH@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+PERL_COVER = @PERL_COVER@
+PERL_COVERAGE = @PERL_COVERAGE@
+PERL_LIBDIR = @PERL_LIBDIR@
+PERL_MIN_VERSION = @PERL_MIN_VERSION@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+PO4A = @PO4A@
+POD2MAN = @POD2MAN@
+POSUB = @POSUB@
+PS_LIBS = @PS_LIBS@
+RANLIB = @RANLIB@
+SED = @SED@
+SELINUX_CFLAGS = @SELINUX_CFLAGS@
+SELINUX_LIBS = @SELINUX_LIBS@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+TAR = @TAR@
+USE_NLS = @USE_NLS@
+USE_PO4A = @USE_PO4A@
+USE_UNICODE = @USE_UNICODE@
+VERSION = @VERSION@
+XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
+Z_LIBS = @Z_LIBS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+admindir = @admindir@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+devlibdir = @devlibdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+logdir = @logdir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+pkgconfdir = @pkgconfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+runstatedir = @runstatedir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+AM_CPPFLAGS = \
+ -DADMINDIR=\"$(admindir)\" \
+ -idirafter $(top_srcdir)/lib/compat \
+ -I$(top_builddir) \
+ -I$(top_srcdir)/lib
+
+LDADD = \
+ $(top_builddir)/lib/dpkg/libdpkg.la \
+ $(LIBINTL)
+
+EXTRA_DIST = \
+ $(test_scripts) \
+ $(nil)
+
+TEST_ENV_VARS = \
+ DPKG_PROGTAR=$(TAR) \
+ $(nil)
+
+t_headers_cpp_SOURCES = t-headers-cpp.cc
+
+# The tests are sorted in order of increasing complexity.
+test_programs = \
+ t-test \
+ t-test-skip \
+ t-macros \
+ t-headers-cpp \
+ t-c-ctype \
+ t-namevalue \
+ t-ehandle \
+ t-error \
+ t-string \
+ t-file \
+ t-buffer \
+ t-path \
+ t-progname \
+ t-subproc \
+ t-command \
+ t-pager \
+ t-varbuf \
+ t-ar \
+ t-tar \
+ t-deb-version \
+ t-arch \
+ t-version \
+ t-pkginfo \
+ t-pkg-list \
+ t-pkg-queue \
+ t-pkg-hash \
+ t-pkg-show \
+ t-pkg-format \
+ t-fsys-dir \
+ t-fsys-hash \
+ t-trigger \
+ t-mod-db \
+ $(nil)
+
+test_scripts = \
+ t-tarextract.t \
+ t-treewalk.t \
+ t-trigdeferred.t \
+ $(nil)
+
+BENCHMARK_LDADD_FLAGS = -lrt $(LDADD)
+b_fsys_hash_LDADD = $(BENCHMARK_LDADD_FLAGS)
+b_pkg_hash_LDADD = $(BENCHMARK_LDADD_FLAGS)
+test_tmpdir = t.tmp
+TEST_RUNNER = '\
+ my $$harness = TAP::Harness->new({ \
+ exec => sub { my (undef, $$test) = @_; \
+ return [ $$test ] if $$test !~ "\.t\$$" and -x $$test; \
+ return }, \
+ lib => [ "$(top_srcdir)/scripts", "$(top_srcdir)/dselect/methods" ], \
+ color => 1, \
+ verbosity => $(TEST_VERBOSE), \
+ jobs => $(TEST_PARALLEL), \
+ failures => 1, \
+ }); \
+ my $$aggregate = $$harness->runtests(@ARGV); \
+ die "FAIL: test suite has errors\n" if $$aggregate->has_errors;'
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .cc .lo .o .obj
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(top_srcdir)/check.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign lib/dpkg/t/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign lib/dpkg/t/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
+ esac;
+$(top_srcdir)/check.am $(am__empty):
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-checkPROGRAMS:
+ @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+
+b-fsys-hash$(EXEEXT): $(b_fsys_hash_OBJECTS) $(b_fsys_hash_DEPENDENCIES) $(EXTRA_b_fsys_hash_DEPENDENCIES)
+ @rm -f b-fsys-hash$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(b_fsys_hash_OBJECTS) $(b_fsys_hash_LDADD) $(LIBS)
+
+b-pkg-hash$(EXEEXT): $(b_pkg_hash_OBJECTS) $(b_pkg_hash_DEPENDENCIES) $(EXTRA_b_pkg_hash_DEPENDENCIES)
+ @rm -f b-pkg-hash$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(b_pkg_hash_OBJECTS) $(b_pkg_hash_LDADD) $(LIBS)
+
+c-tarextract$(EXEEXT): $(c_tarextract_OBJECTS) $(c_tarextract_DEPENDENCIES) $(EXTRA_c_tarextract_DEPENDENCIES)
+ @rm -f c-tarextract$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(c_tarextract_OBJECTS) $(c_tarextract_LDADD) $(LIBS)
+
+c-treewalk$(EXEEXT): $(c_treewalk_OBJECTS) $(c_treewalk_DEPENDENCIES) $(EXTRA_c_treewalk_DEPENDENCIES)
+ @rm -f c-treewalk$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(c_treewalk_OBJECTS) $(c_treewalk_LDADD) $(LIBS)
+
+c-trigdeferred$(EXEEXT): $(c_trigdeferred_OBJECTS) $(c_trigdeferred_DEPENDENCIES) $(EXTRA_c_trigdeferred_DEPENDENCIES)
+ @rm -f c-trigdeferred$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(c_trigdeferred_OBJECTS) $(c_trigdeferred_LDADD) $(LIBS)
+
+t-ar$(EXEEXT): $(t_ar_OBJECTS) $(t_ar_DEPENDENCIES) $(EXTRA_t_ar_DEPENDENCIES)
+ @rm -f t-ar$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(t_ar_OBJECTS) $(t_ar_LDADD) $(LIBS)
+
+t-arch$(EXEEXT): $(t_arch_OBJECTS) $(t_arch_DEPENDENCIES) $(EXTRA_t_arch_DEPENDENCIES)
+ @rm -f t-arch$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(t_arch_OBJECTS) $(t_arch_LDADD) $(LIBS)
+
+t-buffer$(EXEEXT): $(t_buffer_OBJECTS) $(t_buffer_DEPENDENCIES) $(EXTRA_t_buffer_DEPENDENCIES)
+ @rm -f t-buffer$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(t_buffer_OBJECTS) $(t_buffer_LDADD) $(LIBS)
+
+t-c-ctype$(EXEEXT): $(t_c_ctype_OBJECTS) $(t_c_ctype_DEPENDENCIES) $(EXTRA_t_c_ctype_DEPENDENCIES)
+ @rm -f t-c-ctype$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(t_c_ctype_OBJECTS) $(t_c_ctype_LDADD) $(LIBS)
+
+t-command$(EXEEXT): $(t_command_OBJECTS) $(t_command_DEPENDENCIES) $(EXTRA_t_command_DEPENDENCIES)
+ @rm -f t-command$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(t_command_OBJECTS) $(t_command_LDADD) $(LIBS)
+
+t-deb-version$(EXEEXT): $(t_deb_version_OBJECTS) $(t_deb_version_DEPENDENCIES) $(EXTRA_t_deb_version_DEPENDENCIES)
+ @rm -f t-deb-version$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(t_deb_version_OBJECTS) $(t_deb_version_LDADD) $(LIBS)
+
+t-ehandle$(EXEEXT): $(t_ehandle_OBJECTS) $(t_ehandle_DEPENDENCIES) $(EXTRA_t_ehandle_DEPENDENCIES)
+ @rm -f t-ehandle$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(t_ehandle_OBJECTS) $(t_ehandle_LDADD) $(LIBS)
+
+t-error$(EXEEXT): $(t_error_OBJECTS) $(t_error_DEPENDENCIES) $(EXTRA_t_error_DEPENDENCIES)
+ @rm -f t-error$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(t_error_OBJECTS) $(t_error_LDADD) $(LIBS)
+
+t-file$(EXEEXT): $(t_file_OBJECTS) $(t_file_DEPENDENCIES) $(EXTRA_t_file_DEPENDENCIES)
+ @rm -f t-file$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(t_file_OBJECTS) $(t_file_LDADD) $(LIBS)
+
+t-fsys-dir$(EXEEXT): $(t_fsys_dir_OBJECTS) $(t_fsys_dir_DEPENDENCIES) $(EXTRA_t_fsys_dir_DEPENDENCIES)
+ @rm -f t-fsys-dir$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(t_fsys_dir_OBJECTS) $(t_fsys_dir_LDADD) $(LIBS)
+
+t-fsys-hash$(EXEEXT): $(t_fsys_hash_OBJECTS) $(t_fsys_hash_DEPENDENCIES) $(EXTRA_t_fsys_hash_DEPENDENCIES)
+ @rm -f t-fsys-hash$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(t_fsys_hash_OBJECTS) $(t_fsys_hash_LDADD) $(LIBS)
+
+t-headers-cpp$(EXEEXT): $(t_headers_cpp_OBJECTS) $(t_headers_cpp_DEPENDENCIES) $(EXTRA_t_headers_cpp_DEPENDENCIES)
+ @rm -f t-headers-cpp$(EXEEXT)
+ $(AM_V_CXXLD)$(CXXLINK) $(t_headers_cpp_OBJECTS) $(t_headers_cpp_LDADD) $(LIBS)
+
+t-macros$(EXEEXT): $(t_macros_OBJECTS) $(t_macros_DEPENDENCIES) $(EXTRA_t_macros_DEPENDENCIES)
+ @rm -f t-macros$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(t_macros_OBJECTS) $(t_macros_LDADD) $(LIBS)
+
+t-mod-db$(EXEEXT): $(t_mod_db_OBJECTS) $(t_mod_db_DEPENDENCIES) $(EXTRA_t_mod_db_DEPENDENCIES)
+ @rm -f t-mod-db$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(t_mod_db_OBJECTS) $(t_mod_db_LDADD) $(LIBS)
+
+t-namevalue$(EXEEXT): $(t_namevalue_OBJECTS) $(t_namevalue_DEPENDENCIES) $(EXTRA_t_namevalue_DEPENDENCIES)
+ @rm -f t-namevalue$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(t_namevalue_OBJECTS) $(t_namevalue_LDADD) $(LIBS)
+
+t-pager$(EXEEXT): $(t_pager_OBJECTS) $(t_pager_DEPENDENCIES) $(EXTRA_t_pager_DEPENDENCIES)
+ @rm -f t-pager$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(t_pager_OBJECTS) $(t_pager_LDADD) $(LIBS)
+
+t-path$(EXEEXT): $(t_path_OBJECTS) $(t_path_DEPENDENCIES) $(EXTRA_t_path_DEPENDENCIES)
+ @rm -f t-path$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(t_path_OBJECTS) $(t_path_LDADD) $(LIBS)
+
+t-pkg-format$(EXEEXT): $(t_pkg_format_OBJECTS) $(t_pkg_format_DEPENDENCIES) $(EXTRA_t_pkg_format_DEPENDENCIES)
+ @rm -f t-pkg-format$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(t_pkg_format_OBJECTS) $(t_pkg_format_LDADD) $(LIBS)
+
+t-pkg-hash$(EXEEXT): $(t_pkg_hash_OBJECTS) $(t_pkg_hash_DEPENDENCIES) $(EXTRA_t_pkg_hash_DEPENDENCIES)
+ @rm -f t-pkg-hash$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(t_pkg_hash_OBJECTS) $(t_pkg_hash_LDADD) $(LIBS)
+
+t-pkg-list$(EXEEXT): $(t_pkg_list_OBJECTS) $(t_pkg_list_DEPENDENCIES) $(EXTRA_t_pkg_list_DEPENDENCIES)
+ @rm -f t-pkg-list$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(t_pkg_list_OBJECTS) $(t_pkg_list_LDADD) $(LIBS)
+
+t-pkg-queue$(EXEEXT): $(t_pkg_queue_OBJECTS) $(t_pkg_queue_DEPENDENCIES) $(EXTRA_t_pkg_queue_DEPENDENCIES)
+ @rm -f t-pkg-queue$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(t_pkg_queue_OBJECTS) $(t_pkg_queue_LDADD) $(LIBS)
+
+t-pkg-show$(EXEEXT): $(t_pkg_show_OBJECTS) $(t_pkg_show_DEPENDENCIES) $(EXTRA_t_pkg_show_DEPENDENCIES)
+ @rm -f t-pkg-show$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(t_pkg_show_OBJECTS) $(t_pkg_show_LDADD) $(LIBS)
+
+t-pkginfo$(EXEEXT): $(t_pkginfo_OBJECTS) $(t_pkginfo_DEPENDENCIES) $(EXTRA_t_pkginfo_DEPENDENCIES)
+ @rm -f t-pkginfo$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(t_pkginfo_OBJECTS) $(t_pkginfo_LDADD) $(LIBS)
+
+t-progname$(EXEEXT): $(t_progname_OBJECTS) $(t_progname_DEPENDENCIES) $(EXTRA_t_progname_DEPENDENCIES)
+ @rm -f t-progname$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(t_progname_OBJECTS) $(t_progname_LDADD) $(LIBS)
+
+t-string$(EXEEXT): $(t_string_OBJECTS) $(t_string_DEPENDENCIES) $(EXTRA_t_string_DEPENDENCIES)
+ @rm -f t-string$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(t_string_OBJECTS) $(t_string_LDADD) $(LIBS)
+
+t-subproc$(EXEEXT): $(t_subproc_OBJECTS) $(t_subproc_DEPENDENCIES) $(EXTRA_t_subproc_DEPENDENCIES)
+ @rm -f t-subproc$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(t_subproc_OBJECTS) $(t_subproc_LDADD) $(LIBS)
+
+t-tar$(EXEEXT): $(t_tar_OBJECTS) $(t_tar_DEPENDENCIES) $(EXTRA_t_tar_DEPENDENCIES)
+ @rm -f t-tar$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(t_tar_OBJECTS) $(t_tar_LDADD) $(LIBS)
+
+t-test$(EXEEXT): $(t_test_OBJECTS) $(t_test_DEPENDENCIES) $(EXTRA_t_test_DEPENDENCIES)
+ @rm -f t-test$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(t_test_OBJECTS) $(t_test_LDADD) $(LIBS)
+
+t-test-skip$(EXEEXT): $(t_test_skip_OBJECTS) $(t_test_skip_DEPENDENCIES) $(EXTRA_t_test_skip_DEPENDENCIES)
+ @rm -f t-test-skip$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(t_test_skip_OBJECTS) $(t_test_skip_LDADD) $(LIBS)
+
+t-trigger$(EXEEXT): $(t_trigger_OBJECTS) $(t_trigger_DEPENDENCIES) $(EXTRA_t_trigger_DEPENDENCIES)
+ @rm -f t-trigger$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(t_trigger_OBJECTS) $(t_trigger_LDADD) $(LIBS)
+
+t-varbuf$(EXEEXT): $(t_varbuf_OBJECTS) $(t_varbuf_DEPENDENCIES) $(EXTRA_t_varbuf_DEPENDENCIES)
+ @rm -f t-varbuf$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(t_varbuf_OBJECTS) $(t_varbuf_LDADD) $(LIBS)
+
+t-version$(EXEEXT): $(t_version_OBJECTS) $(t_version_DEPENDENCIES) $(EXTRA_t_version_DEPENDENCIES)
+ @rm -f t-version$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(t_version_OBJECTS) $(t_version_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/b-fsys-hash.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/b-pkg-hash.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/c-tarextract.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/c-treewalk.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/c-trigdeferred.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-ar.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-arch.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-buffer.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-c-ctype.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-command.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-deb-version.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-ehandle.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-error.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-file.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-fsys-dir.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-fsys-hash.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-headers-cpp.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-macros.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-mod-db.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-namevalue.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-pager.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-path.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-pkg-format.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-pkg-hash.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-pkg-list.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-pkg-queue.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-pkg-show.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-pkginfo.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-progname.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-string.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-subproc.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-tar.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-test-skip.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-test.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-trigger.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-varbuf.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-version.Po@am__quote@ # am--include-marker
+
+$(am__depfiles_remade):
+ @$(MKDIR_P) $(@D)
+ @echo '# dummy' >$@-t && $(am__mv) $@-t $@
+
+am--depfiles: $(am__depfiles_remade)
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+.cc.o:
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $<
+
+.cc.obj:
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.cc.lo:
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS)
+ $(MAKE) $(AM_MAKEFLAGS) check-local
+check: check-am
+all-am: Makefile
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-checkPROGRAMS clean-generic clean-libtool clean-local \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -f ./$(DEPDIR)/b-fsys-hash.Po
+ -rm -f ./$(DEPDIR)/b-pkg-hash.Po
+ -rm -f ./$(DEPDIR)/c-tarextract.Po
+ -rm -f ./$(DEPDIR)/c-treewalk.Po
+ -rm -f ./$(DEPDIR)/c-trigdeferred.Po
+ -rm -f ./$(DEPDIR)/t-ar.Po
+ -rm -f ./$(DEPDIR)/t-arch.Po
+ -rm -f ./$(DEPDIR)/t-buffer.Po
+ -rm -f ./$(DEPDIR)/t-c-ctype.Po
+ -rm -f ./$(DEPDIR)/t-command.Po
+ -rm -f ./$(DEPDIR)/t-deb-version.Po
+ -rm -f ./$(DEPDIR)/t-ehandle.Po
+ -rm -f ./$(DEPDIR)/t-error.Po
+ -rm -f ./$(DEPDIR)/t-file.Po
+ -rm -f ./$(DEPDIR)/t-fsys-dir.Po
+ -rm -f ./$(DEPDIR)/t-fsys-hash.Po
+ -rm -f ./$(DEPDIR)/t-headers-cpp.Po
+ -rm -f ./$(DEPDIR)/t-macros.Po
+ -rm -f ./$(DEPDIR)/t-mod-db.Po
+ -rm -f ./$(DEPDIR)/t-namevalue.Po
+ -rm -f ./$(DEPDIR)/t-pager.Po
+ -rm -f ./$(DEPDIR)/t-path.Po
+ -rm -f ./$(DEPDIR)/t-pkg-format.Po
+ -rm -f ./$(DEPDIR)/t-pkg-hash.Po
+ -rm -f ./$(DEPDIR)/t-pkg-list.Po
+ -rm -f ./$(DEPDIR)/t-pkg-queue.Po
+ -rm -f ./$(DEPDIR)/t-pkg-show.Po
+ -rm -f ./$(DEPDIR)/t-pkginfo.Po
+ -rm -f ./$(DEPDIR)/t-progname.Po
+ -rm -f ./$(DEPDIR)/t-string.Po
+ -rm -f ./$(DEPDIR)/t-subproc.Po
+ -rm -f ./$(DEPDIR)/t-tar.Po
+ -rm -f ./$(DEPDIR)/t-test-skip.Po
+ -rm -f ./$(DEPDIR)/t-test.Po
+ -rm -f ./$(DEPDIR)/t-trigger.Po
+ -rm -f ./$(DEPDIR)/t-varbuf.Po
+ -rm -f ./$(DEPDIR)/t-version.Po
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f ./$(DEPDIR)/b-fsys-hash.Po
+ -rm -f ./$(DEPDIR)/b-pkg-hash.Po
+ -rm -f ./$(DEPDIR)/c-tarextract.Po
+ -rm -f ./$(DEPDIR)/c-treewalk.Po
+ -rm -f ./$(DEPDIR)/c-trigdeferred.Po
+ -rm -f ./$(DEPDIR)/t-ar.Po
+ -rm -f ./$(DEPDIR)/t-arch.Po
+ -rm -f ./$(DEPDIR)/t-buffer.Po
+ -rm -f ./$(DEPDIR)/t-c-ctype.Po
+ -rm -f ./$(DEPDIR)/t-command.Po
+ -rm -f ./$(DEPDIR)/t-deb-version.Po
+ -rm -f ./$(DEPDIR)/t-ehandle.Po
+ -rm -f ./$(DEPDIR)/t-error.Po
+ -rm -f ./$(DEPDIR)/t-file.Po
+ -rm -f ./$(DEPDIR)/t-fsys-dir.Po
+ -rm -f ./$(DEPDIR)/t-fsys-hash.Po
+ -rm -f ./$(DEPDIR)/t-headers-cpp.Po
+ -rm -f ./$(DEPDIR)/t-macros.Po
+ -rm -f ./$(DEPDIR)/t-mod-db.Po
+ -rm -f ./$(DEPDIR)/t-namevalue.Po
+ -rm -f ./$(DEPDIR)/t-pager.Po
+ -rm -f ./$(DEPDIR)/t-path.Po
+ -rm -f ./$(DEPDIR)/t-pkg-format.Po
+ -rm -f ./$(DEPDIR)/t-pkg-hash.Po
+ -rm -f ./$(DEPDIR)/t-pkg-list.Po
+ -rm -f ./$(DEPDIR)/t-pkg-queue.Po
+ -rm -f ./$(DEPDIR)/t-pkg-show.Po
+ -rm -f ./$(DEPDIR)/t-pkginfo.Po
+ -rm -f ./$(DEPDIR)/t-progname.Po
+ -rm -f ./$(DEPDIR)/t-string.Po
+ -rm -f ./$(DEPDIR)/t-subproc.Po
+ -rm -f ./$(DEPDIR)/t-tar.Po
+ -rm -f ./$(DEPDIR)/t-test-skip.Po
+ -rm -f ./$(DEPDIR)/t-test.Po
+ -rm -f ./$(DEPDIR)/t-trigger.Po
+ -rm -f ./$(DEPDIR)/t-varbuf.Po
+ -rm -f ./$(DEPDIR)/t-version.Po
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: check-am install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am \
+ check-local clean clean-checkPROGRAMS clean-generic \
+ clean-libtool clean-local cscopelist-am ctags ctags-am \
+ distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-man install-pdf install-pdf-am \
+ install-ps install-ps-am install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags tags-am uninstall uninstall-am
+
+.PRECIOUS: Makefile
+
+
+TEST_VERBOSE ?= 0
+TEST_PARALLEL ?= 1
+
+check-clean:
+ [ -z "$(test_tmpdir)" ] || rm -fr $(test_tmpdir)
+
+check-local: $(test_data) $(test_programs) $(test_scripts)
+ [ -z "$(test_tmpdir)" ] || $(MKDIR_P) $(test_tmpdir)
+ PATH="$(abs_top_builddir)/src:$(abs_top_builddir)/scripts:$(abs_top_builddir)/utils:$(PATH)" \
+ LC_ALL=C \
+ DPKG_COLORS=never \
+ $(TEST_ENV_VARS) \
+ srcdir=$(srcdir) builddir=$(builddir) \
+ CC=$(CC) \
+ PERL=$(PERL) \
+ SHELL=$(SHELL) \
+ PERL_DL_NONLAZY=1 \
+ PERL5LIB=$(abs_top_srcdir)/scripts:$(abs_top_srcdir)/dselect/methods \
+ PERL5OPT=$(TEST_COVERAGE) \
+ $(PERL) -MTAP::Harness -e $(TEST_RUNNER) \
+ $(addprefix $(builddir)/,$(test_programs)) \
+ $(addprefix $(srcdir)/,$(test_scripts))
+
+clean-local: check-clean
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/lib/dpkg/t/b-fsys-hash.c b/lib/dpkg/t/b-fsys-hash.c
new file mode 100644
index 0000000..7ae8f9c
--- /dev/null
+++ b/lib/dpkg/t/b-fsys-hash.c
@@ -0,0 +1,81 @@
+/*
+ * libdpkg - Debian packaging suite library routines
+ * b-fsys-hash.c - test fsys database load and hash performance
+ *
+ * Copyright © 2009-2019 Guillem Jover <guillem@debian.org>
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2,
+ * or (at your option) any later version.
+ *
+ * This is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <compat.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <time.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <dpkg/i18n.h>
+#include <dpkg/dpkg.h>
+#include <dpkg/dpkg-db.h>
+
+#include <dpkg/perf.h>
+
+#include <dpkg/db-fsys.h>
+
+static const char *admindir;
+
+int
+main(int argc, const char *const *argv)
+{
+ struct perf_slot ps;
+
+ push_error_context();
+ setvbuf(stdout, NULL, _IONBF, 0);
+
+ admindir = dpkg_db_set_dir(admindir);
+
+ perf_ts_mark_print("init");
+
+ perf_ts_slot_start(&ps);
+ fsys_hash_init();
+ perf_ts_slot_stop(&ps);
+
+ perf_ts_slot_print(&ps, "fsys_hash_init");
+
+ perf_ts_slot_start(&ps);
+ modstatdb_open(msdbrw_readonly | msdbrw_available_readonly);
+ perf_ts_slot_stop(&ps);
+
+ perf_ts_slot_print(&ps, "modstatdb_init");
+
+ perf_ts_slot_start(&ps);
+ ensure_allinstfiles_available_quiet();
+ perf_ts_slot_stop(&ps);
+
+ perf_ts_slot_print(&ps, "load .list");
+
+ if (test_is_verbose()) {
+ pkg_hash_report(stdout);
+ fsys_hash_report(stdout);
+ }
+
+ modstatdb_shutdown();
+ pop_error_context(ehflag_normaltidy);
+
+ perf_ts_mark_print("shutdown");
+
+ return 0;
+}
diff --git a/lib/dpkg/t/b-pkg-hash.c b/lib/dpkg/t/b-pkg-hash.c
new file mode 100644
index 0000000..26cdc12
--- /dev/null
+++ b/lib/dpkg/t/b-pkg-hash.c
@@ -0,0 +1,65 @@
+/*
+ * libdpkg - Debian packaging suite library routines
+ * b-pkg-hash.c - test pkg database load and hash performance
+ *
+ * Copyright © 2009-2019 Guillem Jover <guillem@debian.org>
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2,
+ * or (at your option) any later version.
+ *
+ * This is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <compat.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <time.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <dpkg/i18n.h>
+#include <dpkg/dpkg.h>
+#include <dpkg/dpkg-db.h>
+
+#include <dpkg/perf.h>
+
+static const char *admindir;
+
+int
+main(int argc, const char *const *argv)
+{
+ struct perf_slot ps;
+
+ push_error_context();
+ setvbuf(stdout, NULL, _IONBF, 0);
+
+ admindir = dpkg_db_set_dir(admindir);
+
+ perf_ts_mark_print("init");
+
+ perf_ts_slot_start(&ps);
+ modstatdb_open(msdbrw_readonly | msdbrw_available_readonly);
+ perf_ts_slot_stop(&ps);
+
+ perf_ts_slot_print(&ps, "modstatdb_init");
+
+ if (test_is_verbose())
+ pkg_hash_report(stdout);
+
+ modstatdb_shutdown();
+ pop_error_context(ehflag_normaltidy);
+
+ perf_ts_mark_print("shutdown");
+
+ return 0;
+}
diff --git a/lib/dpkg/t/c-tarextract.c b/lib/dpkg/t/c-tarextract.c
new file mode 100644
index 0000000..882253d
--- /dev/null
+++ b/lib/dpkg/t/c-tarextract.c
@@ -0,0 +1,151 @@
+/*
+ * libdpkg - Debian packaging suite library routines
+ * c-tarextract.c - test tar extractor
+ *
+ * Copyright © 2014 Guillem Jover <guillem@debian.org>
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2,
+ * or (at your option) any later version.
+ *
+ * This is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <compat.h>
+
+#include <sys/types.h>
+#if HAVE_SYS_SYSMACROS_H
+#include <sys/sysmacros.h> /* Needed on AIX for major()/minor(). */
+#endif
+
+#include <fcntl.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <dpkg/ehandle.h>
+#include <dpkg/fdio.h>
+#include <dpkg/buffer.h>
+#include <dpkg/tarfn.h>
+
+struct tar_context {
+ int tar_fd;
+};
+
+static int
+tar_read(struct tar_archive *tar, char *buffer, int size)
+{
+ struct tar_context *tc = tar->ctx;
+
+ return fd_read(tc->tar_fd, buffer, size);
+}
+
+static int
+tar_object_skip(struct tar_archive *tar, struct tar_entry *te)
+{
+ struct tar_context *tc = tar->ctx;
+ off_t size;
+
+ size = (te->size + TARBLKSZ - 1) / TARBLKSZ * TARBLKSZ;
+ if (size == 0)
+ return 0;
+
+ return fd_skip(tc->tar_fd, size, NULL);
+}
+
+static int
+tar_object(struct tar_archive *tar, struct tar_entry *te)
+{
+ printf("%s mode=%o time=%jd.%.9d uid=%d gid=%d", te->name,
+ te->stat.mode, te->mtime, 0, te->stat.uid, te->stat.gid);
+ if (te->stat.uname)
+ printf(" uname=%s", te->stat.uname);
+ if (te->stat.gname)
+ printf(" gname=%s", te->stat.gname);
+
+ switch (te->type) {
+ case TAR_FILETYPE_FILE0:
+ case TAR_FILETYPE_FILE:
+ tar_object_skip(tar, te);
+ printf(" type=file size=%jd", (intmax_t)te->size);
+ break;
+ case TAR_FILETYPE_HARDLINK:
+ printf(" type=hardlink linkto=%s size=%jd",
+ te->linkname, (intmax_t)te->size);
+ break;
+ case TAR_FILETYPE_SYMLINK:
+ printf(" type=symlink linkto=%s size=%jd",
+ te->linkname, (intmax_t)te->size);
+ break;
+ case TAR_FILETYPE_DIR:
+ printf(" type=dir");
+ break;
+ case TAR_FILETYPE_CHARDEV:
+ case TAR_FILETYPE_BLOCKDEV:
+ printf(" type=device id=%d.%d", major(te->dev), minor(te->dev));
+ break;
+ case TAR_FILETYPE_FIFO:
+ printf(" type=fifo");
+ break;
+ default:
+ ohshit("unexpected tar entry type '%c'", te->type);
+ }
+
+ printf("\n");
+
+ return 0;
+}
+
+struct tar_operations tar_ops = {
+ .read = tar_read,
+ .extract_file = tar_object,
+ .link = tar_object,
+ .symlink = tar_object,
+ .mkdir = tar_object,
+ .mknod = tar_object,
+};
+
+int
+main(int argc, char **argv)
+{
+ struct tar_archive tar;
+ struct tar_context tar_ctx;
+ const char *tar_name = argv[1];
+
+ setvbuf(stdout, NULL, _IOLBF, 0);
+
+ push_error_context();
+
+ if (tar_name) {
+ tar_ctx.tar_fd = open(tar_name, O_RDONLY);
+ if (tar_ctx.tar_fd < 0)
+ ohshite("cannot open file '%s'", tar_name);
+ } else {
+ tar_ctx.tar_fd = STDIN_FILENO;
+ }
+
+ tar.err = DPKG_ERROR_OBJECT;
+ tar.ctx = &tar_ctx;
+ tar.ops = &tar_ops;
+
+ if (tar_extractor(&tar))
+ ohshite("extracting tar");
+
+ dpkg_error_destroy(&tar.err);
+
+ if (tar_name)
+ close(tar_ctx.tar_fd);
+
+ pop_error_context(ehflag_normaltidy);
+
+ return 0;
+}
diff --git a/lib/dpkg/t/c-treewalk.c b/lib/dpkg/t/c-treewalk.c
new file mode 100644
index 0000000..0c5d2d5
--- /dev/null
+++ b/lib/dpkg/t/c-treewalk.c
@@ -0,0 +1,132 @@
+/*
+ * libdpkg - Debian packaging suite library routines
+ * c-treewalk.c - test tree walk implementation
+ *
+ * Copyright © 2013-2016 Guillem Jover <guillem@debian.org>
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <compat.h>
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <dpkg/ehandle.h>
+#include <dpkg/treewalk.h>
+
+static int
+treenode_type(struct treenode *node)
+{
+ switch (treenode_get_mode(node) & S_IFMT) {
+ case S_IFREG:
+ return 'f';
+ case S_IFDIR:
+ return 'd';
+ case S_IFLNK:
+ return 'l';
+ case S_IFIFO:
+ return 'p';
+ case S_IFBLK:
+ return 'b';
+ case S_IFCHR:
+ return 'c';
+ case S_IFSOCK:
+ return 's';
+ default:
+ return '?';
+ }
+}
+
+static int
+treenode_visit_meta(struct treenode *node)
+{
+ printf("T=%c N=%s V=%s R=%s\n",
+ treenode_type(node), treenode_get_name(node),
+ treenode_get_virtname(node), treenode_get_pathname(node));
+
+ return 0;
+}
+
+static int
+treenode_visit_virt(struct treenode *node)
+{
+ printf("%s\n", treenode_get_virtname(node));
+
+ return 0;
+}
+
+static int
+treenode_visit_path(struct treenode *node)
+{
+ printf("%s\n", treenode_get_pathname(node));
+
+ return 0;
+}
+
+static const char *skipname;
+
+static bool
+treenode_skip(struct treenode *node)
+{
+ const char *absname = treenode_get_pathname(node);
+
+ if (strcmp(absname, skipname) == 0)
+ return true;
+
+ return false;
+}
+
+static void
+test_treewalk_list(const char *rootdir)
+{
+ const char *visitname = getenv("TREEWALK_VISIT");
+ struct treewalk_funcs funcs = { NULL };
+
+ if (visitname == NULL || strcmp(visitname, "meta") == 0)
+ funcs.visit = treenode_visit_meta;
+ else if (strcmp(visitname, "virt") == 0)
+ funcs.visit = treenode_visit_virt;
+ else if (strcmp(visitname, "path") == 0)
+ funcs.visit = treenode_visit_path;
+ else
+ ohshit("unknown treewalk visit name");
+
+ skipname = getenv("TREEWALK_SKIP");
+ if (skipname)
+ funcs.skip = treenode_skip;
+
+ treewalk(rootdir, 0, &funcs);
+}
+
+int
+main(int argc, char **argv)
+{
+ const char *rootdir = argv[1];
+
+ setvbuf(stdout, NULL, _IOLBF, 0);
+
+ push_error_context();
+
+ if (rootdir == NULL)
+ ohshit("missing treewalk root dir");
+
+ test_treewalk_list(rootdir);
+
+ pop_error_context(ehflag_normaltidy);
+
+ return 0;
+}
diff --git a/lib/dpkg/t/c-trigdeferred.c b/lib/dpkg/t/c-trigdeferred.c
new file mode 100644
index 0000000..6c7ad18
--- /dev/null
+++ b/lib/dpkg/t/c-trigdeferred.c
@@ -0,0 +1,96 @@
+/*
+ * libdpkg - Debian packaging suite library routines
+ * c-trigdeferred.c - test triggered deferred file parser
+ *
+ * Copyright © 2016 Guillem Jover <guillem@debian.org>
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <compat.h>
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <dpkg/dpkg-db.h>
+#include <dpkg/ehandle.h>
+#include <dpkg/trigdeferred.h>
+
+static void
+test_tdm_begin(const char *trig)
+{
+ printf("<T='%s'", trig);
+}
+
+static void
+test_tdm_package(const char *awname)
+{
+ printf(" P='%s'", awname);
+}
+
+static void
+test_tdm_end(void)
+{
+ printf(" E>\n");
+}
+
+static const struct trigdefmeths test_tdm = {
+ .trig_begin = test_tdm_begin,
+ .package = test_tdm_package,
+ .trig_end = test_tdm_end,
+};
+
+static int
+test_trigdeferred_parser(const char *admindir)
+{
+ enum trigdef_update_flags tduf;
+ enum trigdef_update_status tdus;
+
+ dpkg_db_set_dir(admindir);
+
+ trigdef_set_methods(&test_tdm);
+
+ tduf = TDUF_NO_LOCK | TDUF_WRITE_IF_EMPTY | TDUF_WRITE_IF_ENOENT;
+ tdus = trigdef_update_start(tduf);
+ if (tdus < TDUS_OK)
+ return -tdus + TDUS_OK;
+
+ trigdef_parse();
+
+ trigdef_process_done();
+
+ return 0;
+}
+
+int
+main(int argc, char **argv)
+{
+ const char *admindir = argv[1];
+ int ret;
+
+ setvbuf(stdout, NULL, _IOLBF, 0);
+
+ push_error_context();
+
+ if (admindir == NULL)
+ ohshit("missing triggers deferred admindir");
+
+ ret = test_trigdeferred_parser(admindir);
+
+ pop_error_context(ehflag_normaltidy);
+
+ return ret;
+}
diff --git a/lib/dpkg/t/t-ar.c b/lib/dpkg/t/t-ar.c
new file mode 100644
index 0000000..88e9387
--- /dev/null
+++ b/lib/dpkg/t/t-ar.c
@@ -0,0 +1,61 @@
+/*
+ * libdpkg - Debian packaging suite library routines
+ * t-ar.c - test ar implementation
+ *
+ * Copyright © 2010 Guillem Jover <guillem@debian.org>
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <compat.h>
+
+#include <string.h>
+
+#include <dpkg/test.h>
+#include <dpkg/ar.h>
+
+static void
+test_ar_normalize_name(void)
+{
+ struct dpkg_ar_hdr arh;
+
+ memccpy(arh.ar_name, "member-name/ ", '\0', sizeof(arh.ar_name));
+ dpkg_ar_normalize_name(&arh);
+ test_str(arh.ar_name, ==, "member-name");
+
+ memccpy(arh.ar_name, "member-name ", '\0', sizeof(arh.ar_name));
+ dpkg_ar_normalize_name(&arh);
+ test_str(arh.ar_name, ==, "member-name");
+}
+
+static void
+test_ar_member_is_illegal(void)
+{
+ struct dpkg_ar_hdr arh;
+
+ memset(&arh, ' ', sizeof(arh));
+ test_pass(dpkg_ar_member_is_illegal(&arh));
+
+ memcpy(arh.ar_fmag, DPKG_AR_FMAG, sizeof(arh.ar_fmag));
+ test_fail(dpkg_ar_member_is_illegal(&arh));
+}
+
+TEST_ENTRY(test)
+{
+ test_plan(4);
+
+ test_ar_normalize_name();
+ test_ar_member_is_illegal();
+}
diff --git a/lib/dpkg/t/t-arch.c b/lib/dpkg/t/t-arch.c
new file mode 100644
index 0000000..430980e
--- /dev/null
+++ b/lib/dpkg/t/t-arch.c
@@ -0,0 +1,225 @@
+/*
+ * libdpkg - Debian packaging suite library routines
+ * t-arch.c - test dpkg_arch implementation
+ *
+ * Copyright © 2011 Linaro Limited
+ * Copyright © 2011 Raphaël Hertzog <hertzog@debian.org>
+ * Copyright © 2011-2014 Guillem Jover <guillem@debian.org>
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <compat.h>
+
+#include <dpkg/test.h>
+#include <dpkg/varbuf.h>
+#include <dpkg/arch.h>
+
+static void
+test_dpkg_arch_name_is_illegal(void)
+{
+ /* Test invalid architecture names. */
+ test_fail(dpkg_arch_name_is_illegal("") == NULL);
+ test_fail(dpkg_arch_name_is_illegal("-i386") == NULL);
+ test_fail(dpkg_arch_name_is_illegal(" i386") == NULL);
+ test_fail(dpkg_arch_name_is_illegal(":any") == NULL);
+ test_fail(dpkg_arch_name_is_illegal("amd64_test") == NULL);
+ test_fail(dpkg_arch_name_is_illegal("i386:test") == NULL);
+ test_fail(dpkg_arch_name_is_illegal("i386 amd64") == NULL);
+ test_fail(dpkg_arch_name_is_illegal("i386,amd64") == NULL);
+ test_fail(dpkg_arch_name_is_illegal("i386|amd64") == NULL);
+
+ /* Test valid architecture names. */
+ test_pass(dpkg_arch_name_is_illegal("i386") == NULL);
+ test_pass(dpkg_arch_name_is_illegal("amd64") == NULL);
+ test_pass(dpkg_arch_name_is_illegal("hurd-i386") == NULL);
+ test_pass(dpkg_arch_name_is_illegal("kfreebsd-i386") == NULL);
+ test_pass(dpkg_arch_name_is_illegal("kfreebsd-amd64") == NULL);
+ test_pass(dpkg_arch_name_is_illegal("ia64") == NULL);
+ test_pass(dpkg_arch_name_is_illegal("alpha") == NULL);
+ test_pass(dpkg_arch_name_is_illegal("armel") == NULL);
+ test_pass(dpkg_arch_name_is_illegal("hppa") == NULL);
+ test_pass(dpkg_arch_name_is_illegal("mips") == NULL);
+ test_pass(dpkg_arch_name_is_illegal("mipsel") == NULL);
+ test_pass(dpkg_arch_name_is_illegal("powerpc") == NULL);
+ test_pass(dpkg_arch_name_is_illegal("s390") == NULL);
+ test_pass(dpkg_arch_name_is_illegal("sparc") == NULL);
+}
+
+static void
+test_dpkg_arch_get_list(void)
+{
+ struct dpkg_arch *arch;
+ int count = 1;
+
+ /* Must never return NULL. */
+ arch = dpkg_arch_get_list();
+ test_alloc(arch);
+
+ while ((arch = arch->next))
+ count++;
+
+ /* The default list should contain 3 architectures. */
+ test_pass(count == 3);
+}
+
+static void
+test_dpkg_arch_find(void)
+{
+ struct dpkg_arch *arch;
+
+ /* Test existence and initial values of default architectures. */
+ arch = dpkg_arch_find("all");
+ test_pass(arch->type == DPKG_ARCH_ALL);
+ test_pass(dpkg_arch_get(DPKG_ARCH_ALL) == arch);
+ arch = dpkg_arch_find(ARCHITECTURE);
+ test_pass(arch->type == DPKG_ARCH_NATIVE);
+ test_pass(dpkg_arch_get(DPKG_ARCH_NATIVE) == arch);
+ arch = dpkg_arch_find("any");
+ test_pass(arch->type == DPKG_ARCH_WILDCARD);
+ test_pass(dpkg_arch_get(DPKG_ARCH_WILDCARD) == arch);
+
+ /* Test missing architecture. */
+ arch = dpkg_arch_find(NULL);
+ test_pass(arch->type == DPKG_ARCH_NONE);
+ test_pass(dpkg_arch_get(DPKG_ARCH_NONE) == arch);
+ test_str(arch->name, ==, "");
+
+ /* Test empty architectures. */
+ arch = dpkg_arch_find("");
+ test_pass(arch->type == DPKG_ARCH_EMPTY);
+ test_pass(dpkg_arch_get(DPKG_ARCH_EMPTY) == arch);
+ test_str(arch->name, ==, "");
+
+ /* Test for an unknown type. */
+ test_pass(dpkg_arch_get(1000) == NULL);
+
+ /* New valid architectures are marked unknown. */
+ arch = dpkg_arch_find("foobar");
+ test_pass(arch->type == DPKG_ARCH_UNKNOWN);
+ test_str(arch->name, ==, "foobar");
+
+ /* New illegal architectures are marked illegal. */
+ arch = dpkg_arch_find("a:b");
+ test_pass(arch->type == DPKG_ARCH_ILLEGAL);
+ test_str(arch->name, ==, "a:b");
+}
+
+static void
+test_dpkg_arch_reset_list(void)
+{
+ dpkg_arch_reset_list();
+
+ test_dpkg_arch_get_list();
+}
+
+static void
+test_dpkg_arch_modify(void)
+{
+ struct dpkg_arch *arch;
+
+ dpkg_arch_reset_list();
+
+ /* Insert a new unknown arch. */
+ arch = dpkg_arch_find("foo");
+ test_pass(arch->type == DPKG_ARCH_UNKNOWN);
+ test_str(arch->name, ==, "foo");
+
+ /* Check that existing unknown arch gets tagged. */
+ arch = dpkg_arch_add("foo");
+ test_pass(arch->type == DPKG_ARCH_FOREIGN);
+ test_str(arch->name, ==, "foo");
+
+ /* Check that new unknown arch gets tagged. */
+ arch = dpkg_arch_add("quux");
+ test_pass(arch->type == DPKG_ARCH_FOREIGN);
+ test_str(arch->name, ==, "quux");
+
+ /* Unmark foreign architectures. */
+
+ arch = dpkg_arch_find("foo");
+ dpkg_arch_unmark(arch);
+ test_pass(arch->type == DPKG_ARCH_UNKNOWN);
+
+ arch = dpkg_arch_find("bar");
+ dpkg_arch_unmark(arch);
+ test_pass(arch->type == DPKG_ARCH_UNKNOWN);
+
+ arch = dpkg_arch_find("quux");
+ dpkg_arch_unmark(arch);
+ test_pass(arch->type == DPKG_ARCH_UNKNOWN);
+}
+
+static void
+test_dpkg_arch_varbuf_archqual(void)
+{
+ struct varbuf vb = VARBUF_INIT;
+
+ varbuf_add_archqual(&vb, dpkg_arch_get(DPKG_ARCH_NONE));
+ varbuf_end_str(&vb);
+ test_str(vb.buf, ==, "");
+ varbuf_reset(&vb);
+
+ varbuf_add_archqual(&vb, dpkg_arch_get(DPKG_ARCH_EMPTY));
+ varbuf_end_str(&vb);
+ test_str(vb.buf, ==, "");
+ varbuf_reset(&vb);
+
+ varbuf_add_archqual(&vb, dpkg_arch_get(DPKG_ARCH_ALL));
+ varbuf_end_str(&vb);
+ test_str(vb.buf, ==, ":all");
+ varbuf_reset(&vb);
+
+ varbuf_add_archqual(&vb, dpkg_arch_get(DPKG_ARCH_WILDCARD));
+ varbuf_end_str(&vb);
+ test_str(vb.buf, ==, ":any");
+ varbuf_reset(&vb);
+
+ varbuf_destroy(&vb);
+}
+
+static void
+test_dpkg_arch_describe(void)
+{
+ struct dpkg_arch *arch;
+
+ arch = dpkg_arch_get(DPKG_ARCH_NONE);
+ test_str(dpkg_arch_describe(arch), ==, "<none>");
+
+ arch = dpkg_arch_get(DPKG_ARCH_EMPTY);
+ test_str(dpkg_arch_describe(arch), ==, "<empty>");
+
+ arch = dpkg_arch_get(DPKG_ARCH_ALL);
+ test_str(dpkg_arch_describe(arch), ==, "all");
+
+ arch = dpkg_arch_get(DPKG_ARCH_WILDCARD);
+ test_str(dpkg_arch_describe(arch), ==, "any");
+
+ arch = dpkg_arch_get(DPKG_ARCH_NATIVE);
+ test_str(dpkg_arch_describe(arch), ==, ARCHITECTURE);
+}
+
+TEST_ENTRY(test)
+{
+ test_plan(60);
+
+ test_dpkg_arch_name_is_illegal();
+ test_dpkg_arch_get_list();
+ test_dpkg_arch_find();
+ test_dpkg_arch_reset_list();
+ test_dpkg_arch_modify();
+ test_dpkg_arch_varbuf_archqual();
+ test_dpkg_arch_describe();
+}
diff --git a/lib/dpkg/t/t-buffer.c b/lib/dpkg/t/t-buffer.c
new file mode 100644
index 0000000..fa939e5
--- /dev/null
+++ b/lib/dpkg/t/t-buffer.c
@@ -0,0 +1,82 @@
+/*
+ * libdpkg - Debian packaging suite library routines
+ * t-buffer.c - test buffer handling
+ *
+ * Copyright © 2009-2011 Guillem Jover <guillem@debian.org>
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <compat.h>
+
+#include <dpkg/test.h>
+#include <dpkg/buffer.h>
+#include <dpkg/dpkg.h>
+
+#include <sys/types.h>
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+static const char str_empty[] = "";
+static const char ref_hash_empty[] = "d41d8cd98f00b204e9800998ecf8427e";
+static const char str_test[] = "this is a test string\n";
+static const char ref_hash_test[] = "475aae3b885d70a9130eec23ab33f2b9";
+
+static void
+test_buffer_hash(void)
+{
+ char hash[MD5HASHLEN + 1];
+
+ buffer_md5(str_empty, hash, strlen(str_empty));
+ test_str(hash, ==, ref_hash_empty);
+
+ buffer_md5(str_test, hash, strlen(str_test));
+ test_str(hash, ==, ref_hash_test);
+}
+
+static void
+test_fdio_hash(void)
+{
+ char hash[MD5HASHLEN + 1];
+ char *test_file;
+ int fd;
+
+ test_file = test_alloc(strdup("test.XXXXXX"));
+ fd = mkstemp(test_file);
+ test_pass(fd >= 0);
+
+ test_pass(fd_md5(fd, hash, -1, NULL) >= 0);
+ test_str(hash, ==, ref_hash_empty);
+
+ test_pass(write(fd, str_test, strlen(str_test)) == (ssize_t)strlen(str_test));
+ test_pass(lseek(fd, 0, SEEK_SET) == 0);
+
+ test_pass(fd_md5(fd, hash, -1, NULL) >= 0);
+ test_str(hash, ==, ref_hash_test);
+
+ test_pass(unlink(test_file) == 0);
+
+ free(test_file);
+}
+
+TEST_ENTRY(test)
+{
+ test_plan(10);
+
+ test_buffer_hash();
+ test_fdio_hash();
+}
diff --git a/lib/dpkg/t/t-c-ctype.c b/lib/dpkg/t/t-c-ctype.c
new file mode 100644
index 0000000..2da0553
--- /dev/null
+++ b/lib/dpkg/t/t-c-ctype.c
@@ -0,0 +1,106 @@
+/*
+ * libdpkg - Debian packaging suite library routines
+ * t-c-ctype.c - test C locale ctype functions
+ *
+ * Copyright © 2009-2014 Guillem Jover <guillem@debian.org>
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2,
+ * or (at your option) any later version.
+ *
+ * This is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <compat.h>
+
+#include <dpkg/test.h>
+#include <dpkg/c-ctype.h>
+
+static void
+test_ctype(void)
+{
+ int c;
+
+ for (c = -1; c < 256; c++) {
+ /* Test blank. */
+ if (c == '\t' || c == ' ')
+ test_pass(c_isblank(c));
+ else
+ test_fail(c_isblank(c));
+
+ /* Test white. */
+ if (c == '\t' || c == ' ' || c == '\n')
+ test_pass(c_iswhite(c));
+ else
+ test_fail(c_iswhite(c));
+
+ /* Test space. */
+ if (c == '\t' || c == '\v' || c == '\f' ||
+ c == '\r' || c == '\n' || c == ' ')
+ test_pass(c_isspace(c));
+ else
+ test_fail(c_isspace(c));
+
+ /* Test digit. */
+ if (c >= '0' && c <= '9')
+ test_pass(c_isdigit(c));
+ else
+ test_fail(c_isdigit(c));
+
+ /* Test lower case. */
+ if (c >= 'a' && c <= 'z')
+ test_pass(c_islower(c));
+ else
+ test_fail(c_islower(c));
+
+ /* Test upper case. */
+ if (c >= 'A' && c <= 'Z')
+ test_pass(c_isupper(c));
+ else
+ test_fail(c_isupper(c));
+
+ /* Test alpha. */
+ if (c_islower(c) || c_isupper(c))
+ test_pass(c_isalpha(c));
+ else
+ test_fail(c_isalpha(c));
+
+ /* Test alphanumeric. */
+ if (c_isdigit(c) || c_isalpha(c))
+ test_pass(c_isalnum(c));
+ else
+ test_fail(c_isalnum(c));
+ }
+}
+
+static void
+test_casing(void)
+{
+ test_pass(c_tolower('A') == 'a');
+ test_pass(c_tolower('Z') == 'z');
+
+ test_pass(c_tolower('a') == 'a');
+ test_pass(c_tolower('z') == 'z');
+
+ test_pass(c_tolower('0') == '0');
+ test_pass(c_tolower('9') == '9');
+
+ /* Test if we can handle the value for EOF. */
+ test_pass(c_tolower(-1) == -1);
+}
+
+TEST_ENTRY(test)
+{
+ test_plan(2063);
+
+ test_ctype();
+ test_casing();
+}
diff --git a/lib/dpkg/t/t-command.c b/lib/dpkg/t/t-command.c
new file mode 100644
index 0000000..4c36006
--- /dev/null
+++ b/lib/dpkg/t/t-command.c
@@ -0,0 +1,224 @@
+/*
+ * libdpkg - Debian packaging suite library routines
+ * t-command.c - test command implementation
+ *
+ * Copyright © 2010-2012 Guillem Jover <guillem@debian.org>
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <compat.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <dpkg/test.h>
+#include <dpkg/subproc.h>
+#include <dpkg/command.h>
+#include <dpkg/dpkg.h>
+
+static void
+test_command_init(void)
+{
+ struct command cmd;
+
+ command_init(&cmd, "/absolute/path/to/progname", NULL);
+ test_str(cmd.filename, ==, "/absolute/path/to/progname");
+ test_str(cmd.name, ==, "progname");
+ test_pass(cmd.argc == 0);
+ test_pass(cmd.argv[0] == NULL);
+
+ command_destroy(&cmd);
+ test_pass(cmd.filename == NULL);
+ test_pass(cmd.name == NULL);
+ test_pass(cmd.argc == 0);
+ test_pass(cmd.argv == NULL);
+
+ command_init(&cmd, "progname", NULL);
+ test_str(cmd.filename, ==, "progname");
+ test_str(cmd.name, ==, "progname");
+ test_pass(cmd.argc == 0);
+ test_pass(cmd.argv[0] == NULL);
+
+ command_destroy(&cmd);
+
+ command_init(&cmd, "progname", "description");
+ test_str(cmd.filename, ==, "progname");
+ test_str(cmd.name, ==, "description");
+ test_pass(cmd.argc == 0);
+ test_pass(cmd.argv[0] == NULL);
+
+ command_destroy(&cmd);
+}
+
+static void
+test_command_grow_argv(void)
+{
+ struct command cmd;
+ int argv_size, i;
+
+ command_init(&cmd, "test", NULL);
+
+ argv_size = cmd.argv_size + 4;
+ for (i = 0; i < argv_size; i++)
+ command_add_arg(&cmd, "arg");
+
+ test_pass(cmd.argc == argv_size);
+ test_pass(cmd.argv_size >= argv_size);
+ test_str(cmd.argv[0], ==, "arg");
+ test_str(cmd.argv[argv_size - 1], ==, "arg");
+ test_pass(cmd.argv[argv_size] == NULL);
+
+ command_destroy(&cmd);
+}
+
+static void
+test_command_add_arg(void)
+{
+ struct command cmd;
+
+ command_init(&cmd, "test", NULL);
+
+ command_add_arg(&cmd, "arg 0");
+ test_pass(cmd.argc == 1);
+ test_str(cmd.argv[0], ==, "arg 0");
+ test_pass(cmd.argv[1] == NULL);
+
+ command_add_arg(&cmd, "arg 1");
+ test_pass(cmd.argc == 2);
+ test_str(cmd.argv[0], ==, "arg 0");
+ test_str(cmd.argv[1], ==, "arg 1");
+ test_pass(cmd.argv[2] == NULL);
+
+ command_add_arg(&cmd, "arg 2");
+ test_pass(cmd.argc == 3);
+ test_str(cmd.argv[0], ==, "arg 0");
+ test_str(cmd.argv[1], ==, "arg 1");
+ test_str(cmd.argv[2], ==, "arg 2");
+ test_pass(cmd.argv[3] == NULL);
+
+ command_destroy(&cmd);
+}
+
+static void
+test_command_add_argl(void)
+{
+ struct command cmd;
+ const char *args[] = {
+ "arg 1",
+ "arg 2",
+ "arg 3",
+ NULL,
+ };
+
+ command_init(&cmd, "test", NULL);
+
+ command_add_arg(&cmd, "arg 0");
+
+ command_add_argl(&cmd, args);
+ test_pass(cmd.argc == 4);
+ test_str(cmd.argv[0], ==, "arg 0");
+ test_str(cmd.argv[1], ==, "arg 1");
+ test_str(cmd.argv[2], ==, "arg 2");
+ test_str(cmd.argv[3], ==, "arg 3");
+ test_pass(cmd.argv[4] == NULL);
+
+ command_destroy(&cmd);
+}
+
+static void
+test_command_add_args(void)
+{
+ struct command cmd;
+
+ command_init(&cmd, "test", NULL);
+
+ command_add_arg(&cmd, "arg 0");
+
+ command_add_args(&cmd, "arg 1", "arg 2", "arg 3", NULL);
+ test_pass(cmd.argc == 4);
+ test_str(cmd.argv[0], ==, "arg 0");
+ test_str(cmd.argv[1], ==, "arg 1");
+ test_str(cmd.argv[2], ==, "arg 2");
+ test_str(cmd.argv[3], ==, "arg 3");
+ test_pass(cmd.argv[4] == NULL);
+
+ command_destroy(&cmd);
+}
+
+static void
+test_command_exec(void)
+{
+ struct command cmd;
+ pid_t pid;
+ int ret;
+
+ command_init(&cmd, "true", "exec test");
+
+ command_add_arg(&cmd, "arg 0");
+ command_add_arg(&cmd, "arg 1");
+
+ pid = subproc_fork();
+
+ if (pid == 0)
+ command_exec(&cmd);
+
+ ret = subproc_reap(pid, "command exec test", 0);
+ test_pass(ret == 0);
+
+ command_destroy(&cmd);
+}
+
+static void
+test_command_shell(void)
+{
+ pid_t pid;
+ int ret;
+
+ pid = subproc_fork();
+ if (pid == 0)
+ command_shell("true", "command shell pass test");
+ ret = subproc_reap(pid, "command shell pass test", 0);
+ test_pass(ret == 0);
+
+ pid = subproc_fork();
+ if (pid == 0)
+ command_shell("false", "command shell fail test");
+ ret = subproc_reap(pid, "command shell fail test", SUBPROC_RETERROR);
+ test_fail(ret == 0);
+
+ unsetenv("SHELL");
+ pid = subproc_fork();
+ if (pid == 0)
+ command_shell("true", "command default shell test");
+ ret = subproc_reap(pid, "command default shell test", 0);
+ test_pass(ret == 0);
+}
+
+TEST_ENTRY(test)
+{
+ test_plan(49);
+
+ test_command_init();
+ test_command_grow_argv();
+ test_command_add_arg();
+ test_command_add_argl();
+ test_command_add_args();
+ test_command_exec();
+ test_command_shell();
+}
diff --git a/lib/dpkg/t/t-deb-version.c b/lib/dpkg/t/t-deb-version.c
new file mode 100644
index 0000000..88b94e9
--- /dev/null
+++ b/lib/dpkg/t/t-deb-version.c
@@ -0,0 +1,90 @@
+/*
+ * libdpkg - Debian packaging suite library routines
+ * t-deb-version.c - test deb version handling
+ *
+ * Copyright © 2012 Guillem Jover <guillem@debian.org>
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <compat.h>
+
+#include <limits.h>
+#include <stdio.h>
+
+#include <dpkg/test.h>
+#include <dpkg/deb-version.h>
+
+static void
+test_deb_version_parse(void)
+{
+ struct deb_version v;
+ char *vs;
+
+ /* Test valid versions. */
+ test_pass(deb_version_parse(&v, "0.0") == NULL);
+ test_pass(v.major == 0 && v.minor == 0);
+
+ test_pass(deb_version_parse(&v, "1.1") == NULL);
+ test_pass(v.major == 1 && v.minor == 1);
+
+ test_pass(deb_version_parse(&v, "1.001") == NULL);
+ test_pass(v.major == 1 && v.minor == 1);
+
+ test_pass(deb_version_parse(&v, "1.0010") == NULL);
+ test_pass(v.major == 1 && v.minor == 10);
+
+ test_pass(deb_version_parse(&v, "0.939000") == NULL);
+ test_pass(v.major == 0 && v.minor == 939000);
+
+ test_pass(deb_version_parse(&v, "1.1\n") == NULL);
+ test_pass(v.major == 1 && v.minor == 1);
+
+ /* Test invalid versions. */
+ test_fail(deb_version_parse(&v, "0") == NULL);
+ test_fail(deb_version_parse(&v, "a") == NULL);
+ test_fail(deb_version_parse(&v, "a.b") == NULL);
+ test_fail(deb_version_parse(&v, "a~b") == NULL);
+ test_fail(deb_version_parse(&v, " 1.1") == NULL);
+ test_fail(deb_version_parse(&v, "2 .2") == NULL);
+ test_fail(deb_version_parse(&v, "3. 3") == NULL);
+ test_fail(deb_version_parse(&v, "4.4 ") == NULL);
+ test_fail(deb_version_parse(&v, " 5.5 ") == NULL);
+
+ /* Test integer limits. */
+ if (asprintf(&vs, "%d.0", INT_MAX) < 0)
+ test_bail("cannot allocate memory for asprintf()");
+ test_pass(deb_version_parse(&v, vs) == NULL);
+ free(vs);
+
+ if (asprintf(&vs, "%d.0", INT_MAX - 1) < 0)
+ test_bail("cannot allocate memory for asprintf()");
+ test_pass(deb_version_parse(&v, vs) == NULL);
+ free(vs);
+
+ if (asprintf(&vs, "%u.0", 1U + (unsigned int)INT_MAX) < 0)
+ test_bail("cannot allocate memory for asprintf()");
+ test_fail(deb_version_parse(&v, vs) == NULL);
+ free(vs);
+
+ /* FIXME: Complete. */
+}
+
+TEST_ENTRY(test)
+{
+ test_plan(24);
+
+ test_deb_version_parse();
+}
diff --git a/lib/dpkg/t/t-ehandle.c b/lib/dpkg/t/t-ehandle.c
new file mode 100644
index 0000000..1831e61
--- /dev/null
+++ b/lib/dpkg/t/t-ehandle.c
@@ -0,0 +1,128 @@
+/*
+ * libdpkg - Debian packaging suite library routines
+ * t-ehandle.c - test error handling implementation
+ *
+ * Copyright © 2016 Guillem Jover <guillem@debian.org>
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <compat.h>
+
+#include <stdbool.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <dpkg/test.h>
+#include <dpkg/ehandle.h>
+
+jmp_buf global_handler_jump;
+
+static void
+printer_empty(const char *msg, const void *data)
+{
+}
+
+static void
+handler_func(void)
+{
+ longjmp(global_handler_jump, 1);
+}
+
+static void
+test_error_handler_func(void)
+{
+ bool pass;
+
+ if (setjmp(global_handler_jump)) {
+ pass = true;
+ pop_error_context(ehflag_normaltidy);
+ } else {
+ pass = false;
+ push_error_context_func(handler_func, printer_empty, "test func");
+ ohshit("test func error");
+ test_bail("ohshit() is not supposed to return");
+ }
+ test_pass(pass);
+}
+
+static void
+test_error_handler_jump(void)
+{
+ jmp_buf handler_jump;
+ bool pass;
+
+ if (setjmp(handler_jump)) {
+ pass = true;
+ pop_error_context(ehflag_normaltidy);
+ } else {
+ pass = false;
+ push_error_context_jump(&handler_jump, printer_empty, "test jump");
+ ohshit("test jump error");
+ test_bail("ohshit() is not supposed to return");
+ }
+ test_pass(pass);
+}
+
+static void
+cleanup_error(int argc, void **argv)
+{
+ ohshit("cleanup error");
+}
+
+static void
+test_cleanup_error(void)
+{
+ jmp_buf handler_jump;
+ bool pass;
+
+ if (setjmp(handler_jump)) {
+ /* The ohshit() is not supposed to get us here, as it should
+ * be caught by the internal recursive error context. */
+ pass = false;
+
+ pop_cleanup(ehflag_normaltidy);
+ pop_error_context(ehflag_normaltidy);
+ } else {
+ push_error_context_jump(&handler_jump, printer_empty, "test cleanup");
+ push_cleanup(cleanup_error, ~ehflag_normaltidy, 0);
+ pop_error_context(ehflag_bombout);
+
+ /* We should have recovered from the cleanup handler failing,
+ * and arrived here correctly. */
+ pass = true;
+ }
+
+ test_pass(pass);
+}
+
+TEST_ENTRY(test)
+{
+ test_plan(3);
+
+ if (!test_is_verbose()) {
+ int fd;
+
+ /* Shut up stderr, we do not want the error output. */
+ fd = open("/dev/null", O_RDWR);
+ if (fd < 0)
+ test_bail("cannot open /dev/null");
+ dup2(fd, 2);
+ }
+
+ test_error_handler_func();
+ test_error_handler_jump();
+ test_cleanup_error();
+}
diff --git a/lib/dpkg/t/t-error.c b/lib/dpkg/t/t-error.c
new file mode 100644
index 0000000..e93459e
--- /dev/null
+++ b/lib/dpkg/t/t-error.c
@@ -0,0 +1,87 @@
+/*
+ * libdpkg - Debian packaging suite library routines
+ * t-error.c - test error message reporting
+ *
+ * Copyright © 2014 Guillem Jover <guillem@debian.org>
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <compat.h>
+
+#include <errno.h>
+#include <string.h>
+#include <stdio.h>
+
+#include <dpkg/test.h>
+#include <dpkg/error.h>
+
+static void
+test_dpkg_error_put(void)
+{
+ struct dpkg_error err = DPKG_ERROR_INIT;
+ char *errstr_ref = NULL;
+
+ test_pass(err.type == DPKG_MSG_NONE);
+ test_pass(err.str == NULL);
+
+ test_pass(dpkg_put_warn(NULL, "void error") < 0);
+ test_pass(dpkg_put_error(NULL, "void error") < 0);
+ test_pass(dpkg_put_errno(NULL, "void error") < 0);
+
+ test_pass(dpkg_put_warn(&err, "test warning %d", 10) < 0);
+ test_pass(err.syserrno == 0);
+ test_str(err.str, ==, "test warning 10");
+ test_warn(err);
+
+ test_pass(dpkg_put_error(&err, "test error %d", 20) < 0);
+ test_pass(err.syserrno == 0);
+ test_str(err.str, ==, "test error 20");
+ test_error(err);
+
+ errno = ENOENT;
+ if (asprintf(&errstr_ref, "test errno 30 (%s)", strerror(errno)) < 0)
+ test_bail("cannot allocate string");
+ test_pass(dpkg_put_errno(&err, "test errno %d", 30) < 0);
+ test_str(err.str, ==, errstr_ref);
+ test_pass(err.syserrno == ENOENT);
+ test_error(err);
+ free(errstr_ref);
+ errno = 0;
+}
+
+static void
+test_dpkg_error_destroy(void)
+{
+ struct dpkg_error err = DPKG_ERROR_INIT;
+
+ errno = ENOENT;
+ test_pass(dpkg_put_errno(&err, "test destroy") < 0);
+ test_pass(err.syserrno == ENOENT);
+ test_pass(err.type == DPKG_MSG_ERROR);
+ test_pass(err.str != NULL);
+ dpkg_error_destroy(&err);
+ test_pass(err.type == DPKG_MSG_NONE);
+ test_pass(err.syserrno == 0);
+ test_pass(err.str == NULL);
+}
+
+TEST_ENTRY(test)
+{
+ test_plan(24);
+
+ test_dpkg_error_put();
+ test_dpkg_error_destroy();
+}
diff --git a/lib/dpkg/t/t-file.c b/lib/dpkg/t/t-file.c
new file mode 100644
index 0000000..278df91
--- /dev/null
+++ b/lib/dpkg/t/t-file.c
@@ -0,0 +1,98 @@
+/*
+ * libdpkg - Debian packaging suite library routines
+ * t-file.c - test file functions
+ *
+ * Copyright © 2018 Guillem Jover <guillem@debian.org>
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <compat.h>
+
+#include <dpkg/test.h>
+#include <dpkg/dpkg.h>
+#include <dpkg/file.h>
+
+#include <sys/types.h>
+
+#include <errno.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+static const char ref_data[] =
+ "this is a test string\n"
+ "within a test file\n"
+ "containing multiple lines\n"
+;
+
+static void
+test_file_slurp(void)
+{
+ struct varbuf vb = VARBUF_INIT;
+ struct dpkg_error err = DPKG_ERROR_INIT;
+ char *test_file;
+ char *test_dir;
+ int fd;
+
+ test_pass(file_slurp("/nonexistent", &vb, &err) < 0);
+ test_pass(vb.used == 0);
+ test_pass(vb.buf == NULL);
+ test_pass(err.syserrno == ENOENT);
+ test_error(err);
+ varbuf_destroy(&vb);
+
+ test_dir = test_alloc(strdup("test.XXXXXX"));
+ test_pass(mkdtemp(test_dir) != NULL);
+ test_pass(file_slurp(test_dir, &vb, &err) < 0);
+ test_pass(vb.used == 0);
+ test_pass(vb.buf == NULL);
+ test_pass(err.syserrno == 0);
+ test_error(err);
+ varbuf_destroy(&vb);
+ test_pass(rmdir(test_dir) == 0);
+ free(test_dir);
+
+ test_file = test_alloc(strdup("test.XXXXXX"));
+ fd = mkstemp(test_file);
+ test_pass(fd >= 0);
+
+ test_pass(file_slurp(test_file, &vb, &err) == 0);
+ test_pass(vb.used == 0);
+ test_pass(vb.buf == NULL);
+ test_pass(err.syserrno == 0);
+ test_pass(err.type == DPKG_MSG_NONE);
+ varbuf_destroy(&vb);
+
+ test_pass(write(fd, ref_data, strlen(ref_data)) == (ssize_t)strlen(ref_data));
+ test_pass(lseek(fd, 0, SEEK_SET) == 0);
+
+ test_pass(file_slurp(test_file, &vb, &err) == 0);
+ test_pass(vb.used == strlen(ref_data));
+ test_mem(vb.buf, ==, ref_data, min(vb.used, strlen(ref_data)));
+ test_pass(err.syserrno == 0);
+ test_pass(err.type == DPKG_MSG_NONE);
+ varbuf_destroy(&vb);
+
+ test_pass(unlink(test_file) == 0);
+ free(test_file);
+}
+
+TEST_ENTRY(test)
+{
+ test_plan(26);
+
+ test_file_slurp();
+}
diff --git a/lib/dpkg/t/t-fsys-dir.c b/lib/dpkg/t/t-fsys-dir.c
new file mode 100644
index 0000000..721dab6
--- /dev/null
+++ b/lib/dpkg/t/t-fsys-dir.c
@@ -0,0 +1,71 @@
+/*
+ * libdpkg - Debian packaging suite library routines
+ * t-fsys-dir.c - test filesystem handling
+ *
+ * Copyright © 2018 Guillem Jover <guillem@debian.org>
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <compat.h>
+
+#include <stdlib.h>
+
+#include <dpkg/test.h>
+#include <dpkg/fsys.h>
+
+static void
+test_fsys_dir(void)
+{
+ const char *newdir;
+ char *dir;
+
+ test_str(dpkg_fsys_get_dir(), ==, "");
+
+ newdir = dpkg_fsys_set_dir("/testdir");
+ test_str(newdir, ==, "/testdir");
+ test_str(dpkg_fsys_get_dir(), ==, "/testdir");
+
+ newdir = dpkg_fsys_set_dir(newdir);
+ test_str(newdir, ==, "/testdir");
+ test_str(dpkg_fsys_get_dir(), ==, "/testdir");
+
+ dir = dpkg_fsys_get_path("testfile");
+ test_str(dir, ==, "/testdir/testfile");
+ free(dir);
+
+ setenv("DPKG_ROOT", "/testenvdir", 1);
+ dpkg_fsys_set_dir(NULL);
+ test_str(dpkg_fsys_get_dir(), ==, "/testenvdir");
+
+ dir = dpkg_fsys_get_path("testfile");
+ test_str(dir, ==, "/testenvdir/testfile");
+ free(dir);
+
+ unsetenv("DPKG_ROOT");
+ dpkg_fsys_set_dir(NULL);
+ test_str(dpkg_fsys_get_dir(), ==, "");
+
+ dir = dpkg_fsys_get_path("testfile");
+ test_str(dir, ==, "/testfile");
+ free(dir);
+}
+
+TEST_ENTRY(test)
+{
+ test_plan(10);
+
+ test_fsys_dir();
+}
diff --git a/lib/dpkg/t/t-fsys-hash.c b/lib/dpkg/t/t-fsys-hash.c
new file mode 100644
index 0000000..7739328
--- /dev/null
+++ b/lib/dpkg/t/t-fsys-hash.c
@@ -0,0 +1,108 @@
+/*
+ * libdpkg - Debian packaging suite library routines
+ * t-fsys-hash.c - test fsys-hash implementation
+ *
+ * Copyright © 2018 Guillem Jover <guillem@debian.org>
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <compat.h>
+
+#include <dpkg/test.h>
+#include <dpkg/dpkg.h>
+#include <dpkg/fsys.h>
+
+static void
+test_fsys_nodes(void)
+{
+ struct fsys_namenode *fnn;
+ struct fsys_hash_iter *iter;
+ const char *name;
+
+ test_pass(fsys_hash_entries() == 0);
+
+ fsys_hash_init();
+
+ fnn = fsys_hash_find_node("/nonexistent", FHFF_NONE);
+ test_pass(fnn == NULL);
+ test_pass(fsys_hash_entries() == 0);
+
+ name = "/test/path/aa";
+ fnn = fsys_hash_find_node(name, FHFF_NOCOPY);
+ test_pass(fnn != NULL);
+ test_pass(fsys_hash_entries() == 1);
+ test_pass(fnn->name == name);
+ test_str(fnn->name, ==, "/test/path/aa");
+ test_pass(fnn->flags == 0);
+ test_pass(fnn->oldhash == NULL);
+ test_pass(fnn->newhash == NULL);
+
+ fnn = fsys_hash_find_node("//./test/path/bb", 0);
+ test_pass(fnn != NULL);
+ test_pass(fsys_hash_entries() == 2);
+ test_str(fnn->name, ==, "/test/path/bb");
+ test_pass(fnn->flags == 0);
+ test_pass(fnn->oldhash == NULL);
+ test_pass(fnn->newhash == NULL);
+
+ fnn = fsys_hash_find_node("/test/path/cc", 0);
+ test_pass(fnn != NULL);
+ test_pass(fsys_hash_entries() == 3);
+ test_str(fnn->name, ==, "/test/path/cc");
+ test_pass(fnn->flags == 0);
+ test_pass(fnn->oldhash == NULL);
+ test_pass(fnn->newhash == NULL);
+
+ iter = fsys_hash_iter_new();
+ while ((fnn = fsys_hash_iter_next(iter))) {
+ if (strcmp(fnn->name, "/test/path/aa") == 0)
+ test_str(fnn->name, ==, "/test/path/aa");
+ else if (strcmp(fnn->name, "/test/path/bb") == 0)
+ test_str(fnn->name, ==, "/test/path/bb");
+ else if (strcmp(fnn->name, "/test/path/cc") == 0)
+ test_str(fnn->name, ==, "/test/path/cc");
+ else
+ test_fail("unknown fsys_namenode");
+ }
+ fsys_hash_iter_free(iter);
+
+ fsys_hash_init();
+ test_pass(fsys_hash_entries() == 3);
+ fnn = fsys_hash_find_node("/test/path/aa", FHFF_NONE);
+ test_pass(fnn != NULL);
+ fnn = fsys_hash_find_node("/test/path/bb", FHFF_NONE);
+ test_pass(fnn != NULL);
+ fnn = fsys_hash_find_node("/test/path/cc", FHFF_NONE);
+ test_pass(fnn != NULL);
+ test_pass(fsys_hash_entries() == 3);
+
+ fsys_hash_reset();
+ test_pass(fsys_hash_entries() == 0);
+ fnn = fsys_hash_find_node("/test/path/aa", FHFF_NONE);
+ test_pass(fnn == NULL);
+ fnn = fsys_hash_find_node("/test/path/bb", FHFF_NONE);
+ test_pass(fnn == NULL);
+ fnn = fsys_hash_find_node("/test/path/cc", FHFF_NONE);
+ test_pass(fnn == NULL);
+ test_pass(fsys_hash_entries() == 0);
+}
+
+TEST_ENTRY(test)
+{
+ test_plan(35);
+
+ test_fsys_nodes();
+}
diff --git a/lib/dpkg/t/t-headers-cpp.cc b/lib/dpkg/t/t-headers-cpp.cc
new file mode 100644
index 0000000..b5becf9
--- /dev/null
+++ b/lib/dpkg/t/t-headers-cpp.cc
@@ -0,0 +1,82 @@
+/*
+ * libdpkg - Debian packaging suite library routines
+ * t-headers-cpp.cc - test C++ inclusion of headers
+ *
+ * Copyright © 2018 Guillem Jover <guillem@debian.org>
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <compat.h>
+
+#include <cstdbool>
+
+#include <dpkg/ar.h>
+#include <dpkg/arch.h>
+#include <dpkg/atomic-file.h>
+#include <dpkg/buffer.h>
+#include <dpkg/c-ctype.h>
+#include <dpkg/color.h>
+#include <dpkg/command.h>
+#include <dpkg/compress.h>
+#include <dpkg/db-ctrl.h>
+#include <dpkg/db-fsys.h>
+#include <dpkg/deb-version.h>
+#include <dpkg/debug.h>
+#include <dpkg/dir.h>
+#include <dpkg/dlist.h>
+#include <dpkg/dpkg-db.h>
+#include <dpkg/dpkg.h>
+#include <dpkg/ehandle.h>
+#include <dpkg/error.h>
+#include <dpkg/fdio.h>
+#include <dpkg/file.h>
+#include <dpkg/fsys.h>
+#include <dpkg/glob.h>
+#include <dpkg/i18n.h>
+#include <dpkg/macros.h>
+#include <dpkg/namevalue.h>
+#include <dpkg/options.h>
+#include <dpkg/pager.h>
+#include <dpkg/parsedump.h>
+#include <dpkg/path.h>
+#include <dpkg/pkg-array.h>
+#include <dpkg/pkg-files.h>
+#include <dpkg/pkg-format.h>
+#include <dpkg/pkg-list.h>
+#include <dpkg/pkg-queue.h>
+#include <dpkg/pkg-show.h>
+#include <dpkg/pkg-spec.h>
+#include <dpkg/pkg.h>
+#include <dpkg/progname.h>
+#include <dpkg/program.h>
+#include <dpkg/progress.h>
+#include <dpkg/report.h>
+#include <dpkg/string.h>
+#include <dpkg/subproc.h>
+#include <dpkg/tarfn.h>
+#include <dpkg/test.h>
+#include <dpkg/treewalk.h>
+#include <dpkg/trigdeferred.h>
+#include <dpkg/triglib.h>
+#include <dpkg/varbuf.h>
+#include <dpkg/version.h>
+
+TEST_ENTRY(test)
+{
+ test_plan(1);
+
+ test_pass(true);
+}
diff --git a/lib/dpkg/t/t-macros.c b/lib/dpkg/t/t-macros.c
new file mode 100644
index 0000000..9f4eaa1
--- /dev/null
+++ b/lib/dpkg/t/t-macros.c
@@ -0,0 +1,45 @@
+/*
+ * libdpkg - Debian packaging suite library routines
+ * t-macros.c - test C support macros
+ *
+ * Copyright © 2009,2012 Guillem Jover <guillem@debian.org>
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <compat.h>
+
+#include <dpkg/test.h>
+#include <dpkg/macros.h>
+
+TEST_ENTRY(test)
+{
+ test_plan(12);
+
+ test_pass(min(10, 30) == 10);
+ test_pass(min(30, 10) == 10);
+ test_pass(min(0, 10) == 0);
+ test_pass(min(-10, 0) == -10);
+
+ test_pass(max(10, 30) == 30);
+ test_pass(max(30, 10) == 30);
+ test_pass(max(0, 10) == 10);
+ test_pass(max(-10, 0) == 0);
+
+ test_pass(clamp(0, 0, 0) == 0);
+ test_pass(clamp(0, -10, 10) == 0);
+ test_pass(clamp(20, -10, 10) == 10);
+ test_pass(clamp(-20, -10, 10) == -10);
+}
diff --git a/lib/dpkg/t/t-mod-db.c b/lib/dpkg/t/t-mod-db.c
new file mode 100644
index 0000000..c40d8e8
--- /dev/null
+++ b/lib/dpkg/t/t-mod-db.c
@@ -0,0 +1,57 @@
+/*
+ * libdpkg - Debian packaging suite library routines
+ * t-mod-db.c - test database implementation
+ *
+ * Copyright © 2011 Guillem Jover <guillem@debian.org>
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <compat.h>
+
+#include <stdlib.h>
+
+#include <dpkg/test.h>
+#include <dpkg/dpkg-db.h>
+
+static void
+test_db_dir(void)
+{
+ char *dir;
+
+ test_str(dpkg_db_get_dir(), ==, ADMINDIR);
+
+ dpkg_db_set_dir("testdir");
+ test_str(dpkg_db_get_dir(), ==, "testdir");
+
+ setenv("DPKG_ADMINDIR", "testenvdir", 1);
+ dpkg_db_set_dir(NULL);
+ test_str(dpkg_db_get_dir(), ==, "testenvdir");
+
+ unsetenv("DPKG_ADMINDIR");
+ dpkg_db_set_dir(NULL);
+ test_str(dpkg_db_get_dir(), ==, ADMINDIR);
+
+ dir = dpkg_db_get_path("testfile");
+ test_str(dir, ==, ADMINDIR "/testfile");
+ free(dir);
+}
+
+TEST_ENTRY(test)
+{
+ test_plan(5);
+
+ test_db_dir();
+}
diff --git a/lib/dpkg/t/t-namevalue.c b/lib/dpkg/t/t-namevalue.c
new file mode 100644
index 0000000..c864766
--- /dev/null
+++ b/lib/dpkg/t/t-namevalue.c
@@ -0,0 +1,48 @@
+/*
+ * libdpkg - Debian packaging suite library routines
+ * t-namevalue.c - test name/value implementation
+ *
+ * Copyright © 2018 Guillem Jover <guillem@debian.org>
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <compat.h>
+
+#include <dpkg/test.h>
+#include <dpkg/namevalue.h>
+#include <dpkg/dpkg-db.h>
+
+static void
+test_namevalue(void)
+{
+ const struct namevalue *nv;
+
+ nv = namevalue_find_by_name(booleaninfos, "");
+ test_pass(nv == NULL);
+
+ nv = namevalue_find_by_name(booleaninfos, "no");
+ test_pass(nv != NULL);
+ test_pass(nv->value == false);
+ test_pass(nv->length == strlen("no"));
+ test_str(nv->name, ==, "no");
+}
+
+TEST_ENTRY(test)
+{
+ test_plan(5);
+
+ test_namevalue();
+}
diff --git a/lib/dpkg/t/t-pager.c b/lib/dpkg/t/t-pager.c
new file mode 100644
index 0000000..2481e80
--- /dev/null
+++ b/lib/dpkg/t/t-pager.c
@@ -0,0 +1,75 @@
+/*
+ * libdpkg - Debian packaging suite library routines
+ * t-pager.c - test pager implementation
+ *
+ * Copyright © 2010-2012 Guillem Jover <guillem@debian.org>
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <compat.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <fcntl.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <dpkg/test.h>
+#include <dpkg/pager.h>
+#include <dpkg/dpkg.h>
+
+static void
+test_dup_file(int fd, const char *filename, int flags)
+{
+ int newfd;
+
+ newfd = open(filename, flags);
+ dup2(newfd, fd);
+ close(newfd);
+}
+
+static void
+test_pager_get_exec(void)
+{
+ const char *pager, *default_pager;
+ int origfd = dup(STDOUT_FILENO);
+
+ /* Test stdout being a tty. */
+ test_todo_block("environment might not expose controlling terminal") {
+ test_dup_file(STDOUT_FILENO, "/dev/tty", O_WRONLY);
+ setenv("PAGER", "test-pager", 1);
+ pager = pager_get_exec();
+ unsetenv("PAGER");
+ default_pager = pager_get_exec();
+ dup2(origfd, STDOUT_FILENO);
+ test_str(pager, ==, "test-pager");
+ test_str(default_pager, ==, DEFAULTPAGER);
+ }
+
+ /* Test stdout not being a tty. */
+ test_dup_file(STDOUT_FILENO, "/dev/null", O_WRONLY);
+ pager = pager_get_exec();
+ dup2(origfd, STDOUT_FILENO);
+ test_str(pager, ==, CAT);
+}
+
+TEST_ENTRY(test)
+{
+ test_plan(3);
+
+ test_pager_get_exec();
+}
diff --git a/lib/dpkg/t/t-path.c b/lib/dpkg/t/t-path.c
new file mode 100644
index 0000000..deb1b72
--- /dev/null
+++ b/lib/dpkg/t/t-path.c
@@ -0,0 +1,181 @@
+/*
+ * libdpkg - Debian packaging suite library routines
+ * t-path.c - test path handling code
+ *
+ * Copyright © 2009-2012 Guillem Jover <guillem@debian.org>
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <compat.h>
+
+#include <ctype.h>
+#include <stdbool.h>
+#include <stdlib.h>
+
+#include <dpkg/test.h>
+#include <dpkg/path.h>
+
+/* Use the test_trim_eq_ref macro to avoid leaking the string and to get
+ * meaningful line numbers from assert. */
+#define test_trim_eq_ref(p, ref) \
+do { \
+ char *t = test_alloc(strdup((p))); \
+ path_trim_slash_slashdot(t); \
+ test_str(t, ==, (ref)); \
+ free(t); \
+} while (0)
+
+static void
+test_path_trim(void)
+{
+ test_trim_eq_ref("/a", "/a");
+ test_trim_eq_ref("./././.", ".");
+ test_trim_eq_ref("./././", ".");
+ test_trim_eq_ref("./.", ".");
+ test_trim_eq_ref("./", ".");
+ test_trim_eq_ref("/./././.", "/");
+ test_trim_eq_ref("/./", "/");
+ test_trim_eq_ref("/.", "/");
+ test_trim_eq_ref("/", "/");
+ test_trim_eq_ref("", "");
+ test_trim_eq_ref("/./../.", "/./..");
+ test_trim_eq_ref("/foo/bar/./", "/foo/bar");
+ test_trim_eq_ref("./foo/bar/./", "./foo/bar");
+ test_trim_eq_ref("/./foo/bar/./", "/./foo/bar");
+}
+
+static void
+test_path_skip(void)
+{
+ test_str(path_skip_slash_dotslash("./././."), ==, ".");
+ test_str(path_skip_slash_dotslash("./././"), ==, "");
+ test_str(path_skip_slash_dotslash("./."), ==, ".");
+ test_str(path_skip_slash_dotslash("./"), ==, "");
+ test_str(path_skip_slash_dotslash("/./././."), ==, ".");
+ test_str(path_skip_slash_dotslash("/./"), ==, "");
+ test_str(path_skip_slash_dotslash("/."), ==, ".");
+ test_str(path_skip_slash_dotslash("/"), ==, "");
+ test_str(path_skip_slash_dotslash("/./../."), ==, "../.");
+ test_str(path_skip_slash_dotslash("/foo/bar/./"), ==, "foo/bar/./");
+ test_str(path_skip_slash_dotslash("./foo/bar/./"), ==, "foo/bar/./");
+ test_str(path_skip_slash_dotslash("/./foo/bar/./"), ==, "foo/bar/./");
+}
+
+static void
+test_path_basename(void)
+{
+ test_str(path_basename("./."), ==, ".");
+ test_str(path_basename("./"), ==, "");
+ test_str(path_basename("/."), ==, ".");
+ test_str(path_basename("/"), ==, "");
+ test_str(path_basename("/foo"), ==, "foo");
+ test_str(path_basename("/foo/bar"), ==, "bar");
+ test_str(path_basename("/foo/bar/"), ==, "");
+}
+
+static void
+test_path_temp(void)
+{
+ char *template;
+
+ template = path_make_temp_template("test");
+
+ test_pass(strstr(template, "test") != NULL);
+ test_pass(strstr(template, "XXXXXX") != NULL);
+
+ free(template);
+}
+
+static bool
+string_is_ascii(const char *str)
+{
+ while (*str) {
+ if (!isascii(*str))
+ return false;
+
+ str++;
+ }
+
+ return true;
+}
+
+static void
+test_path_quote(void)
+{
+ const char src_7_bit[] = "string with 7-bit chars only";
+ const char src_7_bit_trim[] = "string with 7-bit chars";
+ const char src_8_bit[] = "text w/ 8-bit chars: \\ \370 \300 \342 end";
+ const char src_8_bit_end[] = "text \370";
+ const char src_bs_end[] = "text \\";
+ char *dst;
+ size_t len;
+
+ /* Test 0 length. */
+ dst = NULL;
+ path_quote_filename(dst, src_7_bit, 0);
+
+ /* Test no quoting. */
+ len = strlen(src_7_bit) + 1;
+ dst = test_alloc(malloc(len));
+
+ path_quote_filename(dst, src_7_bit, len);
+ test_str(dst, ==, src_7_bit);
+ free(dst);
+
+ /* Test no quoting with limit. */
+ len = strlen(src_7_bit_trim) + 1;
+ dst = test_alloc(malloc(len));
+
+ path_quote_filename(dst, src_7_bit, len);
+ test_str(dst, ==, src_7_bit_trim);
+ free(dst);
+
+ /* Test normal quoting. */
+ len = strlen(src_8_bit) * 2 + 1;
+ dst = test_alloc(malloc(len));
+
+ path_quote_filename(dst, src_8_bit, len);
+ test_pass(strstr(dst, "end") != NULL);
+ test_pass(string_is_ascii(dst));
+ free(dst);
+
+ /* Test normal quoting with limit. */
+ len = strlen(src_8_bit_end) + 1 + 2;
+ dst = test_alloc(malloc(len));
+
+ path_quote_filename(dst, src_8_bit_end, len);
+ test_str(dst, ==, "text ");
+ free(dst);
+
+ /* Test backslash quoting with limit. */
+ len = strlen(src_bs_end) + 1;
+ dst = test_alloc(malloc(len));
+
+ path_quote_filename(dst, src_bs_end, len);
+ test_str(dst, ==, "text ");
+ free(dst);
+}
+
+TEST_ENTRY(test)
+{
+ test_plan(41);
+
+ test_path_trim();
+ test_path_skip();
+ test_path_basename();
+ test_path_temp();
+ test_path_quote();
+}
diff --git a/lib/dpkg/t/t-pkg-format.c b/lib/dpkg/t/t-pkg-format.c
new file mode 100644
index 0000000..a6d33fe
--- /dev/null
+++ b/lib/dpkg/t/t-pkg-format.c
@@ -0,0 +1,141 @@
+/*
+ * libdpkg - Debian packaging suite library routines
+ * t-pkg-format.c - test pkg-format implementation
+ *
+ * Copyright © 2022 Guillem Jover <guillem@debian.org>
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <compat.h>
+
+#include <dpkg/test.h>
+#include <dpkg/dpkg-db.h>
+#include <dpkg/pkg.h>
+#include <dpkg/pkg-format.h>
+
+static void
+prep_pkg(struct pkgset *set, struct pkginfo *pkg)
+{
+ pkg_blank(pkg);
+
+ pkgset_blank(set);
+ pkgset_link_pkg(set, pkg);
+
+ set->name = "test-bin";
+ pkg->installed.description = "short synopsis -- some package\n"
+ " This is the extended description for this package-\n"
+ " .\n"
+ " Potentially expanding multiple lines.\n";
+ pkg->installed.arch = dpkg_arch_get(DPKG_ARCH_ALL);
+ pkg->installed.version = DPKG_VERSION_OBJECT(0, "4.5", "2");
+}
+
+static void
+prep_virtpkg(struct pkgset *set, struct pkginfo *pkg)
+{
+ pkg_blank(pkg);
+
+ pkgset_blank(set);
+ pkgset_link_pkg(set, pkg);
+
+ set->name = "test-virt";
+}
+
+static void
+test_field(struct pkginfo *pkg, const char *fmt, const char *exp)
+{
+ struct pkg_format_node *head;
+ struct varbuf vb = VARBUF_INIT;
+
+ head = pkg_format_parse(fmt, NULL);
+ test_pass(head);
+ pkg_format_print(&vb, head, pkg, &pkg->installed);
+ test_str(vb.buf, ==, exp);
+ pkg_format_free(head);
+}
+
+static void
+test_pkg_format_real_fields(void)
+{
+ struct pkgset pkgset;
+ struct pkginfo pkg;
+
+ prep_pkg(&pkgset, &pkg);
+
+ test_field(&pkg, "${Package}_${Version}_${Architecture}",
+ "test-bin_4.5-2_all");
+}
+
+static void
+test_pkg_format_virtual_fields(void)
+{
+ struct pkgset pkgset;
+ struct pkginfo pkg;
+
+ prep_pkg(&pkgset, &pkg);
+
+ test_field(&pkg, "${source:Package}_${source:Version}",
+ "test-bin_4.5-2");
+
+ pkg.installed.source = "test-src";
+ test_field(&pkg, "${source:Package}_${source:Version}",
+ "test-src_4.5-2");
+ test_field(&pkg, "${source:Upstream-Version}",
+ "4.5");
+
+ pkg.installed.source = "test-src (1:3.4-6)";
+ test_field(&pkg, "${source:Package}_${source:Version}",
+ "test-src_1:3.4-6");
+ test_field(&pkg, "${source:Upstream-Version}",
+ "3.4");
+
+ test_field(&pkg, "${binary:Synopsis}",
+ "short synopsis -- some package");
+
+ test_field(&pkg, "${binary:Summary}",
+ "short synopsis -- some package");
+
+ prep_virtpkg(&pkgset, &pkg);
+ test_field(&pkg, "${source:Package}_${source:Version}",
+ "test-virt_");
+ test_field(&pkg, "${source:Upstream-Version}",
+ "");
+}
+
+static void
+test_pkg_format_virtual_fields_db_fsys(void)
+{
+ struct pkg_format_node *head;
+
+ head = pkg_format_parse("prefix ${unknown-variable} suffix", NULL);
+ test_pass(head);
+ test_fail(pkg_format_needs_db_fsys(head));
+ pkg_format_free(head);
+
+ head = pkg_format_parse("prefix ${db-fsys:Files} suffix", NULL);
+ test_pass(head);
+ test_pass(pkg_format_needs_db_fsys(head));
+ pkg_format_free(head);
+}
+
+TEST_ENTRY(test)
+{
+ test_plan(24);
+
+ test_pkg_format_real_fields();
+ test_pkg_format_virtual_fields();
+ test_pkg_format_virtual_fields_db_fsys();
+}
diff --git a/lib/dpkg/t/t-pkg-hash.c b/lib/dpkg/t/t-pkg-hash.c
new file mode 100644
index 0000000..72185a2
--- /dev/null
+++ b/lib/dpkg/t/t-pkg-hash.c
@@ -0,0 +1,178 @@
+/*
+ * libdpkg - Debian packaging suite library routines
+ * t-pkg-hash.c - test pkg-hash implementation
+ *
+ * Copyright © 2018 Guillem Jover <guillem@debian.org>
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <compat.h>
+
+#include <dpkg/test.h>
+#include <dpkg/dpkg.h>
+#include <dpkg/dpkg-db.h>
+#include <dpkg/pkg.h>
+
+static void
+test_pkg_hash(void)
+{
+ struct dpkg_arch *arch;
+ struct pkgset *set;
+ struct pkginfo *pkg;
+ struct pkg_hash_iter *iter;
+ int pkginstance;
+
+ test_pass(pkg_hash_count_set() == 0);
+ test_pass(pkg_hash_count_pkg() == 0);
+
+ set = pkg_hash_find_set("pkg-aa");
+ test_pass(set != NULL);
+ test_str(set->name, ==, "pkg-aa");
+ test_pass(pkg_hash_count_set() == 1);
+ test_pass(pkg_hash_count_pkg() == 1);
+
+ set = pkg_hash_find_set("pkg-aa");
+ test_pass(set != NULL);
+ test_str(set->name, ==, "pkg-aa");
+ test_pass(pkg_hash_count_set() == 1);
+ test_pass(pkg_hash_count_pkg() == 1);
+
+ set = pkg_hash_find_set("Pkg-AA");
+ test_pass(set != NULL);
+ test_str(set->name, ==, "pkg-aa");
+ test_pass(pkg_hash_count_set() == 1);
+ test_pass(pkg_hash_count_pkg() == 1);
+
+ set = pkg_hash_find_set("pkg-bb");
+ pkg_set_status(&set->pkg, PKG_STAT_INSTALLED);
+ test_pass(set != NULL);
+ test_str(set->name, ==, "pkg-bb");
+ test_pass(pkg_hash_count_set() == 2);
+ test_pass(pkg_hash_count_pkg() == 2);
+
+ set = pkg_hash_find_set("pkg-cc");
+ test_pass(set != NULL);
+ test_str(set->name, ==, "pkg-cc");
+ test_pass(pkg_hash_count_set() == 3);
+ test_pass(pkg_hash_count_pkg() == 3);
+
+ arch = dpkg_arch_find("arch-xx");
+ pkg = pkg_hash_find_pkg("pkg-aa", arch);
+ pkg_set_status(pkg, PKG_STAT_INSTALLED);
+ test_pass(pkg != NULL);
+ test_str(pkg->set->name, ==, "pkg-aa");
+ test_str(pkg->installed.arch->name, ==, "arch-xx");
+ test_str(pkg->available.arch->name, ==, "arch-xx");
+ test_pass(pkg_hash_count_set() == 3);
+ test_pass(pkg_hash_count_pkg() == 3);
+
+ arch = dpkg_arch_find("arch-yy");
+ pkg = pkg_hash_find_pkg("pkg-aa", arch);
+ test_pass(pkg != NULL);
+ test_str(pkg->set->name, ==, "pkg-aa");
+ test_str(pkg->installed.arch->name, ==, "arch-yy");
+ test_str(pkg->available.arch->name, ==, "arch-yy");
+ test_pass(pkg_hash_count_set() == 3);
+ test_pass(pkg_hash_count_pkg() == 4);
+
+ arch = dpkg_arch_find("arch-zz");
+ pkg = pkg_hash_find_pkg("pkg-aa", arch);
+ pkg_set_status(pkg, PKG_STAT_UNPACKED);
+ test_pass(pkg != NULL);
+ test_str(pkg->set->name, ==, "pkg-aa");
+ test_str(pkg->installed.arch->name, ==, "arch-zz");
+ test_str(pkg->available.arch->name, ==, "arch-zz");
+ test_pass(pkg_hash_count_set() == 3);
+ test_pass(pkg_hash_count_pkg() == 5);
+
+ arch = dpkg_arch_find("arch-xx");
+ pkg = pkg_hash_find_pkg("pkg-aa", arch);
+ test_pass(pkg != NULL);
+ test_str(pkg->set->name, ==, "pkg-aa");
+ test_str(pkg->installed.arch->name, ==, "arch-xx");
+ test_str(pkg->available.arch->name, ==, "arch-xx");
+ test_pass(pkg_hash_count_set() == 3);
+ test_pass(pkg_hash_count_pkg() == 5);
+
+ set = pkg_hash_find_set("pkg-aa");
+ test_str(set->name, ==, "pkg-aa");
+ pkg = pkg_hash_get_singleton(set);
+ test_pass(pkg == NULL);
+ test_pass(pkg_hash_count_set() == 3);
+ test_pass(pkg_hash_count_pkg() == 5);
+
+ pkg = pkg_hash_find_singleton("pkg-bb");
+ test_pass(pkg != NULL);
+ test_str(pkg->set->name, ==, "pkg-bb");
+ test_pass(pkg_hash_count_set() == 3);
+ test_pass(pkg_hash_count_pkg() == 5);
+
+ pkg = pkg_hash_find_singleton("pkg-cc");
+ test_pass(pkg != NULL);
+ test_str(pkg->set->name, ==, "pkg-cc");
+ test_pass(pkg_hash_count_set() == 3);
+ test_pass(pkg_hash_count_pkg() == 5);
+
+ iter = pkg_hash_iter_new();
+ while ((set = pkg_hash_iter_next_set(iter))) {
+ if (strcmp(set->name, "pkg-aa") == 0)
+ test_str(set->name, ==, "pkg-aa");
+ else if (strcmp(set->name, "pkg-bb") == 0)
+ test_str(set->name, ==, "pkg-bb");
+ else if (strcmp(set->name, "pkg-cc") == 0)
+ test_str(set->name, ==, "pkg-cc");
+ else
+ test_fail("unknown fsys_namenode");
+ }
+ pkg_hash_iter_free(iter);
+
+ pkginstance = 0;
+ iter = pkg_hash_iter_new();
+ while ((pkg = pkg_hash_iter_next_pkg(iter))) {
+ pkginstance++;
+ if (strcmp(pkg->set->name, "pkg-aa") == 0) {
+ struct pkgbin *pkgbin = &pkg->installed;
+
+ test_str(pkg->set->name, ==, "pkg-aa");
+ if (strcmp(pkgbin->arch->name, "arch-xx") == 0)
+ test_str(pkgbin->arch->name, ==, "arch-xx");
+ else if (strcmp(pkgbin->arch->name, "arch-yy") == 0)
+ test_str(pkgbin->arch->name, ==, "arch-yy");
+ else if (strcmp(pkgbin->arch->name, "arch-zz") == 0)
+ test_str(pkgbin->arch->name, ==, "arch-zz");
+ else
+ test_fail("unknown pkginfo instance");
+ } else if (strcmp(pkg->set->name, "pkg-bb") == 0) {
+ test_str(pkg->set->name, ==, "pkg-bb");
+ } else if (strcmp(pkg->set->name, "pkg-cc") == 0) {
+ test_str(pkg->set->name, ==, "pkg-cc");
+ } else {
+ test_fail("unknown fsys_namenode");
+ }
+ }
+ pkg_hash_iter_free(iter);
+
+ pkg_hash_reset();
+ test_pass(pkg_hash_count_set() == 0);
+ test_pass(pkg_hash_count_pkg() == 0);
+}
+
+TEST_ENTRY(test)
+{
+ test_plan(71);
+
+ test_pkg_hash();
+}
diff --git a/lib/dpkg/t/t-pkg-list.c b/lib/dpkg/t/t-pkg-list.c
new file mode 100644
index 0000000..722cf2e
--- /dev/null
+++ b/lib/dpkg/t/t-pkg-list.c
@@ -0,0 +1,90 @@
+/*
+ * libdpkg - Debian packaging suite library routines
+ * t-pkg-list.c - test pkg-list implementation
+ *
+ * Copyright © 2010,2012 Guillem Jover <guillem@debian.org>
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <compat.h>
+
+#include <dpkg/test.h>
+#include <dpkg/dpkg-db.h>
+#include <dpkg/pkg-list.h>
+
+static void
+test_pkg_list_new(void)
+{
+ struct pkg_list *l1, *l2, *l3;
+ struct pkginfo pkg1, pkg2, pkg3;
+
+ l1 = pkg_list_new(&pkg1, NULL);
+ test_alloc(l1);
+ test_pass(l1->next == NULL);
+ test_pass(l1->pkg == &pkg1);
+
+ l2 = pkg_list_new(&pkg2, l1);
+ test_alloc(l2);
+ test_pass(l2->next == l1);
+ test_pass(l2->pkg == &pkg2);
+
+ l3 = pkg_list_new(&pkg3, l2);
+ test_alloc(l3);
+ test_pass(l3->next == l2);
+ test_pass(l3->pkg == &pkg3);
+
+ pkg_list_free(l3);
+}
+
+static void
+test_pkg_list_prepend(void)
+{
+ struct pkg_list *head = NULL, *l1, *l2, *l3;
+ struct pkginfo pkg1, pkg2, pkg3, pkg4;
+
+ pkg_list_prepend(&head, &pkg1);
+ test_alloc(head);
+ test_pass(head->next == NULL);
+ test_pass(head->pkg == &pkg1);
+ l1 = head;
+
+ pkg_list_prepend(&head, &pkg2);
+ test_alloc(head);
+ test_pass(head->next == l1);
+ test_pass(head->pkg == &pkg2);
+ l2 = head;
+
+ pkg_list_prepend(&head, &pkg3);
+ test_alloc(head);
+ test_pass(head->next == l2);
+ test_pass(head->pkg == &pkg3);
+ l3 = head;
+
+ pkg_list_prepend(&head, &pkg4);
+ test_alloc(head);
+ test_pass(head->next == l3);
+ test_pass(head->pkg == &pkg4);
+
+ pkg_list_free(head);
+}
+
+TEST_ENTRY(test)
+{
+ test_plan(14);
+
+ test_pkg_list_new();
+ test_pkg_list_prepend();
+}
diff --git a/lib/dpkg/t/t-pkg-queue.c b/lib/dpkg/t/t-pkg-queue.c
new file mode 100644
index 0000000..cf1e327
--- /dev/null
+++ b/lib/dpkg/t/t-pkg-queue.c
@@ -0,0 +1,116 @@
+/*
+ * libdpkg - Debian packaging suite library routines
+ * t-pkg-queue.c - test pkg-queue implementation
+ *
+ * Copyright © 2010,2012 Guillem Jover <guillem@debian.org>
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <compat.h>
+
+#include <dpkg/test.h>
+#include <dpkg/dpkg-db.h>
+#include <dpkg/pkg-queue.h>
+
+static void
+test_pkg_queue_init(void)
+{
+ struct pkg_queue q = PKG_QUEUE_INIT;
+ struct pkg_list l;
+
+ test_pass(q.length == 0);
+ test_pass(q.head == NULL);
+ test_pass(q.tail == NULL);
+
+ test_pass(pkg_queue_is_empty(&q));
+
+ q = (struct pkg_queue){ .length = 10, .head = &l, .tail = &l };
+
+ pkg_queue_init(&q);
+ test_pass(q.length == 0);
+ test_pass(q.head == NULL);
+ test_pass(q.tail == NULL);
+
+ test_pass(pkg_queue_is_empty(&q));
+}
+
+static void
+test_pkg_queue_push_pop(void)
+{
+ struct pkg_queue q = PKG_QUEUE_INIT;
+ struct pkg_list *l1, *l2, *l3;
+ struct pkginfo *pkgp, pkg1, pkg2, pkg3;
+
+ test_pass(pkg_queue_is_empty(&q));
+
+ /* Test push operations. */
+
+ l1 = pkg_queue_push(&q, &pkg1);
+ test_pass(l1 != NULL);
+ test_pass(q.head == l1);
+ test_pass(q.tail == l1);
+ test_pass(q.length == 1);
+
+ l2 = pkg_queue_push(&q, &pkg2);
+ test_pass(l2 != NULL);
+ test_pass(q.head == l1);
+ test_pass(q.tail == l2);
+ test_pass(q.length == 2);
+
+ l3 = pkg_queue_push(&q, &pkg3);
+ test_pass(l3 != NULL);
+ test_pass(q.head == l1);
+ test_pass(q.tail == l3);
+ test_pass(q.length == 3);
+
+ /* Test pop operations. */
+
+ pkgp = pkg_queue_pop(&q);
+ test_pass(pkgp == &pkg1);
+ test_pass(q.head == l2);
+ test_pass(q.tail == l3);
+ test_pass(q.length == 2);
+
+ pkgp = pkg_queue_pop(&q);
+ test_pass(pkgp == &pkg2);
+ test_pass(q.head == l3);
+ test_pass(q.tail == l3);
+ test_pass(q.length == 1);
+
+ pkgp = pkg_queue_pop(&q);
+ test_pass(pkgp == &pkg3);
+ test_pass(q.head == NULL);
+ test_pass(q.tail == NULL);
+ test_pass(q.length == 0);
+
+ test_pass(pkg_queue_is_empty(&q));
+
+ pkgp = pkg_queue_pop(&q);
+ test_pass(pkgp == NULL);
+ test_pass(q.head == NULL);
+ test_pass(q.tail == NULL);
+ test_pass(q.length == 0);
+
+ pkg_queue_destroy(&q);
+}
+
+TEST_ENTRY(test)
+{
+ test_plan(38);
+
+ test_pkg_queue_init();
+ test_pkg_queue_push_pop();
+}
diff --git a/lib/dpkg/t/t-pkg-show.c b/lib/dpkg/t/t-pkg-show.c
new file mode 100644
index 0000000..0f6ece0
--- /dev/null
+++ b/lib/dpkg/t/t-pkg-show.c
@@ -0,0 +1,61 @@
+/*
+ * libdpkg - Debian packaging suite library routines
+ * t-pkg-show.c - test pkg-show implementation
+ *
+ * Copyright © 2018 Guillem Jover <guillem@debian.org>
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <compat.h>
+
+#include <dpkg/test.h>
+#include <dpkg/dpkg-db.h>
+#include <dpkg/arch.h>
+
+static void
+test_pkg_show_name(void)
+{
+ struct dpkg_arch *arch;
+ struct pkginfo *pkg;
+ const char *pkgname;
+
+ arch = dpkg_arch_find("arch");
+ test_pass(arch);
+
+ pkg = pkg_hash_find_pkg("test", arch);
+ test_pass(pkg);
+ test_str(pkg->set->name, ==, "test");
+ test_pass(pkg->installed.arch->type == DPKG_ARCH_UNKNOWN);
+
+ pkgname = pkg_name(pkg, pnaw_never);
+ test_pass(pkgname);
+ test_str(pkgname, ==, "test");
+
+ pkgname = pkg_name(pkg, pnaw_nonambig);
+ test_pass(pkgname);
+ test_str(pkgname, ==, "test:arch");
+
+ pkgname = pkg_name(pkg, pnaw_always);
+ test_pass(pkgname);
+ test_str(pkgname, ==, "test:arch");
+}
+
+TEST_ENTRY(test)
+{
+ test_plan(10);
+
+ test_pkg_show_name();
+}
diff --git a/lib/dpkg/t/t-pkginfo.c b/lib/dpkg/t/t-pkginfo.c
new file mode 100644
index 0000000..876af51
--- /dev/null
+++ b/lib/dpkg/t/t-pkginfo.c
@@ -0,0 +1,153 @@
+/*
+ * libdpkg - Debian packaging suite library routines
+ * t-pkginfo.c - test pkginfo handling
+ *
+ * Copyright © 2009-2010,2012-2014 Guillem Jover <guillem@debian.org>
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <compat.h>
+
+#include <dpkg/test.h>
+#include <dpkg/dpkg-db.h>
+#include <dpkg/pkg.h>
+
+static void
+test_pkginfo_informative(void)
+{
+ struct pkginfo pkg;
+
+ pkg_blank(&pkg);
+ test_fail(pkg_is_informative(&pkg, &pkg.installed));
+
+ pkg_set_want(&pkg, PKG_WANT_PURGE);
+ test_pass(pkg_is_informative(&pkg, &pkg.installed));
+
+ pkg_blank(&pkg);
+ pkg.installed.description = "test description";
+ test_pass(pkg_is_informative(&pkg, &pkg.installed));
+
+ /* FIXME: Complete. */
+}
+
+static void
+test_pkginfo_eflags(void)
+{
+ struct pkginfo pkg;
+
+ pkg_blank(&pkg);
+ test_pass(pkg.eflag == PKG_EFLAG_OK);
+
+ pkg_set_eflags(&pkg, PKG_EFLAG_REINSTREQ);
+ test_pass(pkg.eflag == PKG_EFLAG_REINSTREQ);
+
+ pkg_clear_eflags(&pkg, PKG_EFLAG_REINSTREQ);
+ test_pass(pkg.eflag == PKG_EFLAG_OK);
+
+ pkg_set_eflags(&pkg, 0x11);
+ test_pass(pkg.eflag == 0x11);
+ pkg_reset_eflags(&pkg);
+ test_pass(pkg.eflag == PKG_EFLAG_OK);
+}
+
+static void
+test_pkginfo_instance_tracking(void)
+{
+ struct pkgset set;
+ struct pkginfo pkg2, pkg3, pkg4;
+
+ pkgset_blank(&set);
+ pkg_blank(&pkg2);
+ pkg_blank(&pkg3);
+ pkg_blank(&pkg4);
+
+ test_pass(pkgset_installed_instances(&set) == 0);
+
+ /* Link the other instances into the pkgset. */
+ pkgset_link_pkg(&set, &pkg4);
+ pkgset_link_pkg(&set, &pkg3);
+ pkgset_link_pkg(&set, &pkg2);
+
+ /* Test installation state transitions. */
+ pkg_set_status(&pkg4, PKG_STAT_INSTALLED);
+ test_pass(pkgset_installed_instances(&set) == 1);
+
+ pkg_set_status(&pkg4, PKG_STAT_INSTALLED);
+ test_pass(pkgset_installed_instances(&set) == 1);
+
+ pkg_set_status(&pkg4, PKG_STAT_TRIGGERSPENDING);
+ test_pass(pkgset_installed_instances(&set) == 1);
+
+ pkg_set_status(&pkg4, PKG_STAT_TRIGGERSAWAITED);
+ test_pass(pkgset_installed_instances(&set) == 1);
+
+ pkg_set_status(&pkg4, PKG_STAT_HALFCONFIGURED);
+ test_pass(pkgset_installed_instances(&set) == 1);
+
+ pkg_set_status(&pkg4, PKG_STAT_UNPACKED);
+ test_pass(pkgset_installed_instances(&set) == 1);
+
+ pkg_set_status(&pkg4, PKG_STAT_HALFINSTALLED);
+ test_pass(pkgset_installed_instances(&set) == 1);
+
+ pkg_set_status(&pkg4, PKG_STAT_CONFIGFILES);
+ test_pass(pkgset_installed_instances(&set) == 1);
+
+ pkg_set_status(&pkg4, PKG_STAT_NOTINSTALLED);
+ test_pass(pkgset_installed_instances(&set) == 0);
+
+ pkg_set_status(&pkg4, PKG_STAT_NOTINSTALLED);
+ test_pass(pkgset_installed_instances(&set) == 0);
+
+ /* Toggle installation states on various packages. */
+ pkg_set_status(&pkg4, PKG_STAT_INSTALLED);
+ test_pass(pkgset_installed_instances(&set) == 1);
+
+ pkg_set_status(&pkg2, PKG_STAT_HALFINSTALLED);
+ test_pass(pkgset_installed_instances(&set) == 2);
+
+ pkg_set_status(&set.pkg, PKG_STAT_CONFIGFILES);
+ test_pass(pkgset_installed_instances(&set) == 3);
+
+ pkg_set_status(&pkg3, PKG_STAT_NOTINSTALLED);
+ test_pass(pkgset_installed_instances(&set) == 3);
+
+ pkg_set_status(&pkg3, PKG_STAT_UNPACKED);
+ test_pass(pkgset_installed_instances(&set) == 4);
+
+ pkg_set_status(&set.pkg, PKG_STAT_NOTINSTALLED);
+ test_pass(pkgset_installed_instances(&set) == 3);
+
+ pkg_set_status(&pkg2, PKG_STAT_NOTINSTALLED);
+ test_pass(pkgset_installed_instances(&set) == 2);
+
+ pkg_set_status(&pkg3, PKG_STAT_NOTINSTALLED);
+ test_pass(pkgset_installed_instances(&set) == 1);
+
+ pkg_set_status(&pkg4, PKG_STAT_NOTINSTALLED);
+ test_pass(pkgset_installed_instances(&set) == 0);
+}
+
+TEST_ENTRY(test)
+{
+ test_plan(28);
+
+ test_pkginfo_informative();
+ test_pkginfo_eflags();
+ test_pkginfo_instance_tracking();
+
+ /* FIXME: Complete. */
+}
diff --git a/lib/dpkg/t/t-progname.c b/lib/dpkg/t/t-progname.c
new file mode 100644
index 0000000..e90e923
--- /dev/null
+++ b/lib/dpkg/t/t-progname.c
@@ -0,0 +1,53 @@
+/*
+ * libdpkg - Debian packaging suite library routines
+ * t-progname.c - test program name handling
+ *
+ * Copyright © 2011 Guillem Jover <guillem@debian.org>
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <compat.h>
+
+#include <dpkg/test.h>
+#include <dpkg/progname.h>
+
+static void
+test_progname(void)
+{
+ const char *progname;
+
+ /* Test initially empty progname. */
+ progname = dpkg_get_progname();
+ /* Handle libtool executables. */
+ if (strncmp(progname, "lt-", 3) == 0)
+ progname += 3;
+ test_str(progname, ==, "t-progname");
+
+ /* Test setting a new progname. */
+ dpkg_set_progname("newname");
+ test_str(dpkg_get_progname(), ==, "newname");
+
+ /* Test setting a new progname with path. */
+ dpkg_set_progname("path/newprogname");
+ test_str(dpkg_get_progname(), ==, "newprogname");
+}
+
+TEST_ENTRY(test)
+{
+ test_plan(3);
+
+ test_progname();
+}
diff --git a/lib/dpkg/t/t-string.c b/lib/dpkg/t/t-string.c
new file mode 100644
index 0000000..7b4350d
--- /dev/null
+++ b/lib/dpkg/t/t-string.c
@@ -0,0 +1,281 @@
+/*
+ * libdpkg - Debian packaging suite library routines
+ * t-string.c - test string handling
+ *
+ * Copyright © 2009-2011, 2014-2015 Guillem Jover <guillem@debian.org>
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <compat.h>
+
+#include <dpkg/test.h>
+#include <dpkg/string.h>
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <stdio.h>
+
+static void
+test_str_is_set(void)
+{
+ /* Test if strings are unset. */
+ test_pass(str_is_unset(NULL));
+ test_pass(str_is_unset(""));
+ test_fail(str_is_unset("aaa"));
+
+ /* Test if strings are set. */
+ test_fail(str_is_set(NULL));
+ test_fail(str_is_set(""));
+ test_pass(str_is_set("ccc"));
+}
+
+static void
+test_str_match_end(void)
+{
+ test_pass(str_match_end("foo bar quux", "quux"));
+ test_pass(str_match_end("foo bar quux", "bar quux"));
+ test_pass(str_match_end("foo bar quux", "foo bar quux"));
+ test_fail(str_match_end("foo bar quux", "foo bar quux zorg"));
+ test_fail(str_match_end("foo bar quux", "foo bar"));
+ test_fail(str_match_end("foo bar quux", "foo"));
+}
+
+static void
+test_str_fnv_hash(void)
+{
+ test_pass(str_fnv_hash("") == 0x811c9dc5U);
+ test_pass(str_fnv_hash("a") == 0xe40c292cUL);
+ test_pass(str_fnv_hash("b") == 0xe70c2de5UL);
+ test_pass(str_fnv_hash("c") == 0xe60c2c52UL);
+ test_pass(str_fnv_hash("d") == 0xe10c2473UL);
+ test_pass(str_fnv_hash("e") == 0xe00c22e0UL);
+ test_pass(str_fnv_hash("f") == 0xe30c2799UL);
+ test_pass(str_fnv_hash("fo") == 0x6222e842UL);
+ test_pass(str_fnv_hash("foo") == 0xa9f37ed7UL);
+ test_pass(str_fnv_hash("foob") == 0x3f5076efUL);
+ test_pass(str_fnv_hash("fooba") == 0x39aaa18aUL);
+ test_pass(str_fnv_hash("foobar") == 0xbf9cf968UL);
+
+ test_pass(str_fnv_hash("test-string") == 0xd28f6e61UL);
+ test_pass(str_fnv_hash("Test-string") == 0x00a54b81UL);
+ test_pass(str_fnv_hash("rest-string") == 0x1cdeebffUL);
+ test_pass(str_fnv_hash("Rest-string") == 0x20464b9fUL);
+}
+
+static void
+test_str_concat(void)
+{
+ char buf[1024], *str;
+
+ memset(buf, 0, sizeof(buf));
+ str = str_concat(buf, NULL);
+ test_pass(str == buf);
+ test_str(buf, ==, "");
+
+ memset(buf, 0, sizeof(buf));
+ str = str_concat(buf, "aaa", NULL);
+ test_str(buf, ==, "aaa");
+ test_pass(str == buf + 3);
+
+ memset(buf, 0, sizeof(buf));
+ str = str_concat(buf, "zzzz", "yy", "xxxx", NULL);
+ test_str(buf, ==, "zzzzyyxxxx");
+ test_pass(str == buf + 10);
+
+ memset(buf, 0, sizeof(buf));
+ str = str_concat(buf, "1234", "", "5678", NULL);
+ test_str(buf, ==, "12345678");
+ test_pass(str == buf + 8);
+
+ memset(buf, ' ', sizeof(buf));
+ str = str_concat(buf, "eol", NULL, "bom", NULL);
+ test_str(buf, ==, "eol");
+ test_pass(str == buf + 3);
+}
+
+static void
+test_str_fmt(void)
+{
+ char *str;
+
+ str = str_fmt("%s", "abcde");
+ test_str(str, ==, "abcde");
+ free(str);
+
+ str = str_fmt("%d", 15);
+ test_str(str, ==, "15");
+ free(str);
+}
+
+static void
+test_str_escape_fmt(void)
+{
+ char buf[1024], *q;
+
+ memset(buf, 'a', sizeof(buf));
+ q = str_escape_fmt(buf, "", sizeof(buf));
+ strcpy(q, " end");
+ test_str(buf, ==, " end");
+
+ memset(buf, 'a', sizeof(buf));
+ q = str_escape_fmt(buf, "%", sizeof(buf));
+ strcpy(q, " end");
+ test_str(buf, ==, "%% end");
+
+ memset(buf, 'a', sizeof(buf));
+ q = str_escape_fmt(buf, "%%%", sizeof(buf));
+ strcpy(q, " end");
+ test_str(buf, ==, "%%%%%% end");
+
+ memset(buf, 'a', sizeof(buf));
+ q = str_escape_fmt(buf, "%b%b%c%c%%", sizeof(buf));
+ strcpy(q, " end");
+ test_str(buf, ==, "%%b%%b%%c%%c%%%% end");
+
+ /* Test delimited buffer. */
+ memset(buf, 'a', sizeof(buf));
+ q = str_escape_fmt(buf, NULL, 0);
+ test_mem(buf, ==, "aaaa", 4);
+ test_pass(buf == q);
+ test_pass(strnlen(buf, sizeof(buf)) == sizeof(buf));
+
+ memset(buf, 'a', sizeof(buf));
+ q = str_escape_fmt(buf, "b", 1);
+ test_str(q, ==, "");
+
+ memset(buf, 'a', sizeof(buf));
+ q = str_escape_fmt(buf, "%%%", 5);
+ strcpy(q, " end");
+ test_str(buf, ==, "%%%% end");
+
+ memset(buf, 'a', sizeof(buf));
+ q = str_escape_fmt(buf, "%%%", 4);
+ strcpy(q, " end");
+ test_str(buf, ==, "%% end");
+}
+
+static void
+test_str_rtrim_spaces(void)
+{
+ char buf[1024];
+ char *str_end;
+
+ strcpy(buf, "");
+ str_end = str_rtrim_spaces(buf, buf + strlen(buf));
+ test_pass(str_end == buf);
+ test_str(buf, ==, "");
+
+ strcpy(buf, " \t\t \r\n ");
+ str_end = str_rtrim_spaces(buf, buf + strlen(buf));
+ test_pass(str_end == buf);
+ test_str(buf, ==, "");
+
+ strcpy(buf, "abcd");
+ str_end = str_rtrim_spaces(buf, buf + strlen(buf));
+ test_pass(str_end == buf + 4);
+ test_str(buf, ==, "abcd");
+
+ strcpy(buf, "abcd ");
+ str_end = str_rtrim_spaces(buf, buf + strlen(buf));
+ test_pass(str_end == buf + 4);
+ test_str(buf, ==, "abcd");
+
+ strcpy(buf, "abcd\t \t ");
+ str_end = str_rtrim_spaces(buf, buf + strlen(buf));
+ test_pass(str_end == buf + 4);
+ test_str(buf, ==, "abcd");
+
+ strcpy(buf, " \t \t abcd");
+ str_end = str_rtrim_spaces(buf, buf + strlen(buf));
+ test_pass(str_end == buf + 12);
+ test_str(buf, ==, " \t \t abcd");
+}
+
+static void
+test_str_quote_meta(void)
+{
+ char *str;
+
+ str = str_quote_meta("foo1 2bar");
+ test_str(str, ==, "foo1\\ 2bar");
+ free(str);
+
+ str = str_quote_meta("foo1?2bar");
+ test_str(str, ==, "foo1\\?2bar");
+ free(str);
+
+ str = str_quote_meta("foo1*2bar");
+ test_str(str, ==, "foo1\\*2bar");
+ free(str);
+}
+
+static void
+test_str_strip_quotes(void)
+{
+ char buf[1024], *str;
+
+ strcpy(buf, "unquoted text");
+ str = str_strip_quotes(buf);
+ test_str(str, ==, "unquoted text");
+
+ strcpy(buf, "contained 'quoted text'");
+ str = str_strip_quotes(buf);
+ test_str(str, ==, "contained 'quoted text'");
+
+ strcpy(buf, "contained \"quoted text\"");
+ str = str_strip_quotes(buf);
+ test_str(str, ==, "contained \"quoted text\"");
+
+ strcpy(buf, "'unbalanced quotes");
+ str = str_strip_quotes(buf);
+ test_pass(str == NULL);
+
+ strcpy(buf, "\"unbalanced quotes");
+ str = str_strip_quotes(buf);
+ test_pass(str == NULL);
+
+ strcpy(buf, "'mismatched quotes\"");
+ str = str_strip_quotes(buf);
+ test_pass(str == NULL);
+
+ strcpy(buf, "\"mismatched quotes'");
+ str = str_strip_quotes(buf);
+ test_pass(str == NULL);
+
+ strcpy(buf, "'completely quoted text'");
+ str = str_strip_quotes(buf);
+ test_str(str, ==, "completely quoted text");
+
+ strcpy(buf, "\"completely quoted text\"");
+ str = str_strip_quotes(buf);
+ test_str(str, ==, "completely quoted text");
+}
+
+TEST_ENTRY(test)
+{
+ test_plan(74);
+
+ test_str_is_set();
+ test_str_match_end();
+ test_str_fnv_hash();
+ test_str_concat();
+ test_str_fmt();
+ test_str_escape_fmt();
+ test_str_quote_meta();
+ test_str_strip_quotes();
+ test_str_rtrim_spaces();
+}
diff --git a/lib/dpkg/t/t-subproc.c b/lib/dpkg/t/t-subproc.c
new file mode 100644
index 0000000..7ce610b
--- /dev/null
+++ b/lib/dpkg/t/t-subproc.c
@@ -0,0 +1,100 @@
+/*
+ * libdpkg - Debian packaging suite library routines
+ * t-subproc.c - test sub-process module
+ *
+ * Copyright © 2011 Guillem Jover <guillem@debian.org>
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <compat.h>
+
+#include <sys/types.h>
+
+#include <fcntl.h>
+#include <signal.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+#include <dpkg/test.h>
+#include <dpkg/subproc.h>
+
+static void
+test_subproc_fork(void)
+{
+ struct sigaction sa;
+ pid_t pid;
+ int ret;
+
+ memset(&sa, 0, sizeof(sa));
+ sa.sa_handler = SIG_DFL;
+ sigaction(SIGINT, &sa, NULL);
+ sigaction(SIGTERM, &sa, NULL);
+ sigaction(SIGPIPE, &sa, NULL);
+
+ /* Test exit(). */
+ pid = subproc_fork();
+ if (pid == 0)
+ exit(0);
+ ret = subproc_reap(pid, "subproc exit pass", SUBPROC_RETERROR);
+ test_pass(ret == 0);
+
+ pid = subproc_fork();
+ if (pid == 0)
+ exit(128);
+ ret = subproc_reap(pid, "subproc exit fail", SUBPROC_RETERROR);
+ test_pass(ret == 128);
+
+ /* Test signals. */
+ pid = subproc_fork();
+ if (pid == 0)
+ raise(SIGINT);
+ ret = subproc_reap(pid, "subproc signal", SUBPROC_WARN);
+ test_pass(ret == -1);
+
+ pid = subproc_fork();
+ if (pid == 0)
+ raise(SIGTERM);
+ ret = subproc_reap(pid, "subproc signal", SUBPROC_WARN);
+ test_pass(ret == -1);
+
+ pid = subproc_fork();
+ if (pid == 0)
+ raise(SIGPIPE);
+ ret = subproc_reap(pid, "subproc SIGPIPE",
+ SUBPROC_WARN | SUBPROC_NOPIPE);
+ test_pass(ret == 0);
+
+ pid = subproc_fork();
+ if (pid == 0)
+ raise(SIGPIPE);
+ ret = subproc_reap(pid, "subproc SIGPIPE", SUBPROC_WARN);
+ test_pass(ret == -1);
+}
+
+TEST_ENTRY(test)
+{
+ int fd;
+
+ test_plan(6);
+
+ /* XXX: Shut up stderr, we don't want the error output. */
+ fd = open("/dev/null", O_RDWR);
+ if (fd < 0)
+ test_bail("cannot open /dev/null");
+ dup2(fd, 2);
+
+ test_subproc_fork();
+}
diff --git a/lib/dpkg/t/t-tar.c b/lib/dpkg/t/t-tar.c
new file mode 100644
index 0000000..6fa217d
--- /dev/null
+++ b/lib/dpkg/t/t-tar.c
@@ -0,0 +1,148 @@
+/*
+ * libdpkg - Debian packaging suite library routines
+ * t-tar.c - test tar implementation
+ *
+ * Copyright © 2017 Guillem Jover <guillem@debian.org>
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <compat.h>
+
+#include <errno.h>
+
+#include <dpkg/test.h>
+#include <dpkg/tarfn.h>
+
+static void
+test_tar_atol8(void)
+{
+ uintmax_t u;
+
+ /* Test valid octal numbers. */
+ u = tar_atoul("000000\0\0\0\0\0\0", 12, UINTMAX_MAX);
+ test_pass(u == 0);
+ u = tar_atoul("00000000000\0", 12, UINTMAX_MAX);
+ test_pass(u == 0);
+ u = tar_atoul("00000000001\0", 12, UINTMAX_MAX);
+ test_pass(u == 1);
+ u = tar_atoul("00000000777\0", 12, UINTMAX_MAX);
+ test_pass(u == 511);
+ u = tar_atoul("77777777777\0", 12, UINTMAX_MAX);
+ test_pass(u == 8589934591);
+
+ /* Test legacy formatted octal numbers. */
+ u = tar_atoul(" 0\0", 12, UINTMAX_MAX);
+ test_pass(u == 0);
+ u = tar_atoul(" 1\0", 12, UINTMAX_MAX);
+ test_pass(u == 1);
+ u = tar_atoul(" 777\0", 12, UINTMAX_MAX);
+ test_pass(u == 511);
+
+ /* Test extended octal numbers not terminated by space or NUL,
+ * (as is required by POSIX), but accepted by several implementations
+ * to get one byte larger values. */
+ u = tar_atoul("000000000000", 12, UINTMAX_MAX);
+ test_pass(u == 0);
+ u = tar_atoul("000000000001", 12, UINTMAX_MAX);
+ test_pass(u == 1);
+ u = tar_atoul("000000000777", 12, UINTMAX_MAX);
+ test_pass(u == 511);
+ u = tar_atoul("777777777777", 12, UINTMAX_MAX);
+ test_pass(u == 68719476735);
+
+ /* Test invalid octal numbers. */
+ errno = 0;
+ u = tar_atoul(" ", 12, UINTMAX_MAX);
+ test_pass(u == 0);
+ test_pass(errno == EINVAL);
+
+ errno = 0;
+ u = tar_atoul(" 11111aaa ", 12, UINTMAX_MAX);
+ test_pass(u == 0);
+ test_pass(errno == ERANGE);
+
+ errno = 0;
+ u = tar_atoul(" 8 ", 12, UINTMAX_MAX);
+ test_pass(u == 0);
+ test_pass(errno == ERANGE);
+
+ errno = 0;
+ u = tar_atoul(" 18 ", 12, UINTMAX_MAX);
+ test_pass(u == 0);
+ test_pass(errno == ERANGE);
+
+ errno = 0;
+ u = tar_atoul(" aa ", 12, UINTMAX_MAX);
+ test_pass(u == 0);
+ test_pass(errno == ERANGE);
+}
+
+static void
+test_tar_atol256(void)
+{
+ uintmax_t u;
+ intmax_t i;
+
+ /* Test positive numbers. */
+ u = tar_atoul("\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 12, UINTMAX_MAX);
+ test_pass(u == 0);
+ u = tar_atoul("\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01", 12, UINTMAX_MAX);
+ test_pass(u == 1);
+ u = tar_atoul("\x80\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00", 12, UINTMAX_MAX);
+ test_pass(u == 8589934592);
+ u = tar_atoul("\x80\x00\x00\x00\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF", 12, UINTMAX_MAX);
+ test_pass(u == INTMAX_MAX);
+
+ /* Test overflow. */
+ errno = 0;
+ u = tar_atoul("\x80\x00\x00\x00\x80\x00\x00\x00\x00\x00\x00\x00", 12, UINTMAX_MAX);
+ test_pass(u == UINTMAX_MAX);
+ test_pass(errno == ERANGE);
+
+ errno = 0;
+ u = tar_atoul("\x80\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00", 12, UINTMAX_MAX);
+ test_pass(u == UINTMAX_MAX);
+ test_pass(errno == ERANGE);
+
+ /* Test negative numbers. */
+ i = tar_atosl("\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF", 12, INTMAX_MIN, INTMAX_MAX);
+ test_pass(i == -1);
+ i = tar_atosl("\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFE", 12, INTMAX_MIN, INTMAX_MAX);
+ test_pass(i == -2);
+ i = tar_atosl("\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFE\x00\x00\x00\x00", 12, INTMAX_MIN, INTMAX_MAX);
+ test_pass(i == -8589934592);
+ i = tar_atosl("\xFF\xFF\xFF\xFF\x80\x00\x00\x00\x00\x00\x00\x00", 12, INTMAX_MIN, INTMAX_MAX);
+ test_pass(i == INTMAX_MIN);
+
+ /* Test underflow. */
+ errno = 0;
+ i = tar_atosl("\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00", 12, INTMAX_MIN, INTMAX_MAX);
+ test_pass(i == INTMAX_MIN);
+ test_pass(errno == ERANGE);
+
+ errno = 0;
+ i = tar_atosl("\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 12, INTMAX_MIN, INTMAX_MAX);
+ test_pass(i == INTMAX_MIN);
+ test_pass(errno == ERANGE);
+}
+
+TEST_ENTRY(test)
+{
+ test_plan(38);
+
+ test_tar_atol8();
+ test_tar_atol256();
+}
diff --git a/lib/dpkg/t/t-tarextract.t b/lib/dpkg/t/t-tarextract.t
new file mode 100755
index 0000000..5fb9afa
--- /dev/null
+++ b/lib/dpkg/t/t-tarextract.t
@@ -0,0 +1,165 @@
+#!/usr/bin/perl
+#
+# Copyright © 2014 Guillem Jover <guillem@debian.org>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+use Test::More;
+use Cwd;
+use File::Path qw(make_path remove_tree);
+use File::Temp qw(tempdir);
+use File::Spec;
+use File::Find;
+use POSIX qw(mkfifo);
+
+use Dpkg ();
+use Dpkg::IPC;
+
+use strict;
+use warnings;
+use version;
+
+my $srcdir = $ENV{srcdir} || '.';
+my $builddir = $ENV{builddir} || '.';
+my $tmpdir = 't.tmp/t-tarextract';
+
+# We require GNU tar >= 1.27 for --owner=NAME:ID and --group=NAME:ID.
+my $tar_version = qx($Dpkg::PROGTAR --version 2>/dev/null);
+if ($tar_version and $tar_version =~ m/^tar \(GNU tar\) (\d+\.\d+)/ and
+ qv("v$1") >= qv('v1.27'))
+{
+ plan tests => 12;
+} else {
+ plan skip_all => 'needs GNU tar >= 1.27';
+}
+
+# Set a known umask.
+umask 0022;
+
+sub create {
+ my ($pathname) = @_;
+
+ open my $fh, '>>', $pathname or die "cannot touch $pathname: $!";
+ close $fh;
+}
+
+sub tar_create_tree {
+ my $type = shift;
+
+ my $long_a = 'a' x 29;
+ my $long_b = 'b' x 29;
+ my $long_c = 'c' x 29;
+ my $long_d = 'd' x 29;
+ my $long_e = 'e' x 29;
+ my $long_f = 'f' x 22;
+
+ # Populate tar hierarchy
+ create('file');
+ link 'file', 'hardlink';
+
+ make_path("$long_a/$long_b/$long_c/$long_d/$long_e/");
+ make_path("$long_a/$long_b/$long_c/$long_d/$long_e/$long_f/");
+ create("$long_a/$long_b/$long_c/$long_d/$long_e/$long_f/long");
+
+ # POSIX specifies that symlinks have undefined permissions in their
+ # mode, so their handling is system dependent. Linux does not honor
+ # the umask for symlinks, other systems like GNU/Hurd or kFreeBSD do,
+ # which means we get different results due to this.
+ my $umask = umask 0;
+
+ symlink "$long_a/$long_b/$long_c/$long_d/$long_e/$long_f/long",
+ 'symlink-long';
+ symlink 'file', 'symlink-a';
+ symlink 'hardlink', 'symlink-b';
+ symlink 'dangling', 'symlink-c';
+
+ umask $umask;
+
+ mkdir 'directory';
+ mkfifo('fifo', 0770);
+
+ # FIXME: Need root.
+ # system 'mknod', 'chardev', 'c', '1', '3';
+ # system 'mknod', 'blockdev', 'b', '0', '0';
+}
+
+sub test_tar_extractor {
+ my $stdout;
+ my $stderr;
+
+ my $expected_tar = <<'TAR';
+. mode=40755 time=100000000.000000000 uid=100 gid=200 uname=user gname=group type=dir
+./fifo mode=10750 time=100000000.000000000 uid=100 gid=200 uname=user gname=group type=fifo
+./file mode=100644 time=100000000.000000000 uid=100 gid=200 uname=user gname=group type=file size=0
+./hardlink mode=100644 time=100000000.000000000 uid=100 gid=200 uname=user gname=group type=hardlink linkto=./file size=0
+./aaaaaaaaaaaaaaaaaaaaaaaaaaaaa mode=40755 time=100000000.000000000 uid=100 gid=200 uname=user gname=group type=dir
+./aaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbb mode=40755 time=100000000.000000000 uid=100 gid=200 uname=user gname=group type=dir
+./aaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ccccccccccccccccccccccccccccc mode=40755 time=100000000.000000000 uid=100 gid=200 uname=user gname=group type=dir
+./aaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ccccccccccccccccccccccccccccc/ddddddddddddddddddddddddddddd mode=40755 time=100000000.000000000 uid=100 gid=200 uname=user gname=group type=dir
+./aaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ccccccccccccccccccccccccccccc/ddddddddddddddddddddddddddddd/eeeeeeeeeeeeeeeeeeeeeeeeeeeee mode=40755 time=100000000.000000000 uid=100 gid=200 uname=user gname=group type=dir
+./aaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ccccccccccccccccccccccccccccc/ddddddddddddddddddddddddddddd/eeeeeeeeeeeeeeeeeeeeeeeeeeeee/ffffffffffffffffffffff mode=40755 time=100000000.000000000 uid=100 gid=200 uname=user gname=group type=dir
+./aaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ccccccccccccccccccccccccccccc/ddddddddddddddddddddddddddddd/eeeeeeeeeeeeeeeeeeeeeeeeeeeee/ffffffffffffffffffffff/long mode=100644 time=100000000.000000000 uid=100 gid=200 uname=user gname=group type=file size=0
+./directory mode=40755 time=100000000.000000000 uid=100 gid=200 uname=user gname=group type=dir
+./symlink-a mode=120777 time=100000000.000000000 uid=100 gid=200 uname=user gname=group type=symlink linkto=file size=0
+./symlink-b mode=120777 time=100000000.000000000 uid=100 gid=200 uname=user gname=group type=symlink linkto=hardlink size=0
+./symlink-c mode=120777 time=100000000.000000000 uid=100 gid=200 uname=user gname=group type=symlink linkto=dangling size=0
+./symlink-long mode=120777 time=100000000.000000000 uid=100 gid=200 uname=user gname=group type=symlink linkto=aaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ccccccccccccccccccccccccccccc/ddddddddddddddddddddddddddddd/eeeeeeeeeeeeeeeeeeeeeeeeeeeee/ffffffffffffffffffffff/long size=0
+TAR
+
+ make_path($tmpdir);
+
+ my $cwd = getcwd();
+
+ # Check generated tarballs.
+ foreach my $type (qw(v7 ustar oldgnu gnu)) {
+ my $dirtree = "$tmpdir/$type";
+ my @paths;
+
+ mkdir $dirtree;
+ chdir $dirtree;
+ tar_create_tree($type);
+ find({ no_chdir => 1, wanted => sub {
+ return if $type eq 'v7' and length > 99;
+ return if $type eq 'v7' and -l and length readlink > 99;
+ return if $type eq 'v7' and not (-f or -l or -d);
+ return if $type eq 'ustar' and length > 256;
+ return if $type eq 'ustar' and -l and length readlink > 100;
+ push @paths, $_;
+ },
+ preprocess => sub { my (@files) = sort @_; @files } }, '.');
+ chdir $cwd;
+
+ my $paths_list = join "\0", @paths;
+ spawn(exec => [ $Dpkg::PROGTAR, '-cf', "$dirtree.tar",
+ '--format', $type,
+ '-C', $dirtree, '--mtime=@100000000',
+ '--owner=user:100', '--group=group:200',
+ '--null', '--no-unquote', '--no-recursion', '-T-' ],
+ wait_child => 1, from_string => \$paths_list);
+
+ my $expected = $expected_tar;
+ $expected =~ s/[ug]name=[^ ]+ //g if $type eq 'v7';
+ $expected =~ s/\n^.*fifo.*$//mg if $type eq 'v7';
+ $expected =~ s/\n^.*dddd.*$//mg if $type eq 'v7';
+ $expected =~ s/\n^.*symlink-long.*$//mg if $type eq 'ustar';
+
+ spawn(exec => [ './c-tarextract', "$dirtree.tar" ],
+ nocheck => 1, to_string => \$stdout, to_error => \$stderr);
+ ok($? == 0, "tar extractor $type should succeed");
+ is($stderr, undef, "tar extractor $type stderr is empty");
+ is($stdout, $expected, "tar extractor $type is ok");
+ }
+}
+
+test_tar_extractor();
diff --git a/lib/dpkg/t/t-test-skip.c b/lib/dpkg/t/t-test-skip.c
new file mode 100644
index 0000000..972cdf1
--- /dev/null
+++ b/lib/dpkg/t/t-test-skip.c
@@ -0,0 +1,31 @@
+/*
+ * libdpkg - Debian packaging suite library routines
+ * t-test-skip.c - test suite self tests, skip all
+ *
+ * Copyright © 2014 Guillem Jover <guillem@debian.org>
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <compat.h>
+
+#include <dpkg/test.h>
+
+TEST_ENTRY(test)
+{
+ test_skip_all("ignore all tests");
+
+ test_fail(1);
+}
diff --git a/lib/dpkg/t/t-test.c b/lib/dpkg/t/t-test.c
new file mode 100644
index 0000000..48ce872
--- /dev/null
+++ b/lib/dpkg/t/t-test.c
@@ -0,0 +1,66 @@
+/*
+ * libdpkg - Debian packaging suite library routines
+ * t-test.c - test suite self tests
+ *
+ * Copyright © 2009, 2014 Guillem Jover <guillem@debian.org>
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <compat.h>
+
+#include <dpkg/test.h>
+
+TEST_ENTRY(test)
+{
+ test_plan(22);
+
+ test_pass(1);
+ test_fail(0);
+
+ test_skip("ignore test");
+
+ test_skip_block(1) {
+ test_pass(0);
+ test_pass(1);
+ }
+
+ test_todo(0, "unimplemented test", "failing test");
+
+ test_todo_block("unimplemented block") {
+ test_pass(0);
+ test_fail(1);
+ }
+
+ test_str("aaa", ==, "aaa");
+ test_str("aaa", <, "bbb");
+ test_str("ccc", >, "bbb");
+ test_str("ccc", !=, "bbb");
+
+ test_mem("aaa", ==, "aaa", 3);
+ test_mem("aaa", <, "bbb", 3);
+ test_mem("ccc", >, "bbb", 3);
+ test_mem("ccc", !=, "bbb", 3);
+
+ test_mem("abcd", ==, "abcd", 4);
+ test_mem("abcd", ==, "abcd", 5);
+ test_mem("ababcd", ==, "ababff", 4);
+ test_mem("ababcd", !=, "ababff", 6);
+
+ setenv("srcdir", "aaa", 1);
+ setenv("builddir", "bbb", 1);
+ test_str(test_get_srcdir(), ==, "aaa");
+ test_str(test_get_builddir(), ==, "bbb");
+}
diff --git a/lib/dpkg/t/t-treewalk.t b/lib/dpkg/t/t-treewalk.t
new file mode 100755
index 0000000..6f379c8
--- /dev/null
+++ b/lib/dpkg/t/t-treewalk.t
@@ -0,0 +1,160 @@
+#!/usr/bin/perl
+#
+# Copyright © 2016 Guillem Jover <guillem@debian.org>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+use strict;
+use warnings;
+use version;
+
+use Test::More tests => 6;
+use Cwd;
+use File::Path qw(make_path remove_tree);
+use File::Temp qw(tempdir);
+use File::Basename;
+use File::Find;
+
+use Dpkg::IPC;
+
+my $srcdir = $ENV{srcdir} || '.';
+my $builddir = $ENV{builddir} || '.';
+my $tmpdir = 't.tmp/t-treewalk';
+
+# Set a known umask.
+umask 0022;
+
+sub make_file {
+ my ($pathname) = @_;
+
+ open my $fh, '>>', $pathname or die "cannot touch $pathname: $!";
+ close $fh;
+}
+
+# Populate the tree hierarchy.
+sub make_tree {
+ my ($dirtree) = @_;
+ my $cwd = getcwd();
+
+ make_path($dirtree);
+ chdir $dirtree;
+
+ # Deep tree.
+ make_path('aaaa/aaaa/aaaa/aaaa/');
+ make_file('aaaa/aaaa/aaaa/aaaa/abcde');
+ make_file('aaaa/aaaa/aaaa/aaaa/ddddd');
+ make_file('aaaa/aaaa/aaaa/aaaa/wwwwa');
+ make_file('aaaa/aaaa/aaaa/aaaa/wwwwz');
+ make_file('aaaa/aaaa/aaaa/aaaa/zzzzz');
+
+ # Shallow tree.
+ make_path('bbbb/');
+ make_file('bbbb/abcde');
+ make_file('bbbb/ddddd');
+ make_file('bbbb/wwwwa');
+ make_file('bbbb/wwwwz');
+ make_file('bbbb/zzzzz');
+
+ # Populated tree.
+ make_path('cccc/aa/aa/aa/');
+ make_path('cccc/aa/aa/bb/aa/');
+ make_file('cccc/aa/aa/bb/aa/file-a');
+ make_file('cccc/aa/aa/bb/aa/file-z');
+ make_path('cccc/aa/bb/');
+ make_path('cccc/bb/aa/');
+ make_path('cccc/bb/bb/aa/aa/');
+ make_file('cccc/bb/bb/aa/aa/file-a');
+ make_file('cccc/bb/bb/aa/aa/file-z');
+ make_path('cccc/bb/bb/bb/');
+ make_file('cccc/bb/bb/bb/file-w');
+ make_path('cccc/cc/aa/');
+ make_path('cccc/cc/bb/aa/');
+ make_file('cccc/cc/bb/aa/file-t');
+ make_path('cccc/cc/bb/bb/');
+ make_file('cccc/cc/bb/bb/file-x');
+ make_path('cccc/cc/cc/');
+ make_path('cccc/dd/aa/aa/aa/');
+ make_file('cccc/dd/aa/aa/aa/file-y');
+ make_path('cccc/dd/aa/aa/bb/');
+ make_file('cccc/dd/aa/aa/bb/file-o');
+ make_path('cccc/dd/aa/bb/aa/');
+ make_file('cccc/dd/aa/bb/aa/file-k');
+ make_path('cccc/dd/aa/bb/bb/');
+ make_file('cccc/dd/aa/bb/bb/file-l');
+ make_path('cccc/dd/aa/cc/aa/');
+ make_file('cccc/dd/aa/cc/aa/file-s');
+ make_path('cccc/dd/aa/cc/bb/');
+ make_file('cccc/dd/aa/cc/bb/file-u');
+
+ # Tree with symlinks cycles.
+ make_path('llll/self/');
+ make_file('llll/file');
+ symlink '..', 'llll/self/loop';
+ make_path('llll/real/');
+ make_file('llll/real/file-r');
+ symlink '../virt', 'llll/real/loop';
+ make_path('llll/virt/');
+ make_file('llll/virt/file-v');
+ symlink '../real', 'llll/virt/loop';
+
+ chdir $cwd;
+}
+
+sub test_treewalker {
+ my $stdout;
+ my $stderr;
+ my $dirtree = $tmpdir;
+
+ # Check generated tarballs.
+ foreach my $type (qw(full skip)) {
+ my @paths;
+
+ make_tree($dirtree);
+
+ find({ no_chdir => 1, wanted => sub {
+ return if $type eq 'skip' and m{^\Q$dirtree\E/cccc};
+ push @paths, s{\./}{}r;
+ },
+ }, $dirtree);
+
+ my $expected;
+
+ foreach my $path (sort @paths) {
+ lstat $path;
+
+ my $ptype;
+ if (-f _) {
+ $ptype = 'f';
+ } elsif (-l _) {
+ $ptype = 'l';
+ } elsif (-d _) {
+ $ptype = 'd';
+ }
+ my $pname = basename($path);
+ my $pvirt = $path =~ s{\Q$dirtree\E/?}{}r;
+
+ $expected .= "T=$ptype N=$pname V=$pvirt R=$path\n";
+ }
+
+ $ENV{TREEWALK_SKIP} = $type eq 'skip' ? "$dirtree/cccc" : undef;
+
+ spawn(exec => [ './c-treewalk', $dirtree ],
+ nocheck => 1, to_string => \$stdout, to_error => \$stderr);
+ ok($? == 0, "tree walker $type should succeed");
+ is($stderr, undef, "tree walker $type stderr is empty");
+ is($stdout, $expected, "tree walker $type is ok");
+ }
+}
+
+test_treewalker();
diff --git a/lib/dpkg/t/t-trigdeferred.t b/lib/dpkg/t/t-trigdeferred.t
new file mode 100755
index 0000000..21da412
--- /dev/null
+++ b/lib/dpkg/t/t-trigdeferred.t
@@ -0,0 +1,123 @@
+#!/usr/bin/perl
+#
+# Copyright © 2016 Guillem Jover <guillem@debian.org>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+use strict;
+use warnings;
+use version;
+
+use Test::More;
+use Cwd;
+use File::Path qw(make_path remove_tree);
+use File::Temp qw(tempdir);
+use File::Basename;
+use File::Find;
+
+use Dpkg::IPC;
+
+my $srcdir = $ENV{srcdir} || '.';
+my $builddir = $ENV{builddir} || '.';
+my $tmpdir = 't.tmp/t-trigdeferred';
+
+my @deferred = (
+ {
+ exitcode => 0,
+ original => <<'TEXT',
+
+ # Comment
+ # Another Comment
+ /root/pathname/file-trigger pkg-a pkg-b pkg-c
+named-trigger pkg-1 pkg-2 pkg-3
+parse-trigger pkg:a pkg+b pkg.0 0-pkg
+:other-trigger -
+TEXT
+ expected => <<'TEXT',
+<T='/root/pathname/file-trigger' P='pkg-a' P='pkg-b' P='pkg-c' E>
+<T='named-trigger' P='pkg-1' P='pkg-2' P='pkg-3' E>
+<T='parse-trigger' P='pkg:a' P='pkg+b' P='pkg.0' P='0-pkg' E>
+<T=':other-trigger' P='-' E>
+TEXT
+ }, {
+ exitcode => 2,
+ original => <<"TEXT",
+\b # invalid character
+TEXT
+ }, {
+ exitcode => 2,
+ original => <<'TEXT',
+trigger -pkg
+TEXT
+ }, {
+ exitcode => 2,
+ original => <<'TEXT',
+trigger +pkg
+TEXT
+ }, {
+ exitcode => 2,
+ original => <<'TEXT',
+trigger .pkg
+TEXT
+ }, {
+ exitcode => 2,
+ original => <<'TEXT',
+trigger :pkg
+TEXT
+ }, {
+ exitcode => 2,
+ original => 'missing newline',
+ }
+);
+
+plan tests => scalar(@deferred) * 3;
+
+# Set a known umask.
+umask 0022;
+
+sub make_file {
+ my ($pathname, $text) = @_;
+
+ open my $fh, '>', $pathname or die "cannot touch $pathname: $!";
+ print { $fh } $text;
+ close $fh;
+}
+
+sub test_trigdeferred {
+ my $stdout;
+ my $stderr;
+ my $admindir = "$tmpdir";
+
+ # Check triggers deferred file parsing.
+ make_path("$admindir/triggers");
+
+ foreach my $test (@deferred) {
+ make_file("$admindir/triggers/Unincorp", $test->{original});
+
+ spawn(exec => [ './c-trigdeferred', $admindir ],
+ nocheck => 1, to_string => \$stdout, error_to_string => \$stderr);
+ my $exitcode = $? >> 8;
+
+ is($exitcode, $test->{exitcode}, 'trigger deferred expected exitcode');
+ if ($test->{exitcode} == 0) {
+ is($stderr, '', 'trigger deferred expected stderr');
+ is($stdout, $test->{expected}, 'trigger deferred expected stdout');
+ } else {
+ isnt($stderr, '', 'trigger deferred expected stderr');
+ isnt($stdout, undef, 'trigger deferred expected stdout');
+ }
+ }
+}
+
+test_trigdeferred();
diff --git a/lib/dpkg/t/t-trigger.c b/lib/dpkg/t/t-trigger.c
new file mode 100644
index 0000000..af78f23
--- /dev/null
+++ b/lib/dpkg/t/t-trigger.c
@@ -0,0 +1,49 @@
+/*
+ * libdpkg - Debian packaging suite library routines
+ * t-trigger.c - test triggers
+ *
+ * Copyright © 2012 Guillem Jover <guillem@debian.org>
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <compat.h>
+
+#include <dpkg/test.h>
+#include <dpkg/triglib.h>
+
+static void
+test_trig_name_is_illegal(void)
+{
+ /* Test invalid trigger names. */
+ test_fail(trig_name_is_illegal("") == NULL);
+ test_fail(trig_name_is_illegal("\a") == NULL);
+ test_fail(trig_name_is_illegal("\t") == NULL);
+ test_fail(trig_name_is_illegal("\200") == NULL);
+ test_fail(trig_name_is_illegal("trigger name") == NULL);
+
+ /* Test valid trigger names. */
+ test_pass(trig_name_is_illegal("TRIGGER") == NULL);
+ test_pass(trig_name_is_illegal("trigger") == NULL);
+ test_pass(trig_name_is_illegal("0123456789") == NULL);
+ test_pass(trig_name_is_illegal("/file/trigger") == NULL);
+}
+
+TEST_ENTRY(test)
+{
+ test_plan(9);
+
+ test_trig_name_is_illegal();
+}
diff --git a/lib/dpkg/t/t-varbuf.c b/lib/dpkg/t/t-varbuf.c
new file mode 100644
index 0000000..0dbdf4b
--- /dev/null
+++ b/lib/dpkg/t/t-varbuf.c
@@ -0,0 +1,414 @@
+/*
+ * libdpkg - Debian packaging suite library routines
+ * t-varbuf.c - test varbuf implementation
+ *
+ * Copyright © 2009-2011, 2013-2015 Guillem Jover <guillem@debian.org>
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <compat.h>
+
+#include <dpkg/test.h>
+#include <dpkg/varbuf.h>
+
+#include <string.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+static void
+test_varbuf_init(void)
+{
+ struct varbuf vb;
+
+ varbuf_init(&vb, 0);
+ test_pass(vb.used == 0);
+ test_pass(vb.size == 0);
+ test_pass(vb.buf == NULL);
+
+ varbuf_destroy(&vb);
+ test_pass(vb.used == 0);
+ test_pass(vb.size == 0);
+ test_pass(vb.buf == NULL);
+}
+
+static void
+test_varbuf_prealloc(void)
+{
+ struct varbuf vb;
+
+ varbuf_init(&vb, 10);
+ test_pass(vb.used == 0);
+ test_pass(vb.size >= 10);
+ test_pass(vb.buf != NULL);
+
+ varbuf_destroy(&vb);
+ test_pass(vb.used == 0);
+ test_pass(vb.size == 0);
+ test_pass(vb.buf == NULL);
+}
+
+static void
+test_varbuf_new(void)
+{
+ struct varbuf *vb;
+
+ vb = varbuf_new(0);
+ test_pass(vb != NULL);
+ test_pass(vb->used == 0);
+ test_pass(vb->size == 0);
+ test_pass(vb->buf == NULL);
+ varbuf_free(vb);
+
+ vb = varbuf_new(10);
+ test_pass(vb != NULL);
+ test_pass(vb->used == 0);
+ test_pass(vb->size >= 10);
+ test_pass(vb->buf != NULL);
+ varbuf_free(vb);
+}
+
+static void
+test_varbuf_grow(void)
+{
+ struct varbuf vb;
+ jmp_buf grow_jump;
+ size_t old_size;
+ bool grow_overflow;
+ int i;
+
+ varbuf_init(&vb, 10);
+
+ /* Test that we grow when needed. */
+ varbuf_grow(&vb, 100);
+ test_pass(vb.used == 0);
+ test_pass(vb.size >= 100);
+
+ old_size = vb.size;
+
+ /* Test that we are not leaking. */
+ for (i = 0; i < 10; i++) {
+ varbuf_grow(&vb, 100);
+ test_pass(vb.used == 0);
+ test_pass(vb.size >= 100);
+ test_pass(vb.size == old_size);
+ }
+
+ /* Test that we grow when needed, with used space. */
+ vb.used = 10;
+ varbuf_grow(&vb, 100);
+ test_pass(vb.used == 10);
+ test_pass(vb.size >= 110);
+
+ /* Test that we do not allow allocation overflows. */
+ grow_overflow = false;
+ old_size = vb.size;
+ test_try(grow_jump) {
+ varbuf_grow(&vb, SIZE_MAX - vb.size + 2);
+ } test_catch {
+ grow_overflow = true;
+ } test_finally;
+ test_pass(vb.size == old_size && grow_overflow);
+
+ grow_overflow = false;
+ old_size = vb.size;
+ test_try(grow_jump) {
+ varbuf_grow(&vb, (SIZE_MAX - vb.size - 2) / 2);
+ } test_catch {
+ grow_overflow = true;
+ } test_finally;
+ test_pass(vb.size == old_size && grow_overflow);
+
+ varbuf_destroy(&vb);
+}
+
+static void
+test_varbuf_trunc(void)
+{
+ struct varbuf vb;
+
+ varbuf_init(&vb, 50);
+
+ /* Test that we truncate (grow). */
+ varbuf_trunc(&vb, 20);
+ test_pass(vb.used == 20);
+ test_pass(vb.size >= 50);
+
+ /* Test that we truncate (shrink). */
+ varbuf_trunc(&vb, 10);
+ test_pass(vb.used == 10);
+ test_pass(vb.size >= 50);
+
+ varbuf_destroy(&vb);
+}
+
+static void
+test_varbuf_add_buf(void)
+{
+ struct varbuf vb;
+
+ varbuf_init(&vb, 5);
+
+ varbuf_add_buf(&vb, "1234567890", 10);
+ test_pass(vb.used == 10);
+ test_pass(vb.size >= vb.used);
+ test_mem(vb.buf, ==, "1234567890", 10);
+
+ varbuf_add_buf(&vb, "abcde", 5);
+ test_pass(vb.used == 15);
+ test_pass(vb.size >= vb.used);
+ test_mem(vb.buf, ==, "1234567890abcde", 15);
+
+ varbuf_destroy(&vb);
+}
+
+static void
+test_varbuf_add_char(void)
+{
+ struct varbuf vb;
+
+ varbuf_init(&vb, 1);
+
+ varbuf_add_char(&vb, 'a');
+ test_pass(vb.used == 1);
+ test_pass(vb.size >= vb.used);
+ test_pass(vb.buf[0] == 'a');
+
+ varbuf_add_char(&vb, 'b');
+ test_pass(vb.used == 2);
+ test_pass(vb.size >= vb.used);
+ test_mem(vb.buf, ==, "ab", 2);
+
+ varbuf_add_char(&vb, 'c');
+ test_pass(vb.used == 3);
+ test_pass(vb.size >= vb.used);
+ test_mem(vb.buf, ==, "abc", 3);
+
+ varbuf_add_char(&vb, 'd');
+ test_pass(vb.used == 4);
+ test_pass(vb.size >= vb.used);
+ test_mem(vb.buf, ==, "abcd", 4);
+
+ varbuf_destroy(&vb);
+}
+
+static void
+test_varbuf_dup_char(void)
+{
+ struct varbuf vb;
+
+ varbuf_init(&vb, 5);
+
+ varbuf_dup_char(&vb, 'z', 10);
+ test_pass(vb.used == 10);
+ test_pass(vb.size >= vb.used);
+ test_mem(vb.buf, ==, "zzzzzzzzzz", 10);
+
+ varbuf_dup_char(&vb, 'y', 5);
+ test_pass(vb.used == 15);
+ test_pass(vb.size >= vb.used);
+ test_mem(vb.buf, ==, "zzzzzzzzzzyyyyy", 15);
+
+ varbuf_destroy(&vb);
+}
+
+static void
+test_varbuf_map_char(void)
+{
+ struct varbuf vb;
+
+ varbuf_init(&vb, 5);
+
+ varbuf_add_buf(&vb, "1234a5678a9012a", 15);
+
+ varbuf_map_char(&vb, 'a', 'z');
+ test_pass(vb.used == 15);
+ test_pass(vb.size >= vb.used);
+ test_mem(vb.buf, ==, "1234z5678z9012z", 15);
+
+ varbuf_destroy(&vb);
+}
+
+static void
+test_varbuf_end_str(void)
+{
+ struct varbuf vb;
+
+ varbuf_init(&vb, 10);
+
+ varbuf_add_buf(&vb, "1234567890X", 11);
+ test_pass(vb.used == 11);
+ test_pass(vb.size >= vb.used);
+ test_mem(vb.buf, ==, "1234567890X", 11);
+
+ varbuf_trunc(&vb, 10);
+
+ varbuf_end_str(&vb);
+ test_pass(vb.used == 10);
+ test_pass(vb.size >= vb.used + 1);
+ test_pass(vb.buf[10] == '\0');
+ test_str(vb.buf, ==, "1234567890");
+
+ varbuf_destroy(&vb);
+}
+
+static void
+test_varbuf_get_str(void)
+{
+ struct varbuf vb;
+ const char *str;
+
+ varbuf_init(&vb, 10);
+
+ varbuf_add_buf(&vb, "1234567890", 10);
+ str = varbuf_get_str(&vb);
+ test_pass(vb.buf == str);
+ test_pass(vb.used == 10);
+ test_pass(vb.buf[vb.used] == '\0');
+ test_pass(str[vb.used] == '\0');
+ test_str(vb.buf, ==, "1234567890");
+ test_str(str, ==, "1234567890");
+
+ varbuf_add_buf(&vb, "abcde", 5);
+ str = varbuf_get_str(&vb);
+ test_pass(vb.buf == str);
+ test_pass(vb.used == 15);
+ test_pass(vb.buf[vb.used] == '\0');
+ test_pass(str[vb.used] == '\0');
+ test_str(vb.buf, ==, "1234567890abcde");
+ test_str(str, ==, "1234567890abcde");
+
+ varbuf_destroy(&vb);
+}
+
+static void
+test_varbuf_printf(void)
+{
+ struct varbuf vb;
+
+ varbuf_init(&vb, 5);
+
+ /* Test normal format printing. */
+ varbuf_printf(&vb, "format %s number %d", "string", 10);
+ test_pass(vb.used == strlen("format string number 10"));
+ test_pass(vb.size >= vb.used);
+ test_str(vb.buf, ==, "format string number 10");
+
+ varbuf_reset(&vb);
+
+ /* Test concatenated format printing. */
+ varbuf_printf(&vb, "format %s number %d", "string", 10);
+ varbuf_printf(&vb, " extra %s", "string");
+ test_pass(vb.used == strlen("format string number 10 extra string"));
+ test_pass(vb.size >= vb.used);
+ test_str(vb.buf, ==, "format string number 10 extra string");
+
+ varbuf_destroy(&vb);
+}
+
+static void
+test_varbuf_reset(void)
+{
+ struct varbuf vb;
+
+ varbuf_init(&vb, 10);
+
+ varbuf_add_buf(&vb, "1234567890", 10);
+
+ varbuf_reset(&vb);
+ test_pass(vb.used == 0);
+ test_pass(vb.size >= vb.used);
+
+ varbuf_add_buf(&vb, "abcdefghijklmno", 15);
+ test_pass(vb.used == 15);
+ test_pass(vb.size >= vb.used);
+ test_mem(vb.buf, ==, "abcdefghijklmno", 15);
+
+ varbuf_destroy(&vb);
+}
+
+static void
+test_varbuf_snapshot(void)
+{
+ struct varbuf vb;
+ struct varbuf_state vbs;
+
+ varbuf_init(&vb, 0);
+
+ test_pass(vb.used == 0);
+ varbuf_snapshot(&vb, &vbs);
+ test_pass(vb.used == 0);
+ test_pass(vb.used == vbs.used);
+
+ varbuf_add_buf(&vb, "1234567890", 10);
+ test_pass(vb.used == 10);
+ varbuf_rollback(&vb, &vbs);
+ test_pass(vb.used == 0);
+
+ varbuf_add_buf(&vb, "1234567890", 10);
+ test_pass(vb.used == 10);
+ varbuf_snapshot(&vb, &vbs);
+ test_pass(vb.used == 10);
+
+ varbuf_add_buf(&vb, "1234567890", 10);
+ test_pass(vb.used == 20);
+ varbuf_rollback(&vb, &vbs);
+ test_pass(vb.used == 10);
+
+ varbuf_destroy(&vb);
+}
+
+static void
+test_varbuf_detach(void)
+{
+ struct varbuf vb;
+ char *str;
+
+ varbuf_init(&vb, 0);
+
+ varbuf_add_buf(&vb, "1234567890", 10);
+
+ str = varbuf_detach(&vb);
+
+ test_mem(str, ==, "1234567890", 10);
+ test_pass(vb.used == 0);
+ test_pass(vb.size == 0);
+ test_pass(vb.buf == NULL);
+
+ free(str);
+}
+
+TEST_ENTRY(test)
+{
+ test_plan(130);
+
+ test_varbuf_init();
+ test_varbuf_prealloc();
+ test_varbuf_new();
+ test_varbuf_grow();
+ test_varbuf_trunc();
+ test_varbuf_add_buf();
+ test_varbuf_add_char();
+ test_varbuf_dup_char();
+ test_varbuf_map_char();
+ test_varbuf_end_str();
+ test_varbuf_get_str();
+ test_varbuf_printf();
+ test_varbuf_reset();
+ test_varbuf_snapshot();
+ test_varbuf_detach();
+
+ /* FIXME: Complete. */
+}
diff --git a/lib/dpkg/t/t-version.c b/lib/dpkg/t/t-version.c
new file mode 100644
index 0000000..719ab96
--- /dev/null
+++ b/lib/dpkg/t/t-version.c
@@ -0,0 +1,308 @@
+/*
+ * libdpkg - Debian packaging suite library routines
+ * t-version.c - test version handling
+ *
+ * Copyright © 2009-2014 Guillem Jover <guillem@debian.org>
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <compat.h>
+
+#include <stdlib.h>
+
+#include <dpkg/test.h>
+#include <dpkg/dpkg.h>
+#include <dpkg/dpkg-db.h>
+
+static void
+test_version_blank(void)
+{
+ struct dpkg_version a;
+
+ dpkg_version_blank(&a);
+ test_pass(a.epoch == 0);
+ test_pass(a.version == NULL);
+ test_pass(a.revision == NULL);
+}
+
+static void
+test_version_is_informative(void)
+{
+ struct dpkg_version a;
+
+ dpkg_version_blank(&a);
+ test_fail(dpkg_version_is_informative(&a));
+
+ a.epoch = 1;
+ test_pass(dpkg_version_is_informative(&a));
+
+ dpkg_version_blank(&a);
+ a.version = "1";
+ test_pass(dpkg_version_is_informative(&a));
+
+ dpkg_version_blank(&a);
+ a.revision = "1";
+ test_pass(dpkg_version_is_informative(&a));
+}
+
+static void
+test_version_compare(void)
+{
+ struct dpkg_version a, b;
+
+ dpkg_version_blank(&a);
+ dpkg_version_blank(&b);
+ test_pass(dpkg_version_compare(&a, &b) == 0);
+
+ a.epoch = 1;
+ b.epoch = 2;
+ test_fail(dpkg_version_compare(&a, &b) == 0);
+
+ a = DPKG_VERSION_OBJECT(0, "1", "1");
+ b = DPKG_VERSION_OBJECT(0, "2", "1");
+ test_fail(dpkg_version_compare(&a, &b) == 0);
+
+ a = DPKG_VERSION_OBJECT(0, "1", "1");
+ b = DPKG_VERSION_OBJECT(0, "1", "2");
+ test_fail(dpkg_version_compare(&a, &b) == 0);
+
+ /* Test for version equality. */
+ a = b = DPKG_VERSION_OBJECT(0, "0", "0");
+ test_pass(dpkg_version_compare(&a, &b) == 0);
+
+ a = DPKG_VERSION_OBJECT(0, "0", "00");
+ b = DPKG_VERSION_OBJECT(0, "00", "0");
+ test_pass(dpkg_version_compare(&a, &b) == 0);
+
+ a = b = DPKG_VERSION_OBJECT(1, "2", "3");
+ test_pass(dpkg_version_compare(&a, &b) == 0);
+
+ /* Test for epoch difference. */
+ a = DPKG_VERSION_OBJECT(0, "0", "0");
+ b = DPKG_VERSION_OBJECT(1, "0", "0");
+ test_pass(dpkg_version_compare(&a, &b) < 0);
+ test_pass(dpkg_version_compare(&b, &a) > 0);
+
+ /* Test for version component difference. */
+ a = DPKG_VERSION_OBJECT(0, "a", "0");
+ b = DPKG_VERSION_OBJECT(0, "b", "0");
+ test_pass(dpkg_version_compare(&a, &b) < 0);
+ test_pass(dpkg_version_compare(&b, &a) > 0);
+
+ /* Test for revision component difference. */
+ a = DPKG_VERSION_OBJECT(0, "0", "a");
+ b = DPKG_VERSION_OBJECT(0, "0", "b");
+ test_pass(dpkg_version_compare(&a, &b) < 0);
+ test_pass(dpkg_version_compare(&b, &a) > 0);
+
+ /* FIXME: Complete. */
+}
+
+static void
+test_version_relate(void)
+{
+ struct dpkg_version a, b;
+
+ dpkg_version_blank(&a);
+ dpkg_version_blank(&b);
+ test_pass(dpkg_version_relate(&a, DPKG_RELATION_NONE, &b));
+
+ a = DPKG_VERSION_OBJECT(0, "1", "1");
+ b = DPKG_VERSION_OBJECT(0, "1", "1");
+ test_pass(dpkg_version_relate(&a, DPKG_RELATION_EQ, &b));
+ test_fail(dpkg_version_relate(&a, DPKG_RELATION_LT, &b));
+ test_pass(dpkg_version_relate(&a, DPKG_RELATION_LE, &b));
+ test_fail(dpkg_version_relate(&a, DPKG_RELATION_GT, &b));
+ test_pass(dpkg_version_relate(&a, DPKG_RELATION_GE, &b));
+
+ a = DPKG_VERSION_OBJECT(0, "1", "1");
+ b = DPKG_VERSION_OBJECT(0, "2", "1");
+ test_fail(dpkg_version_relate(&a, DPKG_RELATION_EQ, &b));
+ test_pass(dpkg_version_relate(&a, DPKG_RELATION_LT, &b));
+ test_pass(dpkg_version_relate(&a, DPKG_RELATION_LE, &b));
+ test_fail(dpkg_version_relate(&a, DPKG_RELATION_GT, &b));
+ test_fail(dpkg_version_relate(&a, DPKG_RELATION_GE, &b));
+
+ a = DPKG_VERSION_OBJECT(0, "2", "1");
+ b = DPKG_VERSION_OBJECT(0, "1", "1");
+ test_fail(dpkg_version_relate(&a, DPKG_RELATION_EQ, &b));
+ test_fail(dpkg_version_relate(&a, DPKG_RELATION_LT, &b));
+ test_fail(dpkg_version_relate(&a, DPKG_RELATION_LE, &b));
+ test_pass(dpkg_version_relate(&a, DPKG_RELATION_GT, &b));
+ test_pass(dpkg_version_relate(&a, DPKG_RELATION_GE, &b));
+}
+
+static void
+test_version_parse(void)
+{
+ struct dpkg_error err;
+ struct dpkg_version a, b;
+ const char *p;
+ char *verstr;
+
+ /* Test 0 versions. */
+ dpkg_version_blank(&a);
+ b = DPKG_VERSION_OBJECT(0, "0", "");
+
+ test_pass(parseversion(&a, "0", NULL) == 0);
+ test_pass(dpkg_version_compare(&a, &b) == 0);
+
+ test_pass(parseversion(&a, "0:0", NULL) == 0);
+ test_pass(dpkg_version_compare(&a, &b) == 0);
+
+ b = DPKG_VERSION_OBJECT(0, "0", "0");
+ test_pass(parseversion(&a, "0:0-0", NULL) == 0);
+ test_pass(dpkg_version_compare(&a, &b) == 0);
+
+ b = DPKG_VERSION_OBJECT(0, "0.0", "0.0");
+ test_pass(parseversion(&a, "0:0.0-0.0", NULL) == 0);
+ test_pass(dpkg_version_compare(&a, &b) == 0);
+
+ /* Test epoched versions. */
+ b = DPKG_VERSION_OBJECT(1, "0", "");
+ test_pass(parseversion(&a, "1:0", NULL) == 0);
+ test_pass(dpkg_version_compare(&a, &b) == 0);
+
+ b = DPKG_VERSION_OBJECT(5, "1", "");
+ test_pass(parseversion(&a, "5:1", NULL) == 0);
+ test_pass(dpkg_version_compare(&a, &b) == 0);
+
+ /* Test multiple hyphens. */
+ b = DPKG_VERSION_OBJECT(0, "0-0", "0");
+ test_pass(parseversion(&a, "0:0-0-0", NULL) == 0);
+ test_pass(dpkg_version_compare(&a, &b) == 0);
+
+ b = DPKG_VERSION_OBJECT(0, "0-0-0", "0");
+ test_pass(parseversion(&a, "0:0-0-0-0", NULL) == 0);
+ test_pass(dpkg_version_compare(&a, &b) == 0);
+
+ /* Test multiple colons. */
+ b = DPKG_VERSION_OBJECT(0, "0:0", "0");
+ test_pass(parseversion(&a, "0:0:0-0", NULL) == 0);
+ test_pass(dpkg_version_compare(&a, &b) == 0);
+
+ b = DPKG_VERSION_OBJECT(0, "0:0:0", "0");
+ test_pass(parseversion(&a, "0:0:0:0-0", NULL) == 0);
+ test_pass(dpkg_version_compare(&a, &b) == 0);
+
+ /* Test multiple hyphens and colons. */
+ b = DPKG_VERSION_OBJECT(0, "0:0-0", "0");
+ test_pass(parseversion(&a, "0:0:0-0-0", NULL) == 0);
+ test_pass(dpkg_version_compare(&a, &b) == 0);
+
+ b = DPKG_VERSION_OBJECT(0, "0-0:0", "0");
+ test_pass(parseversion(&a, "0:0-0:0-0", NULL) == 0);
+ test_pass(dpkg_version_compare(&a, &b) == 0);
+
+ /* Test valid characters in upstream version. */
+ b = DPKG_VERSION_OBJECT(0, "09azAZ.-+~:", "0");
+ test_pass(parseversion(&a, "0:09azAZ.-+~:-0", NULL) == 0);
+ test_pass(dpkg_version_compare(&a, &b) == 0);
+
+ /* Test valid characters in revision. */
+ b = DPKG_VERSION_OBJECT(0, "0", "azAZ09.+~");
+ test_pass(parseversion(&a, "0:0-azAZ09.+~", NULL) == 0);
+ test_pass(dpkg_version_compare(&a, &b) == 0);
+
+ /* Test version with leading and trailing spaces. */
+ b = DPKG_VERSION_OBJECT(0, "0", "1");
+ test_pass(parseversion(&a, " 0:0-1", &err) == 0);
+ test_pass(dpkg_version_compare(&a, &b) == 0);
+ test_pass(parseversion(&a, "0:0-1 ", &err) == 0);
+ test_pass(dpkg_version_compare(&a, &b) == 0);
+ test_pass(parseversion(&a, " 0:0-1 ", &err) == 0);
+ test_pass(dpkg_version_compare(&a, &b) == 0);
+
+ /* Test empty version. */
+ test_pass(parseversion(&a, "", &err) != 0);
+ test_error(err);
+ test_pass(parseversion(&a, " ", &err) != 0);
+ test_error(err);
+
+ /* Test empty upstream version after epoch. */
+ test_fail(parseversion(&a, "0:", &err) == 0);
+ test_error(err);
+
+ /* Test empty epoch in version. */
+ test_fail(parseversion(&a, ":1.0", &err) == 0);
+ test_error(err);
+
+ /* Test empty revision in version. */
+ test_fail(parseversion(&a, "1.0-", &err) == 0);
+ test_error(err);
+
+ /* Test version with embedded spaces. */
+ test_fail(parseversion(&a, "0:0 0-1", &err) == 0);
+ test_error(err);
+
+ /* Test version with negative epoch. */
+ test_fail(parseversion(&a, "-1:0-1", &err) == 0);
+ test_error(err);
+
+ /* Test version with huge epoch. */
+ test_fail(parseversion(&a, "999999999999999999999999:0-1", &err) == 0);
+ test_error(err);
+
+ /* Test invalid characters in epoch. */
+ test_fail(parseversion(&a, "a:0-0", &err) == 0);
+ test_error(err);
+ test_fail(parseversion(&a, "A:0-0", &err) == 0);
+ test_error(err);
+
+ /* Test invalid empty upstream version. */
+ test_fail(parseversion(&a, "-0", &err) == 0);
+ test_error(err);
+ test_fail(parseversion(&a, "0:-0", &err) == 0);
+ test_error(err);
+
+ /* Test upstream version not starting with a digit */
+ test_fail(parseversion(&a, "0:abc3-0", &err) == 0);
+ test_warn(err);
+
+ /* Test invalid characters in upstream version. */
+ verstr = test_alloc(strdup("0:0a-0"));
+ for (p = "!#@$%&/|\\<>()[]{};,_=*^'"; *p; p++) {
+ verstr[3] = *p;
+ test_fail(parseversion(&a, verstr, &err) == 0);
+ test_warn(err);
+ }
+ free(verstr);
+
+ /* Test invalid characters in revision. */
+ test_fail(parseversion(&a, "0:0-0:0", &err) == 0);
+ test_warn(err);
+
+ verstr = test_alloc(strdup("0:0-0"));
+ for (p = "!#@$%&/|\\<>()[]{}:;,_=*^'"; *p; p++) {
+ verstr[4] = *p;
+ test_fail(parseversion(&a, verstr, &err) == 0);
+ test_warn(err);
+ }
+ free(verstr);
+
+ /* FIXME: Complete. */
+}
+
+TEST_ENTRY(test)
+{
+ test_plan(196);
+
+ test_version_blank();
+ test_version_is_informative();
+ test_version_compare();
+ test_version_relate();
+ test_version_parse();
+}