Compare commits

..

13 Commits

Author SHA1 Message Date
Ariadne Conill 20db9ffcbe cli: if --exists is specified, require the full dependency graph to validate 2023-01-22 10:46:27 +00:00
Ariadne Conill 5436648cd4 pkgconf 1.8.1. 2023-01-22 10:02:10 +00:00
Ariadne Conill 66046df940 libpkgconf 1.8.1 2023-01-22 10:01:42 +00:00
Ariadne Conill 81e1785db2 add NEWS for 1.8.1 2023-01-22 10:01:23 +00:00
wi24rd 2b850d2648 Update sum value of types of property. 2023-01-22 09:59:37 +00:00
Eli Schwartz c87a6c2ec1 meson: remove useless command that isn't needed
The tests/*.sh are executable in the source tree, and don't need to be
chmodded after being copied to the build tree.
2023-01-22 09:58:55 +00:00
Doug Freed 1f282295ff doc: update libpkgconf-pkg docs to match 2023-01-22 09:57:45 +00:00
Ariadne Conill e3957c6155 tests: fix test regressions caused by tilde changes 2023-01-22 09:57:39 +00:00
Doug Freed f58d54e77b pkg: make pkgconf_compare_version consistent
The code taken from rpmvercmp in pkg-config returns -1 if a is less than
b, 0 if a is equal to b, and 1 if a is greater than b. This matches the
expectations of the comparison operators that use this function.
However, the tilde handling, the NULL handling, and the docstring all do
the opposite.

This fixes the tilde handling, the NULL handling, and the docstring to
match the behavior of the rpmvercmp code and the expectations of the
comparison operators.
2023-01-22 09:57:34 +00:00
Timo Röhling 2837bbcc4c Ignore whitespace indentation
Fixes #265
2023-01-22 09:57:29 +00:00
Ariadne Conill 0b5f360bce tests: add regression test for billion-laughs 2023-01-22 09:57:08 +00:00
Ariadne Conill 81cc9b3e6d tuple: test for, and stop string processing, on truncation
otherwise a buffer overflow occurs.
this has been a bug in pkgconf since the beginning, it seems.
instead of disclosing the bug correctly, a "hotshot" developer
decided to blog about it instead.  sigh.

https://nullprogram.com/blog/2023/01/18/
2023-01-22 09:55:45 +00:00
Ariadne Conill 4b0264de8b add billion-laughs test fixture 2023-01-22 09:53:49 +00:00
71 changed files with 1296 additions and 3755 deletions

View File

@ -35,13 +35,13 @@ jobs:
# the code assumes msvc style printf atm # the code assumes msvc style printf atm
export CFLAGS=-D__USE_MINGW_ANSI_STDIO=0 export CFLAGS=-D__USE_MINGW_ANSI_STDIO=0
meson -Dtests=disabled _build meson -Dtests=false _build
meson compile -C _build meson compile -C _build
debian-meson: debian-meson:
runs-on: ubuntu-latest runs-on: ubuntu-latest
container: container:
image: debian:testing image: debian:bullseye
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v2 uses: actions/checkout@v2
@ -53,41 +53,17 @@ jobs:
- name: Build - name: Build
run: | run: |
meson _build -Dwerror=true meson _build
meson compile -C _build meson compile -C _build
- name: Run tests - name: Run tests
run: | run: |
meson test -v -C _build meson test -v -C _build
debian-meson-asan:
runs-on: ubuntu-latest
container:
image: debian:testing
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Update system and add dependencies
run: |
apt-get update
apt-get install -y kyua atf-sh build-essential meson
- name: Build
run: |
meson _build -Db_sanitize=address
meson compile -C _build
- name: Run tests
run: |
meson test -v -C _build
env:
ASAN_OPTIONS: "exitcode=7"
debian-autotools: debian-autotools:
runs-on: ubuntu-latest runs-on: ubuntu-latest
container: container:
image: debian:testing image: debian:bullseye
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v2 uses: actions/checkout@v2
@ -122,7 +98,7 @@ jobs:
- name: Build - name: Build
run: | run: |
meson _build -Dwerror=true meson _build
meson compile -C _build meson compile -C _build
- name: Run tests - name: Run tests

49
.gitignore vendored
View File

@ -1,19 +1,13 @@
Makefile
Makefile.in
.dirstamp
stamp-h*
*.h.in~ *.h.in~
*.o *.o
*.og *.og
*.op *.op
*.lo
*.gcno *.gcno
*.gcda *.gcda
*.gcov *.gcov
core core
.gdb_history .gdb_history
.libs
.deps .deps
*.exe *.exe
@ -22,8 +16,8 @@ core
*.orig *.orig
*.patch *.patch
*.rej *.rej
/tests/run.sh
# autoconf stuff
/aclocal.m4 /aclocal.m4
/autom4te.cache/ /autom4te.cache/
/buildsys.mk /buildsys.mk
@ -32,47 +26,8 @@ core
/config.log /config.log
/config.status /config.status
/configure /configure
/compile
/config.guess
/config.sub
/depcomp
/install-sh
/missing
# programs
/bomtool
/pkgconf /pkgconf
/pkgconf-gcov /pkgconf-gcov
/pkgconf-profile /pkgconf-profile
# libtool Makefile
/libtool
/ltmain.sh
/libpkgconf.la
/m4/libtool.m4
/m4/lt~obsolete.m4
/m4/ltoptions.m4
/m4/ltsugar.m4
/m4/ltversion.m4
# pkgconfig file
/libpkgconf.pc
# autoheader
/libpkgconf/config.h
/libpkgconf/config.h.in
# tests
/Kyuafile
/tests/Kyuafile
/tests/basic
/tests/builtins
/tests/conflicts
/tests/framework
/tests/parser
/tests/provides
/tests/regress
/tests/requires
/tests/sysroot
/tests/test_env.sh
/tests/version

View File

@ -1,75 +0,0 @@
pipeline:
debian-meson:
image: debian:testing
commands:
- apt-get update
- apt-get install -y kyua atf-sh build-essential meson
- meson _build -Dwerror=true
- meson compile -C _build
- meson test -v -C _build
when:
matrix:
IMAGE: debian
BUILD: meson
debian-meson-asan:
image: debian:testing
environment:
- ASAN_OPTIONS="exitcode=7"
commands:
- apt-get update
- apt-get install -y kyua atf-sh build-essential meson
- meson _build -Db_sanitize=address
- meson compile -C _build
- meson test -v -C _build
when:
matrix:
IMAGE: debian
BUILD: meson
debian-autotools:
image: debian:testing
commands:
- apt-get update
- apt-get install -y kyua atf-sh build-essential autoconf libtool
- ./autogen.sh
- ./configure
- make -j
- make distcheck
when:
matrix:
IMAGE: debian
BUILD: autotools
alpine-meson:
image: alpine
commands:
- apk add -U --no-cache kyua atf build-base meson
- meson _build -Dwerror=true
- meson compile -C _build
- meson test -v -C _build
when:
matrix:
IMAGE: alpine
BUILD: meson
alpine-autotools:
image: alpine
commands:
- apk add -U --no-cache kyua atf build-base autoconf automake libtool xz gzip
- ./autogen.sh
- ./configure
- make -j
- make distcheck
when:
matrix:
IMAGE: alpine
BUILD: autotools
matrix:
IMAGE:
- debian
- alpine
BUILD:
- meson
- autotools

View File

@ -9,10 +9,9 @@ personality_dir = @PERSONALITY_PATH@
pkgconfigdir = $(libdir)/pkgconfig pkgconfigdir = $(libdir)/pkgconfig
nodist_pkgconfig_DATA = libpkgconf.pc nodist_pkgconfig_DATA = libpkgconf.pc
ACLOCAL_AMFLAGS = -I m4
AM_CFLAGS = -DPERSONALITY_PATH=\"$(personality_dir)\" -DPKG_DEFAULT_PATH=\"$(pkg_default_dir)\" -DSYSTEM_INCLUDEDIR=\"$(system_includedir)\" -DSYSTEM_LIBDIR=\"$(system_libdir)\" AM_CFLAGS = -DPERSONALITY_PATH=\"$(personality_dir)\" -DPKG_DEFAULT_PATH=\"$(pkg_default_dir)\" -DSYSTEM_INCLUDEDIR=\"$(system_includedir)\" -DSYSTEM_LIBDIR=\"$(system_libdir)\"
bin_PROGRAMS = pkgconf bomtool bin_PROGRAMS = pkgconf
lib_LTLIBRARIES = libpkgconf.la lib_LTLIBRARIES = libpkgconf.la
EXTRA_DIST = pkg.m4 \ EXTRA_DIST = pkg.m4 \
@ -28,8 +27,6 @@ EXTRA_DIST = pkg.m4 \
tests/lib1/paren-quoting.pc \ tests/lib1/paren-quoting.pc \
tests/lib1/argv-parse-3.pc \ tests/lib1/argv-parse-3.pc \
tests/lib1/foo.pc \ tests/lib1/foo.pc \
tests/lib1/foobar.pc \
tests/lib1/unavailable-provider.pc \
tests/lib1/prefix-foo1.pc \ tests/lib1/prefix-foo1.pc \
tests/lib1/argv-parse.pc \ tests/lib1/argv-parse.pc \
tests/lib1/framework-1.pc \ tests/lib1/framework-1.pc \
@ -65,7 +62,6 @@ EXTRA_DIST = pkg.m4 \
tests/lib3/bar.pc \ tests/lib3/bar.pc \
tests/lib1/conflicts.pc \ tests/lib1/conflicts.pc \
tests/lib1/omg-uninstalled.pc \ tests/lib1/omg-uninstalled.pc \
tests/lib1/omg-sysroot-uninstalled.pc \
tests/lib1/isystem.pc \ tests/lib1/isystem.pc \
tests/lib1/idirafter.pc \ tests/lib1/idirafter.pc \
tests/lib1/idirafter-ordering.pc \ tests/lib1/idirafter-ordering.pc \
@ -93,10 +89,6 @@ EXTRA_DIST = pkg.m4 \
tests/lib1/malformed-1.pc \ tests/lib1/malformed-1.pc \
tests/lib1/malformed-quoting.pc \ tests/lib1/malformed-quoting.pc \
tests/lib1/malformed-version.pc \ tests/lib1/malformed-version.pc \
tests/lib1/metapackage.pc \
tests/lib1/metapackage-1.pc \
tests/lib1/metapackage-2.pc \
tests/lib1/metapackage-3.pc \
tests/lib1/explicit-sysroot.pc \ tests/lib1/explicit-sysroot.pc \
tests/lib1/escaped-backslash.pc \ tests/lib1/escaped-backslash.pc \
tests/lib1/cflags-internal.pc \ tests/lib1/cflags-internal.pc \
@ -107,11 +99,6 @@ EXTRA_DIST = pkg.m4 \
tests/lib1/tuple-quoting.pc \ tests/lib1/tuple-quoting.pc \
tests/lib1/empty-tuple.pc \ tests/lib1/empty-tuple.pc \
tests/lib1/orphaned-requires-private.pc \ tests/lib1/orphaned-requires-private.pc \
tests/lib1/sysroot-dir-2.pc \
tests/lib1/sysroot-dir-3.pc \
tests/lib1/sysroot-dir-4.pc \
tests/lib1/sysroot-dir-5.pc \
tests/lib1/child-prefix/pkgconfig/child-prefix-1.pc \
$(test_scripts) \ $(test_scripts) \
doc/conf.py \ doc/conf.py \
doc/extract.py \ doc/extract.py \
@ -140,8 +127,7 @@ test_scripts= tests/meson.build \
tests/sysroot.sh \ tests/sysroot.sh \
tests/version.sh tests/version.sh
test_sh = $(filter-out tests/meson.build, $(test_scripts)) check_SCRIPTS= $(test_scripts:.sh=)
check_SCRIPTS = $(test_sh:.sh=)
SUFFIXES= .sh SUFFIXES= .sh
@ -161,7 +147,7 @@ libpkgconf_la_SOURCES = \
libpkgconf/path.c \ libpkgconf/path.c \
libpkgconf/personality.c \ libpkgconf/personality.c \
libpkgconf/parser.c libpkgconf/parser.c
libpkgconf_la_LDFLAGS = -no-undefined -version-info 5:0:0 -export-symbols-regex '^pkgconf_' libpkgconf_la_LDFLAGS = -no-undefined -version-info 3:0:0 -export-symbols-regex '^pkgconf_'
dist_man_MANS = \ dist_man_MANS = \
man/pkgconf.1 \ man/pkgconf.1 \
@ -174,17 +160,11 @@ pkgconf_SOURCES = \
cli/main.c \ cli/main.c \
cli/getopt_long.c \ cli/getopt_long.c \
cli/renderer-msvc.c cli/renderer-msvc.c
pkgconf_CPPFLAGS = -I$(top_srcdir)/libpkgconf -I$(top_srcdir)/cli pkgconf_CPPFLAGS = -Ilibpkgconf -Icli
noinst_HEADERS = \ noinst_HEADERS = \
cli/getopt_long.h \ cli/getopt_long.h \
cli/renderer-msvc.h cli/renderer-msvc.h
bomtool_LDADD = libpkgconf.la
bomtool_SOURCES = \
cli/bomtool/main.c \
cli/getopt_long.c
bomtool_CPPFLAGS = -I$(top_srcdir)/libpkgconf -I$(top_srcdir)/cli -I$(top_srcdir)/cli/bomtool
dist_doc_DATA = README.md AUTHORS dist_doc_DATA = README.md AUTHORS
m4datadir = $(datadir)/aclocal m4datadir = $(datadir)/aclocal

View File

@ -39,7 +39,7 @@ all: pkgconf-lite
libpkgconf/config.h: libpkgconf/config.h:
@echo '#define PACKAGE_NAME "pkgconf-lite"' >> $@ @echo '#define PACKAGE_NAME "pkgconf-lite"' >> $@
@echo '#define PACKAGE_BUGREPORT "https://git.dereferenced.org/pkgconf/pkgconf/issues"' >> $@ @echo '#define PACKAGE_BUGREPORT "https://git.dereferenced.org/pkgconf/pkgconf/issues"' >> $@
@echo '#define PACKAGE_VERSION "2.3.0"' >> $@ @echo '#define PACKAGE_VERSION "1.6.2"' >> $@
@echo '#define PACKAGE PACKAGE_NAME " " PACKAGE_VERSION' >> $@ @echo '#define PACKAGE PACKAGE_NAME " " PACKAGE_VERSION' >> $@
@echo '#define HAVE_STRLCPY' >> $@ @echo '#define HAVE_STRLCPY' >> $@
@echo '#define HAVE_STRLCAT' >> $@ @echo '#define HAVE_STRLCAT' >> $@

250
NEWS
View File

@ -1,262 +1,14 @@
Changes from previous version of pkgconf Changes from previous version of pkgconf
======================================== ========================================
Changes from 2.2.0 to 2.3.0: Changes from 1.8.0 to 1.8.1:
----------------------------
* Fix compile with Meson on Solaris by defining __EXTENSIONS__.
* Add support for the PKG_CONFIG_RELOCATE_PATHS environmental variable.
When set, the program will act as if --define-prefix is always enabled.
* Color solution nodes that were part of the original query, and use
that coloring to skip over dependencies when generating DocumentNames
in bomtool.
* Enhance --env option to support variables with both --variable=varname
and --print-variables.
* Add --exists-cflags option which creates synthetic preprocessor
definition flags for every queried dependency when found.
* Document that Requires.private is always used for header paths.
Patch by Petr Písař.
* Fix minor documentation typos.
Patch by Pierce.
* Ensure string comparisons using <ctype.h> functions are done with
unsigned bytes to avoid undefined behavior.
Patch by Taylor R Campbell.
* Fix parsing edge-case bugs with dependency versions.
Patch by Kai Pastor.
* Change PKG_PROG_PKG_CONFIG autoconf macro to add a customizable
failure handler if pkg-config is not found.
Patch by Ismael Luceno.
Changes from 2.1.1 to 2.2.0:
----------------------------
* libpkgconf SOVERSION is now 5.
* Significant solver rework to flatten both requires and requires.private
dependencies in a single pass. Improves performance slightly and ensures
proper dependency order.
Patches by Kai Pastor.
* Improve `--digraph` output to reflect more of the solver's state in the
rendered dependency graph.
Patches by Kai Pastor.
* Do not reference the graph root by name when presenting error messages about
directly requested dependency nodes.
Patch by Kai Pastor.
Changes from 2.1.0 to 2.1.1:
----------------------------
* Documentation fixes from Sam James and Stefan Weil.
* Fix --modversion with constraints.
Patch by Kai Pastor.
* Reintroduce an optimization to the dependency graph walker which avoids
revisiting already visited nodes.
Patch by Yi Chou with some modifications.
* Add a regression test to check that the dependency flattener is working
as expected.
Patch by Kai Pastor.
Changes from 2.0.3 to 2.1.0:
----------------------------
* Do not flatten the solver solution into the original world used as
input to the solver.
Patches by Kai Pastor.
* Fix warnings with GCC 14 -Walloc-size.
Patch by Sam James.
* Add --solution to the pkgconf CLI to dump the solver state.
* Improve the --digraph output to clarify cancelled edges in a given
solution.
* Demote requires dependencies to requires.private when a parent
dependency is pulled in via requires.private.
* Trim trailing whitespace when processing package arguments.
Patch by Colin Gillespie.
* Avoid strncmp() in --modversion version comparison.
Patch by Colin Gillespie.
* Update autoconf compile flag checking macro.
Patch by Peter Kokot.
* Add system default path configuration to Meson.
Patch by L. E. Segovia.
* Fix order of PKG_CONFIG_LIBDIR and PKG_CONFIG_PATH element processing.
Changes from 2.0.2 to 2.0.3:
----------------------------
* Fix some edge-cases with the new `--modversion` implementation
and add additional regression tests.
Patch by Colin Gillespie.
* Fix some format specifiers to use PRIu64 in debug tracing.
Changes from 2.0.1 to 2.0.2:
----------------------------
* Fix long-standing bug where package identifiers for "uninstalled"
packages incorrectly included the "-uninstalled" suffix.
This was exposed by the recent change to `--modversion` in 2.0.1.
Changes from 2.0.0 to 2.0.1:
----------------------------
* The behavior of --modversion was largely reverted back to the traditional
pkg-config behavior, but still operates on a solved dependency graph.
The order of --modversion output is based on the dependency resolution
queue which is passed to the solver, which itself generally maps to the
order of the constrants provided on the command line.
* A new flag, --verbose, has been added. When used with `--modversion`, it
is possible to disambiguate which version belongs to which module:
% pkgconf --modversion --verbose foo bar
foo: 1.2.3
bar: 1.3
Changes from 1.9.5 to 2.0.0:
----------------------------
* When flattening the dependency graph, retain the latest seen edges
rather than the earliest.
* Fix a long-standing bug where the dependency resolution queue was
evaluated in reverse. This bug masked the aforementioned dependency
flattening bug in many cases.
* Fix handling of --with-path, which was appending paths to the search
list rather than prepending them as intended.
* Error when --modversion is requested with more than one package, as
the output is ambiguous.
Changes from 1.9.4 to 1.9.5:
----------------------------
* Fix incorrect assumptions involving the use of ctype(3) functions.
Patch by Taylor R Campbell.
* Fix detection of provided functions on autoconf.
Patches by Harmen Stoppels.
* Fix deletion of tests/meson.build by the autoconf build system.
Patch by h30032433.
* Fix quoting rules in argvsplit.c.
Patch by huyubiao.
* Update libpkgconf documentation and documentation building scripts.
Patches by Andrew Shadura.
* Enforce maximum package count correctly for --modversion.
Changes from 1.9.3 to 1.9.4:
---------------------------- ----------------------------
* Fix a buffer overflow vulnerability involving very large variable expansions. * Fix a buffer overflow vulnerability involving very large variable expansions.
CVE-2023-24056 CVE-2023-24056
* Fix a bunch of minor regressions with the solver.
* Create separate solutions for `--cflags` and `--libs` when `--static` is not
used.
* Remove final trailing whitespace in pkgconf_fragment_render_buf().
* Revert broken pkg.m4 change involving querying module versions in
PKG_CHECK_MODULES.
* Fix handling of tildes in version strings. * Fix handling of tildes in version strings.
* Various C99 formatting string fixes involving SIZE_FMT_SPECIFIER.
Changes from 1.9.2 to 1.9.3:
----------------------------
* Fix a bunch of minor code issues pointed out using Clang static analyzer.
* New API: pkgconf_solution_free(), which frees a compiled solution graph.
* Fix behavior when overriding global variables with `--define-variable`.
Changes from 1.9.1 to 1.9.2:
----------------------------
* Do not try to break dependency cycles across dependency lists. This causes
the solved graph to sometimes miss required dependency nodes because the
solver detected an incorrect dependency cycle.
* New API: pkgconf_queue_solve(), which replaces pkgconf_queue_apply().
pkgconf_queue_apply is now deprecated and should not be used in new code.
Changes from 1.9.0 to 1.9.1:
----------------------------
* Skip graph flattening and traversal for query types which only make sense
for a single pkg-config module.
The old solver walked these graphs with --maximum-traverse-depth=1 in
these cases, but this is no longer helpful because the graph is flattened
by the new solver.
Changes from 1.8.0 to 1.9.0:
----------------------------
* pkgconf 1.9.0 is the first testing release in the pkgconf 2.0 development
series. While it is believed to be suitable for production, there may be
bugs due to the overall redesign of the solver and other initiatives.
Additionally, a future release of pkgconf plans will have additional ABI
breaks for the libpkgconf library before the pkgconf 2.0 release is cut.
* There is now a new solver that is designed to provide higher performance
with complicated graphs, which works by flattening the dependency graph
into a smaller set of dependencies. This graph can then be evaluated
instead of the original dependency graph without having to visit every
edge in the graph.
NOTE: This solver, while providing significant performance improvements,
does so, at the cost of changed behavior for some edge cases (such as
circular dependencies).
* Bug fixes:
- Resolved several memory leaks with edge cases when using libpkgconf
directly.
- pkgconf CLI now consistently frees libpkgconf resources under all
circumstances.
- SYSROOT rules are no longer applied to `-uninstalled` packages by
default. Use `PKG_CONFIG_PKGCONF1_SYSROOT_RULES` for legacy behavior.
* A new `--license` selector has been added to the pkgconf CLI. This uses
SPDX expressions which can be set as the `License` field in `.pc` files.
See the `pc(5)` manpage for more information.
* The canonical location for pkgconf maintenance going forward is
<https://gitea.treehouse.systems/ariadne/pkgconf>. This is presently
mirrored to GitHub for user convenience, but that mirroring will
be terminated at some point (due to GitHub Copilot).
Changes from 1.7.4 to 1.8.0: Changes from 1.7.4 to 1.8.0:
---------------------------- ----------------------------

View File

@ -3,9 +3,9 @@
`pkgconf` is a program which helps to configure compiler and linker flags for `pkgconf` is a program which helps to configure compiler and linker flags for
development libraries. It is similar to pkg-config from freedesktop.org. development libraries. It is similar to pkg-config from freedesktop.org.
`libpkgconf` is a library which provides access to most of `pkgconf`'s functionality, `libpkgconf` is a library which provides access to most of `pkgconf`'s functionality, to allow
to allow other tooling such as compilers and IDEs to discover and use libraries other tooling such as compilers and IDEs to discover and use libraries configured by
configured by pkgconf. pkgconf.
## using `pkgconf` with autotools ## using `pkgconf` with autotools
@ -41,7 +41,7 @@ to improve this behaviour.
As of the 1.1 series, pkgconf also fully implements support for `Provides` rules, As of the 1.1 series, pkgconf also fully implements support for `Provides` rules,
while pkg-config does not. pkg-config only provides the `--print-provides` functionality while pkg-config does not. pkg-config only provides the `--print-provides` functionality
as a stub. There are other intentional implementation differences in pkgconf's dependency as a stub. There are other intentional implementation differences in pkgconf's dependency
resolver versus pkg-config's dependency resolver in terms of completeness and correctness, resolver verses pkg-config's dependency resolver in terms of completeness and correctness,
such as, for example, how `Conflicts` rules are processed. such as, for example, how `Conflicts` rules are processed.
## linker flags optimization ## linker flags optimization
@ -50,7 +50,7 @@ As previously mentioned, pkgconf makes optimizations to the linker flags in both
case of static and shared linking in order to avoid overlinking binaries and also case of static and shared linking in order to avoid overlinking binaries and also
simplifies the `CFLAGS` and `LIBS` output of the pkgconf tool for improved readability. simplifies the `CFLAGS` and `LIBS` output of the pkgconf tool for improved readability.
This functionality depends on the pkg-config module properly declaring its dependency This functionality depends on the pkg-config module properly declaring it's dependency
tree instead of using `Libs` and `Cflags` fields to directly link against other modules tree instead of using `Libs` and `Cflags` fields to directly link against other modules
which have pkg-config metadata files installed. which have pkg-config metadata files installed.
@ -71,25 +71,16 @@ do let us know, but also make sure that the .pc files are valid and follow the r
the [pkg-config tutorial][fd-tut], as most likely fixing them to follow the specified the [pkg-config tutorial][fd-tut], as most likely fixing them to follow the specified
rules will solve the problem. rules will solve the problem.
Additionally, **we do not consider pkgconf doing what you tell it to do, in cases for Additionally, **we do not consider pkgconf doing what you tell it to do, when pkg-config
which pkg-config fails to do so, to be a bug**. fails to do so, to be a bug**.
If, for example, you use environment variables such as `PKG_CONFIG_SYSTEM_[INCLUDE|LIBRARY]_PATH` If, for example, you use environment variables such as `PKG_CONFIG_SYSTEM_[INCLUDE|LIBRARY]_PATH`
and then find yourself surprised that `pkgconf` is stripping `-I` and `-L` flags relating and then find yourself surprised that `pkgconf` is stripping `-I` and `-L` flags relating
to those paths, it is not a `pkgconf` problem -- `pkgconf` is doing exactly what you told to those paths, it's not a `pkgconf` problem -- `pkgconf` is doing exactly what you told
it to do. it to do.
We will reject bugs like this, and if someone insists on fixing such a non-bug, this We will reject bugs like this, and if you choose to violate our [Code of Conduct](CODE_OF_CONDUCT.md)
constitutes a violation of our [Code of Conduct](CODE_OF_CONDUCT.md), which may be by demanding we fix your non-bug, we will fix the problem by banning you from the repo instead.
addressed by banning from this repository.
## debug output
Please use only the stable interfaces to query pkg-config. Do not screen-scrape the
output from `--debug`: this is sent to `stderr` for a reason, it is not intended to be
scraped. The `--debug` output is **not** a stable interface, and should **never** be
depended on as a source of information. If you need a stable interface to query pkg-config
which is not covered, please get in touch.
## compiling `pkgconf` and `libpkgconf` on UNIX ## compiling `pkgconf` and `libpkgconf` on UNIX
@ -112,16 +103,17 @@ flags like so:
$ make $ make
$ sudo make install $ sudo make install
## compiling `pkgconf` and `libpkgconf` with Meson (usually for Windows) ## compiling `pkgconf` and `libpkgconf` with CMake (usually for Windows)
pkgconf is compiled using CMake on Windows. In theory, you could also use CMake to build
on UNIX, but this is not recommended at this time as it pkgconf is typically built much earlier
than CMake.
pkgconf is compiled using [Meson](https://mesonbuild.com) on Windows. In theory, you could also use $ mkdir build
Meson to build on UNIX, but this is not recommended at this time as pkgconf is typically built $ cd build
much earlier than Meson. $ cmake ..
$ make
$ meson setup build -Dtests=disabled $ sudo make install
$ meson compile -C build
$ meson install -C build
There are a few defines such as SYSTEM_LIBDIR, PKGCONFIGDIR and SYSTEM_INCLUDEDIR. There are a few defines such as SYSTEM_LIBDIR, PKGCONFIGDIR and SYSTEM_INCLUDEDIR.
However, on Windows, the default PKGCONFIGDIR value is usually overridden at runtime based However, on Windows, the default PKGCONFIGDIR value is usually overridden at runtime based
@ -137,8 +129,8 @@ to make this determination themselves.
## release tarballs ## release tarballs
Release tarballs are available at <https://distfiles.ariadne.space/pkgconf/>. Release tarballs are available at <https://distfiles.dereferenced.org/pkgconf/>.
Please only use the tarballs from distfiles.ariadne.space. Please only use the tarballs from distfiles.dereferenced.org.
## contacts ## contacts

View File

@ -1,368 +0,0 @@
/*
* bomtool/main.c
* main() routine, printer functions
*
* Copyright (c) 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019
* pkgconf authors (see AUTHORS).
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* This software is provided 'as is' and without any warranty, express or
* implied. In no event shall the authors be liable for any damages arising
* from the use of this software.
*/
#include "libpkgconf/config.h"
#include <libpkgconf/stdinc.h>
#include <libpkgconf/libpkgconf.h>
#include "getopt_long.h"
#define PKG_VERSION (((uint64_t) 1) << 1)
#define PKG_ABOUT (((uint64_t) 1) << 2)
#define PKG_HELP (((uint64_t) 1) << 3)
static const char *spdx_version = "SPDX-2.2";
static const char *bom_license = "CC0-1.0";
static const char *document_ref = "SPDXRef-DOCUMENT";
static pkgconf_client_t pkg_client;
static uint64_t want_flags;
static size_t maximum_package_count = 0;
static int maximum_traverse_depth = 2000;
FILE *error_msgout = NULL;
static bool
error_handler(const char *msg, const pkgconf_client_t *client, void *data)
{
(void) client;
(void) data;
fprintf(error_msgout, "%s", msg);
return true;
}
static const char *
sbom_spdx_identity(pkgconf_pkg_t *pkg)
{
static char buf[PKGCONF_ITEM_SIZE];
snprintf(buf, sizeof buf, "%sC64%s", pkg->id, pkg->version);
return buf;
}
static const char *
sbom_name(pkgconf_pkg_t *world)
{
static char buf[PKGCONF_BUFSIZE];
pkgconf_node_t *node;
pkgconf_strlcpy(buf, "SBOM-SPDX", sizeof buf);
PKGCONF_FOREACH_LIST_ENTRY(world->required.head, node)
{
pkgconf_dependency_t *dep = node->data;
pkgconf_pkg_t *match = dep->match;
if ((dep->flags & PKGCONF_PKG_DEPF_QUERY) != PKGCONF_PKG_DEPF_QUERY)
continue;
if (!dep->match)
continue;
pkgconf_strlcat(buf, "-", sizeof buf);
pkgconf_strlcat(buf, sbom_spdx_identity(match), sizeof buf);
}
return buf;
}
static void
write_sbom_header(pkgconf_client_t *client, pkgconf_pkg_t *world)
{
(void) client;
(void) world;
printf("SPDXVersion: %s\n", spdx_version);
printf("DataLicense: %s\n", bom_license);
printf("SPDXID: %s\n", document_ref);
printf("DocumentName: %s\n", sbom_name(world));
printf("DocumentNamespace: https://spdx.org/spdxdocs/bomtool-%s\n", PACKAGE_VERSION);
printf("Creator: Tool: bomtool %s\n", PACKAGE_VERSION);
printf("\n\n");
}
static const char *
sbom_identity(pkgconf_pkg_t *pkg)
{
static char buf[PKGCONF_ITEM_SIZE];
snprintf(buf, sizeof buf, "%s@%s", pkg->id, pkg->version);
return buf;
}
static void
write_sbom_package(pkgconf_client_t *client, pkgconf_pkg_t *pkg, void *unused)
{
(void) client;
(void) unused;
if (pkg->flags & PKGCONF_PKG_PROPF_VIRTUAL)
return;
printf("##### Package: %s\n\n", sbom_identity(pkg));
printf("PackageName: %s\n", sbom_identity(pkg));
printf("SPDXID: SPDXRef-Package-%s\n", sbom_spdx_identity(pkg));
printf("PackageVersion: %s\n", pkg->version);
printf("PackageDownloadLocation: NOASSERTION\n");
printf("PackageVerificationCode: NOASSERTION\n");
/* XXX: What about projects? */
if (pkg->maintainer != NULL)
printf("PackageSupplier: Person: %s\n", pkg->maintainer);
if (pkg->url != NULL)
printf("PackageHomePage: %s\n", pkg->url);
printf("PackageLicenseDeclared: %s\n", pkg->license != NULL ? pkg->license : "NOASSERTION");
if (pkg->copyright != NULL)
printf("PackageCopyrightText: <text>%s</text>\n", pkg->copyright);
if (pkg->description != NULL)
printf("PackageSummary: <text>%s</text>\n", pkg->description);
printf("\n\n");
}
static void
write_sbom_relationships(pkgconf_client_t *client, pkgconf_pkg_t *pkg, void *unused)
{
(void) client;
(void) unused;
char baseref[PKGCONF_ITEM_SIZE];
pkgconf_node_t *node;
if (pkg->flags & PKGCONF_PKG_PROPF_VIRTUAL)
return;
snprintf(baseref, sizeof baseref, "SPDXRef-Package-%sC64%s", pkg->id, pkg->version);
PKGCONF_FOREACH_LIST_ENTRY(pkg->required.head, node)
{
pkgconf_dependency_t *dep = node->data;
pkgconf_pkg_t *match = dep->match;
if (!dep->match)
continue;
printf("Relationship: %s DEPENDS_ON SPDXRef-Package-%s\n", baseref, sbom_spdx_identity(match));
printf("Relationship: SPDXRef-Package-%s DEPENDENCY_OF %s\n", sbom_spdx_identity(match), baseref);
}
PKGCONF_FOREACH_LIST_ENTRY(pkg->requires_private.head, node)
{
pkgconf_dependency_t *dep = node->data;
pkgconf_pkg_t *match = dep->match;
if (!dep->match)
continue;
printf("Relationship: %s DEPENDS_ON SPDXRef-Package-%s\n", baseref, sbom_spdx_identity(match));
printf("Relationship: SPDXRef-Package-%s DEV_DEPENDENCY_OF %s\n", sbom_spdx_identity(match), baseref);
}
if (pkg->required.head != NULL || pkg->requires_private.head != NULL)
printf("\n\n");
}
static bool
generate_sbom_from_world(pkgconf_client_t *client, pkgconf_pkg_t *world)
{
int eflag;
pkgconf_node_t *node;
write_sbom_header(client, world);
eflag = pkgconf_pkg_traverse(client, world, write_sbom_package, NULL, maximum_traverse_depth, 0);
if (eflag != PKGCONF_PKG_ERRF_OK)
return false;
eflag = pkgconf_pkg_traverse(client, world, write_sbom_relationships, NULL, maximum_traverse_depth, 0);
if (eflag != PKGCONF_PKG_ERRF_OK)
return false;
PKGCONF_FOREACH_LIST_ENTRY(world->required.head, node)
{
pkgconf_dependency_t *dep = node->data;
pkgconf_pkg_t *match = dep->match;
if (!dep->match)
continue;
printf("Relationship: %s DESCRIBES SPDXRef-Package-%s\n", document_ref, sbom_spdx_identity(match));
}
return true;
}
static int
version(void)
{
printf("bomtool %s\n", PACKAGE_VERSION);
return EXIT_SUCCESS;
}
static int
about(void)
{
printf("bomtool (%s %s)\n", PACKAGE_NAME, PACKAGE_VERSION);
printf("Copyright (c) 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021\n");
printf(" pkgconf authors (see AUTHORS in documentation directory).\n\n");
printf("Permission to use, copy, modify, and/or distribute this software for any\n");
printf("purpose with or without fee is hereby granted, provided that the above\n");
printf("copyright notice and this permission notice appear in all copies.\n\n");
printf("This software is provided 'as is' and without any warranty, express or\n");
printf("implied. In no event shall the authors be liable for any damages arising\n");
printf("from the use of this software.\n\n");
printf("Report bugs at <%s>.\n", PACKAGE_BUGREPORT);
return EXIT_SUCCESS;
}
static int
usage(void)
{
printf("usage: bomtool [--flags] [modules]\n");
printf("\nbasic options:\n\n");
printf(" --help this message\n");
printf(" --about print bomtool version and license to stdout\n");
printf(" --version print bomtool version to stdout\n");
return EXIT_SUCCESS;
}
int
main(int argc, char *argv[])
{
int ret = EXIT_SUCCESS;
pkgconf_list_t pkgq = PKGCONF_LIST_INITIALIZER;
unsigned int want_client_flags = PKGCONF_PKG_PKGF_SEARCH_PRIVATE;
pkgconf_cross_personality_t *personality = pkgconf_cross_personality_default();
pkgconf_pkg_t world = {
.id = "virtual:world",
.realname = "virtual world package",
.flags = PKGCONF_PKG_PROPF_STATIC | PKGCONF_PKG_PROPF_VIRTUAL,
};
error_msgout = stderr;
struct pkg_option options[] = {
{ "version", no_argument, &want_flags, PKG_VERSION, },
{ "about", no_argument, &want_flags, PKG_ABOUT, },
{ "help", no_argument, &want_flags, PKG_HELP, },
{ NULL, 0, NULL, 0 }
};
while ((ret = pkg_getopt_long_only(argc, argv, "", options, NULL)) != -1)
{
switch (ret)
{
case '?':
case ':':
return EXIT_FAILURE;
default:
break;
}
}
pkgconf_client_init(&pkg_client, error_handler, NULL, personality);
/* we have determined what features we want most likely. in some cases, we override later. */
pkgconf_client_set_flags(&pkg_client, want_client_flags);
/* at this point, want_client_flags should be set, so build the dir list */
pkgconf_client_dir_list_build(&pkg_client, personality);
if ((want_flags & PKG_ABOUT) == PKG_ABOUT)
return about();
if ((want_flags & PKG_VERSION) == PKG_VERSION)
return version();
if ((want_flags & PKG_HELP) == PKG_HELP)
return usage();
while (1)
{
const char *package = argv[pkg_optind];
if (package == NULL)
break;
/* check if there is a limit to the number of packages allowed to be included, if so and we have hit
* the limit, stop adding packages to the queue.
*/
if (maximum_package_count > 0 && pkgq.length > maximum_package_count)
break;
while (isspace((unsigned char)package[0]))
package++;
/* skip empty packages */
if (package[0] == '\0') {
pkg_optind++;
continue;
}
if (argv[pkg_optind + 1] == NULL || !PKGCONF_IS_OPERATOR_CHAR(*(argv[pkg_optind + 1])))
{
pkgconf_queue_push(&pkgq, package);
pkg_optind++;
}
else
{
char packagebuf[PKGCONF_BUFSIZE];
snprintf(packagebuf, sizeof packagebuf, "%s %s %s", package, argv[pkg_optind + 1], argv[pkg_optind + 2]);
pkg_optind += 3;
pkgconf_queue_push(&pkgq, packagebuf);
}
}
if (pkgq.head == NULL)
{
fprintf(stderr, "Please specify at least one package name on the command line.\n");
ret = EXIT_FAILURE;
goto out;
}
ret = EXIT_SUCCESS;
if (!pkgconf_queue_solve(&pkg_client, &pkgq, &world, maximum_traverse_depth))
{
ret = EXIT_FAILURE;
goto out;
}
if (!generate_sbom_from_world(&pkg_client, &world))
{
ret = EXIT_FAILURE;
goto out;
}
out:
pkgconf_solution_free(&pkg_client, &world);
pkgconf_queue_free(&pkgq);
pkgconf_cross_personality_deinit(personality);
pkgconf_client_deinit(&pkg_client);
return ret;
}

View File

@ -70,15 +70,11 @@
#define PKG_INTERNAL_CFLAGS (((uint64_t) 1) << 42) #define PKG_INTERNAL_CFLAGS (((uint64_t) 1) << 42)
#define PKG_DUMP_PERSONALITY (((uint64_t) 1) << 43) #define PKG_DUMP_PERSONALITY (((uint64_t) 1) << 43)
#define PKG_SHARED (((uint64_t) 1) << 44) #define PKG_SHARED (((uint64_t) 1) << 44)
#define PKG_DUMP_LICENSE (((uint64_t) 1) << 45)
#define PKG_SOLUTION (((uint64_t) 1) << 46)
#define PKG_EXISTS_CFLAGS (((uint64_t) 1) << 47)
static pkgconf_client_t pkg_client; static pkgconf_client_t pkg_client;
static const pkgconf_fragment_render_ops_t *want_render_ops = NULL; static const pkgconf_fragment_render_ops_t *want_render_ops = NULL;
static uint64_t want_flags; static uint64_t want_flags;
static int verbosity = 0;
static int maximum_traverse_depth = 2000; static int maximum_traverse_depth = 2000;
static size_t maximum_package_count = 0; static size_t maximum_package_count = 0;
@ -89,7 +85,7 @@ FILE *error_msgout = NULL;
FILE *logfile_out = NULL; FILE *logfile_out = NULL;
static bool static bool
error_handler(const char *msg, const pkgconf_client_t *client, void *data) error_handler(const char *msg, const pkgconf_client_t *client, const void *data)
{ {
(void) client; (void) client;
(void) data; (void) data;
@ -255,71 +251,32 @@ apply_provides(pkgconf_client_t *client, pkgconf_pkg_t *world, void *unused, int
#ifndef PKGCONF_LITE #ifndef PKGCONF_LITE
static void static void
print_digraph_node(pkgconf_client_t *client, pkgconf_pkg_t *pkg, void *data) print_digraph_node(pkgconf_client_t *client, pkgconf_pkg_t *pkg, void *unused)
{ {
pkgconf_node_t *node; pkgconf_node_t *node;
(void) client; (void) client;
pkgconf_pkg_t **last_seen = data; (void) unused;
if(pkg->flags & PKGCONF_PKG_PROPF_VIRTUAL)
return;
if (pkg->flags & PKGCONF_PKG_PROPF_VISITED_PRIVATE)
printf("\"%s\" [fontname=Sans fontsize=8 fontcolor=gray color=gray]\n", pkg->id);
else
printf("\"%s\" [fontname=Sans fontsize=8]\n", pkg->id); printf("\"%s\" [fontname=Sans fontsize=8]\n", pkg->id);
if (last_seen != NULL)
{
if (*last_seen != NULL)
printf("\"%s\" -> \"%s\" [fontname=Sans fontsize=8 color=red]\n", (*last_seen)->id, pkg->id);
*last_seen = pkg;
}
PKGCONF_FOREACH_LIST_ENTRY(pkg->required.head, node) PKGCONF_FOREACH_LIST_ENTRY(pkg->required.head, node)
{ {
pkgconf_dependency_t *dep = node->data; pkgconf_dependency_t *dep = node->data;
const char *dep_id = (dep->match != NULL) ? dep->match->id : dep->package;
if ((dep->flags & PKGCONF_PKG_DEPF_PRIVATE) == 0) printf("\"%s\" -- \"%s\" [fontname=Sans fontsize=8]\n", dep->package, pkg->id);
printf("\"%s\" -> \"%s\" [fontname=Sans fontsize=8]\n", pkg->id, dep_id);
else
printf("\"%s\" -> \"%s\" [fontname=Sans fontsize=8 color=gray]\n", pkg->id, dep_id);
}
PKGCONF_FOREACH_LIST_ENTRY(pkg->requires_private.head, node)
{
pkgconf_dependency_t *dep = node->data;
const char *dep_id = (dep->match != NULL) ? dep->match->id : dep->package;
printf("\"%s\" -> \"%s\" [fontname=Sans fontsize=8 color=gray]\n", pkg->id, dep_id);
} }
} }
static bool static bool
apply_digraph(pkgconf_client_t *client, pkgconf_pkg_t *world, void *data, int maxdepth) apply_digraph(pkgconf_client_t *client, pkgconf_pkg_t *world, void *unused, int maxdepth)
{ {
int eflag; int eflag;
pkgconf_list_t *list = data;
pkgconf_pkg_t *last_seen = NULL;
pkgconf_node_t *iter;
printf("digraph deptree {\n"); printf("graph deptree {\n");
printf("edge [color=blue len=7.5 fontname=Sans fontsize=8]\n"); printf("edge [color=blue len=7.5 fontname=Sans fontsize=8]\n");
printf("node [fontname=Sans fontsize=8]\n"); printf("node [fontname=Sans fontsize=8]\n");
printf("\"user:request\" [fontname=Sans fontsize=8]\n");
PKGCONF_FOREACH_LIST_ENTRY(list->head, iter) eflag = pkgconf_pkg_traverse(client, world, print_digraph_node, unused, maxdepth, 0);
{
pkgconf_queue_t *pkgq = iter->data;
pkgconf_pkg_t *pkg = pkgconf_pkg_find(client, pkgq->package);
printf("\"user:request\" -> \"%s\" [fontname=Sans fontsize=8]\n", pkg == NULL ? pkgq->package : pkg->id);
if (pkg != NULL)
pkgconf_pkg_unref(client, pkg);
}
eflag = pkgconf_pkg_traverse(client, world, print_digraph_node, &last_seen, maxdepth, 0);
if (eflag != PKGCONF_PKG_ERRF_OK) if (eflag != PKGCONF_PKG_ERRF_OK)
return false; return false;
@ -327,64 +284,25 @@ apply_digraph(pkgconf_client_t *client, pkgconf_pkg_t *world, void *data, int ma
printf("}\n"); printf("}\n");
return true; return true;
} }
static void
print_solution_node(pkgconf_client_t *client, pkgconf_pkg_t *pkg, void *unused)
{
(void) client;
(void) unused;
printf("%s (%"PRIu64")\n", pkg->id, pkg->identifier);
}
static bool
apply_print_solution(pkgconf_client_t *client, pkgconf_pkg_t *world, void *unused, int maxdepth)
{
int eflag;
eflag = pkgconf_pkg_traverse(client, world, print_solution_node, unused, maxdepth, 0);
return eflag == PKGCONF_PKG_ERRF_OK;
}
#endif #endif
static bool static bool
apply_modversion(pkgconf_client_t *client, pkgconf_pkg_t *world, void *data, int maxdepth) apply_modversion(pkgconf_client_t *client, pkgconf_pkg_t *world, void *unused, int maxdepth)
{ {
pkgconf_node_t *queue_iter; pkgconf_node_t *iter;
pkgconf_list_t *pkgq = data;
(void) client; (void) client;
(void) unused;
(void) maxdepth; (void) maxdepth;
PKGCONF_FOREACH_LIST_ENTRY(pkgq->head, queue_iter) PKGCONF_FOREACH_LIST_ENTRY(world->required.head, iter)
{ {
pkgconf_node_t *world_iter; pkgconf_dependency_t *dep = iter->data;
pkgconf_queue_t *queue_node = queue_iter->data;
PKGCONF_FOREACH_LIST_ENTRY(world->required.head, world_iter)
{
pkgconf_dependency_t *dep = world_iter->data;
pkgconf_pkg_t *pkg = dep->match; pkgconf_pkg_t *pkg = dep->match;
const size_t name_len = strlen(pkg->why); if (pkg->version != NULL)
if (name_len > strlen(queue_node->package) ||
strncmp(pkg->why, queue_node->package, name_len) ||
(queue_node->package[name_len] != 0 &&
!isspace((unsigned char)queue_node->package[name_len]) &&
!PKGCONF_IS_OPERATOR_CHAR(queue_node->package[name_len])))
continue;
if (pkg->version != NULL) {
if (verbosity)
printf("%s: ", pkg->id);
printf("%s\n", pkg->version); printf("%s\n", pkg->version);
} }
break;
}
}
return true; return true;
} }
@ -428,6 +346,16 @@ apply_path(pkgconf_client_t *client, pkgconf_pkg_t *world, void *unused, int max
return true; return true;
} }
static void
print_variable(pkgconf_client_t *client, pkgconf_pkg_t *pkg, const char *variable)
{
const char *var;
var = pkgconf_tuple_find(client, &pkg->vars, variable);
if (var != NULL)
printf("%s", var);
}
static bool static bool
apply_variable(pkgconf_client_t *client, pkgconf_pkg_t *world, void *variable, int maxdepth) apply_variable(pkgconf_client_t *client, pkgconf_pkg_t *world, void *variable, int maxdepth)
{ {
@ -438,12 +366,11 @@ apply_variable(pkgconf_client_t *client, pkgconf_pkg_t *world, void *variable, i
{ {
pkgconf_dependency_t *dep = iter->data; pkgconf_dependency_t *dep = iter->data;
pkgconf_pkg_t *pkg = dep->match; pkgconf_pkg_t *pkg = dep->match;
const char *var;
var = pkgconf_tuple_find(client, &pkg->vars, variable); if (iter->prev != NULL)
printf(" ");
if (var != NULL) print_variable(client, pkg, variable);
printf("%s%s", iter->prev != NULL ? " " : "", var);
} }
printf("\n"); printf("\n");
@ -454,8 +381,7 @@ apply_variable(pkgconf_client_t *client, pkgconf_pkg_t *world, void *variable, i
static bool static bool
apply_env_var(const char *prefix, pkgconf_client_t *client, pkgconf_pkg_t *world, int maxdepth, apply_env_var(const char *prefix, pkgconf_client_t *client, pkgconf_pkg_t *world, int maxdepth,
unsigned int (*collect_fn)(pkgconf_client_t *client, pkgconf_pkg_t *world, pkgconf_list_t *list, int maxdepth), unsigned int (*collect_fn)(pkgconf_client_t *client, pkgconf_pkg_t *world, pkgconf_list_t *list, int maxdepth),
bool (*filter_fn)(const pkgconf_client_t *client, const pkgconf_fragment_t *frag, void *data), bool (*filter_fn)(const pkgconf_client_t *client, const pkgconf_fragment_t *frag, void *data))
void (*postprocess_fn)(pkgconf_client_t *client, pkgconf_pkg_t *world, pkgconf_list_t *fragment_list))
{ {
pkgconf_list_t unfiltered_list = PKGCONF_LIST_INITIALIZER; pkgconf_list_t unfiltered_list = PKGCONF_LIST_INITIALIZER;
pkgconf_list_t filtered_list = PKGCONF_LIST_INITIALIZER; pkgconf_list_t filtered_list = PKGCONF_LIST_INITIALIZER;
@ -468,9 +394,6 @@ apply_env_var(const char *prefix, pkgconf_client_t *client, pkgconf_pkg_t *world
pkgconf_fragment_filter(client, &filtered_list, &unfiltered_list, filter_fn, NULL); pkgconf_fragment_filter(client, &filtered_list, &unfiltered_list, filter_fn, NULL);
if (postprocess_fn != NULL)
postprocess_fn(client, world, &filtered_list);
if (filtered_list.head == NULL) if (filtered_list.head == NULL)
goto out; goto out;
@ -485,94 +408,6 @@ out:
return true; return true;
} }
static void
maybe_add_module_definitions(pkgconf_client_t *client, pkgconf_pkg_t *world, pkgconf_list_t *fragment_list)
{
pkgconf_node_t *world_iter;
if ((want_flags & PKG_EXISTS_CFLAGS) != PKG_EXISTS_CFLAGS)
return;
PKGCONF_FOREACH_LIST_ENTRY(world->required.head, world_iter)
{
pkgconf_dependency_t *dep = world_iter->data;
char havebuf[PKGCONF_ITEM_SIZE];
char *p;
if ((dep->flags & PKGCONF_PKG_DEPF_QUERY) != PKGCONF_PKG_DEPF_QUERY)
continue;
if (dep->match == NULL)
continue;
snprintf(havebuf, sizeof havebuf, "HAVE_%s", dep->match->id);
for (p = havebuf; *p; p++)
{
switch (*p)
{
case ' ':
case '-':
*p = '_';
break;
default:
*p = toupper((unsigned char) *p);
}
}
pkgconf_fragment_insert(client, fragment_list, 'D', havebuf, false);
}
}
static void
apply_env_variables(pkgconf_client_t *client, pkgconf_pkg_t *world, const char *env_prefix)
{
(void) client;
pkgconf_node_t *world_iter;
PKGCONF_FOREACH_LIST_ENTRY(world->required.head, world_iter)
{
pkgconf_dependency_t *dep = world_iter->data;
pkgconf_pkg_t *pkg = dep->match;
pkgconf_node_t *tuple_iter;
if ((dep->flags & PKGCONF_PKG_DEPF_QUERY) != PKGCONF_PKG_DEPF_QUERY)
continue;
if (dep->match == NULL)
continue;
PKGCONF_FOREACH_LIST_ENTRY(pkg->vars.head, tuple_iter)
{
pkgconf_tuple_t *tuple = tuple_iter->data;
char havebuf[PKGCONF_ITEM_SIZE];
char *p;
if (want_variable != NULL && strcmp(want_variable, tuple->key))
continue;
snprintf(havebuf, sizeof havebuf, "%s_%s", env_prefix, tuple->key);
for (p = havebuf; *p; p++)
{
switch (*p)
{
case ' ':
case '-':
*p = '_';
break;
default:
*p = toupper((unsigned char) *p);
}
}
printf("%s='%s'\n", havebuf, tuple->value);
}
}
}
static bool static bool
apply_env(pkgconf_client_t *client, pkgconf_pkg_t *world, void *env_prefix_p, int maxdepth) apply_env(pkgconf_client_t *client, pkgconf_pkg_t *world, void *env_prefix_p, int maxdepth)
{ {
@ -580,21 +415,17 @@ apply_env(pkgconf_client_t *client, pkgconf_pkg_t *world, void *env_prefix_p, in
char workbuf[PKGCONF_ITEM_SIZE]; char workbuf[PKGCONF_ITEM_SIZE];
for (it = want_env_prefix; *it != '\0'; it++) for (it = want_env_prefix; *it != '\0'; it++)
if (!isalpha((unsigned char)*it) && if (!isalpha(*it) && !isdigit(*it))
!isdigit((unsigned char)*it))
return false; return false;
snprintf(workbuf, sizeof workbuf, "%s_CFLAGS", want_env_prefix); snprintf(workbuf, sizeof workbuf, "%s_CFLAGS", want_env_prefix);
if (!apply_env_var(workbuf, client, world, maxdepth, pkgconf_pkg_cflags, filter_cflags, maybe_add_module_definitions)) if (!apply_env_var(workbuf, client, world, maxdepth, pkgconf_pkg_cflags, filter_cflags))
return false; return false;
snprintf(workbuf, sizeof workbuf, "%s_LIBS", want_env_prefix); snprintf(workbuf, sizeof workbuf, "%s_LIBS", want_env_prefix);
if (!apply_env_var(workbuf, client, world, maxdepth, pkgconf_pkg_libs, filter_libs, NULL)) if (!apply_env_var(workbuf, client, world, maxdepth, pkgconf_pkg_libs, filter_libs))
return false; return false;
if ((want_flags & PKG_VARIABLES) == PKG_VARIABLES || want_variable != NULL)
apply_env_variables(client, world, want_env_prefix);
return true; return true;
} }
@ -612,7 +443,6 @@ apply_cflags(pkgconf_client_t *client, pkgconf_pkg_t *world, void *unused, int m
return false; return false;
pkgconf_fragment_filter(client, &filtered_list, &unfiltered_list, filter_cflags, NULL); pkgconf_fragment_filter(client, &filtered_list, &unfiltered_list, filter_cflags, NULL);
maybe_add_module_definitions(client, world, &filtered_list);
if (filtered_list.head == NULL) if (filtered_list.head == NULL)
goto out; goto out;
@ -763,32 +593,6 @@ apply_simulate(pkgconf_client_t *client, pkgconf_pkg_t *world, void *data, int m
} }
#endif #endif
static void
print_license(pkgconf_client_t *client, pkgconf_pkg_t *pkg, void *data)
{
(void) client;
(void) data;
if (pkg->flags & PKGCONF_PKG_PROPF_VIRTUAL)
return;
/* NOASSERTION is the default when the license is unknown, per SPDX spec § 3.15 */
printf("%s: %s\n", pkg->id, pkg->license != NULL ? pkg->license : "NOASSERTION");
}
static bool
apply_license(pkgconf_client_t *client, pkgconf_pkg_t *world, void *data, int maxdepth)
{
int eflag;
eflag = pkgconf_pkg_traverse(client, world, print_license, data, maxdepth, 0);
if (eflag != PKGCONF_PKG_ERRF_OK)
return false;
return true;
}
static void static void
version(void) version(void)
{ {
@ -820,7 +624,6 @@ usage(void)
printf(" --help this message\n"); printf(" --help this message\n");
printf(" --about print pkgconf version and license to stdout\n"); printf(" --about print pkgconf version and license to stdout\n");
printf(" --version print supported pkg-config version to stdout\n"); printf(" --version print supported pkg-config version to stdout\n");
printf(" --verbose print additional information\n");
printf(" --atleast-pkgconfig-version check whether or not pkgconf is compatible\n"); printf(" --atleast-pkgconfig-version check whether or not pkgconf is compatible\n");
printf(" with a specified pkg-config version\n"); printf(" with a specified pkg-config version\n");
printf(" --errors-to-stdout print all errors on stdout instead of stderr\n"); printf(" --errors-to-stdout print all errors on stdout instead of stderr\n");
@ -887,22 +690,18 @@ usage(void)
printf(" --print-variables print all known variables in module to stdout\n"); printf(" --print-variables print all known variables in module to stdout\n");
#ifndef PKGCONF_LITE #ifndef PKGCONF_LITE
printf(" --digraph print entire dependency graph in graphviz 'dot' format\n"); printf(" --digraph print entire dependency graph in graphviz 'dot' format\n");
printf(" --solution print dependency graph solution in a simple format\n");
#endif #endif
printf(" --keep-system-cflags keep -I%s entries in cflags output\n", SYSTEM_INCLUDEDIR); printf(" --keep-system-cflags keep -I%s entries in cflags output\n", SYSTEM_INCLUDEDIR);
printf(" --keep-system-libs keep -L%s entries in libs output\n", SYSTEM_LIBDIR); printf(" --keep-system-libs keep -L%s entries in libs output\n", SYSTEM_LIBDIR);
printf(" --path show the exact filenames for any matching .pc files\n"); printf(" --path show the exact filenames for any matching .pc files\n");
printf(" --modversion print the specified module's version to stdout\n"); printf(" --modversion print the specified module's version to stdout\n");
printf(" --internal-cflags do not filter 'internal' cflags from output\n"); printf(" --internal-cflags do not filter 'internal' cflags from output\n");
printf(" --license print the specified module's license to stdout if known\n");
printf(" --exists-cflags add -DHAVE_FOO fragments to cflags for each found module\n");
printf("\nfiltering output:\n\n"); printf("\nfiltering output:\n\n");
#ifndef PKGCONF_LITE #ifndef PKGCONF_LITE
printf(" --msvc-syntax print translatable fragments in MSVC syntax\n"); printf(" --msvc-syntax print translatable fragments in MSVC syntax\n");
#endif #endif
printf(" --fragment-filter=types filter output fragments to the specified types\n"); printf(" --fragment-filter=types filter output fragments to the specified types\n");
printf(" --env=prefix print output as shell-compatible environmental variables\n");
printf("\nreport bugs to <%s>.\n", PACKAGE_BUGREPORT); printf("\nreport bugs to <%s>.\n", PACKAGE_BUGREPORT);
} }
@ -1002,13 +801,8 @@ main(int argc, char *argv[])
char *logfile_arg = NULL; char *logfile_arg = NULL;
char *want_env_prefix = NULL; char *want_env_prefix = NULL;
unsigned int want_client_flags = PKGCONF_PKG_PKGF_NONE; unsigned int want_client_flags = PKGCONF_PKG_PKGF_NONE;
pkgconf_cross_personality_t *personality = NULL; pkgconf_cross_personality_t *personality;
bool opened_error_msgout = false; bool opened_error_msgout = false;
pkgconf_pkg_t world = {
.id = "virtual:world",
.realname = "virtual world package",
.flags = PKGCONF_PKG_PROPF_STATIC | PKGCONF_PKG_PROPF_VIRTUAL,
};
want_flags = 0; want_flags = 0;
@ -1042,7 +836,6 @@ main(int argc, char *argv[])
{ "print-variables", no_argument, &want_flags, PKG_VARIABLES|PKG_PRINT_ERRORS, }, { "print-variables", no_argument, &want_flags, PKG_VARIABLES|PKG_PRINT_ERRORS, },
#ifndef PKGCONF_LITE #ifndef PKGCONF_LITE
{ "digraph", no_argument, &want_flags, PKG_DIGRAPH, }, { "digraph", no_argument, &want_flags, PKG_DIGRAPH, },
{ "solution", no_argument, &want_flags, PKG_SOLUTION, },
#endif #endif
{ "help", no_argument, &want_flags, PKG_HELP, }, { "help", no_argument, &want_flags, PKG_HELP, },
{ "env-only", no_argument, &want_flags, PKG_ENV_ONLY, }, { "env-only", no_argument, &want_flags, PKG_ENV_ONLY, },
@ -1090,9 +883,6 @@ main(int argc, char *argv[])
{ "dump-personality", no_argument, &want_flags, PKG_DUMP_PERSONALITY }, { "dump-personality", no_argument, &want_flags, PKG_DUMP_PERSONALITY },
{ "personality", required_argument, NULL, 53 }, { "personality", required_argument, NULL, 53 },
#endif #endif
{ "license", no_argument, &want_flags, PKG_DUMP_LICENSE },
{ "verbose", no_argument, NULL, 55 },
{ "exists-cflags", no_argument, &want_flags, PKG_EXISTS_CFLAGS },
{ NULL, 0, NULL, 0 } { NULL, 0, NULL, 0 }
}; };
@ -1104,6 +894,12 @@ main(int argc, char *argv[])
} }
#endif #endif
#ifndef PKGCONF_LITE
personality = deduce_personality(argv);
#else
personality = pkgconf_cross_personality_default();
#endif
while ((ret = pkg_getopt_long_only(argc, argv, "", options, NULL)) != -1) while ((ret = pkg_getopt_long_only(argc, argv, "", options, NULL)) != -1)
{ {
switch (ret) switch (ret)
@ -1133,7 +929,7 @@ main(int argc, char *argv[])
logfile_arg = pkg_optarg; logfile_arg = pkg_optarg;
break; break;
case 42: case 42:
pkgconf_path_prepend(pkg_optarg, &dir_list, true); pkgconf_path_add(pkg_optarg, &dir_list, true);
break; break;
case 43: case 43:
pkgconf_client_set_prefix_varname(&pkg_client, pkg_optarg); pkgconf_client_set_prefix_varname(&pkg_client, pkg_optarg);
@ -1152,26 +948,15 @@ main(int argc, char *argv[])
personality = pkgconf_cross_personality_find(pkg_optarg); personality = pkgconf_cross_personality_find(pkg_optarg);
break; break;
#endif #endif
case 55:
verbosity++;
break;
case '?': case '?':
case ':': case ':':
ret = EXIT_FAILURE; return EXIT_FAILURE;
goto out; break;
default: default:
break; break;
} }
} }
if (personality == NULL) {
#ifndef PKGCONF_LITE
personality = deduce_personality(argv);
#else
personality = pkgconf_cross_personality_default();
#endif
}
pkgconf_path_copy_list(&personality->dir_list, &dir_list); pkgconf_path_copy_list(&personality->dir_list, &dir_list);
pkgconf_path_free(&dir_list); pkgconf_path_free(&dir_list);
@ -1216,33 +1001,24 @@ main(int argc, char *argv[])
if ((want_flags & PKG_ABOUT) == PKG_ABOUT) if ((want_flags & PKG_ABOUT) == PKG_ABOUT)
{ {
about(); about();
return EXIT_SUCCESS;
ret = EXIT_SUCCESS;
goto out;
} }
if ((want_flags & PKG_VERSION) == PKG_VERSION) if ((want_flags & PKG_VERSION) == PKG_VERSION)
{ {
version(); version();
return EXIT_SUCCESS;
ret = EXIT_SUCCESS;
goto out;
} }
if ((want_flags & PKG_HELP) == PKG_HELP) if ((want_flags & PKG_HELP) == PKG_HELP)
{ {
usage(); usage();
return EXIT_SUCCESS;
ret = EXIT_SUCCESS;
goto out;
} }
if (getenv("PKG_CONFIG_FDO_SYSROOT_RULES")) if (getenv("PKG_CONFIG_FDO_SYSROOT_RULES"))
want_client_flags |= PKGCONF_PKG_PKGF_FDO_SYSROOT_RULES; want_client_flags |= PKGCONF_PKG_PKGF_FDO_SYSROOT_RULES;
if (getenv("PKG_CONFIG_PKGCONF1_SYSROOT_RULES"))
want_client_flags |= PKGCONF_PKG_PKGF_PKGCONF1_SYSROOT_RULES;
if ((want_flags & PKG_SHORT_ERRORS) == PKG_SHORT_ERRORS) if ((want_flags & PKG_SHORT_ERRORS) == PKG_SHORT_ERRORS)
want_client_flags |= PKGCONF_PKG_PKGF_SIMPLIFY_ERRORS; want_client_flags |= PKGCONF_PKG_PKGF_SIMPLIFY_ERRORS;
@ -1263,6 +1039,9 @@ main(int argc, char *argv[])
if ((want_flags & PKG_STATIC) == PKG_STATIC || personality->want_default_static) if ((want_flags & PKG_STATIC) == PKG_STATIC || personality->want_default_static)
want_client_flags |= (PKGCONF_PKG_PKGF_SEARCH_PRIVATE | PKGCONF_PKG_PKGF_MERGE_PRIVATE_FRAGMENTS); want_client_flags |= (PKGCONF_PKG_PKGF_SEARCH_PRIVATE | PKGCONF_PKG_PKGF_MERGE_PRIVATE_FRAGMENTS);
if ((want_flags & PKG_EXISTS) == PKG_EXISTS)
want_client_flags |= PKGCONF_PKG_PKGF_SEARCH_PRIVATE;
if ((want_flags & PKG_SHARED) == PKG_SHARED) if ((want_flags & PKG_SHARED) == PKG_SHARED)
want_client_flags &= ~(PKGCONF_PKG_PKGF_SEARCH_PRIVATE | PKGCONF_PKG_PKGF_MERGE_PRIVATE_FRAGMENTS); want_client_flags &= ~(PKGCONF_PKG_PKGF_SEARCH_PRIVATE | PKGCONF_PKG_PKGF_MERGE_PRIVATE_FRAGMENTS);
@ -1282,7 +1061,7 @@ main(int argc, char *argv[])
/* On Windows we want to always redefine the prefix by default /* On Windows we want to always redefine the prefix by default
* but allow that behavior to be manually disabled */ * but allow that behavior to be manually disabled */
#if !defined(_WIN32) && !defined(_WIN64) #if !defined(_WIN32) && !defined(_WIN64)
if ((want_flags & PKG_DEFINE_PREFIX) == PKG_DEFINE_PREFIX || getenv("PKG_CONFIG_RELOCATE_PATHS") != NULL) if ((want_flags & PKG_DEFINE_PREFIX) == PKG_DEFINE_PREFIX)
#endif #endif
want_client_flags |= PKGCONF_PKG_PKGF_REDEFINE_PREFIX; want_client_flags |= PKGCONF_PKG_PKGF_REDEFINE_PREFIX;
@ -1298,24 +1077,28 @@ main(int argc, char *argv[])
if ((want_flags & PKG_INTERNAL_CFLAGS) == PKG_INTERNAL_CFLAGS) if ((want_flags & PKG_INTERNAL_CFLAGS) == PKG_INTERNAL_CFLAGS)
want_client_flags |= PKGCONF_PKG_PKGF_DONT_FILTER_INTERNAL_CFLAGS; want_client_flags |= PKGCONF_PKG_PKGF_DONT_FILTER_INTERNAL_CFLAGS;
/* if these selectors are used, it means that we are querying metadata. #ifdef XXX_NOTYET
* so signal to libpkgconf that we only want to walk the flattened dependency set. /* if these selectors are used, it means that we are inquiring about a single package.
* so signal to libpkgconf that we do not want to use the dependency resolver for more than one level,
* and also limit the SAT problem to a single package.
*
* i disabled this because too many upstream maintainers are still invoking pkg-config correctly to have
* the more sane behaviour as default. use --maximum-traverse-depth=1 or PKG_CONFIG_MAXIMUM_TRAVERSE_DEPTH
* environment variable to get the same results in meantime.
*/ */
if ((want_flags & PKG_MODVERSION) == PKG_MODVERSION || if ((want_flags & PKG_EXISTS) == 0 &&
(want_flags & PKG_REQUIRES) == PKG_REQUIRES || ((want_flags & PKG_REQUIRES) == PKG_REQUIRES ||
(want_flags & PKG_REQUIRES_PRIVATE) == PKG_REQUIRES_PRIVATE || (want_flags & PKG_REQUIRES_PRIVATE) == PKG_REQUIRES_PRIVATE ||
(want_flags & PKG_PROVIDES) == PKG_PROVIDES || (want_flags & PKG_PROVIDES) == PKG_PROVIDES ||
(want_flags & PKG_VARIABLES) == PKG_VARIABLES || (want_flags & PKG_VARIABLES) == PKG_VARIABLES ||
(want_flags & PKG_PATH) == PKG_PATH) (want_flags & PKG_MODVERSION) == PKG_MODVERSION ||
maximum_traverse_depth = 1;
/* if we are asking for a variable, path or list of variables, this only makes sense
* for a single package.
*/
if ((want_flags & PKG_VARIABLES) == PKG_VARIABLES ||
(want_flags & PKG_PATH) == PKG_PATH || (want_flags & PKG_PATH) == PKG_PATH ||
want_variable != NULL) want_variable != NULL))
{
maximum_package_count = 1; maximum_package_count = 1;
maximum_traverse_depth = 1;
}
#endif
if (getenv("PKG_CONFIG_ALLOW_SYSTEM_CFLAGS") != NULL) if (getenv("PKG_CONFIG_ALLOW_SYSTEM_CFLAGS") != NULL)
want_flags |= PKG_KEEP_SYSTEM_CFLAGS; want_flags |= PKG_KEEP_SYSTEM_CFLAGS;
@ -1326,12 +1109,6 @@ main(int argc, char *argv[])
if ((builddir = getenv("PKG_CONFIG_TOP_BUILD_DIR")) != NULL) if ((builddir = getenv("PKG_CONFIG_TOP_BUILD_DIR")) != NULL)
pkgconf_client_set_buildroot_dir(&pkg_client, builddir); pkgconf_client_set_buildroot_dir(&pkg_client, builddir);
if ((want_flags & PKG_REQUIRES_PRIVATE) == PKG_REQUIRES_PRIVATE ||
(want_flags & PKG_CFLAGS))
{
want_client_flags |= PKGCONF_PKG_PKGF_SEARCH_PRIVATE;
}
if ((sysroot_dir = getenv("PKG_CONFIG_SYSROOT_DIR")) != NULL) if ((sysroot_dir = getenv("PKG_CONFIG_SYSROOT_DIR")) != NULL)
{ {
const char *destdir; const char *destdir;
@ -1354,25 +1131,21 @@ main(int argc, char *argv[])
if (required_pkgconfig_version != NULL) if (required_pkgconfig_version != NULL)
{ {
if (pkgconf_compare_version(PACKAGE_VERSION, required_pkgconfig_version) >= 0) if (pkgconf_compare_version(PACKAGE_VERSION, required_pkgconfig_version) >= 0)
ret = EXIT_SUCCESS; return EXIT_SUCCESS;
else
ret = EXIT_FAILURE;
goto out; return EXIT_FAILURE;
} }
if ((want_flags & PKG_LIST) == PKG_LIST) if ((want_flags & PKG_LIST) == PKG_LIST)
{ {
pkgconf_scan_all(&pkg_client, NULL, print_list_entry); pkgconf_scan_all(&pkg_client, NULL, print_list_entry);
ret = EXIT_SUCCESS; return EXIT_SUCCESS;
goto out;
} }
if ((want_flags & PKG_LIST_PACKAGE_NAMES) == PKG_LIST_PACKAGE_NAMES) if ((want_flags & PKG_LIST_PACKAGE_NAMES) == PKG_LIST_PACKAGE_NAMES)
{ {
pkgconf_scan_all(&pkg_client, NULL, print_package_entry); pkgconf_scan_all(&pkg_client, NULL, print_package_entry);
ret = EXIT_SUCCESS; return EXIT_SUCCESS;
goto out;
} }
if (logfile_arg == NULL) if (logfile_arg == NULL)
@ -1386,7 +1159,7 @@ main(int argc, char *argv[])
if (required_module_version != NULL) if (required_module_version != NULL)
{ {
pkgconf_pkg_t *pkg = NULL; pkgconf_pkg_t *pkg;
pkgconf_node_t *node; pkgconf_node_t *node;
pkgconf_list_t deplist = PKGCONF_LIST_INITIALIZER; pkgconf_list_t deplist = PKGCONF_LIST_INITIALIZER;
@ -1405,28 +1178,18 @@ main(int argc, char *argv[])
{ {
if (want_flags & PKG_PRINT_ERRORS) if (want_flags & PKG_PRINT_ERRORS)
pkgconf_error(&pkg_client, "Package '%s' was not found\n", pkgiter->package); pkgconf_error(&pkg_client, "Package '%s' was not found\n", pkgiter->package);
return EXIT_FAILURE;
ret = EXIT_FAILURE;
goto cleanup;
} }
if (pkgconf_compare_version(pkg->version, required_module_version) >= 0) if (pkgconf_compare_version(pkg->version, required_module_version) >= 0)
{ return EXIT_SUCCESS;
ret = EXIT_SUCCESS;
goto cleanup;
}
} }
ret = EXIT_FAILURE; return EXIT_FAILURE;
cleanup:
if (pkg != NULL)
pkgconf_pkg_unref(&pkg_client, pkg);
pkgconf_dependency_free(&deplist);
goto out;
} }
else if (required_exact_module_version != NULL) else if (required_exact_module_version != NULL)
{ {
pkgconf_pkg_t *pkg = NULL; pkgconf_pkg_t *pkg;
pkgconf_node_t *node; pkgconf_node_t *node;
pkgconf_list_t deplist = PKGCONF_LIST_INITIALIZER; pkgconf_list_t deplist = PKGCONF_LIST_INITIALIZER;
@ -1445,28 +1208,18 @@ cleanup:
{ {
if (want_flags & PKG_PRINT_ERRORS) if (want_flags & PKG_PRINT_ERRORS)
pkgconf_error(&pkg_client, "Package '%s' was not found\n", pkgiter->package); pkgconf_error(&pkg_client, "Package '%s' was not found\n", pkgiter->package);
return EXIT_FAILURE;
ret = EXIT_FAILURE;
goto cleanup2;
} }
if (pkgconf_compare_version(pkg->version, required_exact_module_version) == 0) if (pkgconf_compare_version(pkg->version, required_exact_module_version) == 0)
{ return EXIT_SUCCESS;
ret = EXIT_SUCCESS;
goto cleanup2;
}
} }
ret = EXIT_FAILURE; return EXIT_FAILURE;
cleanup2:
if (pkg != NULL)
pkgconf_pkg_unref(&pkg_client, pkg);
pkgconf_dependency_free(&deplist);
goto out;
} }
else if (required_max_module_version != NULL) else if (required_max_module_version != NULL)
{ {
pkgconf_pkg_t *pkg = NULL; pkgconf_pkg_t *pkg;
pkgconf_node_t *node; pkgconf_node_t *node;
pkgconf_list_t deplist = PKGCONF_LIST_INITIALIZER; pkgconf_list_t deplist = PKGCONF_LIST_INITIALIZER;
@ -1485,30 +1238,19 @@ cleanup2:
{ {
if (want_flags & PKG_PRINT_ERRORS) if (want_flags & PKG_PRINT_ERRORS)
pkgconf_error(&pkg_client, "Package '%s' was not found\n", pkgiter->package); pkgconf_error(&pkg_client, "Package '%s' was not found\n", pkgiter->package);
return EXIT_FAILURE;
ret = EXIT_FAILURE;
goto cleanup3;
} }
if (pkgconf_compare_version(pkg->version, required_max_module_version) <= 0) if (pkgconf_compare_version(pkg->version, required_max_module_version) <= 0)
{ return EXIT_SUCCESS;
ret = EXIT_SUCCESS;
goto cleanup3;
}
} }
ret = EXIT_FAILURE; return EXIT_FAILURE;
cleanup3:
if (pkg != NULL)
pkgconf_pkg_unref(&pkg_client, pkg);
pkgconf_dependency_free(&deplist);
goto out;
} }
while (1) while (1)
{ {
char *package = argv[pkg_optind]; const char *package = argv[pkg_optind];
char *end;
if (package == NULL) if (package == NULL)
break; break;
@ -1516,10 +1258,10 @@ cleanup3:
/* check if there is a limit to the number of packages allowed to be included, if so and we have hit /* check if there is a limit to the number of packages allowed to be included, if so and we have hit
* the limit, stop adding packages to the queue. * the limit, stop adding packages to the queue.
*/ */
if (maximum_package_count > 0 && pkgq.length >= maximum_package_count) if (maximum_package_count > 0 && pkgq.length > maximum_package_count)
break; break;
while (isspace((unsigned char)package[0])) while (isspace((unsigned int)package[0]))
package++; package++;
/* skip empty packages */ /* skip empty packages */
@ -1528,24 +1270,11 @@ cleanup3:
continue; continue;
} }
end = package + strlen(package) - 1;
while(end > package && isspace((unsigned char)end[0])) end--;
end[1] = '\0';
if (argv[pkg_optind + 1] == NULL || !PKGCONF_IS_OPERATOR_CHAR(*(argv[pkg_optind + 1]))) if (argv[pkg_optind + 1] == NULL || !PKGCONF_IS_OPERATOR_CHAR(*(argv[pkg_optind + 1])))
{ {
pkgconf_queue_push(&pkgq, package); pkgconf_queue_push(&pkgq, package);
pkg_optind++; pkg_optind++;
} }
else if (argv[pkg_optind + 2] == NULL)
{
char packagebuf[PKGCONF_BUFSIZE];
snprintf(packagebuf, sizeof packagebuf, "%s %s", package, argv[pkg_optind + 1]);
pkg_optind += 2;
pkgconf_queue_push(&pkgq, packagebuf);
}
else else
{ {
char packagebuf[PKGCONF_BUFSIZE]; char packagebuf[PKGCONF_BUFSIZE];
@ -1560,74 +1289,85 @@ cleanup3:
if (pkgq.head == NULL) if (pkgq.head == NULL)
{ {
fprintf(stderr, "Please specify at least one package name on the command line.\n"); fprintf(stderr, "Please specify at least one package name on the command line.\n");
ret = EXIT_FAILURE; return EXIT_FAILURE;
goto out;
} }
ret = EXIT_SUCCESS; ret = EXIT_SUCCESS;
if (!pkgconf_queue_solve(&pkg_client, &pkgq, &world, maximum_traverse_depth))
{
ret = EXIT_FAILURE;
goto out;
}
#ifndef PKGCONF_LITE #ifndef PKGCONF_LITE
if ((want_flags & PKG_SIMULATE) == PKG_SIMULATE) if ((want_flags & PKG_SIMULATE) == PKG_SIMULATE)
{ {
want_flags &= ~(PKG_CFLAGS|PKG_LIBS); want_flags &= ~(PKG_CFLAGS|PKG_LIBS);
pkgconf_client_set_flags(&pkg_client, want_client_flags | PKGCONF_PKG_PKGF_SKIP_ERRORS); pkgconf_client_set_flags(&pkg_client, want_client_flags | PKGCONF_PKG_PKGF_SKIP_ERRORS);
apply_simulate(&pkg_client, &world, NULL, -1); if (!pkgconf_queue_apply(&pkg_client, &pkgq, apply_simulate, -1, NULL))
{
ret = EXIT_FAILURE;
goto out;
}
} }
#endif #endif
if ((want_flags & PKG_VALIDATE) == PKG_VALIDATE) if (!pkgconf_queue_validate(&pkg_client, &pkgq, maximum_traverse_depth))
goto out;
if ((want_flags & PKG_DUMP_LICENSE) == PKG_DUMP_LICENSE)
{ {
apply_license(&pkg_client, &world, &ret, 2); ret = EXIT_FAILURE;
goto out; goto out;
} }
if ((want_flags & PKG_VALIDATE) == PKG_VALIDATE)
return 0;
if ((want_flags & PKG_UNINSTALLED) == PKG_UNINSTALLED) if ((want_flags & PKG_UNINSTALLED) == PKG_UNINSTALLED)
{ {
ret = EXIT_FAILURE; ret = EXIT_FAILURE;
apply_uninstalled(&pkg_client, &world, &ret, 2); pkgconf_queue_apply(&pkg_client, &pkgq, apply_uninstalled, maximum_traverse_depth, &ret);
goto out; goto out;
} }
if (want_env_prefix != NULL) if (want_env_prefix != NULL)
{ {
apply_env(&pkg_client, &world, want_env_prefix, 2); if (!pkgconf_queue_apply(&pkg_client, &pkgq, apply_env, maximum_traverse_depth, want_env_prefix))
{
ret = EXIT_FAILURE;
goto out; goto out;
} }
want_flags = 0;
}
if ((want_flags & PKG_PROVIDES) == PKG_PROVIDES) if ((want_flags & PKG_PROVIDES) == PKG_PROVIDES)
{ {
want_flags &= ~(PKG_CFLAGS|PKG_LIBS); want_flags &= ~(PKG_CFLAGS|PKG_LIBS);
apply_provides(&pkg_client, &world, NULL, 2);
if (!pkgconf_queue_apply(&pkg_client, &pkgq, apply_provides, maximum_traverse_depth, NULL))
{
ret = EXIT_FAILURE;
goto out;
}
} }
#ifndef PKGCONF_LITE #ifndef PKGCONF_LITE
if ((want_flags & PKG_DIGRAPH) == PKG_DIGRAPH) if ((want_flags & PKG_DIGRAPH) == PKG_DIGRAPH)
{ {
want_flags &= ~(PKG_CFLAGS|PKG_LIBS); want_flags &= ~(PKG_CFLAGS|PKG_LIBS);
apply_digraph(&pkg_client, &world, &pkgq, 2);
}
if ((want_flags & PKG_SOLUTION) == PKG_SOLUTION) if (!pkgconf_queue_apply(&pkg_client, &pkgq, apply_digraph, maximum_traverse_depth, NULL))
{ {
want_flags &= ~(PKG_CFLAGS|PKG_LIBS); ret = EXIT_FAILURE;
apply_print_solution(&pkg_client, &world, NULL, 2); goto out;
}
} }
#endif #endif
if ((want_flags & PKG_MODVERSION) == PKG_MODVERSION) if ((want_flags & PKG_MODVERSION) == PKG_MODVERSION)
{ {
want_flags &= ~(PKG_CFLAGS|PKG_LIBS); want_flags &= ~(PKG_CFLAGS|PKG_LIBS);
apply_modversion(&pkg_client, &world, &pkgq, 2);
if (!pkgconf_queue_apply(&pkg_client, &pkgq, apply_modversion, maximum_traverse_depth, NULL))
{
ret = EXIT_FAILURE;
goto out;
}
} }
if ((want_flags & PKG_PATH) == PKG_PATH) if ((want_flags & PKG_PATH) == PKG_PATH)
@ -1635,13 +1375,22 @@ cleanup3:
want_flags &= ~(PKG_CFLAGS|PKG_LIBS); want_flags &= ~(PKG_CFLAGS|PKG_LIBS);
pkgconf_client_set_flags(&pkg_client, want_client_flags | PKGCONF_PKG_PKGF_SKIP_ROOT_VIRTUAL); pkgconf_client_set_flags(&pkg_client, want_client_flags | PKGCONF_PKG_PKGF_SKIP_ROOT_VIRTUAL);
apply_path(&pkg_client, &world, NULL, 2); if (!pkgconf_queue_apply(&pkg_client, &pkgq, apply_path, maximum_traverse_depth, NULL))
{
ret = EXIT_FAILURE;
goto out;
}
} }
if ((want_flags & PKG_VARIABLES) == PKG_VARIABLES) if ((want_flags & PKG_VARIABLES) == PKG_VARIABLES)
{ {
want_flags &= ~(PKG_CFLAGS|PKG_LIBS); want_flags &= ~(PKG_CFLAGS|PKG_LIBS);
apply_variables(&pkg_client, &world, NULL, 2);
if (!pkgconf_queue_apply(&pkg_client, &pkgq, apply_variables, maximum_traverse_depth, NULL))
{
ret = EXIT_FAILURE;
goto out;
}
} }
if (want_variable) if (want_variable)
@ -1649,44 +1398,68 @@ cleanup3:
want_flags &= ~(PKG_CFLAGS|PKG_LIBS); want_flags &= ~(PKG_CFLAGS|PKG_LIBS);
pkgconf_client_set_flags(&pkg_client, want_client_flags | PKGCONF_PKG_PKGF_SKIP_ROOT_VIRTUAL); pkgconf_client_set_flags(&pkg_client, want_client_flags | PKGCONF_PKG_PKGF_SKIP_ROOT_VIRTUAL);
apply_variable(&pkg_client, &world, want_variable, 2); if (!pkgconf_queue_apply(&pkg_client, &pkgq, apply_variable, maximum_traverse_depth, want_variable))
{
ret = EXIT_FAILURE;
goto out;
}
} }
if ((want_flags & PKG_REQUIRES) == PKG_REQUIRES) if ((want_flags & PKG_REQUIRES) == PKG_REQUIRES)
{ {
want_flags &= ~(PKG_CFLAGS|PKG_LIBS); want_flags &= ~(PKG_CFLAGS|PKG_LIBS);
apply_requires(&pkg_client, &world, NULL, 2);
if (!pkgconf_queue_apply(&pkg_client, &pkgq, apply_requires, maximum_traverse_depth, NULL))
{
ret = EXIT_FAILURE;
goto out;
}
} }
if ((want_flags & PKG_REQUIRES_PRIVATE) == PKG_REQUIRES_PRIVATE) if ((want_flags & PKG_REQUIRES_PRIVATE) == PKG_REQUIRES_PRIVATE)
{ {
want_flags &= ~(PKG_CFLAGS|PKG_LIBS); want_flags &= ~(PKG_CFLAGS|PKG_LIBS);
apply_requires_private(&pkg_client, &world, NULL, 2); pkgconf_client_set_flags(&pkg_client, want_client_flags | PKGCONF_PKG_PKGF_SEARCH_PRIVATE);
if (!pkgconf_queue_apply(&pkg_client, &pkgq, apply_requires_private, maximum_traverse_depth, NULL))
{
ret = EXIT_FAILURE;
goto out;
}
pkgconf_client_set_flags(&pkg_client, want_client_flags);
} }
if ((want_flags & PKG_CFLAGS)) if ((want_flags & PKG_CFLAGS))
{ {
apply_cflags(&pkg_client, &world, NULL, 2); pkgconf_client_set_flags(&pkg_client, want_client_flags | PKGCONF_PKG_PKGF_SEARCH_PRIVATE);
if (!pkgconf_queue_apply(&pkg_client, &pkgq, apply_cflags, maximum_traverse_depth, NULL))
{
ret = EXIT_FAILURE;
goto out_println;
}
pkgconf_client_set_flags(&pkg_client, want_client_flags);
} }
if ((want_flags & PKG_LIBS)) if ((want_flags & PKG_LIBS))
{ {
if (want_flags & PKG_CFLAGS) if (!pkgconf_queue_apply(&pkg_client, &pkgq, apply_libs, maximum_traverse_depth, NULL))
printf(" "); {
ret = EXIT_FAILURE;
if (!(want_flags & PKG_STATIC)) goto out_println;
pkgconf_client_set_flags(&pkg_client, pkg_client.flags & ~PKGCONF_PKG_PKGF_SEARCH_PRIVATE); }
apply_libs(&pkg_client, &world, NULL, 2);
} }
pkgconf_queue_free(&pkgq);
out_println:
if (want_flags & (PKG_CFLAGS|PKG_LIBS)) if (want_flags & (PKG_CFLAGS|PKG_LIBS))
printf("\n"); printf("\n");
out: out:
pkgconf_solution_free(&pkg_client, &world);
pkgconf_queue_free(&pkgq);
pkgconf_cross_personality_deinit(personality); pkgconf_cross_personality_deinit(personality);
pkgconf_client_deinit(&pkg_client); pkgconf_client_deinit(&pkg_client);

View File

@ -149,6 +149,7 @@ msvc_renderer_render_buf(const pkgconf_list_t *list, char *buf, size_t buflen, b
{ {
cnt = pkgconf_strlcpy(bptr, ".lib", buf_remaining); cnt = pkgconf_strlcpy(bptr, ".lib", buf_remaining);
bptr += cnt; bptr += cnt;
buf_remaining -= cnt;
} }
if (escape) if (escape)

View File

@ -11,8 +11,8 @@ dnl This software is provided 'as is' and without any warranty, express or
dnl implied. In no event shall the authors be liable for any damages arising dnl implied. In no event shall the authors be liable for any damages arising
dnl from the use of this software. dnl from the use of this software.
AC_PREREQ([2.71]) AC_PREREQ([2.68])
AC_INIT([pkgconf],[2.3.0],[https://github.com/pkgconf/pkgconf/issues/new]) AC_INIT([pkgconf], [1.8.1], [https://github.com/pkgconf/pkgconf/issues/new])
AC_CONFIG_SRCDIR([cli/main.c]) AC_CONFIG_SRCDIR([cli/main.c])
AC_CONFIG_MACRO_DIR([m4]) AC_CONFIG_MACRO_DIR([m4])
AX_CHECK_COMPILE_FLAG([-Wall], [CFLAGS="$CFLAGS -Wall"]) AX_CHECK_COMPILE_FLAG([-Wall], [CFLAGS="$CFLAGS -Wall"])
@ -22,8 +22,7 @@ AX_CHECK_COMPILE_FLAG([-std=gnu99], [CFLAGS="$CFLAGS -std=gnu99"], [
AX_CHECK_COMPILE_FLAG([-std=c99], [CFLAGS="$CFLAGS -std=c99"]) AX_CHECK_COMPILE_FLAG([-std=c99], [CFLAGS="$CFLAGS -std=c99"])
]) ])
AC_CONFIG_HEADERS([libpkgconf/config.h]) AC_CONFIG_HEADERS([libpkgconf/config.h])
AC_CHECK_DECLS([strlcpy, strlcat, strndup], [], [], [[#include <string.h>]]) AC_CHECK_FUNCS([strlcpy strlcat strndup])
AC_CHECK_DECLS([reallocarray])
AC_CHECK_HEADERS([sys/stat.h]) AC_CHECK_HEADERS([sys/stat.h])
AM_INIT_AUTOMAKE([foreign dist-xz subdir-objects]) AM_INIT_AUTOMAKE([foreign dist-xz subdir-objects])
AM_SILENT_RULES([yes]) AM_SILENT_RULES([yes])
@ -31,26 +30,26 @@ LT_INIT
AC_SYS_LARGEFILE AC_SYS_LARGEFILE
AC_ARG_WITH([personality-dir],[AS_HELP_STRING([--with-personality-dir],[specify AC_ARG_WITH([personality-dir],[AC_HELP_STRING([--with-personality-dir],[specify
the place where cross-compile personality files will be found])], the place where cross-compile personality files will be found])],
PERSONALITY_PATH="$withval", PERSONALITY_PATH="$withval",
PERSONALITY_PATH="${datadir}/pkgconfig/personality.d:${sysconfdir}/pkgconfig/personality.d") PERSONALITY_PATH="${datadir}/pkgconfig/personality.d:${sysconfdir}/pkgconfig/personality.d")
AC_SUBST([PERSONALITY_PATH]) AC_SUBST([PERSONALITY_PATH])
AC_ARG_WITH([pkg-config-dir],[AS_HELP_STRING([--with-pkg-config-dir],[specify AC_ARG_WITH([pkg-config-dir],[AC_HELP_STRING([--with-pkg-config-dir],[specify
the place where pc files will be found])],PKG_DEFAULT_PATH="$withval", the place where pc files will be found])],PKG_DEFAULT_PATH="$withval",
PKG_DEFAULT_PATH="${libdir}/pkgconfig:${datadir}/pkgconfig") PKG_DEFAULT_PATH="${libdir}/pkgconfig:${datadir}/pkgconfig")
AC_SUBST([PKG_DEFAULT_PATH]) AC_SUBST([PKG_DEFAULT_PATH])
AC_ARG_WITH([system-libdir],[AS_HELP_STRING([--with-system-libdir],[specify the AC_ARG_WITH([system-libdir],[AC_HELP_STRING([--with-system-libdir],[specify the
system library directory (default LIBDIR)])], system library directory (default LIBDIR)])],
SYSTEM_LIBDIR="$withval", SYSTEM_LIBDIR="${libdir}") SYSTEM_LIBDIR="$withval", SYSTEM_LIBDIR="${libdir}")
AC_SUBST([SYSTEM_LIBDIR]) AC_SUBST([SYSTEM_LIBDIR])
AC_ARG_WITH([system-includedir],[AS_HELP_STRING([--with-system-includedir],[specify the AC_ARG_WITH([system-includedir],[AC_HELP_STRING([--with-system-includedir],[specify the
system include directory (default INCLUDEDIR)])], system include directory (default INCLUDEDIR)])],
SYSTEM_INCLUDEDIR="$withval", SYSTEM_INCLUDEDIR="${includedir}") SYSTEM_INCLUDEDIR="$withval", SYSTEM_INCLUDEDIR="${includedir}")

View File

@ -70,21 +70,21 @@ def extract_comments(filename):
while True: while True:
char = source_file.read(1) char = source_file.read(1)
if not char: if not char:
if state == 3 or state == 4: if state is 3 or state is 4:
raise UnterminatedCommentError() raise UnterminatedCommentError()
if state == 2: if state is 2:
# Was in single line comment. Create comment. # Was in single line comment. Create comment.
comment = Comment(current_comment, line_counter, False) comment = Comment(current_comment, line_counter, False)
comments.append(comment) comments.append(comment)
return comments return comments
if state == 0: if state is 0:
# Waiting for comment start character or beginning of # Waiting for comment start character or beginning of
# string. # string.
if char == '/': if char == '/':
state = 1 state = 1
elif char == '"': elif char == '"':
state = 5 state = 5
elif state == 1: elif state is 1:
# Found comment start character, classify next character and # Found comment start character, classify next character and
# determine if single or multiline comment. # determine if single or multiline comment.
if char == '/': if char == '/':
@ -94,7 +94,7 @@ def extract_comments(filename):
state = 3 state = 3
else: else:
state = 0 state = 0
elif state == 2: elif state is 2:
# In single line comment, read characters until EOL. # In single line comment, read characters until EOL.
if char == '\n': if char == '\n':
comment = Comment(current_comment, line_counter, False) comment = Comment(current_comment, line_counter, False)
@ -103,14 +103,14 @@ def extract_comments(filename):
state = 0 state = 0
else: else:
current_comment += char current_comment += char
elif state == 3: elif state is 3:
# In multi-line comment, add characters until '*' # In multi-line comment, add characters until '*'
# encountered. # encountered.
if char == '*': if char == '*':
state = 4 state = 4
else: else:
current_comment += char current_comment += char
elif state == 4: elif state is 4:
# In multi-line comment with asterisk found. Determine if # In multi-line comment with asterisk found. Determine if
# comment is ending. # comment is ending.
if char == '/': if char == '/':
@ -125,13 +125,13 @@ def extract_comments(filename):
if char != '*': if char != '*':
current_comment += char current_comment += char
state = 3 state = 3
elif state == 5: elif state is 5:
# In string literal, expect literal end or escape char. # In string literal, expect literal end or escape char.
if char == '"': if char == '"':
state = 0 state = 0
elif char == '\\': elif char == '\\':
state = 6 state = 6
elif state == 6: elif state is 6:
# In string literal, escaping current char. # In string literal, escaping current char.
state = 5 state = 5
if char == '\n': if char == '\n':

View File

@ -9,32 +9,21 @@ in parallel.
Client objects are not thread safe, in other words, a client object should not be shared across Client objects are not thread safe, in other words, a client object should not be shared across
thread boundaries. thread boundaries.
.. c:function:: void pkgconf_client_dir_list_build(pkgconf_client_t *client) .. c:function:: void pkgconf_client_init(pkgconf_client_t *client, pkgconf_error_handler_func_t error_handler)
Bootstraps the package search paths. If the ``PKGCONF_PKG_PKGF_ENV_ONLY`` `flag` is set on the client,
then only the ``PKG_CONFIG_PATH`` environment variable will be used, otherwise both the
``PKG_CONFIG_PATH`` and ``PKG_CONFIG_LIBDIR`` environment variables will be used.
:param pkgconf_client_t* client: The pkgconf client object to bootstrap.
:return: nothing
.. c:function:: void pkgconf_client_init(pkgconf_client_t *client, pkgconf_error_handler_func_t error_handler, void *error_handler_data, const pkgconf_cross_personality_t *personality)
Initialise a pkgconf client object. Initialise a pkgconf client object.
:param pkgconf_client_t* client: The client to initialise. :param pkgconf_client_t* client: The client to initialise.
:param pkgconf_error_handler_func_t error_handler: An optional error handler to use for logging errors. :param pkgconf_error_handler_func_t error_handler: An optional error handler to use for logging errors.
:param void* error_handler_data: user data passed to optional error handler :param void* error_handler_data: user data passed to optional error handler
:param pkgconf_cross_personality_t* personality: the cross-compile personality to use for defaults
:return: nothing :return: nothing
.. c:function:: pkgconf_client_t* pkgconf_client_new(pkgconf_error_handler_func_t error_handler, void *error_handler_data, const pkgconf_cross_personality_t *personality) .. c:function:: pkgconf_client_t* pkgconf_client_new(pkgconf_error_handler_func_t error_handler)
Allocate and initialise a pkgconf client object. Allocate and initialise a pkgconf client object.
:param pkgconf_error_handler_func_t error_handler: An optional error handler to use for logging errors. :param pkgconf_error_handler_func_t error_handler: An optional error handler to use for logging errors.
:param void* error_handler_data: user data passed to optional error handler :param void* error_handler_data: user data passed to optional error handler
:param pkgconf_cross_personality_t* personality: cross-compile personality to use
:return: A pkgconf client object. :return: A pkgconf client object.
:rtype: pkgconf_client_t* :rtype: pkgconf_client_t*
@ -108,14 +97,11 @@ thread boundaries.
:return: true if the warn handler processed the message, else false. :return: true if the warn handler processed the message, else false.
:rtype: bool :rtype: bool
.. c:function:: bool pkgconf_trace(const pkgconf_client_t *client, const char *filename, size_t len, const char *funcname, const char *format, ...) .. c:function:: bool pkgconf_trace(const pkgconf_client_t *client, const char *format, ...)
Report a message to a client-registered trace handler. Report a message to a client-registered trace handler.
:param pkgconf_client_t* client: The pkgconf client object to report the trace message to. :param pkgconf_client_t* client: The pkgconf client object to report the trace message to.
:param char* filename: The file the function is in.
:param size_t lineno: The line number currently being executed.
:param char* funcname: The function name to use.
:param char* format: A printf-style format string to use for formatting the trace message. :param char* format: A printf-style format string to use for formatting the trace message.
:return: true if the trace handler processed the message, else false. :return: true if the trace handler processed the message, else false.
:rtype: bool :rtype: bool

View File

@ -14,7 +14,6 @@ The `dependency` module provides support for building `dependency lists` (the ba
:param char* package: The package `atom` to set on the dependency node. :param char* package: The package `atom` to set on the dependency node.
:param char* version: The package `version` to set on the dependency node. :param char* version: The package `version` to set on the dependency node.
:param pkgconf_pkg_comparator_t compare: The comparison operator to set on the dependency node. :param pkgconf_pkg_comparator_t compare: The comparison operator to set on the dependency node.
:param uint flags: Any flags to attach to the dependency node.
:return: A dependency node. :return: A dependency node.
:rtype: pkgconf_dependency_t * :rtype: pkgconf_dependency_t *
@ -26,32 +25,9 @@ The `dependency` module provides support for building `dependency lists` (the ba
:param pkgconf_dependency_t* tail: The dependency node to add to the tail of the dependency list. :param pkgconf_dependency_t* tail: The dependency node to add to the tail of the dependency list.
:return: nothing :return: nothing
.. c:function:: void pkgconf_dependency_free_one(pkgconf_dependency_t *dep)
Frees a dependency node.
:param pkgconf_dependency_t* dep: The dependency node to free.
:return: nothing
.. c:function:: pkgconf_dependency_t *pkgconf_dependency_ref(pkgconf_client_t *owner, pkgconf_dependency_t *dep)
Increases a dependency node's refcount.
:param pkgconf_client_t* owner: The client object which owns the memory of this dependency node.
:param pkgconf_dependency_t* dep: The dependency to increase the refcount of.
:return: the dependency node on success, else NULL
.. c:function:: void pkgconf_dependency_unref(pkgconf_client_t *owner, pkgconf_dependency_t *dep)
Decreases a dependency node's refcount and frees it if necessary.
:param pkgconf_client_t* owner: The client object which owns the memory of this dependency node.
:param pkgconf_dependency_t* dep: The dependency to decrease the refcount of.
:return: nothing
.. c:function:: void pkgconf_dependency_free(pkgconf_list_t *list) .. c:function:: void pkgconf_dependency_free(pkgconf_list_t *list)
Release a dependency list and its child dependency nodes. Release a dependency list and it's child dependency nodes.
:param pkgconf_list_t* list: The dependency list to release. :param pkgconf_list_t* list: The dependency list to release.
:return: nothing :return: nothing
@ -65,7 +41,6 @@ The `dependency` module provides support for building `dependency lists` (the ba
:param pkgconf_client_t* client: The client object that owns the package this dependency list belongs to. :param pkgconf_client_t* client: The client object that owns the package this dependency list belongs to.
:param pkgconf_list_t* deplist_head: The dependency list to populate with dependency nodes. :param pkgconf_list_t* deplist_head: The dependency list to populate with dependency nodes.
:param char* depends: The dependency data to parse. :param char* depends: The dependency data to parse.
:param uint flags: Any flags to attach to the dependency nodes.
:return: nothing :return: nothing
.. c:function:: void pkgconf_dependency_parse(const pkgconf_client_t *client, pkgconf_pkg_t *pkg, pkgconf_list_t *deplist, const char *depends) .. c:function:: void pkgconf_dependency_parse(const pkgconf_client_t *client, pkgconf_pkg_t *pkg, pkgconf_list_t *deplist, const char *depends)
@ -78,13 +53,4 @@ The `dependency` module provides support for building `dependency lists` (the ba
:param pkgconf_pkg_t* pkg: The package object that owns this dependency list. :param pkgconf_pkg_t* pkg: The package object that owns this dependency list.
:param pkgconf_list_t* deplist: The dependency list to populate with dependency nodes. :param pkgconf_list_t* deplist: The dependency list to populate with dependency nodes.
:param char* depends: The dependency data to parse. :param char* depends: The dependency data to parse.
:param uint flags: Any flags to attach to the dependency nodes.
:return: nothing :return: nothing
.. c:function:: pkgconf_dependency_t *pkgconf_dependency_copy(pkgconf_client_t *client, const pkgconf_dependency_t *dep)
Copies a dependency node to a new one.
:param pkgconf_client_t* client: The client object that will own this dependency.
:param pkgconf_dependency_t* dep: The dependency node to copy.
:return: a pointer to a new dependency node, else NULL

View File

@ -6,14 +6,13 @@ The `fragment` module provides low-level management and rendering of fragment li
`fragment list` contains various `fragments` of text (such as ``-I /usr/include``) in a matter `fragment list` contains various `fragments` of text (such as ``-I /usr/include``) in a matter
which is composable, mergeable and reorderable. which is composable, mergeable and reorderable.
.. c:function:: void pkgconf_fragment_add(const pkgconf_client_t *client, pkgconf_list_t *list, const char *string, unsigned int flags) .. c:function:: void pkgconf_fragment_add(const pkgconf_client_t *client, pkgconf_list_t *list, const char *string)
Adds a `fragment` of text to a `fragment list`, possibly modifying the fragment if a sysroot is set. Adds a `fragment` of text to a `fragment list`, possibly modifying the fragment if a sysroot is set.
:param pkgconf_client_t* client: The pkgconf client being accessed. :param pkgconf_client_t* client: The pkgconf client being accessed.
:param pkgconf_list_t* list: The fragment list. :param pkgconf_list_t* list: The fragment list.
:param char* string: The string of text to add as a fragment to the fragment list. :param char* string: The string of text to add as a fragment to the fragment list.
:param uint flags: Parsing-related flags for the package.
:return: nothing :return: nothing
.. c:function:: bool pkgconf_fragment_has_system_dir(const pkgconf_client_t *client, const pkgconf_fragment_t *frag) .. c:function:: bool pkgconf_fragment_has_system_dir(const pkgconf_client_t *client, const pkgconf_fragment_t *frag)
@ -111,6 +110,5 @@ which is composable, mergeable and reorderable.
:param pkgconf_client_t* client: The pkgconf client being accessed. :param pkgconf_client_t* client: The pkgconf client being accessed.
:param pkgconf_list_t* list: The `fragment list` to add the fragment entries to. :param pkgconf_list_t* list: The `fragment list` to add the fragment entries to.
:param pkgconf_list_t* vars: A list of variables to use for variable substitution. :param pkgconf_list_t* vars: A list of variables to use for variable substitution.
:param uint flags: Any parsing flags to be aware of.
:param char* value: The string to parse into fragments. :param char* value: The string to parse into fragments.
:return: true on success, false on parse error :return: true on success, false on parse error

View File

@ -25,12 +25,12 @@ variables.
:return: number of path nodes added to the path list :return: number of path nodes added to the path list
:rtype: size_t :rtype: size_t
.. c:function:: size_t pkgconf_path_build_from_environ(const char *envvarname, const char *fallback, pkgconf_list_t *dirlist) .. c:function:: size_t pkgconf_path_build_from_environ(const char *environ, const char *fallback, pkgconf_list_t *dirlist)
Adds the paths specified in an environment variable to a path list. If the environment variable is not set, Adds the paths specified in an environment variable to a path list. If the environment variable is not set,
an optional default set of paths is added. an optional default set of paths is added.
:param char* envvarname: The environment variable to look up. :param char* environ: The environment variable to look up.
:param char* fallback: The fallback paths to use if the environment variable is not set. :param char* fallback: The fallback paths to use if the environment variable is not set.
:param pkgconf_list_t* dirlist: The path list to add the path nodes to. :param pkgconf_list_t* dirlist: The path list to add the path nodes to.
:param bool filter: Whether to perform duplicate filtering. :param bool filter: Whether to perform duplicate filtering.
@ -46,14 +46,6 @@ variables.
:return: true if the path list has a matching prefix, otherwise false :return: true if the path list has a matching prefix, otherwise false
:rtype: bool :rtype: bool
.. c:function:: void pkgconf_path_copy_list(pkgconf_list_t *dst, const pkgconf_list_t *src)
Copies a path list to another path list.
:param pkgconf_list_t* dst: The path list to copy to.
:param pkgconf_list_t* src: The path list to copy from.
:return: nothing
.. c:function:: void pkgconf_path_free(pkgconf_list_t *dirlist) .. c:function:: void pkgconf_path_free(pkgconf_list_t *dirlist)
Releases any path nodes attached to the given path list. Releases any path nodes attached to the given path list.

View File

@ -1,27 +0,0 @@
libpkgconf `personality` module
=========================
.. c:function:: const pkgconf_cross_personality_t *pkgconf_cross_personality_default(void)
Returns the default cross-compile personality.
Not thread safe.
:rtype: pkgconf_cross_personality_t*
:return: the default cross-compile personality
.. c:function:: void pkgconf_cross_personality_deinit(pkgconf_cross_personality_t *)
Decrements the count of default cross personality instances.
Not thread safe.
:rtype: void
.. c:function:: pkgconf_cross_personality_t *pkgconf_cross_personality_find(const char *triplet)
Attempts to find a cross-compile personality given a triplet.
:rtype: pkgconf_cross_personality_t*
:return: the default cross-compile personality

View File

@ -5,14 +5,22 @@ libpkgconf `pkg` module
The `pkg` module provides dependency resolution services and the overall `.pc` file parsing The `pkg` module provides dependency resolution services and the overall `.pc` file parsing
routines. routines.
.. c:function:: pkgconf_pkg_t *pkgconf_pkg_new_from_file(const pkgconf_client_t *client, const char *filename, FILE *f, unsigned int flags) .. c:function:: void pkgconf_pkg_dir_list_build(pkgconf_client_t *client)
Bootstraps the package search paths. If the ``PKGCONF_PKG_PKGF_ENV_ONLY`` `flag` is set on the client,
then only the ``PKG_CONFIG_PATH`` environment variable will be used, otherwise both the
``PKG_CONFIG_PATH`` and ``PKG_CONFIG_LIBDIR`` environment variables will be used.
:param pkgconf_client_t* client: The pkgconf client object to bootstrap.
:return: nothing
.. c:function:: pkgconf_pkg_t *pkgconf_pkg_new_from_file(const pkgconf_client_t *client, const char *filename, FILE *f)
Parse a .pc file into a pkgconf_pkg_t object structure. Parse a .pc file into a pkgconf_pkg_t object structure.
:param pkgconf_client_t* client: The pkgconf client object to use for dependency resolution. :param pkgconf_client_t* client: The pkgconf client object to use for dependency resolution.
:param char* filename: The filename of the package file (including full path). :param char* filename: The filename of the package file (including full path).
:param FILE* f: The file object to read from. :param FILE* f: The file object to read from.
:param uint flags: The flags to use when parsing.
:returns: A ``pkgconf_pkg_t`` object which contains the package data. :returns: A ``pkgconf_pkg_t`` object which contains the package data.
:rtype: pkgconf_pkg_t * :rtype: pkgconf_pkg_t *
@ -118,7 +126,7 @@ routines.
:return: On success, ``PKGCONF_PKG_ERRF_OK`` (0), else an error code. :return: On success, ``PKGCONF_PKG_ERRF_OK`` (0), else an error code.
:rtype: unsigned int :rtype: unsigned int
.. c:function:: unsigned int pkgconf_pkg_traverse(pkgconf_client_t *client, pkgconf_pkg_t *root, pkgconf_pkg_traverse_func_t func, void *data, int maxdepth, unsigned int skip_flags) .. c:function:: unsigned int pkgconf_pkg_traverse(pkgconf_client_t *client, pkgconf_pkg_t *root, pkgconf_pkg_traverse_func_t func, void *data, int maxdepth)
Walk and resolve the dependency graph up to `maxdepth` levels. Walk and resolve the dependency graph up to `maxdepth` levels.
@ -127,7 +135,6 @@ routines.
:param pkgconf_pkg_traverse_func_t func: A traversal function to call for each resolved node in the dependency graph. :param pkgconf_pkg_traverse_func_t func: A traversal function to call for each resolved node in the dependency graph.
:param void* data: An opaque pointer to data to be passed to the traversal function. :param void* data: An opaque pointer to data to be passed to the traversal function.
:param int maxdepth: The maximum depth to walk the dependency graph for. -1 means infinite recursion. :param int maxdepth: The maximum depth to walk the dependency graph for. -1 means infinite recursion.
:param uint skip_flags: Skip over dependency nodes containing the specified flags. A setting of 0 skips no dependency nodes.
:return: ``PKGCONF_PKG_ERRF_OK`` on success, else an error code. :return: ``PKGCONF_PKG_ERRF_OK`` on success, else an error code.
:rtype: unsigned int :rtype: unsigned int

View File

@ -33,32 +33,11 @@ Using the `queue` module functions is the recommended way of working with depend
:param pkgconf_list_t* list: The dependency resolution queue to release. :param pkgconf_list_t* list: The dependency resolution queue to release.
:return: nothing :return: nothing
.. c:function:: void pkgconf_solution_free(pkgconf_client_t *client, pkgconf_pkg_t *world, int maxdepth)
Removes references to package nodes contained in a solution.
:param pkgconf_client_t* client: The pkgconf client object to use for dependency resolution.
:param pkgconf_pkg_t* world: The root for the generated dependency graph. Should have PKGCONF_PKG_PROPF_VIRTUAL flag.
:returns: nothing
.. c:function:: bool pkgconf_queue_solve(pkgconf_client_t *client, pkgconf_list_t *list, pkgconf_pkg_t *world, int maxdepth)
Solves and flattens the dependency graph for the supplied dependency list.
:param pkgconf_client_t* client: The pkgconf client object to use for dependency resolution.
:param pkgconf_list_t* list: The list of dependency requests to consider.
:param pkgconf_pkg_t* world: The root for the generated dependency graph, provided by the caller. Should have PKGCONF_PKG_PROPF_VIRTUAL flag.
:param int maxdepth: The maximum allowed depth for the dependency resolver. A depth of -1 means unlimited.
:returns: true if the dependency resolver found a solution, otherwise false.
:rtype: bool
.. c:function:: void pkgconf_queue_apply(pkgconf_client_t *client, pkgconf_list_t *list, pkgconf_queue_apply_func_t func, int maxdepth, void *data) .. c:function:: void pkgconf_queue_apply(pkgconf_client_t *client, pkgconf_list_t *list, pkgconf_queue_apply_func_t func, int maxdepth, void *data)
Attempt to compile a dependency resolution queue into a dependency resolution problem, then attempt to solve the problem and Attempt to compile a dependency resolution queue into a dependency resolution problem, then attempt to solve the problem and
feed the solution to a callback function if a complete dependency graph is found. feed the solution to a callback function if a complete dependency graph is found.
This function should not be used in new code. Use pkgconf_queue_solve instead.
:param pkgconf_client_t* client: The pkgconf client object to use for dependency resolution. :param pkgconf_client_t* client: The pkgconf client object to use for dependency resolution.
:param pkgconf_list_t* list: The list of dependency requests to consider. :param pkgconf_list_t* list: The list of dependency requests to consider.
:param pkgconf_queue_apply_func_t func: The callback function to call if a solution is found by the dependency resolver. :param pkgconf_queue_apply_func_t func: The callback function to call if a solution is found by the dependency resolver.

View File

@ -64,14 +64,13 @@ attached to a given client object.
:return: the value of the variable or ``NULL`` :return: the value of the variable or ``NULL``
:rtype: char * :rtype: char *
.. c:function:: char *pkgconf_tuple_parse(const pkgconf_client_t *client, pkgconf_list_t *vars, const char *value, unsigned int flags) .. c:function:: char *pkgconf_tuple_parse(const pkgconf_client_t *client, pkgconf_list_t *vars, const char *value)
Parse an expression for variable substitution. Parse an expression for variable substitution.
:param pkgconf_client_t* client: The pkgconf client object to access. :param pkgconf_client_t* client: The pkgconf client object to access.
:param pkgconf_list_t* list: The variable list to search for variables (along side the global variable list). :param pkgconf_list_t* list: The variable list to search for variables (along side the global variable list).
:param char* value: The ``key=value`` string to parse. :param char* value: The ``key=value`` string to parse.
:param uint flags: Any flags to consider while parsing.
:return: the variable data with any variables substituted :return: the variable data with any variables substituted
:rtype: char * :rtype: char *

View File

@ -11,7 +11,6 @@ libpkgconf - an API for managing `pkg-config` modules
libpkgconf-dependency libpkgconf-dependency
libpkgconf-fragment libpkgconf-fragment
libpkgconf-path libpkgconf-path
libpkgconf-personality
libpkgconf-pkg libpkgconf-pkg
libpkgconf-queue libpkgconf-queue
libpkgconf-tuple libpkgconf-tuple

View File

@ -5,8 +5,7 @@ libdir=@libdir@
Name: libpkgconf Name: libpkgconf
Description: a library for accessing and manipulating development framework configuration Description: a library for accessing and manipulating development framework configuration
URL: https://gitea.treehouse.systems/ariadne/pkgconf URL: http://github.com/pkgconf/pkgconf
License: ISC
Version: @PACKAGE_VERSION@ Version: @PACKAGE_VERSION@
CFlags: -I${includedir}/pkgconf CFlags: -I${includedir}/pkgconf
Libs: -L${libdir} -lpkgconf Libs: -L${libdir} -lpkgconf

View File

@ -72,7 +72,7 @@ pkgconf_argv_split(const char *src, int *argc, char ***argv)
memset(buf, 0, strlen(src) + 1); memset(buf, 0, strlen(src) + 1);
*argv = calloc(argv_size, sizeof (void *)); *argv = calloc(sizeof (void *), argv_size);
(*argv)[argc_count] = dst_iter; (*argv)[argc_count] = dst_iter;
while (*src_iter) while (*src_iter)
@ -80,7 +80,7 @@ pkgconf_argv_split(const char *src, int *argc, char ***argv)
if (escaped) if (escaped)
{ {
/* POSIX: only \CHAR is special inside a double quote if CHAR is {$, `, ", \, newline}. */ /* POSIX: only \CHAR is special inside a double quote if CHAR is {$, `, ", \, newline}. */
if (quote == '"') if (quote == '\"')
{ {
if (!(*src_iter == '$' || *src_iter == '`' || *src_iter == '"' || *src_iter == '\\')) if (!(*src_iter == '$' || *src_iter == '`' || *src_iter == '"' || *src_iter == '\\'))
*dst_iter++ = '\\'; *dst_iter++ = '\\';
@ -88,9 +88,7 @@ pkgconf_argv_split(const char *src, int *argc, char ***argv)
*dst_iter++ = *src_iter; *dst_iter++ = *src_iter;
} }
else else
{
*dst_iter++ = *src_iter; *dst_iter++ = *src_iter;
}
escaped = false; escaped = false;
} }
@ -103,7 +101,7 @@ pkgconf_argv_split(const char *src, int *argc, char ***argv)
else else
*dst_iter++ = *src_iter; *dst_iter++ = *src_iter;
} }
else if (isspace((unsigned char)*src_iter)) else if (isspace((unsigned int)*src_iter))
{ {
if ((*argv)[argc_count] != NULL) if ((*argv)[argc_count] != NULL)
{ {
@ -120,9 +118,11 @@ pkgconf_argv_split(const char *src, int *argc, char ***argv)
} }
else switch(*src_iter) else switch(*src_iter)
{ {
#ifndef _WIN32
case '\\': case '\\':
escaped = true; escaped = true;
break; break;
#endif
case '\"': case '\"':
case '\'': case '\'':

View File

@ -20,12 +20,11 @@
#include <stdlib.h> #include <stdlib.h>
#include <sys/types.h> #include <sys/types.h>
#include <string.h> #include <string.h>
#include <errno.h>
#include <libpkgconf/bsdstubs.h> #include <libpkgconf/bsdstubs.h>
#include <libpkgconf/config.h> #include <libpkgconf/config.h>
#if !HAVE_DECL_STRLCPY #ifndef HAVE_STRLCPY
/* /*
* Copy src to string dst of size siz. At most siz-1 characters * Copy src to string dst of size siz. At most siz-1 characters
* will be copied. Always NUL terminates (unless siz == 0). * will be copied. Always NUL terminates (unless siz == 0).
@ -58,7 +57,7 @@ strlcpy(char *dst, const char *src, size_t siz)
} }
#endif #endif
#if !HAVE_DECL_STRLCAT #ifndef HAVE_STRLCAT
/* /*
* Appends src to string dst of size siz (unlike strncat, siz is the * Appends src to string dst of size siz (unlike strncat, siz is the
* full size of dst, not space left). At most siz-1 characters * full size of dst, not space left). At most siz-1 characters
@ -107,7 +106,7 @@ strlcat(char *dst, const char *src, size_t siz)
* from the use of this software. * from the use of this software.
*/ */
#if !HAVE_DECL_STRNDUP #ifndef HAVE_STRNDUP
/* /*
* Creates a memory buffer and copies at most 'len' characters to it. * Creates a memory buffer and copies at most 'len' characters to it.
* If 'len' is less than the length of the source string, truncation occured. * If 'len' is less than the length of the source string, truncation occured.
@ -138,23 +137,3 @@ pkgconf_strndup(const char *src, size_t len)
{ {
return strndup(src, len); return strndup(src, len);
} }
#if !HAVE_DECL_REALLOCARRAY
void *
reallocarray(void *ptr, size_t m, size_t n)
{
if (n && m > -1 / n)
{
errno = ENOMEM;
return 0;
}
return realloc(ptr, m * n);
}
#endif
void *
pkgconf_reallocarray(void *ptr, size_t m, size_t n)
{
return reallocarray(ptr, m, n);
}

View File

@ -25,7 +25,6 @@ extern "C" {
PKGCONF_API extern size_t pkgconf_strlcpy(char *dst, const char *src, size_t siz); PKGCONF_API extern size_t pkgconf_strlcpy(char *dst, const char *src, size_t siz);
PKGCONF_API extern size_t pkgconf_strlcat(char *dst, const char *src, size_t siz); PKGCONF_API extern size_t pkgconf_strlcat(char *dst, const char *src, size_t siz);
PKGCONF_API extern char *pkgconf_strndup(const char *src, size_t len); PKGCONF_API extern char *pkgconf_strndup(const char *src, size_t len);
PKGCONF_API extern void *pkgconf_reallocarray(void *ptr, size_t m, size_t n);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -16,8 +16,6 @@
#include <libpkgconf/stdinc.h> #include <libpkgconf/stdinc.h>
#include <libpkgconf/libpkgconf.h> #include <libpkgconf/libpkgconf.h>
#include <assert.h>
/* /*
* !doc * !doc
* *
@ -31,46 +29,6 @@
* be shared across threads. * be shared across threads.
*/ */
static int
cache_member_cmp(const void *a, const void *b)
{
const char *key = a;
const pkgconf_pkg_t *pkg = *(void **) b;
return strcmp(key, pkg->id);
}
static int
cache_member_sort_cmp(const void *a, const void *b)
{
const pkgconf_pkg_t *pkgA = *(void **) a;
const pkgconf_pkg_t *pkgB = *(void **) b;
if (pkgA == NULL)
return 1;
if (pkgB == NULL)
return -1;
return strcmp(pkgA->id, pkgB->id);
}
static void
cache_dump(const pkgconf_client_t *client)
{
size_t i;
PKGCONF_TRACE(client, "dumping package cache contents");
for (i = 0; i < client->cache_count; i++)
{
const pkgconf_pkg_t *pkg = client->cache_table[i];
PKGCONF_TRACE(client, SIZE_FMT_SPECIFIER": %p(%s)",
i, pkg, pkg == NULL ? "NULL" : pkg->id);
}
}
/* /*
* !doc * !doc
* *
@ -88,19 +46,17 @@ cache_dump(const pkgconf_client_t *client)
pkgconf_pkg_t * pkgconf_pkg_t *
pkgconf_cache_lookup(pkgconf_client_t *client, const char *id) pkgconf_cache_lookup(pkgconf_client_t *client, const char *id)
{ {
if (client->cache_table == NULL) pkgconf_node_t *node;
return NULL;
pkgconf_pkg_t **pkg; PKGCONF_FOREACH_LIST_ENTRY(client->pkg_cache.head, node)
pkg = bsearch(id, client->cache_table,
client->cache_count, sizeof (void *),
cache_member_cmp);
if (pkg != NULL)
{ {
PKGCONF_TRACE(client, "found: %s @%p", id, *pkg); pkgconf_pkg_t *pkg = node->data;
return pkgconf_pkg_ref(client, *pkg);
if (!strcmp(pkg->id, id))
{
PKGCONF_TRACE(client, "found: %s @%p", id, pkg);
return pkgconf_pkg_ref(client, pkg);
}
} }
PKGCONF_TRACE(client, "miss: %s", id); PKGCONF_TRACE(client, "miss: %s", id);
@ -126,19 +82,12 @@ pkgconf_cache_add(pkgconf_client_t *client, pkgconf_pkg_t *pkg)
return; return;
pkgconf_pkg_ref(client, pkg); pkgconf_pkg_ref(client, pkg);
pkgconf_node_insert(&pkg->cache_iter, pkg, &client->pkg_cache);
PKGCONF_TRACE(client, "added @%p to cache", pkg); PKGCONF_TRACE(client, "added @%p to cache", pkg);
/* mark package as cached */ /* mark package as cached */
pkg->flags |= PKGCONF_PKG_PROPF_CACHED; pkg->flags |= PKGCONF_PKG_PROPF_CACHED;
++client->cache_count;
client->cache_table = pkgconf_reallocarray(client->cache_table,
client->cache_count, sizeof (void *));
client->cache_table[client->cache_count - 1] = pkg;
qsort(client->cache_table, client->cache_count,
sizeof(void *), cache_member_sort_cmp);
} }
/* /*
@ -155,9 +104,6 @@ pkgconf_cache_add(pkgconf_client_t *client, pkgconf_pkg_t *pkg)
void void
pkgconf_cache_remove(pkgconf_client_t *client, pkgconf_pkg_t *pkg) pkgconf_cache_remove(pkgconf_client_t *client, pkgconf_pkg_t *pkg)
{ {
if (client->cache_table == NULL)
return;
if (pkg == NULL) if (pkg == NULL)
return; return;
@ -166,41 +112,7 @@ pkgconf_cache_remove(pkgconf_client_t *client, pkgconf_pkg_t *pkg)
PKGCONF_TRACE(client, "removed @%p from cache", pkg); PKGCONF_TRACE(client, "removed @%p from cache", pkg);
pkgconf_pkg_t **slot; pkgconf_node_delete(&pkg->cache_iter, &client->pkg_cache);
slot = bsearch(pkg->id, client->cache_table,
client->cache_count, sizeof (void *),
cache_member_cmp);
if (slot == NULL)
return;
(*slot)->flags &= ~PKGCONF_PKG_PROPF_CACHED;
pkgconf_pkg_unref(client, *slot);
*slot = NULL;
qsort(client->cache_table, client->cache_count,
sizeof(void *), cache_member_sort_cmp);
if (client->cache_table[client->cache_count - 1] != NULL)
{
PKGCONF_TRACE(client, "end of cache table refers to %p, not NULL",
client->cache_table[client->cache_count - 1]);
cache_dump(client);
abort();
}
client->cache_count--;
if (client->cache_count > 0)
{
client->cache_table = pkgconf_reallocarray(client->cache_table,
client->cache_count, sizeof(void *));
}
else
{
free(client->cache_table);
client->cache_table = NULL;
}
} }
/* /*
@ -217,15 +129,15 @@ pkgconf_cache_remove(pkgconf_client_t *client, pkgconf_pkg_t *pkg)
void void
pkgconf_cache_free(pkgconf_client_t *client) pkgconf_cache_free(pkgconf_client_t *client)
{ {
if (client->cache_table == NULL) pkgconf_node_t *iter, *iter2;
return;
while (client->cache_count > 0) PKGCONF_FOREACH_LIST_ENTRY_SAFE(client->pkg_cache.head, iter2, iter)
pkgconf_cache_remove(client, client->cache_table[0]); {
pkgconf_pkg_t *pkg = iter->data;
pkgconf_pkg_unref(client, pkg);
}
free(client->cache_table); memset(&client->pkg_cache, 0, sizeof client->pkg_cache);
client->cache_table = NULL;
client->cache_count = 0;
PKGCONF_TRACE(client, "cleared package cache"); PKGCONF_TRACE(client, "cleared package cache");
} }

View File

@ -98,8 +98,6 @@ pkgconf_client_init(pkgconf_client_t *client, pkgconf_error_handler_func_t error
client->error_handler_data = error_handler_data; client->error_handler_data = error_handler_data;
client->error_handler = error_handler; client->error_handler = error_handler;
client->auditf = NULL; client->auditf = NULL;
client->cache_table = NULL;
client->cache_count = 0;
#ifndef PKGCONF_LITE #ifndef PKGCONF_LITE
if (client->trace_handler == NULL) if (client->trace_handler == NULL)
@ -161,7 +159,7 @@ pkgconf_client_init(pkgconf_client_t *client, pkgconf_error_handler_func_t error
pkgconf_client_t * pkgconf_client_t *
pkgconf_client_new(pkgconf_error_handler_func_t error_handler, void *error_handler_data, const pkgconf_cross_personality_t *personality) pkgconf_client_new(pkgconf_error_handler_func_t error_handler, void *error_handler_data, const pkgconf_cross_personality_t *personality)
{ {
pkgconf_client_t *out = calloc(1, sizeof(pkgconf_client_t)); pkgconf_client_t *out = calloc(sizeof(pkgconf_client_t), 1);
pkgconf_client_init(out, error_handler, error_handler_data, personality); pkgconf_client_init(out, error_handler, error_handler_data, personality);
return out; return out;
} }
@ -403,7 +401,7 @@ pkgconf_trace(const pkgconf_client_t *client, const char *filename, size_t linen
* :rtype: bool * :rtype: bool
*/ */
bool bool
pkgconf_default_error_handler(const char *msg, const pkgconf_client_t *client, void *data) pkgconf_default_error_handler(const char *msg, const pkgconf_client_t *client, const void *data)
{ {
(void) msg; (void) msg;
(void) client; (void) client;

View File

@ -9,21 +9,6 @@
/* Define to 1 if you have the `strndup' function. */ /* Define to 1 if you have the `strndup' function. */
#mesondefine HAVE_STRNDUP #mesondefine HAVE_STRNDUP
/* Define to 1 if you have the `reallocarray' function. */
#mesondefine HAVE_REALLOCARRAY
/* Define to 1 if you have the `strlcat' function. */
#mesondefine HAVE_DECL_STRLCAT
/* Define to 1 if you have the `strlcpy' function. */
#mesondefine HAVE_DECL_STRLCPY
/* Define to 1 if you have the `strndup' function. */
#mesondefine HAVE_DECL_STRNDUP
/* Define to 1 if you have the `reallocarray' function. */
#mesondefine HAVE_DECL_REALLOCARRAY
/* Name of package */ /* Name of package */
#mesondefine PACKAGE #mesondefine PACKAGE
@ -66,8 +51,3 @@
#mesondefine SYSTEM_INCLUDEDIR #mesondefine SYSTEM_INCLUDEDIR
#mesondefine SYSTEM_LIBDIR #mesondefine SYSTEM_LIBDIR
#mesondefine PERSONALITY_PATH #mesondefine PERSONALITY_PATH
/* Enable Solaris extensions. */
#ifndef __EXTENSIONS__
# define __EXTENSIONS__ 1
#endif

View File

@ -73,7 +73,7 @@ find_colliding_dependency(const pkgconf_dependency_t *dep, const pkgconf_list_t
} }
static inline pkgconf_dependency_t * static inline pkgconf_dependency_t *
add_or_replace_dependency_node(pkgconf_client_t *client, pkgconf_dependency_t *dep, pkgconf_list_t *list) add_or_replace_dependency_node(const pkgconf_client_t *client, pkgconf_dependency_t *dep, pkgconf_list_t *list)
{ {
char depbuf[PKGCONF_ITEM_SIZE]; char depbuf[PKGCONF_ITEM_SIZE];
pkgconf_dependency_t *dep2 = find_colliding_dependency(dep, list); pkgconf_dependency_t *dep2 = find_colliding_dependency(dep, list);
@ -92,7 +92,7 @@ add_or_replace_dependency_node(pkgconf_client_t *client, pkgconf_dependency_t *d
{ {
PKGCONF_TRACE(client, "dropping dependency [%s]@%p because of collision", depbuf, dep); PKGCONF_TRACE(client, "dropping dependency [%s]@%p because of collision", depbuf, dep);
pkgconf_dependency_unref(dep->owner, dep); free(dep);
return NULL; return NULL;
} }
else if (dep2->flags && dep->flags == 0) else if (dep2->flags && dep->flags == 0)
@ -100,7 +100,7 @@ add_or_replace_dependency_node(pkgconf_client_t *client, pkgconf_dependency_t *d
PKGCONF_TRACE(client, "dropping dependency [%s]@%p because of collision", depbuf2, dep2); PKGCONF_TRACE(client, "dropping dependency [%s]@%p because of collision", depbuf2, dep2);
pkgconf_node_delete(&dep2->iter, list); pkgconf_node_delete(&dep2->iter, list);
pkgconf_dependency_unref(dep2->owner, dep2); free(dep2);
} }
else else
/* If both dependencies have equal strength, we keep both, because of situations like: /* If both dependencies have equal strength, we keep both, because of situations like:
@ -113,24 +113,17 @@ add_or_replace_dependency_node(pkgconf_client_t *client, pkgconf_dependency_t *d
} }
PKGCONF_TRACE(client, "added dependency [%s] to list @%p; flags=%x", dependency_to_str(dep, depbuf, sizeof depbuf), list, dep->flags); PKGCONF_TRACE(client, "added dependency [%s] to list @%p; flags=%x", dependency_to_str(dep, depbuf, sizeof depbuf), list, dep->flags);
pkgconf_node_insert_tail(&dep->iter, pkgconf_dependency_ref(dep->owner, dep), list); pkgconf_node_insert_tail(&dep->iter, dep, list);
/* This dependency is intentionally unowned.
*
* Internally we have no use for the returned type, and usually just
* discard it. However, there is a publig pkgconf_dependency_add
* function, which references this return value before returning it,
* giving ownership at that point.
*/
return dep; return dep;
} }
static inline pkgconf_dependency_t * static inline pkgconf_dependency_t *
pkgconf_dependency_addraw(pkgconf_client_t *client, pkgconf_list_t *list, const char *package, size_t package_sz, const char *version, size_t version_sz, pkgconf_pkg_comparator_t compare, unsigned int flags) pkgconf_dependency_addraw(const pkgconf_client_t *client, pkgconf_list_t *list, const char *package, size_t package_sz, const char *version, size_t version_sz, pkgconf_pkg_comparator_t compare, unsigned int flags)
{ {
pkgconf_dependency_t *dep; pkgconf_dependency_t *dep;
dep = calloc(1, sizeof(pkgconf_dependency_t)); dep = calloc(sizeof(pkgconf_dependency_t), 1);
dep->package = pkgconf_strndup(package, package_sz); dep->package = pkgconf_strndup(package, package_sz);
if (version_sz != 0) if (version_sz != 0)
@ -138,8 +131,6 @@ pkgconf_dependency_addraw(pkgconf_client_t *client, pkgconf_list_t *list, const
dep->compare = compare; dep->compare = compare;
dep->flags = flags; dep->flags = flags;
dep->owner = client;
dep->refcount = 0;
return add_or_replace_dependency_node(client, dep, list); return add_or_replace_dependency_node(client, dep, list);
} }
@ -161,12 +152,12 @@ pkgconf_dependency_addraw(pkgconf_client_t *client, pkgconf_list_t *list, const
* :rtype: pkgconf_dependency_t * * :rtype: pkgconf_dependency_t *
*/ */
pkgconf_dependency_t * pkgconf_dependency_t *
pkgconf_dependency_add(pkgconf_client_t *client, pkgconf_list_t *list, const char *package, const char *version, pkgconf_pkg_comparator_t compare, unsigned int flags) pkgconf_dependency_add(const pkgconf_client_t *client, pkgconf_list_t *list, const char *package, const char *version, pkgconf_pkg_comparator_t compare, unsigned int flags)
{ {
pkgconf_dependency_t *dep; if (version != NULL)
dep = pkgconf_dependency_addraw(client, list, package, strlen(package), version, return pkgconf_dependency_addraw(client, list, package, strlen(package), version, strlen(version), compare, flags);
version != NULL ? strlen(version) : 0, compare, flags);
return pkgconf_dependency_ref(dep->owner, dep); return pkgconf_dependency_addraw(client, list, package, strlen(package), NULL, 0, compare, flags);
} }
/* /*
@ -186,83 +177,12 @@ pkgconf_dependency_append(pkgconf_list_t *list, pkgconf_dependency_t *tail)
pkgconf_node_insert_tail(&tail->iter, tail, list); pkgconf_node_insert_tail(&tail->iter, tail, list);
} }
/*
* !doc
*
* .. c:function:: void pkgconf_dependency_free_one(pkgconf_dependency_t *dep)
*
* Frees a dependency node.
*
* :param pkgconf_dependency_t* dep: The dependency node to free.
* :return: nothing
*/
void
pkgconf_dependency_free_one(pkgconf_dependency_t *dep)
{
if (dep->match != NULL)
pkgconf_pkg_unref(dep->match->owner, dep->match);
if (dep->package != NULL)
free(dep->package);
if (dep->version != NULL)
free(dep->version);
free(dep);
}
/*
* !doc
*
* .. c:function:: pkgconf_dependency_t *pkgconf_dependency_ref(pkgconf_client_t *owner, pkgconf_dependency_t *dep)
*
* Increases a dependency node's refcount.
*
* :param pkgconf_client_t* owner: The client object which owns the memory of this dependency node.
* :param pkgconf_dependency_t* dep: The dependency to increase the refcount of.
* :return: the dependency node on success, else NULL
*/
pkgconf_dependency_t *
pkgconf_dependency_ref(pkgconf_client_t *client, pkgconf_dependency_t *dep)
{
if (client != dep->owner)
return NULL;
dep->refcount++;
PKGCONF_TRACE(client, "%s refcount@%p: %d", dep->package, dep, dep->refcount);
return dep;
}
/*
* !doc
*
* .. c:function:: void pkgconf_dependency_unref(pkgconf_client_t *owner, pkgconf_dependency_t *dep)
*
* Decreases a dependency node's refcount and frees it if necessary.
*
* :param pkgconf_client_t* owner: The client object which owns the memory of this dependency node.
* :param pkgconf_dependency_t* dep: The dependency to decrease the refcount of.
* :return: nothing
*/
void
pkgconf_dependency_unref(pkgconf_client_t *client, pkgconf_dependency_t *dep)
{
if (client != dep->owner)
return;
--dep->refcount;
PKGCONF_TRACE(client, "%s refcount@%p: %d", dep->package, dep, dep->refcount);
if (dep->refcount <= 0)
pkgconf_dependency_free_one(dep);
}
/* /*
* !doc * !doc
* *
* .. c:function:: void pkgconf_dependency_free(pkgconf_list_t *list) * .. c:function:: void pkgconf_dependency_free(pkgconf_list_t *list)
* *
* Release a dependency list and its child dependency nodes. * Release a dependency list and it's child dependency nodes.
* *
* :param pkgconf_list_t* list: The dependency list to release. * :param pkgconf_list_t* list: The dependency list to release.
* :return: nothing * :return: nothing
@ -276,11 +196,17 @@ pkgconf_dependency_free(pkgconf_list_t *list)
{ {
pkgconf_dependency_t *dep = node->data; pkgconf_dependency_t *dep = node->data;
pkgconf_node_delete(&dep->iter, list); if (dep->match != NULL)
pkgconf_dependency_unref(dep->owner, dep); pkgconf_pkg_unref(NULL, dep->match);
}
pkgconf_list_zero(list); if (dep->package != NULL)
free(dep->package);
if (dep->version != NULL)
free(dep->version);
free(dep);
}
} }
/* /*
@ -299,7 +225,7 @@ pkgconf_dependency_free(pkgconf_list_t *list)
* :return: nothing * :return: nothing
*/ */
void void
pkgconf_dependency_parse_str(pkgconf_client_t *client, pkgconf_list_t *deplist_head, const char *depends, unsigned int flags) pkgconf_dependency_parse_str(const pkgconf_client_t *client, pkgconf_list_t *deplist_head, const char *depends, unsigned int flags)
{ {
parse_state_t state = OUTSIDE_MODULE; parse_state_t state = OUTSIDE_MODULE;
pkgconf_pkg_comparator_t compare = PKGCONF_CMP_ANY; pkgconf_pkg_comparator_t compare = PKGCONF_CMP_ANY;
@ -329,11 +255,11 @@ pkgconf_dependency_parse_str(pkgconf_client_t *client, pkgconf_list_t *deplist_h
break; break;
case INSIDE_MODULE_NAME: case INSIDE_MODULE_NAME:
if (isspace((unsigned char)*ptr)) if (isspace((unsigned int)*ptr))
{ {
const char *sptr = ptr; const char *sptr = ptr;
while (*sptr && isspace((unsigned char)*sptr)) while (*sptr && isspace((unsigned int)*sptr))
sptr++; sptr++;
if (*sptr == '\0') if (*sptr == '\0')
@ -386,19 +312,18 @@ pkgconf_dependency_parse_str(pkgconf_client_t *client, pkgconf_list_t *deplist_h
break; break;
case INSIDE_OPERATOR: case INSIDE_OPERATOR:
if (PKGCONF_IS_OPERATOR_CHAR(*ptr)) if (!PKGCONF_IS_OPERATOR_CHAR(*ptr))
{ {
if (cnameptr < cnameend)
*cnameptr++ = *ptr;
break;
}
state = AFTER_OPERATOR; state = AFTER_OPERATOR;
compare = pkgconf_pkg_comparator_lookup_by_name(cmpname); compare = pkgconf_pkg_comparator_lookup_by_name(cmpname);
// fallthrough }
else if (cnameptr < cnameend)
*cnameptr++ = *ptr;
break;
case AFTER_OPERATOR: case AFTER_OPERATOR:
if (!isspace((unsigned char)*ptr)) if (!isspace((unsigned int)*ptr))
{ {
vstart = ptr; vstart = ptr;
state = INSIDE_VERSION; state = INSIDE_VERSION;
@ -446,43 +371,10 @@ pkgconf_dependency_parse_str(pkgconf_client_t *client, pkgconf_list_t *deplist_h
* :return: nothing * :return: nothing
*/ */
void void
pkgconf_dependency_parse(pkgconf_client_t *client, pkgconf_pkg_t *pkg, pkgconf_list_t *deplist, const char *depends, unsigned int flags) pkgconf_dependency_parse(const pkgconf_client_t *client, pkgconf_pkg_t *pkg, pkgconf_list_t *deplist, const char *depends, unsigned int flags)
{ {
char *kvdepends = pkgconf_tuple_parse(client, &pkg->vars, depends, pkg->flags); char *kvdepends = pkgconf_tuple_parse(client, &pkg->vars, depends);
pkgconf_dependency_parse_str(client, deplist, kvdepends, flags); pkgconf_dependency_parse_str(client, deplist, kvdepends, flags);
free(kvdepends); free(kvdepends);
} }
/*
* !doc
*
* .. c:function:: pkgconf_dependency_t *pkgconf_dependency_copy(pkgconf_client_t *client, const pkgconf_dependency_t *dep)
*
* Copies a dependency node to a new one.
*
* :param pkgconf_client_t* client: The client object that will own this dependency.
* :param pkgconf_dependency_t* dep: The dependency node to copy.
* :return: a pointer to a new dependency node, else NULL
*/
pkgconf_dependency_t *
pkgconf_dependency_copy(pkgconf_client_t *client, const pkgconf_dependency_t *dep)
{
pkgconf_dependency_t *new_dep;
new_dep = calloc(1, sizeof(pkgconf_dependency_t));
new_dep->package = strdup(dep->package);
if (dep->version != NULL)
new_dep->version = strdup(dep->version);
new_dep->compare = dep->compare;
new_dep->flags = dep->flags;
new_dep->owner = client;
new_dep->refcount = 0;
if (dep->match != NULL)
new_dep->match = pkgconf_pkg_ref(client, dep->match);
return pkgconf_dependency_ref(client, new_dep);
}

View File

@ -93,18 +93,15 @@ pkgconf_fragment_is_special(const char *string)
} }
static inline void static inline void
pkgconf_fragment_munge(const pkgconf_client_t *client, char *buf, size_t buflen, const char *source, const char *sysroot_dir, unsigned int flags) pkgconf_fragment_munge(const pkgconf_client_t *client, char *buf, size_t buflen, const char *source, const char *sysroot_dir)
{ {
*buf = '\0'; *buf = '\0';
if (!(flags & PKGCONF_PKG_PROPF_UNINSTALLED) || (client->flags & PKGCONF_PKG_PKGF_PKGCONF1_SYSROOT_RULES))
{
if (sysroot_dir == NULL) if (sysroot_dir == NULL)
sysroot_dir = pkgconf_tuple_find_global(client, "pc_sysrootdir"); sysroot_dir = pkgconf_tuple_find_global(client, "pc_sysrootdir");
if (sysroot_dir != NULL && pkgconf_fragment_should_munge(source, sysroot_dir)) if (sysroot_dir != NULL && pkgconf_fragment_should_munge(source, sysroot_dir))
pkgconf_strlcat(buf, sysroot_dir, buflen); pkgconf_strlcat(buf, sysroot_dir, buflen);
}
pkgconf_strlcat(buf, source, buflen); pkgconf_strlcat(buf, source, buflen);
@ -113,60 +110,27 @@ pkgconf_fragment_munge(const pkgconf_client_t *client, char *buf, size_t buflen,
} }
static inline char * static inline char *
pkgconf_fragment_copy_munged(const pkgconf_client_t *client, const char *source, unsigned int flags) pkgconf_fragment_copy_munged(const pkgconf_client_t *client, const char *source)
{ {
char mungebuf[PKGCONF_ITEM_SIZE]; char mungebuf[PKGCONF_ITEM_SIZE];
pkgconf_fragment_munge(client, mungebuf, sizeof mungebuf, source, client->sysroot_dir, flags); pkgconf_fragment_munge(client, mungebuf, sizeof mungebuf, source, client->sysroot_dir);
return strdup(mungebuf); return strdup(mungebuf);
} }
/* /*
* !doc * !doc
* *
* .. c:function:: void pkgconf_fragment_insert(const pkgconf_client_t *client, pkgconf_list_t *list, char type, const char *data, bool tail) * .. c:function:: void pkgconf_fragment_add(const pkgconf_client_t *client, pkgconf_list_t *list, const char *string)
*
* Adds a `fragment` of text to a `fragment list` directly without interpreting it.
*
* :param pkgconf_client_t* client: The pkgconf client being accessed.
* :param pkgconf_list_t* list: The fragment list.
* :param char type: The type of the fragment.
* :param char* data: The data of the fragment.
* :param bool tail: Whether to place the fragment at the beginning of the list or the end.
* :return: nothing
*/
void
pkgconf_fragment_insert(const pkgconf_client_t *client, pkgconf_list_t *list, char type, const char *data, bool tail)
{
pkgconf_fragment_t *frag;
frag = calloc(1, sizeof(pkgconf_fragment_t));
frag->type = type;
frag->data = pkgconf_fragment_copy_munged(client, data, 0);
if (tail)
{
pkgconf_node_insert_tail(&frag->iter, frag, list);
return;
}
pkgconf_node_insert(&frag->iter, frag, list);
}
/*
* !doc
*
* .. c:function:: void pkgconf_fragment_add(const pkgconf_client_t *client, pkgconf_list_t *list, const char *string, unsigned int flags)
* *
* Adds a `fragment` of text to a `fragment list`, possibly modifying the fragment if a sysroot is set. * Adds a `fragment` of text to a `fragment list`, possibly modifying the fragment if a sysroot is set.
* *
* :param pkgconf_client_t* client: The pkgconf client being accessed. * :param pkgconf_client_t* client: The pkgconf client being accessed.
* :param pkgconf_list_t* list: The fragment list. * :param pkgconf_list_t* list: The fragment list.
* :param char* string: The string of text to add as a fragment to the fragment list. * :param char* string: The string of text to add as a fragment to the fragment list.
* :param uint flags: Parsing-related flags for the package.
* :return: nothing * :return: nothing
*/ */
void void
pkgconf_fragment_add(const pkgconf_client_t *client, pkgconf_list_t *list, const char *string, unsigned int flags) pkgconf_fragment_add(const pkgconf_client_t *client, pkgconf_list_t *list, const char *string)
{ {
pkgconf_fragment_t *frag; pkgconf_fragment_t *frag;
@ -175,10 +139,10 @@ pkgconf_fragment_add(const pkgconf_client_t *client, pkgconf_list_t *list, const
if (strlen(string) > 1 && !pkgconf_fragment_is_special(string)) if (strlen(string) > 1 && !pkgconf_fragment_is_special(string))
{ {
frag = calloc(1, sizeof(pkgconf_fragment_t)); frag = calloc(sizeof(pkgconf_fragment_t), 1);
frag->type = *(string + 1); frag->type = *(string + 1);
frag->data = pkgconf_fragment_copy_munged(client, string + 2, flags); frag->data = pkgconf_fragment_copy_munged(client, string + 2);
PKGCONF_TRACE(client, "added fragment {%c, '%s'} to list @%p", frag->type, frag->data, list); PKGCONF_TRACE(client, "added fragment {%c, '%s'} to list @%p", frag->type, frag->data, list);
} }
@ -192,12 +156,12 @@ pkgconf_fragment_add(const pkgconf_client_t *client, pkgconf_list_t *list, const
pkgconf_fragment_t *parent = list->tail->data; pkgconf_fragment_t *parent = list->tail->data;
/* only attempt to merge 'special' fragments together */ /* only attempt to merge 'special' fragments together */
if (!parent->type && parent->data != NULL && pkgconf_fragment_is_unmergeable(parent->data)) if (!parent->type && pkgconf_fragment_is_unmergeable(parent->data))
{ {
size_t len; size_t len;
char *newdata; char *newdata;
pkgconf_fragment_munge(client, mungebuf, sizeof mungebuf, string, NULL, flags); pkgconf_fragment_munge(client, mungebuf, sizeof mungebuf, string, NULL);
len = strlen(parent->data) + strlen(mungebuf) + 2; len = strlen(parent->data) + strlen(mungebuf) + 2;
newdata = malloc(len); newdata = malloc(len);
@ -224,7 +188,7 @@ pkgconf_fragment_add(const pkgconf_client_t *client, pkgconf_list_t *list, const
} }
} }
frag = calloc(1, sizeof(pkgconf_fragment_t)); frag = calloc(sizeof(pkgconf_fragment_t), 1);
frag->type = 0; frag->type = 0;
frag->data = strdup(string); frag->data = strdup(string);
@ -385,7 +349,7 @@ pkgconf_fragment_copy(const pkgconf_client_t *client, pkgconf_list_t *list, cons
else if (!is_private && !pkgconf_fragment_can_merge_back(base, client->flags, is_private) && (pkgconf_fragment_lookup(list, base) != NULL)) else if (!is_private && !pkgconf_fragment_can_merge_back(base, client->flags, is_private) && (pkgconf_fragment_lookup(list, base) != NULL))
return; return;
frag = calloc(1, sizeof(pkgconf_fragment_t)); frag = calloc(sizeof(pkgconf_fragment_t), 1);
frag->type = base->type; frag->type = base->type;
frag->merged = base->merged; frag->merged = base->merged;
@ -459,7 +423,7 @@ fragment_quote(const pkgconf_fragment_t *frag)
if (frag->data == NULL) if (frag->data == NULL)
return NULL; return NULL;
out = dst = calloc(1, outlen); out = dst = calloc(outlen, 1);
for (; *src; src++) for (; *src; src++)
{ {
@ -563,7 +527,6 @@ fragment_render_buf(const pkgconf_list_t *list, char *buf, size_t buflen, bool e
free(quoted); free(quoted);
} }
if (node->next != NULL)
*bptr++ = ' '; *bptr++ = ' ';
} }
@ -700,16 +663,15 @@ pkgconf_fragment_free(pkgconf_list_t *list)
* :param pkgconf_client_t* client: The pkgconf client being accessed. * :param pkgconf_client_t* client: The pkgconf client being accessed.
* :param pkgconf_list_t* list: The `fragment list` to add the fragment entries to. * :param pkgconf_list_t* list: The `fragment list` to add the fragment entries to.
* :param pkgconf_list_t* vars: A list of variables to use for variable substitution. * :param pkgconf_list_t* vars: A list of variables to use for variable substitution.
* :param uint flags: Any parsing flags to be aware of.
* :param char* value: The string to parse into fragments. * :param char* value: The string to parse into fragments.
* :return: true on success, false on parse error * :return: true on success, false on parse error
*/ */
bool bool
pkgconf_fragment_parse(const pkgconf_client_t *client, pkgconf_list_t *list, pkgconf_list_t *vars, const char *value, unsigned int flags) pkgconf_fragment_parse(const pkgconf_client_t *client, pkgconf_list_t *list, pkgconf_list_t *vars, const char *value)
{ {
int i, ret, argc; int i, ret, argc;
char **argv; char **argv;
char *repstr = pkgconf_tuple_parse(client, vars, value, flags); char *repstr = pkgconf_tuple_parse(client, vars, value);
PKGCONF_TRACE(client, "post-subst: [%s] -> [%s]", value, repstr); PKGCONF_TRACE(client, "post-subst: [%s] -> [%s]", value, repstr);
@ -723,8 +685,6 @@ pkgconf_fragment_parse(const pkgconf_client_t *client, pkgconf_list_t *list, pkg
for (i = 0; i < argc; i++) for (i = 0; i < argc; i++)
{ {
PKGCONF_TRACE(client, "processing %s", argv[i]);
if (argv[i] == NULL) if (argv[i] == NULL)
{ {
PKGCONF_TRACE(client, "parsed fragment string is inconsistent: argc = %d while argv[%d] == NULL", argc, i); PKGCONF_TRACE(client, "parsed fragment string is inconsistent: argc = %d while argv[%d] == NULL", argc, i);
@ -733,7 +693,7 @@ pkgconf_fragment_parse(const pkgconf_client_t *client, pkgconf_list_t *list, pkg
return false; return false;
} }
pkgconf_fragment_add(client, list, argv[i], flags); pkgconf_fragment_add(client, list, argv[i]);
} }
pkgconf_argv_free(argv); pkgconf_argv_free(argv);

View File

@ -34,14 +34,6 @@ typedef struct {
#define PKGCONF_LIST_INITIALIZER { NULL, NULL, 0 } #define PKGCONF_LIST_INITIALIZER { NULL, NULL, 0 }
static inline void
pkgconf_list_zero(pkgconf_list_t *list)
{
list->head = NULL;
list->tail = NULL;
list->length = 0;
}
static inline void static inline void
pkgconf_node_insert(pkgconf_node_t *node, void *data, pkgconf_list_t *list) pkgconf_node_insert(pkgconf_node_t *node, void *data, pkgconf_list_t *list)
{ {

View File

@ -2,7 +2,8 @@
#define LIBPKGCONF_LIBPKGCONF_API_H #define LIBPKGCONF_LIBPKGCONF_API_H
/* Makefile.am specifies visibility using the libtool option -export-symbols-regex '^pkgconf_' /* Makefile.am specifies visibility using the libtool option -export-symbols-regex '^pkgconf_'
* Unfortunately, that is not available when building with meson, so use attributes instead. * Unfortunately, that is not available when building with cmake, so use attributes instead,
* in a way that doesn't depend on any cmake magic.
*/ */
#if defined(PKGCONFIG_IS_STATIC) #if defined(PKGCONFIG_IS_STATIC)
# define PKGCONF_API # define PKGCONF_API

View File

@ -16,12 +16,10 @@
#ifndef LIBPKGCONF__LIBPKGCONF_H #ifndef LIBPKGCONF__LIBPKGCONF_H
#define LIBPKGCONF__LIBPKGCONF_H #define LIBPKGCONF__LIBPKGCONF_H
#include <inttypes.h>
#include <stdio.h> #include <stdio.h>
#include <stdarg.h> #include <stdarg.h>
#include <stddef.h> #include <stddef.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h>
#include <libpkgconf/libpkgconf-api.h> #include <libpkgconf/libpkgconf-api.h>
#include <libpkgconf/iter.h> #include <libpkgconf/iter.h>
#include <libpkgconf/bsdstubs.h> #include <libpkgconf/bsdstubs.h>
@ -68,7 +66,6 @@ typedef struct pkgconf_fragment_ pkgconf_fragment_t;
typedef struct pkgconf_path_ pkgconf_path_t; typedef struct pkgconf_path_ pkgconf_path_t;
typedef struct pkgconf_client_ pkgconf_client_t; typedef struct pkgconf_client_ pkgconf_client_t;
typedef struct pkgconf_cross_personality_ pkgconf_cross_personality_t; typedef struct pkgconf_cross_personality_ pkgconf_cross_personality_t;
typedef struct pkgconf_queue_ pkgconf_queue_t;
#define PKGCONF_ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x))) #define PKGCONF_ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x)))
@ -81,13 +78,8 @@ typedef struct pkgconf_queue_ pkgconf_queue_t;
#define PKGCONF_FOREACH_LIST_ENTRY_REVERSE(tail, value) \ #define PKGCONF_FOREACH_LIST_ENTRY_REVERSE(tail, value) \
for ((value) = (tail); (value) != NULL; (value) = (value)->prev) for ((value) = (tail); (value) != NULL; (value) = (value)->prev)
#define LIBPKGCONF_VERSION 20300 #define LIBPKGCONF_VERSION 10801
#define LIBPKGCONF_VERSION_STR "2.3.0" #define LIBPKGCONF_VERSION_STR "1.8.1"
struct pkgconf_queue_ {
pkgconf_node_t iter;
char *package;
};
struct pkgconf_fragment_ { struct pkgconf_fragment_ {
pkgconf_node_t iter; pkgconf_node_t iter;
@ -108,9 +100,6 @@ struct pkgconf_dependency_ {
pkgconf_pkg_t *match; pkgconf_pkg_t *match;
unsigned int flags; unsigned int flags;
int refcount;
pkgconf_client_t *owner;
}; };
struct pkgconf_tuple_ { struct pkgconf_tuple_ {
@ -118,12 +107,8 @@ struct pkgconf_tuple_ {
char *key; char *key;
char *value; char *value;
unsigned int flags;
}; };
#define PKGCONF_PKG_TUPLEF_OVERRIDE 0x1
struct pkgconf_path_ { struct pkgconf_path_ {
pkgconf_node_t lnode; pkgconf_node_t lnode;
@ -135,12 +120,13 @@ struct pkgconf_path_ {
#define PKGCONF_PKG_PROPF_NONE 0x00 #define PKGCONF_PKG_PROPF_NONE 0x00
#define PKGCONF_PKG_PROPF_STATIC 0x01 #define PKGCONF_PKG_PROPF_STATIC 0x01
#define PKGCONF_PKG_PROPF_CACHED 0x02 #define PKGCONF_PKG_PROPF_CACHED 0x02
#define PKGCONF_PKG_PROPF_SEEN 0x04
#define PKGCONF_PKG_PROPF_UNINSTALLED 0x08 #define PKGCONF_PKG_PROPF_UNINSTALLED 0x08
#define PKGCONF_PKG_PROPF_VIRTUAL 0x10 #define PKGCONF_PKG_PROPF_VIRTUAL 0x10
#define PKGCONF_PKG_PROPF_ANCESTOR 0x20
#define PKGCONF_PKG_PROPF_VISITED_PRIVATE 0x40
struct pkgconf_pkg_ { struct pkgconf_pkg_ {
pkgconf_node_t cache_iter;
int refcount; int refcount;
char *id; char *id;
char *filename; char *filename;
@ -149,10 +135,6 @@ struct pkgconf_pkg_ {
char *description; char *description;
char *url; char *url;
char *pc_filedir; char *pc_filedir;
char *license;
char *maintainer;
char *copyright;
char *why;
pkgconf_list_t libs; pkgconf_list_t libs;
pkgconf_list_t libs_private; pkgconf_list_t libs_private;
@ -175,18 +157,16 @@ struct pkgconf_pkg_ {
*/ */
pkgconf_tuple_t *orig_prefix; pkgconf_tuple_t *orig_prefix;
pkgconf_tuple_t *prefix; pkgconf_tuple_t *prefix;
uint64_t serial;
uint64_t identifier;
}; };
typedef bool (*pkgconf_pkg_iteration_func_t)(const pkgconf_pkg_t *pkg, void *data); typedef bool (*pkgconf_pkg_iteration_func_t)(const pkgconf_pkg_t *pkg, void *data);
typedef void (*pkgconf_pkg_traverse_func_t)(pkgconf_client_t *client, pkgconf_pkg_t *pkg, void *data); typedef void (*pkgconf_pkg_traverse_func_t)(pkgconf_client_t *client, pkgconf_pkg_t *pkg, void *data);
typedef bool (*pkgconf_queue_apply_func_t)(pkgconf_client_t *client, pkgconf_pkg_t *world, void *data, int maxdepth); typedef bool (*pkgconf_queue_apply_func_t)(pkgconf_client_t *client, pkgconf_pkg_t *world, void *data, int maxdepth);
typedef bool (*pkgconf_error_handler_func_t)(const char *msg, const pkgconf_client_t *client, void *data); typedef bool (*pkgconf_error_handler_func_t)(const char *msg, const pkgconf_client_t *client, const void *data);
struct pkgconf_client_ { struct pkgconf_client_ {
pkgconf_list_t dir_list; pkgconf_list_t dir_list;
pkgconf_list_t pkg_cache;
pkgconf_list_t filter_libdirs; pkgconf_list_t filter_libdirs;
pkgconf_list_t filter_includedirs; pkgconf_list_t filter_includedirs;
@ -211,12 +191,6 @@ struct pkgconf_client_ {
char *prefix_varname; char *prefix_varname;
bool already_sent_notice; bool already_sent_notice;
uint64_t serial;
uint64_t identifier;
pkgconf_pkg_t **cache_table;
size_t cache_count;
}; };
struct pkgconf_cross_personality_ { struct pkgconf_cross_personality_ {
@ -259,7 +233,7 @@ PKGCONF_API pkgconf_cross_personality_t *pkgconf_cross_personality_default(void)
PKGCONF_API pkgconf_cross_personality_t *pkgconf_cross_personality_find(const char *triplet); PKGCONF_API pkgconf_cross_personality_t *pkgconf_cross_personality_find(const char *triplet);
PKGCONF_API void pkgconf_cross_personality_deinit(pkgconf_cross_personality_t *personality); PKGCONF_API void pkgconf_cross_personality_deinit(pkgconf_cross_personality_t *personality);
#define PKGCONF_IS_MODULE_SEPARATOR(c) ((c) == ',' || isspace ((unsigned char)(c))) #define PKGCONF_IS_MODULE_SEPARATOR(c) ((c) == ',' || isspace ((unsigned int)(c)))
#define PKGCONF_IS_OPERATOR_CHAR(c) ((c) == '<' || (c) == '>' || (c) == '!' || (c) == '=') #define PKGCONF_IS_OPERATOR_CHAR(c) ((c) == '<' || (c) == '>' || (c) == '!' || (c) == '=')
#define PKGCONF_PKG_PKGF_NONE 0x0000 #define PKGCONF_PKG_PKGF_NONE 0x0000
@ -279,11 +253,8 @@ PKGCONF_API void pkgconf_cross_personality_deinit(pkgconf_cross_personality_t *p
#define PKGCONF_PKG_PKGF_DONT_FILTER_INTERNAL_CFLAGS 0x2000 #define PKGCONF_PKG_PKGF_DONT_FILTER_INTERNAL_CFLAGS 0x2000
#define PKGCONF_PKG_PKGF_DONT_MERGE_SPECIAL_FRAGMENTS 0x4000 #define PKGCONF_PKG_PKGF_DONT_MERGE_SPECIAL_FRAGMENTS 0x4000
#define PKGCONF_PKG_PKGF_FDO_SYSROOT_RULES 0x8000 #define PKGCONF_PKG_PKGF_FDO_SYSROOT_RULES 0x8000
#define PKGCONF_PKG_PKGF_PKGCONF1_SYSROOT_RULES 0x10000
#define PKGCONF_PKG_DEPF_INTERNAL 0x1 #define PKGCONF_PKG_DEPF_INTERNAL 0x1
#define PKGCONF_PKG_DEPF_PRIVATE 0x2
#define PKGCONF_PKG_DEPF_QUERY 0x4
#define PKGCONF_PKG_ERRF_OK 0x0 #define PKGCONF_PKG_ERRF_OK 0x0
#define PKGCONF_PKG_ERRF_PACKAGE_NOT_FOUND 0x1 #define PKGCONF_PKG_ERRF_PACKAGE_NOT_FOUND 0x1
@ -311,17 +282,17 @@ PKGCONF_API void pkgconf_parser_parse(FILE *f, void *data, const pkgconf_parser_
PKGCONF_API bool pkgconf_error(const pkgconf_client_t *client, const char *format, ...) PRINTFLIKE(2, 3); PKGCONF_API bool pkgconf_error(const pkgconf_client_t *client, const char *format, ...) PRINTFLIKE(2, 3);
PKGCONF_API bool pkgconf_warn(const pkgconf_client_t *client, const char *format, ...) PRINTFLIKE(2, 3); PKGCONF_API bool pkgconf_warn(const pkgconf_client_t *client, const char *format, ...) PRINTFLIKE(2, 3);
PKGCONF_API bool pkgconf_trace(const pkgconf_client_t *client, const char *filename, size_t lineno, const char *funcname, const char *format, ...) PRINTFLIKE(5, 6); PKGCONF_API bool pkgconf_trace(const pkgconf_client_t *client, const char *filename, size_t lineno, const char *funcname, const char *format, ...) PRINTFLIKE(5, 6);
PKGCONF_API bool pkgconf_default_error_handler(const char *msg, const pkgconf_client_t *client, void *data); PKGCONF_API bool pkgconf_default_error_handler(const char *msg, const pkgconf_client_t *client, const void *data);
#ifndef PKGCONF_LITE #ifndef PKGCONF_LITE
#if defined(__GNUC__) || defined(__INTEL_COMPILER) #if defined(__GNUC__) || defined(__INTEL_COMPILER)
#define PKGCONF_TRACE(client, ...) do { \ #define PKGCONF_TRACE(client, ...) do { \
pkgconf_trace(client, __FILE__, __LINE__, __PRETTY_FUNCTION__, __VA_ARGS__); \ pkgconf_trace(client, __FILE__, __LINE__, __PRETTY_FUNCTION__, __VA_ARGS__); \
} while (0) } while (0);
#else #else
#define PKGCONF_TRACE(client, ...) do { \ #define PKGCONF_TRACE(client, ...) do { \
pkgconf_trace(client, __FILE__, __LINE__, __func__, __VA_ARGS__); \ pkgconf_trace(client, __FILE__, __LINE__, __func__, __VA_ARGS__); \
} while (0) } while (0);
#endif #endif
#else #else
#define PKGCONF_TRACE(client, ...) #define PKGCONF_TRACE(client, ...)
@ -344,16 +315,12 @@ PKGCONF_API int pkgconf_compare_version(const char *a, const char *b);
PKGCONF_API pkgconf_pkg_t *pkgconf_scan_all(pkgconf_client_t *client, void *ptr, pkgconf_pkg_iteration_func_t func); PKGCONF_API pkgconf_pkg_t *pkgconf_scan_all(pkgconf_client_t *client, void *ptr, pkgconf_pkg_iteration_func_t func);
/* parse.c */ /* parse.c */
PKGCONF_API pkgconf_pkg_t *pkgconf_pkg_new_from_file(pkgconf_client_t *client, const char *path, FILE *f, unsigned int flags); PKGCONF_API pkgconf_pkg_t *pkgconf_pkg_new_from_file(pkgconf_client_t *client, const char *path, FILE *f);
PKGCONF_API void pkgconf_dependency_parse_str(pkgconf_client_t *client, pkgconf_list_t *deplist_head, const char *depends, unsigned int flags); PKGCONF_API void pkgconf_dependency_parse_str(const pkgconf_client_t *client, pkgconf_list_t *deplist_head, const char *depends, unsigned int flags);
PKGCONF_API void pkgconf_dependency_parse(pkgconf_client_t *client, pkgconf_pkg_t *pkg, pkgconf_list_t *deplist_head, const char *depends, unsigned int flags); PKGCONF_API void pkgconf_dependency_parse(const pkgconf_client_t *client, pkgconf_pkg_t *pkg, pkgconf_list_t *deplist_head, const char *depends, unsigned int flags);
PKGCONF_API void pkgconf_dependency_append(pkgconf_list_t *list, pkgconf_dependency_t *tail); PKGCONF_API void pkgconf_dependency_append(pkgconf_list_t *list, pkgconf_dependency_t *tail);
PKGCONF_API void pkgconf_dependency_free(pkgconf_list_t *list); PKGCONF_API void pkgconf_dependency_free(pkgconf_list_t *list);
PKGCONF_API void pkgconf_dependency_free_one(pkgconf_dependency_t *dep); PKGCONF_API pkgconf_dependency_t *pkgconf_dependency_add(const pkgconf_client_t *client, pkgconf_list_t *list, const char *package, const char *version, pkgconf_pkg_comparator_t compare, unsigned int flags);
PKGCONF_API pkgconf_dependency_t *pkgconf_dependency_add(pkgconf_client_t *client, pkgconf_list_t *list, const char *package, const char *version, pkgconf_pkg_comparator_t compare, unsigned int flags);
PKGCONF_API pkgconf_dependency_t *pkgconf_dependency_ref(pkgconf_client_t *client, pkgconf_dependency_t *dep);
PKGCONF_API void pkgconf_dependency_unref(pkgconf_client_t *client, pkgconf_dependency_t *dep);
PKGCONF_API pkgconf_dependency_t *pkgconf_dependency_copy(pkgconf_client_t *client, const pkgconf_dependency_t *dep);
/* argvsplit.c */ /* argvsplit.c */
PKGCONF_API int pkgconf_argv_split(const char *src, int *argc, char ***argv); PKGCONF_API int pkgconf_argv_split(const char *src, int *argc, char ***argv);
@ -366,9 +333,8 @@ typedef struct pkgconf_fragment_render_ops_ {
} pkgconf_fragment_render_ops_t; } pkgconf_fragment_render_ops_t;
typedef bool (*pkgconf_fragment_filter_func_t)(const pkgconf_client_t *client, const pkgconf_fragment_t *frag, void *data); typedef bool (*pkgconf_fragment_filter_func_t)(const pkgconf_client_t *client, const pkgconf_fragment_t *frag, void *data);
PKGCONF_API bool pkgconf_fragment_parse(const pkgconf_client_t *client, pkgconf_list_t *list, pkgconf_list_t *vars, const char *value, unsigned int flags); PKGCONF_API bool pkgconf_fragment_parse(const pkgconf_client_t *client, pkgconf_list_t *list, pkgconf_list_t *vars, const char *value);
PKGCONF_API void pkgconf_fragment_insert(const pkgconf_client_t *client, pkgconf_list_t *list, char type, const char *data, bool tail); PKGCONF_API void pkgconf_fragment_add(const pkgconf_client_t *client, pkgconf_list_t *list, const char *string);
PKGCONF_API void pkgconf_fragment_add(const pkgconf_client_t *client, pkgconf_list_t *list, const char *string, unsigned int flags);
PKGCONF_API void pkgconf_fragment_copy(const pkgconf_client_t *client, pkgconf_list_t *list, const pkgconf_fragment_t *base, bool is_private); PKGCONF_API void pkgconf_fragment_copy(const pkgconf_client_t *client, pkgconf_list_t *list, const pkgconf_fragment_t *base, bool is_private);
PKGCONF_API void pkgconf_fragment_copy_list(const pkgconf_client_t *client, pkgconf_list_t *list, const pkgconf_list_t *base); PKGCONF_API void pkgconf_fragment_copy_list(const pkgconf_client_t *client, pkgconf_list_t *list, const pkgconf_list_t *base);
PKGCONF_API void pkgconf_fragment_delete(pkgconf_list_t *list, pkgconf_fragment_t *node); PKGCONF_API void pkgconf_fragment_delete(pkgconf_list_t *list, pkgconf_fragment_t *node);
@ -383,9 +349,9 @@ PKGCONF_API bool pkgconf_fragment_has_system_dir(const pkgconf_client_t *client,
PKGCONF_API char *pkgconf_fgetline(char *line, size_t size, FILE *stream); PKGCONF_API char *pkgconf_fgetline(char *line, size_t size, FILE *stream);
/* tuple.c */ /* tuple.c */
PKGCONF_API pkgconf_tuple_t *pkgconf_tuple_add(const pkgconf_client_t *client, pkgconf_list_t *parent, const char *key, const char *value, bool parse, unsigned int flags); PKGCONF_API pkgconf_tuple_t *pkgconf_tuple_add(const pkgconf_client_t *client, pkgconf_list_t *parent, const char *key, const char *value, bool parse);
PKGCONF_API char *pkgconf_tuple_find(const pkgconf_client_t *client, pkgconf_list_t *list, const char *key); PKGCONF_API char *pkgconf_tuple_find(const pkgconf_client_t *client, pkgconf_list_t *list, const char *key);
PKGCONF_API char *pkgconf_tuple_parse(const pkgconf_client_t *client, pkgconf_list_t *list, const char *value, unsigned int flags); PKGCONF_API char *pkgconf_tuple_parse(const pkgconf_client_t *client, pkgconf_list_t *list, const char *value);
PKGCONF_API void pkgconf_tuple_free(pkgconf_list_t *list); PKGCONF_API void pkgconf_tuple_free(pkgconf_list_t *list);
PKGCONF_API void pkgconf_tuple_free_entry(pkgconf_tuple_t *tuple, pkgconf_list_t *list); PKGCONF_API void pkgconf_tuple_free_entry(pkgconf_tuple_t *tuple, pkgconf_list_t *list);
PKGCONF_API void pkgconf_tuple_add_global(pkgconf_client_t *client, const char *key, const char *value); PKGCONF_API void pkgconf_tuple_add_global(pkgconf_client_t *client, const char *key, const char *value);
@ -396,11 +362,9 @@ PKGCONF_API void pkgconf_tuple_define_global(pkgconf_client_t *client, const cha
/* queue.c */ /* queue.c */
PKGCONF_API void pkgconf_queue_push(pkgconf_list_t *list, const char *package); PKGCONF_API void pkgconf_queue_push(pkgconf_list_t *list, const char *package);
PKGCONF_API bool pkgconf_queue_compile(pkgconf_client_t *client, pkgconf_pkg_t *world, pkgconf_list_t *list); PKGCONF_API bool pkgconf_queue_compile(pkgconf_client_t *client, pkgconf_pkg_t *world, pkgconf_list_t *list);
PKGCONF_API bool pkgconf_queue_solve(pkgconf_client_t *client, pkgconf_list_t *list, pkgconf_pkg_t *world, int maxdepth);
PKGCONF_API void pkgconf_queue_free(pkgconf_list_t *list); PKGCONF_API void pkgconf_queue_free(pkgconf_list_t *list);
PKGCONF_API bool pkgconf_queue_apply(pkgconf_client_t *client, pkgconf_list_t *list, pkgconf_queue_apply_func_t func, int maxdepth, void *data); PKGCONF_API bool pkgconf_queue_apply(pkgconf_client_t *client, pkgconf_list_t *list, pkgconf_queue_apply_func_t func, int maxdepth, void *data);
PKGCONF_API bool pkgconf_queue_validate(pkgconf_client_t *client, pkgconf_list_t *list, int maxdepth); PKGCONF_API bool pkgconf_queue_validate(pkgconf_client_t *client, pkgconf_list_t *list, int maxdepth);
PKGCONF_API void pkgconf_solution_free(pkgconf_client_t *client, pkgconf_pkg_t *world);
/* cache.c */ /* cache.c */
PKGCONF_API pkgconf_pkg_t *pkgconf_cache_lookup(pkgconf_client_t *client, const char *id); PKGCONF_API pkgconf_pkg_t *pkgconf_cache_lookup(pkgconf_client_t *client, const char *id);
@ -415,7 +379,6 @@ PKGCONF_API void pkgconf_audit_log_dependency(pkgconf_client_t *client, const pk
/* path.c */ /* path.c */
PKGCONF_API void pkgconf_path_add(const char *text, pkgconf_list_t *dirlist, bool filter); PKGCONF_API void pkgconf_path_add(const char *text, pkgconf_list_t *dirlist, bool filter);
PKGCONF_API void pkgconf_path_prepend(const char *text, pkgconf_list_t *dirlist, bool filter);
PKGCONF_API size_t pkgconf_path_split(const char *text, pkgconf_list_t *dirlist, bool filter); PKGCONF_API size_t pkgconf_path_split(const char *text, pkgconf_list_t *dirlist, bool filter);
PKGCONF_API size_t pkgconf_path_build_from_environ(const char *envvarname, const char *fallback, pkgconf_list_t *dirlist, bool filter); PKGCONF_API size_t pkgconf_path_build_from_environ(const char *envvarname, const char *fallback, pkgconf_list_t *dirlist, bool filter);
PKGCONF_API bool pkgconf_path_match_list(const char *path, const pkgconf_list_t *dirlist); PKGCONF_API bool pkgconf_path_match_list(const char *path, const pkgconf_list_t *dirlist);

View File

@ -44,7 +44,7 @@ pkgconf_parser_parse(FILE *f, void *data, const pkgconf_parser_operand_func_t *o
lineno++; lineno++;
p = readbuf; p = readbuf;
while (*p && isspace((unsigned char)*p)) while (*p && isspace((unsigned int)*p))
p++; p++;
if (*p && p != readbuf) if (*p && p != readbuf)
{ {
@ -53,14 +53,13 @@ pkgconf_parser_parse(FILE *f, void *data, const pkgconf_parser_operand_func_t *o
warned_key_whitespace = true; warned_key_whitespace = true;
} }
key = p; key = p;
while (*p && (isalpha((unsigned char)*p) || isdigit((unsigned char)*p) || *p == '_' || *p == '.')) while (*p && (isalpha((unsigned int)*p) || isdigit((unsigned int)*p) || *p == '_' || *p == '.'))
p++; p++;
if (!isalpha((unsigned char)*key) && if (!isalpha((unsigned int)*key) && !isdigit((unsigned int)*p))
!isdigit((unsigned char)*p))
continue; continue;
while (*p && isspace((unsigned char)*p)) while (*p && isspace((unsigned int)*p))
{ {
if (!warned_key_whitespace) if (!warned_key_whitespace)
{ {
@ -81,12 +80,12 @@ pkgconf_parser_parse(FILE *f, void *data, const pkgconf_parser_operand_func_t *o
p++; p++;
} }
while (*p && isspace((unsigned char)*p)) while (*p && isspace((unsigned int)*p))
p++; p++;
value = p; value = p;
p = value + (strlen(value) - 1); p = value + (strlen(value) - 1);
while (*p && isspace((unsigned char) *p) && p > value) while (*p && isspace((unsigned int) *p) && p > value)
{ {
if (!warned_value_whitespace && op == '=') if (!warned_value_whitespace && op == '=')
{ {

View File

@ -58,51 +58,6 @@ path_list_contains_entry(const char *text, pkgconf_list_t *dirlist)
* variables. * variables.
*/ */
static pkgconf_path_t *
prepare_path_node(const char *text, pkgconf_list_t *dirlist, bool filter)
{
pkgconf_path_t *node;
char path[PKGCONF_ITEM_SIZE];
pkgconf_strlcpy(path, text, sizeof path);
pkgconf_path_relocate(path, sizeof path);
#ifdef PKGCONF_CACHE_INODES
struct stat st;
if (filter)
{
if (lstat(path, &st) == -1)
return NULL;
if (S_ISLNK(st.st_mode))
{
char pathbuf[PKGCONF_ITEM_SIZE * 4];
char *linkdest = realpath(path, pathbuf);
if (linkdest != NULL && stat(linkdest, &st) == -1)
return NULL;
}
if (path_list_contains_entry(path, dirlist, &st))
return NULL;
}
#else
if (filter && path_list_contains_entry(path, dirlist))
return NULL;
#endif
node = calloc(1, sizeof(pkgconf_path_t));
node->path = strdup(path);
#ifdef PKGCONF_CACHE_INODES
if (filter) {
node->handle_path = (void *)(intptr_t) st.st_ino;
node->handle_device = (void *)(intptr_t) st.st_dev;
}
#endif
return node;
}
/* /*
* !doc * !doc
* *
@ -118,35 +73,48 @@ prepare_path_node(const char *text, pkgconf_list_t *dirlist, bool filter)
void void
pkgconf_path_add(const char *text, pkgconf_list_t *dirlist, bool filter) pkgconf_path_add(const char *text, pkgconf_list_t *dirlist, bool filter)
{ {
pkgconf_path_t *node = prepare_path_node(text, dirlist, filter); pkgconf_path_t *node;
if (node == NULL) char path[PKGCONF_ITEM_SIZE];
pkgconf_strlcpy(path, text, sizeof path);
pkgconf_path_relocate(path, sizeof path);
#ifdef PKGCONF_CACHE_INODES
struct stat st;
if (filter)
{
if (lstat(path, &st) == -1)
return; return;
if (S_ISLNK(st.st_mode))
{
char pathbuf[PKGCONF_ITEM_SIZE * 4];
char *linkdest = realpath(path, pathbuf);
if (linkdest != NULL && stat(linkdest, &st) == -1)
return;
}
if (path_list_contains_entry(path, dirlist, &st))
return;
}
#else
if (filter && path_list_contains_entry(path, dirlist))
return;
#endif
node = calloc(sizeof(pkgconf_path_t), 1);
node->path = strdup(path);
#ifdef PKGCONF_CACHE_INODES
if (filter) {
node->handle_path = (void *)(intptr_t) st.st_ino;
node->handle_device = (void *)(intptr_t) st.st_dev;
}
#endif
pkgconf_node_insert_tail(&node->lnode, node, dirlist); pkgconf_node_insert_tail(&node->lnode, node, dirlist);
} }
/*
* !doc
*
* .. c:function:: void pkgconf_path_prepend(const char *text, pkgconf_list_t *dirlist)
*
* Prepends a path node to a path list. If the path is already in the list, do nothing.
*
* :param char* text: The path text to add as a path node.
* :param pkgconf_list_t* dirlist: The path list to add the path node to.
* :param bool filter: Whether to perform duplicate filtering.
* :return: nothing
*/
void
pkgconf_path_prepend(const char *text, pkgconf_list_t *dirlist, bool filter)
{
pkgconf_path_t *node = prepare_path_node(text, dirlist, filter);
if (node == NULL)
return;
pkgconf_node_insert(&node->lnode, node, dirlist);
}
/* /*
* !doc * !doc
* *
@ -266,7 +234,7 @@ pkgconf_path_copy_list(pkgconf_list_t *dst, const pkgconf_list_t *src)
{ {
pkgconf_path_t *srcpath = n->data, *path; pkgconf_path_t *srcpath = n->data, *path;
path = calloc(1, sizeof(pkgconf_path_t)); path = calloc(sizeof(pkgconf_path_t), 1);
path->path = strdup(srcpath->path); path->path = strdup(srcpath->path);
#ifdef PKGCONF_CACHE_INODES #ifdef PKGCONF_CACHE_INODES
@ -300,8 +268,6 @@ pkgconf_path_free(pkgconf_list_t *dirlist)
free(pnode->path); free(pnode->path);
free(pnode); free(pnode);
} }
pkgconf_list_zero(dirlist);
} }
static char * static char *

View File

@ -17,34 +17,16 @@
#include <libpkgconf/stdinc.h> #include <libpkgconf/stdinc.h>
#include <libpkgconf/libpkgconf.h> #include <libpkgconf/libpkgconf.h>
/*
* !doc
*
* libpkgconf `personality` module
* =========================
*/
#ifdef _WIN32 #ifdef _WIN32
# define strcasecmp _stricmp # define strcasecmp _stricmp
#endif #endif
/* static bool default_personality_init = false;
* Increment each time the default personality is inited, decrement each time
* it's deinited. Whenever it is 0, then the deinit frees the personality. In
* that case an additional call to init will create it anew.
*/
static unsigned default_personality_init = 0;
static pkgconf_cross_personality_t default_personality = { static pkgconf_cross_personality_t default_personality = {
.name = "default", .name = "default",
#ifdef _WIN32 #ifdef _WIN32
/* PE/COFF uses a different linking model than ELF and Mach-O, where
* all transitive dependency references must be processed by the linker
* when linking the final executable image, even if those dependencies
* are pulled in as DLLs.
* This translates to always using --static on Windows targets.
*/
.want_default_static = true, .want_default_static = true,
.want_default_pure = true,
#endif #endif
}; };
@ -103,47 +85,30 @@ build_default_search_path(pkgconf_list_t* dirlist)
* *
* Returns the default cross-compile personality. * Returns the default cross-compile personality.
* *
* Not thread safe.
*
* :rtype: pkgconf_cross_personality_t* * :rtype: pkgconf_cross_personality_t*
* :return: the default cross-compile personality * :return: the default cross-compile personality
*/ */
pkgconf_cross_personality_t * pkgconf_cross_personality_t *
pkgconf_cross_personality_default(void) pkgconf_cross_personality_default(void)
{ {
if (default_personality_init) { if (default_personality_init)
++default_personality_init;
return &default_personality; return &default_personality;
}
build_default_search_path(&default_personality.dir_list); build_default_search_path(&default_personality.dir_list);
pkgconf_path_split(SYSTEM_LIBDIR, &default_personality.filter_libdirs, false); pkgconf_path_split(SYSTEM_LIBDIR, &default_personality.filter_libdirs, false);
pkgconf_path_split(SYSTEM_INCLUDEDIR, &default_personality.filter_includedirs, false); pkgconf_path_split(SYSTEM_INCLUDEDIR, &default_personality.filter_includedirs, false);
++default_personality_init; default_personality_init = true;
return &default_personality; return &default_personality;
} }
/*
* !doc
*
* .. c:function:: void pkgconf_cross_personality_deinit(pkgconf_cross_personality_t *)
*
* Decrements the count of default cross personality instances.
*
* Not thread safe.
*
* :rtype: void
*/
void void
pkgconf_cross_personality_deinit(pkgconf_cross_personality_t *personality) pkgconf_cross_personality_deinit(pkgconf_cross_personality_t *personality)
{ {
if (--default_personality_init == 0) {
pkgconf_path_free(&personality->dir_list); pkgconf_path_free(&personality->dir_list);
pkgconf_path_free(&personality->filter_libdirs); pkgconf_path_free(&personality->filter_libdirs);
pkgconf_path_free(&personality->filter_includedirs); pkgconf_path_free(&personality->filter_includedirs);
}
} }
#ifndef PKGCONF_LITE #ifndef PKGCONF_LITE
@ -153,7 +118,7 @@ valid_triplet(const char *triplet)
const char *c = triplet; const char *c = triplet;
for (; *c; c++) for (; *c; c++)
if (!isalnum((unsigned char)*c) && *c != '-' && *c != '_') if (!isalnum(*c) && *c != '-' && *c != '_')
return false; return false;
return true; return true;
@ -246,25 +211,23 @@ personality_warn_func(void *p, const char *fmt, ...)
} }
static pkgconf_cross_personality_t * static pkgconf_cross_personality_t *
load_personality_with_path(const char *path, const char *triplet, bool datadir) load_personality_with_path(const char *path, const char *triplet)
{ {
char pathbuf[PKGCONF_ITEM_SIZE]; char pathbuf[PKGCONF_ITEM_SIZE];
FILE *f; FILE *f;
pkgconf_cross_personality_t *p; pkgconf_cross_personality_t *p;
/* if triplet is null, assume that path is a direct path to the personality file */ /* if triplet is null, assume that path is a direct path to the personality file */
if (triplet == NULL) if (triplet != NULL)
pkgconf_strlcpy(pathbuf, path, sizeof pathbuf);
else if (datadir)
snprintf(pathbuf, sizeof pathbuf, "%s/pkgconfig/personality.d/%s.personality", path, triplet);
else
snprintf(pathbuf, sizeof pathbuf, "%s/%s.personality", path, triplet); snprintf(pathbuf, sizeof pathbuf, "%s/%s.personality", path, triplet);
else
pkgconf_strlcpy(pathbuf, path, sizeof pathbuf);
f = fopen(pathbuf, "r"); f = fopen(pathbuf, "r");
if (f == NULL) if (f == NULL)
return NULL; return NULL;
p = calloc(1, sizeof(pkgconf_cross_personality_t)); p = calloc(sizeof(pkgconf_cross_personality_t), 1);
if (triplet != NULL) if (triplet != NULL)
p->name = strdup(triplet); p->name = strdup(triplet);
pkgconf_parser_parse(f, p, personality_parser_ops, personality_warn_func, pathbuf); pkgconf_parser_parse(f, p, personality_parser_ops, personality_warn_func, pathbuf);
@ -288,51 +251,21 @@ pkgconf_cross_personality_find(const char *triplet)
pkgconf_list_t plist = PKGCONF_LIST_INITIALIZER; pkgconf_list_t plist = PKGCONF_LIST_INITIALIZER;
pkgconf_node_t *n; pkgconf_node_t *n;
pkgconf_cross_personality_t *out = NULL; pkgconf_cross_personality_t *out = NULL;
#if ! defined(_WIN32) && ! defined(__HAIKU__)
char pathbuf[PKGCONF_ITEM_SIZE];
const char *envvar;
#endif
out = load_personality_with_path(triplet, NULL, false); out = load_personality_with_path(triplet, NULL);
if (out != NULL) if (out != NULL)
return out; return out;
if (!valid_triplet(triplet)) if (!valid_triplet(triplet))
return NULL; return NULL;
#if ! defined(_WIN32) && ! defined(__HAIKU__)
envvar = getenv("XDG_DATA_HOME");
if (envvar != NULL)
pkgconf_path_add(envvar, &plist, true);
else {
envvar = getenv("HOME");
if (envvar != NULL) {
pkgconf_strlcpy(pathbuf, envvar, sizeof pathbuf);
pkgconf_strlcat(pathbuf, "/.local/share", sizeof pathbuf);
pkgconf_path_add(pathbuf, &plist, true);
}
}
pkgconf_path_build_from_environ("XDG_DATA_DIRS", "/usr/local/share" PKG_CONFIG_PATH_SEP_S "/usr/share", &plist, true);
PKGCONF_FOREACH_LIST_ENTRY(plist.head, n)
{
pkgconf_path_t *pn = n->data;
out = load_personality_with_path(pn->path, triplet, true);
if (out != NULL)
goto finish;
}
pkgconf_path_free(&plist);
#endif
pkgconf_path_split(PERSONALITY_PATH, &plist, true); pkgconf_path_split(PERSONALITY_PATH, &plist, true);
PKGCONF_FOREACH_LIST_ENTRY(plist.head, n) PKGCONF_FOREACH_LIST_ENTRY(plist.head, n)
{ {
pkgconf_path_t *pn = n->data; pkgconf_path_t *pn = n->data;
out = load_personality_with_path(pn->path, triplet, false); out = load_personality_with_path(pn->path, triplet);
if (out != NULL) if (out != NULL)
goto finish; goto finish;
} }

View File

@ -37,14 +37,6 @@
#define PKG_CONFIG_EXT ".pc" #define PKG_CONFIG_EXT ".pc"
static unsigned int
pkgconf_pkg_traverse_main(pkgconf_client_t *client,
pkgconf_pkg_t *root,
pkgconf_pkg_traverse_func_t func,
void *data,
int maxdepth,
unsigned int skip_flags);
static inline bool static inline bool
str_has_suffix(const char *str, const char *suffix) str_has_suffix(const char *str, const char *suffix)
{ {
@ -72,7 +64,7 @@ pkg_get_parent_dir(pkgconf_pkg_t *pkg)
return strdup(buf); return strdup(buf);
} }
typedef void (*pkgconf_pkg_parser_keyword_func_t)(pkgconf_client_t *client, pkgconf_pkg_t *pkg, const char *keyword, const size_t lineno, const ptrdiff_t offset, const char *value); typedef void (*pkgconf_pkg_parser_keyword_func_t)(const pkgconf_client_t *client, pkgconf_pkg_t *pkg, const char *keyword, const size_t lineno, const ptrdiff_t offset, const char *value);
typedef struct { typedef struct {
const char *keyword; const char *keyword;
const pkgconf_pkg_parser_keyword_func_t func; const pkgconf_pkg_parser_keyword_func_t func;
@ -86,17 +78,17 @@ static int pkgconf_pkg_parser_keyword_pair_cmp(const void *key, const void *ptr)
} }
static void static void
pkgconf_pkg_parser_tuple_func(pkgconf_client_t *client, pkgconf_pkg_t *pkg, const char *keyword, const size_t lineno, const ptrdiff_t offset, const char *value) pkgconf_pkg_parser_tuple_func(const pkgconf_client_t *client, pkgconf_pkg_t *pkg, const char *keyword, const size_t lineno, const ptrdiff_t offset, const char *value)
{ {
(void) keyword; (void) keyword;
(void) lineno; (void) lineno;
char **dest = (char **)((char *) pkg + offset); char **dest = (char **)((char *) pkg + offset);
*dest = pkgconf_tuple_parse(client, &pkg->vars, value, pkg->flags); *dest = pkgconf_tuple_parse(client, &pkg->vars, value);
} }
static void static void
pkgconf_pkg_parser_version_func(pkgconf_client_t *client, pkgconf_pkg_t *pkg, const char *keyword, const size_t lineno, const ptrdiff_t offset, const char *value) pkgconf_pkg_parser_version_func(const pkgconf_client_t *client, pkgconf_pkg_t *pkg, const char *keyword, const size_t lineno, const ptrdiff_t offset, const char *value)
{ {
(void) keyword; (void) keyword;
(void) lineno; (void) lineno;
@ -105,7 +97,7 @@ pkgconf_pkg_parser_version_func(pkgconf_client_t *client, pkgconf_pkg_t *pkg, co
char **dest = (char **)((char *) pkg + offset); char **dest = (char **)((char *) pkg + offset);
/* cut at any detected whitespace */ /* cut at any detected whitespace */
p = pkgconf_tuple_parse(client, &pkg->vars, value, pkg->flags); p = pkgconf_tuple_parse(client, &pkg->vars, value);
len = strcspn(p, " \t"); len = strcspn(p, " \t");
if (len != strlen(p)) if (len != strlen(p))
@ -121,10 +113,10 @@ pkgconf_pkg_parser_version_func(pkgconf_client_t *client, pkgconf_pkg_t *pkg, co
} }
static void static void
pkgconf_pkg_parser_fragment_func(pkgconf_client_t *client, pkgconf_pkg_t *pkg, const char *keyword, const size_t lineno, const ptrdiff_t offset, const char *value) pkgconf_pkg_parser_fragment_func(const pkgconf_client_t *client, pkgconf_pkg_t *pkg, const char *keyword, const size_t lineno, const ptrdiff_t offset, const char *value)
{ {
pkgconf_list_t *dest = (pkgconf_list_t *)((char *) pkg + offset); pkgconf_list_t *dest = (pkgconf_list_t *)((char *) pkg + offset);
bool ret = pkgconf_fragment_parse(client, dest, &pkg->vars, value, pkg->flags); bool ret = pkgconf_fragment_parse(client, dest, &pkg->vars, value);
if (!ret) if (!ret)
{ {
@ -134,7 +126,7 @@ pkgconf_pkg_parser_fragment_func(pkgconf_client_t *client, pkgconf_pkg_t *pkg, c
} }
static void static void
pkgconf_pkg_parser_dependency_func(pkgconf_client_t *client, pkgconf_pkg_t *pkg, const char *keyword, const size_t lineno, const ptrdiff_t offset, const char *value) pkgconf_pkg_parser_dependency_func(const pkgconf_client_t *client, pkgconf_pkg_t *pkg, const char *keyword, const size_t lineno, const ptrdiff_t offset, const char *value)
{ {
(void) keyword; (void) keyword;
(void) lineno; (void) lineno;
@ -145,7 +137,7 @@ pkgconf_pkg_parser_dependency_func(pkgconf_client_t *client, pkgconf_pkg_t *pkg,
/* a variant of pkgconf_pkg_parser_dependency_func which colors the dependency node as an "internal" dependency. */ /* a variant of pkgconf_pkg_parser_dependency_func which colors the dependency node as an "internal" dependency. */
static void static void
pkgconf_pkg_parser_internal_dependency_func(pkgconf_client_t *client, pkgconf_pkg_t *pkg, const char *keyword, const size_t lineno, const ptrdiff_t offset, const char *value) pkgconf_pkg_parser_internal_dependency_func(const pkgconf_client_t *client, pkgconf_pkg_t *pkg, const char *keyword, const size_t lineno, const ptrdiff_t offset, const char *value)
{ {
(void) keyword; (void) keyword;
(void) lineno; (void) lineno;
@ -154,34 +146,19 @@ pkgconf_pkg_parser_internal_dependency_func(pkgconf_client_t *client, pkgconf_pk
pkgconf_dependency_parse(client, pkg, dest, value, PKGCONF_PKG_DEPF_INTERNAL); pkgconf_dependency_parse(client, pkg, dest, value, PKGCONF_PKG_DEPF_INTERNAL);
} }
/* a variant of pkgconf_pkg_parser_dependency_func which colors the dependency node as a "private" dependency. */
static void
pkgconf_pkg_parser_private_dependency_func(pkgconf_client_t *client, pkgconf_pkg_t *pkg, const char *keyword, const size_t lineno, const ptrdiff_t offset, const char *value)
{
(void) keyword;
(void) lineno;
pkgconf_list_t *dest = (pkgconf_list_t *)((char *) pkg + offset);
pkgconf_dependency_parse(client, pkg, dest, value, PKGCONF_PKG_DEPF_PRIVATE);
}
/* keep this in alphabetical order */ /* keep this in alphabetical order */
static const pkgconf_pkg_parser_keyword_pair_t pkgconf_pkg_parser_keyword_funcs[] = { static const pkgconf_pkg_parser_keyword_pair_t pkgconf_pkg_parser_keyword_funcs[] = {
{"CFLAGS", pkgconf_pkg_parser_fragment_func, offsetof(pkgconf_pkg_t, cflags)}, {"CFLAGS", pkgconf_pkg_parser_fragment_func, offsetof(pkgconf_pkg_t, cflags)},
{"CFLAGS.private", pkgconf_pkg_parser_fragment_func, offsetof(pkgconf_pkg_t, cflags_private)}, {"CFLAGS.private", pkgconf_pkg_parser_fragment_func, offsetof(pkgconf_pkg_t, cflags_private)},
{"Conflicts", pkgconf_pkg_parser_dependency_func, offsetof(pkgconf_pkg_t, conflicts)}, {"Conflicts", pkgconf_pkg_parser_dependency_func, offsetof(pkgconf_pkg_t, conflicts)},
{"Copyright", pkgconf_pkg_parser_tuple_func, offsetof(pkgconf_pkg_t, copyright)},
{"Description", pkgconf_pkg_parser_tuple_func, offsetof(pkgconf_pkg_t, description)}, {"Description", pkgconf_pkg_parser_tuple_func, offsetof(pkgconf_pkg_t, description)},
{"LIBS", pkgconf_pkg_parser_fragment_func, offsetof(pkgconf_pkg_t, libs)}, {"LIBS", pkgconf_pkg_parser_fragment_func, offsetof(pkgconf_pkg_t, libs)},
{"LIBS.private", pkgconf_pkg_parser_fragment_func, offsetof(pkgconf_pkg_t, libs_private)}, {"LIBS.private", pkgconf_pkg_parser_fragment_func, offsetof(pkgconf_pkg_t, libs_private)},
{"License", pkgconf_pkg_parser_tuple_func, offsetof(pkgconf_pkg_t, license)},
{"Maintainer", pkgconf_pkg_parser_tuple_func, offsetof(pkgconf_pkg_t, maintainer)},
{"Name", pkgconf_pkg_parser_tuple_func, offsetof(pkgconf_pkg_t, realname)}, {"Name", pkgconf_pkg_parser_tuple_func, offsetof(pkgconf_pkg_t, realname)},
{"Provides", pkgconf_pkg_parser_dependency_func, offsetof(pkgconf_pkg_t, provides)}, {"Provides", pkgconf_pkg_parser_dependency_func, offsetof(pkgconf_pkg_t, provides)},
{"Requires", pkgconf_pkg_parser_dependency_func, offsetof(pkgconf_pkg_t, required)}, {"Requires", pkgconf_pkg_parser_dependency_func, offsetof(pkgconf_pkg_t, required)},
{"Requires.internal", pkgconf_pkg_parser_internal_dependency_func, offsetof(pkgconf_pkg_t, requires_private)}, {"Requires.internal", pkgconf_pkg_parser_internal_dependency_func, offsetof(pkgconf_pkg_t, requires_private)},
{"Requires.private", pkgconf_pkg_parser_private_dependency_func, offsetof(pkgconf_pkg_t, requires_private)}, {"Requires.private", pkgconf_pkg_parser_dependency_func, offsetof(pkgconf_pkg_t, requires_private)},
{"URL", pkgconf_pkg_parser_tuple_func, offsetof(pkgconf_pkg_t, url)},
{"Version", pkgconf_pkg_parser_version_func, offsetof(pkgconf_pkg_t, version)}, {"Version", pkgconf_pkg_parser_version_func, offsetof(pkgconf_pkg_t, version)},
}; };
@ -250,7 +227,7 @@ determine_prefix(const pkgconf_pkg_t *pkg, char *buf, size_t buflen)
static char * static char *
convert_path_to_value(const char *path) convert_path_to_value(const char *path)
{ {
char *buf = calloc(1, (strlen(path) + 1) * 2); char *buf = calloc((strlen(path) + 1) * 2, 1);
char *bptr = buf; char *bptr = buf;
const char *i; const char *i;
@ -320,17 +297,19 @@ pkgconf_pkg_parser_value_set(void *opaque, const size_t lineno, const char *keyw
* which is broken when redefining the prefix. We try to outsmart the * which is broken when redefining the prefix. We try to outsmart the
* file and rewrite any directory that starts with the same prefix. * file and rewrite any directory that starts with the same prefix.
*/ */
if (pkg->owner->flags & PKGCONF_PKG_PKGF_REDEFINE_PREFIX && pkg->orig_prefix if (strcmp(keyword, pkg->owner->prefix_varname) || !(pkg->owner->flags & PKGCONF_PKG_PKGF_REDEFINE_PREFIX))
{
pkgconf_tuple_add(pkg->owner, &pkg->vars, keyword, value, true);
}
else if (pkg->owner->flags & PKGCONF_PKG_PKGF_REDEFINE_PREFIX && pkg->orig_prefix
&& is_path_prefix_equal(canonicalized_value, pkg->orig_prefix->value, strlen(pkg->orig_prefix->value))) && is_path_prefix_equal(canonicalized_value, pkg->orig_prefix->value, strlen(pkg->orig_prefix->value)))
{ {
char newvalue[PKGCONF_ITEM_SIZE]; char newvalue[PKGCONF_ITEM_SIZE];
pkgconf_strlcpy(newvalue, pkg->prefix->value, sizeof newvalue); pkgconf_strlcpy(newvalue, pkg->prefix->value, sizeof newvalue);
pkgconf_strlcat(newvalue, canonicalized_value + strlen(pkg->orig_prefix->value), sizeof newvalue); pkgconf_strlcat(newvalue, canonicalized_value + strlen(pkg->orig_prefix->value), sizeof newvalue);
pkgconf_tuple_add(pkg->owner, &pkg->vars, keyword, newvalue, false, pkg->flags); pkgconf_tuple_add(pkg->owner, &pkg->vars, keyword, newvalue, false);
} }
else if (strcmp(keyword, pkg->owner->prefix_varname) || !(pkg->owner->flags & PKGCONF_PKG_PKGF_REDEFINE_PREFIX))
pkgconf_tuple_add(pkg->owner, &pkg->vars, keyword, value, true, pkg->flags);
else else
{ {
char pathbuf[PKGCONF_ITEM_SIZE]; char pathbuf[PKGCONF_ITEM_SIZE];
@ -339,12 +318,12 @@ pkgconf_pkg_parser_value_set(void *opaque, const size_t lineno, const char *keyw
if (relvalue != NULL) if (relvalue != NULL)
{ {
char *prefix_value = convert_path_to_value(relvalue); char *prefix_value = convert_path_to_value(relvalue);
pkg->orig_prefix = pkgconf_tuple_add(pkg->owner, &pkg->vars, "orig_prefix", canonicalized_value, true, pkg->flags); pkg->orig_prefix = pkgconf_tuple_add(pkg->owner, &pkg->vars, "orig_prefix", canonicalized_value, true);
pkg->prefix = pkgconf_tuple_add(pkg->owner, &pkg->vars, keyword, prefix_value, false, pkg->flags); pkgconf_tuple_add_global(pkg->owner, keyword, prefix_value);
free(prefix_value); free(prefix_value);
} }
else else
pkgconf_tuple_add(pkg->owner, &pkg->vars, keyword, value, true, pkg->flags); pkgconf_tuple_add(pkg->owner, &pkg->vars, keyword, value, true);
} }
} }
@ -402,39 +381,40 @@ pkgconf_pkg_validate(const pkgconf_client_t *client, const pkgconf_pkg_t *pkg)
/* /*
* !doc * !doc
* *
* .. c:function:: pkgconf_pkg_t *pkgconf_pkg_new_from_file(const pkgconf_client_t *client, const char *filename, FILE *f, unsigned int flags) * .. c:function:: pkgconf_pkg_t *pkgconf_pkg_new_from_file(const pkgconf_client_t *client, const char *filename, FILE *f)
* *
* Parse a .pc file into a pkgconf_pkg_t object structure. * Parse a .pc file into a pkgconf_pkg_t object structure.
* *
* :param pkgconf_client_t* client: The pkgconf client object to use for dependency resolution. * :param pkgconf_client_t* client: The pkgconf client object to use for dependency resolution.
* :param char* filename: The filename of the package file (including full path). * :param char* filename: The filename of the package file (including full path).
* :param FILE* f: The file object to read from. * :param FILE* f: The file object to read from.
* :param uint flags: The flags to use when parsing.
* :returns: A ``pkgconf_pkg_t`` object which contains the package data. * :returns: A ``pkgconf_pkg_t`` object which contains the package data.
* :rtype: pkgconf_pkg_t * * :rtype: pkgconf_pkg_t *
*/ */
pkgconf_pkg_t * pkgconf_pkg_t *
pkgconf_pkg_new_from_file(pkgconf_client_t *client, const char *filename, FILE *f, unsigned int flags) pkgconf_pkg_new_from_file(pkgconf_client_t *client, const char *filename, FILE *f)
{ {
pkgconf_pkg_t *pkg; pkgconf_pkg_t *pkg;
char *idptr; char *idptr;
pkg = calloc(1, sizeof(pkgconf_pkg_t)); pkg = calloc(sizeof(pkgconf_pkg_t), 1);
pkg->owner = client; pkg->owner = client;
pkg->filename = strdup(filename); pkg->filename = strdup(filename);
pkg->pc_filedir = pkg_get_parent_dir(pkg); pkg->pc_filedir = pkg_get_parent_dir(pkg);
pkg->flags = flags;
char *pc_filedir_value = convert_path_to_value(pkg->pc_filedir); char *pc_filedir_value = convert_path_to_value(pkg->pc_filedir);
pkgconf_tuple_add(client, &pkg->vars, "pcfiledir", pc_filedir_value, true, pkg->flags); pkgconf_tuple_add(client, &pkg->vars, "pcfiledir", pc_filedir_value, true);
free(pc_filedir_value); free(pc_filedir_value);
/* If pc_filedir is outside of sysroot_dir, override sysroot_dir for this /* If pc_filedir is outside of sysroot_dir, clear pc_filedir
* package.
* See https://github.com/pkgconf/pkgconf/issues/213 * See https://github.com/pkgconf/pkgconf/issues/213
*/ */
if (client->sysroot_dir && strncmp(pkg->pc_filedir, client->sysroot_dir, strlen(client->sysroot_dir))) if (client->sysroot_dir && strncmp(pkg->pc_filedir, client->sysroot_dir, strlen(client->sysroot_dir)))
pkgconf_tuple_add(client, &pkg->vars, "pc_sysrootdir", "", false, pkg->flags); {
free(client->sysroot_dir);
client->sysroot_dir = NULL;
pkgconf_client_set_sysroot_dir(client, NULL);
}
/* make module id */ /* make module id */
if ((idptr = strrchr(pkg->filename, PKG_DIR_SEP_S)) != NULL) if ((idptr = strrchr(pkg->filename, PKG_DIR_SEP_S)) != NULL)
@ -457,13 +437,6 @@ pkgconf_pkg_new_from_file(pkgconf_client_t *client, const char *filename, FILE *
if (idptr) if (idptr)
*idptr = '\0'; *idptr = '\0';
if (pkg->flags & PKGCONF_PKG_PROPF_UNINSTALLED)
{
idptr = strrchr(pkg->id, '-');
if (idptr)
*idptr = '\0';
}
pkgconf_parser_parse(f, pkg, pkg_parser_funcs, (pkgconf_parser_warn_func_t) pkg_warn_func, pkg->filename); pkgconf_parser_parse(f, pkg, pkg_parser_funcs, (pkgconf_parser_warn_func_t) pkg_warn_func, pkg->filename);
if (!pkgconf_pkg_validate(client, pkg)) if (!pkgconf_pkg_validate(client, pkg))
@ -473,8 +446,7 @@ pkgconf_pkg_new_from_file(pkgconf_client_t *client, const char *filename, FILE *
return NULL; return NULL;
} }
pkgconf_dependency_t *dep = pkgconf_dependency_add(client, &pkg->provides, pkg->id, pkg->version, PKGCONF_CMP_EQUAL, 0); pkgconf_dependency_add(client, &pkg->provides, pkg->id, pkg->version, PKGCONF_CMP_EQUAL, 0);
pkgconf_dependency_unref(dep->owner, dep);
return pkgconf_pkg_ref(client, pkg); return pkgconf_pkg_ref(client, pkg);
} }
@ -537,18 +509,6 @@ pkgconf_pkg_free(pkgconf_client_t *client, pkgconf_pkg_t *pkg)
if (pkg->pc_filedir != NULL) if (pkg->pc_filedir != NULL)
free(pkg->pc_filedir); free(pkg->pc_filedir);
if (pkg->license != NULL)
free(pkg->license);
if (pkg->maintainer != NULL)
free(pkg->maintainer);
if (pkg->copyright != NULL)
free(pkg->copyright);
if (pkg->why != NULL)
free(pkg->why);
free(pkg); free(pkg);
} }
@ -571,7 +531,7 @@ pkgconf_pkg_ref(pkgconf_client_t *client, pkgconf_pkg_t *pkg)
PKGCONF_TRACE(client, "WTF: client %p refers to package %p owned by other client %p", client, pkg, pkg->owner); PKGCONF_TRACE(client, "WTF: client %p refers to package %p owned by other client %p", client, pkg, pkg->owner);
pkg->refcount++; pkg->refcount++;
PKGCONF_TRACE(client, "%s refcount@%p: %d", pkg->id, pkg, pkg->refcount); PKGCONF_TRACE(client, "refcount@%p: %d", pkg, pkg->refcount);
return pkg; return pkg;
} }
@ -594,7 +554,7 @@ pkgconf_pkg_unref(pkgconf_client_t *client, pkgconf_pkg_t *pkg)
PKGCONF_TRACE(client, "WTF: client %p unrefs package %p owned by other client %p", client, pkg, pkg->owner); PKGCONF_TRACE(client, "WTF: client %p unrefs package %p owned by other client %p", client, pkg, pkg->owner);
pkg->refcount--; pkg->refcount--;
PKGCONF_TRACE(pkg->owner, "%s refcount@%p: %d", pkg->id, pkg, pkg->refcount); PKGCONF_TRACE(pkg->owner, "refcount@%p: %d", pkg, pkg->refcount);
if (pkg->refcount <= 0) if (pkg->refcount <= 0)
pkgconf_pkg_free(pkg->owner, pkg); pkgconf_pkg_free(pkg->owner, pkg);
@ -616,12 +576,14 @@ pkgconf_pkg_try_specific_path(pkgconf_client_t *client, const char *path, const
if (!(client->flags & PKGCONF_PKG_PKGF_NO_UNINSTALLED) && (f = fopen(uninst_locbuf, "r")) != NULL) if (!(client->flags & PKGCONF_PKG_PKGF_NO_UNINSTALLED) && (f = fopen(uninst_locbuf, "r")) != NULL)
{ {
PKGCONF_TRACE(client, "found (uninstalled): %s", uninst_locbuf); PKGCONF_TRACE(client, "found (uninstalled): %s", uninst_locbuf);
pkg = pkgconf_pkg_new_from_file(client, uninst_locbuf, f, PKGCONF_PKG_PROPF_UNINSTALLED); pkg = pkgconf_pkg_new_from_file(client, uninst_locbuf, f);
if (pkg != NULL)
pkg->flags |= PKGCONF_PKG_PROPF_UNINSTALLED;
} }
else if ((f = fopen(locbuf, "r")) != NULL) else if ((f = fopen(locbuf, "r")) != NULL)
{ {
PKGCONF_TRACE(client, "found: %s", locbuf); PKGCONF_TRACE(client, "found: %s", locbuf);
pkg = pkgconf_pkg_new_from_file(client, locbuf, f, 0); pkg = pkgconf_pkg_new_from_file(client, locbuf, f);
} }
return pkg; return pkg;
@ -659,7 +621,7 @@ pkgconf_pkg_scan_dir(pkgconf_client_t *client, const char *path, void *data, pkg
if (f == NULL) if (f == NULL)
continue; continue;
pkg = pkgconf_pkg_new_from_file(client, filebuf, f, 0); pkg = pkgconf_pkg_new_from_file(client, filebuf, f);
if (pkg != NULL) if (pkg != NULL)
{ {
if (func(pkg, data)) if (func(pkg, data))
@ -775,13 +737,15 @@ pkgconf_pkg_find(pkgconf_client_t *client, const char *name)
{ {
if ((f = fopen(name, "r")) != NULL) if ((f = fopen(name, "r")) != NULL)
{ {
pkgconf_pkg_t *pkg;
PKGCONF_TRACE(client, "%s is a file", name); PKGCONF_TRACE(client, "%s is a file", name);
pkg = pkgconf_pkg_new_from_file(client, name, f, 0); pkg = pkgconf_pkg_new_from_file(client, name, f);
if (pkg != NULL) if (pkg != NULL)
{ {
pkgconf_path_add(pkg->pc_filedir, &client->dir_list, true); pkgconf_path_add(pkg->pc_filedir, &client->dir_list, true);
goto out; return pkg;
} }
} }
} }
@ -860,14 +824,14 @@ pkgconf_compare_version(const char *a, const char *b)
pkgconf_strlcpy(buf1, a, sizeof buf1); pkgconf_strlcpy(buf1, a, sizeof buf1);
pkgconf_strlcpy(buf2, b, sizeof buf2); pkgconf_strlcpy(buf2, b, sizeof buf2);
one = buf1; one = str1 = buf1;
two = buf2; two = str2 = buf2;
while (*one || *two) while (*one || *two)
{ {
while (*one && !isalnum((unsigned char)*one) && *one != '~') while (*one && !isalnum((unsigned int)*one) && *one != '~')
one++; one++;
while (*two && !isalnum((unsigned char)*two) && *two != '~') while (*two && !isalnum((unsigned int)*two) && *two != '~')
two++; two++;
if (*one == '~' || *two == '~') if (*one == '~' || *two == '~')
@ -888,22 +852,22 @@ pkgconf_compare_version(const char *a, const char *b)
str1 = one; str1 = one;
str2 = two; str2 = two;
if (isdigit((unsigned char)*str1)) if (isdigit((unsigned int)*str1))
{ {
while (*str1 && isdigit((unsigned char)*str1)) while (*str1 && isdigit((unsigned int)*str1))
str1++; str1++;
while (*str2 && isdigit((unsigned char)*str2)) while (*str2 && isdigit((unsigned int)*str2))
str2++; str2++;
isnum = true; isnum = true;
} }
else else
{ {
while (*str1 && isalpha((unsigned char)*str1)) while (*str1 && isalpha((unsigned int)*str1))
str1++; str1++;
while (*str2 && isalpha((unsigned char)*str2)) while (*str2 && isalpha((unsigned int)*str2))
str2++; str2++;
isnum = false; isnum = false;
@ -996,7 +960,6 @@ static pkgconf_pkg_t pkgconf_virtual = {
.description = "virtual package defining pkgconf API version supported", .description = "virtual package defining pkgconf API version supported",
.url = PACKAGE_BUGREPORT, .url = PACKAGE_BUGREPORT,
.version = PACKAGE_VERSION, .version = PACKAGE_VERSION,
.license = "ISC",
.flags = PKGCONF_PKG_PROPF_STATIC, .flags = PKGCONF_PKG_PROPF_STATIC,
.vars = { .vars = {
.head = &(pkgconf_node_t){ .head = &(pkgconf_node_t){
@ -1399,10 +1362,9 @@ pkgconf_pkg_verify_dependency(pkgconf_client_t *client, pkgconf_dependency_t *pk
return NULL; return NULL;
} }
pkg = pkgconf_pkg_scan_providers(client, pkgdep, eflags); return pkgconf_pkg_scan_providers(client, pkgdep, eflags);
} }
else
{
if (pkg->id == NULL) if (pkg->id == NULL)
pkg->id = strdup(pkgdep->package); pkg->id = strdup(pkgdep->package);
@ -1413,10 +1375,6 @@ pkgconf_pkg_verify_dependency(pkgconf_client_t *client, pkgconf_dependency_t *pk
} }
else else
pkgdep->match = pkgconf_pkg_ref(client, pkg); pkgdep->match = pkgconf_pkg_ref(client, pkg);
}
if (pkg != NULL && pkg->why == NULL)
pkg->why = strdup(pkgdep->package);
return pkg; return pkg;
} }
@ -1454,11 +1412,7 @@ pkgconf_pkg_report_graph_error(pkgconf_client_t *client, pkgconf_pkg_t *parent,
client->already_sent_notice = true; client->already_sent_notice = true;
} }
if (parent->flags & PKGCONF_PKG_PROPF_VIRTUAL)
pkgconf_error(client, "Package '%s' not found\n", node->package);
else
pkgconf_error(client, "Package '%s', required by '%s', not found\n", node->package, parent->id); pkgconf_error(client, "Package '%s', required by '%s', not found\n", node->package, parent->id);
pkgconf_audit_log(client, "%s NOT-FOUND\n", node->package); pkgconf_audit_log(client, "%s NOT-FOUND\n", node->package);
} }
else if (eflags & PKGCONF_PKG_ERRF_PACKAGE_VER_MISMATCH) else if (eflags & PKGCONF_PKG_ERRF_PACKAGE_VER_MISMATCH)
@ -1487,11 +1441,9 @@ pkgconf_pkg_walk_list(pkgconf_client_t *client,
unsigned int skip_flags) unsigned int skip_flags)
{ {
unsigned int eflags = PKGCONF_PKG_ERRF_OK; unsigned int eflags = PKGCONF_PKG_ERRF_OK;
pkgconf_node_t *node, *next; pkgconf_node_t *node;
parent->flags |= PKGCONF_PKG_PROPF_ANCESTOR; PKGCONF_FOREACH_LIST_ENTRY(deplist->head, node)
PKGCONF_FOREACH_LIST_ENTRY_SAFE(deplist->head, next, node)
{ {
unsigned int eflags_local = PKGCONF_PKG_ERRF_OK; unsigned int eflags_local = PKGCONF_PKG_ERRF_OK;
pkgconf_dependency_t *depnode = node->data; pkgconf_dependency_t *depnode = node->data;
@ -1511,42 +1463,26 @@ pkgconf_pkg_walk_list(pkgconf_client_t *client,
if (pkgdep == NULL) if (pkgdep == NULL)
continue; continue;
if((pkgdep->flags & PKGCONF_PKG_PROPF_ANCESTOR) != 0) if (pkgdep->flags & PKGCONF_PKG_PROPF_SEEN)
{ {
/* In this case we have a circular reference. pkgconf_pkg_unref(client, pkgdep);
* We break that by deleteing the circular node from the continue;
* the list, so that we dont create a situation where
* memory is leaked due to circular ownership.
* i.e: A owns B owns A
*
* TODO(ariadne): Breaking circular references between Requires and Requires.private
* lists causes problems. Find a way to refactor the Requires.private list out.
*/
if (!(depnode->flags & PKGCONF_PKG_DEPF_PRIVATE) &&
!(parent->flags & PKGCONF_PKG_PROPF_VIRTUAL))
{
pkgconf_warn(client, "%s: breaking circular reference (%s -> %s -> %s)\n",
parent->id, parent->id, pkgdep->id, parent->id);
pkgconf_node_delete(node, deplist);
pkgconf_dependency_unref(client, depnode);
}
goto next;
} }
if (skip_flags && (depnode->flags & skip_flags) == skip_flags) if (skip_flags && (depnode->flags & skip_flags) == skip_flags)
goto next; {
pkgconf_pkg_unref(client, pkgdep);
continue;
}
pkgconf_audit_log_dependency(client, pkgdep, depnode); pkgconf_audit_log_dependency(client, pkgdep, depnode);
eflags |= pkgconf_pkg_traverse_main(client, pkgdep, func, data, depth - 1, skip_flags); pkgdep->flags |= PKGCONF_PKG_PROPF_SEEN;
next: eflags |= pkgconf_pkg_traverse(client, pkgdep, func, data, depth - 1, skip_flags);
pkgdep->flags &= ~PKGCONF_PKG_PROPF_SEEN;
pkgconf_pkg_unref(client, pkgdep); pkgconf_pkg_unref(client, pkgdep);
} }
parent->flags &= ~PKGCONF_PKG_PROPF_ANCESTOR;
return eflags; return eflags;
} }
@ -1613,8 +1549,8 @@ pkgconf_pkg_walk_conflicts_list(pkgconf_client_t *client,
* :return: ``PKGCONF_PKG_ERRF_OK`` on success, else an error code. * :return: ``PKGCONF_PKG_ERRF_OK`` on success, else an error code.
* :rtype: unsigned int * :rtype: unsigned int
*/ */
static unsigned int unsigned int
pkgconf_pkg_traverse_main(pkgconf_client_t *client, pkgconf_pkg_traverse(pkgconf_client_t *client,
pkgconf_pkg_t *root, pkgconf_pkg_t *root,
pkgconf_pkg_traverse_func_t func, pkgconf_pkg_traverse_func_t func,
void *data, void *data,
@ -1626,17 +1562,7 @@ pkgconf_pkg_traverse_main(pkgconf_client_t *client,
if (maxdepth == 0) if (maxdepth == 0)
return eflags; return eflags;
/* Short-circuit if we have already visited this node. PKGCONF_TRACE(client, "%s: level %d", root->id, maxdepth);
*/
if (root->serial == client->serial)
return eflags;
root->serial = client->serial;
if (root->identifier == 0)
root->identifier = ++client->identifier;
PKGCONF_TRACE(client, "%s: level %d, serial %"PRIu64, root->id, maxdepth, client->serial);
if ((root->flags & PKGCONF_PKG_PROPF_VIRTUAL) != PKGCONF_PKG_PROPF_VIRTUAL || (client->flags & PKGCONF_PKG_PKGF_SKIP_ROOT_VIRTUAL) != PKGCONF_PKG_PKGF_SKIP_ROOT_VIRTUAL) if ((root->flags & PKGCONF_PKG_PROPF_VIRTUAL) != PKGCONF_PKG_PROPF_VIRTUAL || (client->flags & PKGCONF_PKG_PKGF_SKIP_ROOT_VIRTUAL) != PKGCONF_PKG_PKGF_SKIP_ROOT_VIRTUAL)
{ {
@ -1644,23 +1570,21 @@ pkgconf_pkg_traverse_main(pkgconf_client_t *client,
func(client, root, data); func(client, root, data);
} }
if (!(client->flags & PKGCONF_PKG_PKGF_SKIP_CONFLICTS) && root->conflicts.head != NULL) if (!(client->flags & PKGCONF_PKG_PKGF_SKIP_CONFLICTS))
{ {
PKGCONF_TRACE(client, "%s: walking 'Conflicts' list", root->id);
eflags = pkgconf_pkg_walk_conflicts_list(client, root, &root->conflicts); eflags = pkgconf_pkg_walk_conflicts_list(client, root, &root->conflicts);
if (eflags != PKGCONF_PKG_ERRF_OK) if (eflags != PKGCONF_PKG_ERRF_OK)
return eflags; return eflags;
} }
PKGCONF_TRACE(client, "%s: walking 'Requires' list", root->id); PKGCONF_TRACE(client, "%s: walking requires list", root->id);
eflags = pkgconf_pkg_walk_list(client, root, &root->required, func, data, maxdepth, skip_flags); eflags = pkgconf_pkg_walk_list(client, root, &root->required, func, data, maxdepth, skip_flags);
if (eflags != PKGCONF_PKG_ERRF_OK) if (eflags != PKGCONF_PKG_ERRF_OK)
return eflags; return eflags;
if (client->flags & PKGCONF_PKG_PKGF_SEARCH_PRIVATE) if (client->flags & PKGCONF_PKG_PKGF_SEARCH_PRIVATE)
{ {
PKGCONF_TRACE(client, "%s: walking 'Requires.private' list", root->id); PKGCONF_TRACE(client, "%s: walking requires.private list", root->id);
/* XXX: ugly */ /* XXX: ugly */
client->flags |= PKGCONF_PKG_PKGF_ITER_PKG_IS_PRIVATE; client->flags |= PKGCONF_PKG_PKGF_ITER_PKG_IS_PRIVATE;
@ -1674,23 +1598,6 @@ pkgconf_pkg_traverse_main(pkgconf_client_t *client,
return eflags; return eflags;
} }
unsigned int
pkgconf_pkg_traverse(pkgconf_client_t *client,
pkgconf_pkg_t *root,
pkgconf_pkg_traverse_func_t func,
void *data,
int maxdepth,
unsigned int skip_flags)
{
if (root->flags & PKGCONF_PKG_PROPF_VIRTUAL)
client->serial++;
if ((client->flags & PKGCONF_PKG_PKGF_SEARCH_PRIVATE) == 0)
skip_flags |= PKGCONF_PKG_DEPF_PRIVATE;
return pkgconf_pkg_traverse_main(client, root, func, data, maxdepth, skip_flags);
}
static void static void
pkgconf_pkg_cflags_collect(pkgconf_client_t *client, pkgconf_pkg_t *pkg, void *data) pkgconf_pkg_cflags_collect(pkgconf_client_t *client, pkgconf_pkg_t *pkg, void *data)
{ {

View File

@ -29,6 +29,11 @@
* Using the `queue` module functions is the recommended way of working with dependency graphs. * Using the `queue` module functions is the recommended way of working with dependency graphs.
*/ */
typedef struct {
pkgconf_node_t iter;
char *package;
} pkgconf_queue_t;
/* /*
* !doc * !doc
* *
@ -43,7 +48,7 @@
void void
pkgconf_queue_push(pkgconf_list_t *list, const char *package) pkgconf_queue_push(pkgconf_list_t *list, const char *package)
{ {
pkgconf_queue_t *pkgq = calloc(1, sizeof(pkgconf_queue_t)); pkgconf_queue_t *pkgq = calloc(sizeof(pkgconf_queue_t), 1);
pkgq->package = strdup(package); pkgq->package = strdup(package);
pkgconf_node_insert_tail(&pkgq->iter, pkgq, list); pkgconf_node_insert_tail(&pkgq->iter, pkgq, list);
@ -72,7 +77,7 @@ pkgconf_queue_compile(pkgconf_client_t *client, pkgconf_pkg_t *world, pkgconf_li
pkgconf_queue_t *pkgq; pkgconf_queue_t *pkgq;
pkgq = iter->data; pkgq = iter->data;
pkgconf_dependency_parse(client, world, &world->required, pkgq->package, PKGCONF_PKG_DEPF_QUERY); pkgconf_dependency_parse(client, world, &world->required, pkgq->package, 0);
} }
return (world->required.head != NULL); return (world->required.head != NULL);
@ -102,225 +107,13 @@ pkgconf_queue_free(pkgconf_list_t *list)
} }
} }
static void
pkgconf_queue_mark_public(pkgconf_client_t *client, pkgconf_pkg_t *pkg, void *data)
{
if (pkg->flags & PKGCONF_PKG_PROPF_VISITED_PRIVATE)
{
pkgconf_list_t *list = data;
pkgconf_node_t *node;
PKGCONF_FOREACH_LIST_ENTRY(list->head, node)
{
pkgconf_dependency_t *dep = node->data;
if (dep->match == pkg)
dep->flags &= ~PKGCONF_PKG_DEPF_PRIVATE;
}
pkg->flags &= ~PKGCONF_PKG_PROPF_VISITED_PRIVATE;
PKGCONF_TRACE(client, "%s: updated, public", pkg->id);
}
}
static unsigned int
pkgconf_queue_collect_dependencies_main(pkgconf_client_t *client,
pkgconf_pkg_t *root,
void *data,
int maxdepth);
static inline unsigned int
pkgconf_queue_collect_dependencies_walk(pkgconf_client_t *client,
pkgconf_list_t *deplist,
void *data,
int depth)
{
unsigned int eflags = PKGCONF_PKG_ERRF_OK;
pkgconf_node_t *node;
pkgconf_pkg_t *world = data;
PKGCONF_FOREACH_LIST_ENTRY_REVERSE(deplist->tail, node)
{
pkgconf_dependency_t *dep = node->data;
pkgconf_dependency_t *flattened_dep;
pkgconf_pkg_t *pkg = dep->match;
if (*dep->package == '\0')
continue;
if (pkg == NULL)
{
PKGCONF_TRACE(client, "WTF: unmatched dependency %p <%s>", dep, dep->package);
abort();
}
if (pkg->serial == client->serial)
continue;
if (client->flags & PKGCONF_PKG_PKGF_ITER_PKG_IS_PRIVATE)
pkg->flags |= PKGCONF_PKG_PROPF_VISITED_PRIVATE;
else
pkg->flags &= ~PKGCONF_PKG_PROPF_VISITED_PRIVATE;
eflags |= pkgconf_queue_collect_dependencies_main(client, pkg, data, depth - 1);
flattened_dep = pkgconf_dependency_copy(client, dep);
pkgconf_node_insert(&flattened_dep->iter, flattened_dep, &world->required);
}
return eflags;
}
static unsigned int
pkgconf_queue_collect_dependencies_main(pkgconf_client_t *client,
pkgconf_pkg_t *root,
void *data,
int maxdepth)
{
unsigned int eflags = PKGCONF_PKG_ERRF_OK;
if (maxdepth == 0)
return eflags;
/* Short-circuit if we have already visited this node.
*/
if (root->serial == client->serial)
return eflags;
root->serial = client->serial;
if (client->flags & PKGCONF_PKG_PKGF_SEARCH_PRIVATE)
{
PKGCONF_TRACE(client, "%s: collecting private dependencies, level %d", root->id, maxdepth);
/* XXX: ugly */
const unsigned int saved_flags = client->flags;
client->flags |= PKGCONF_PKG_PKGF_ITER_PKG_IS_PRIVATE;
eflags = pkgconf_queue_collect_dependencies_walk(client, &root->requires_private, data, maxdepth);
client->flags = saved_flags;
if (eflags != PKGCONF_PKG_ERRF_OK)
return eflags;
}
PKGCONF_TRACE(client, "%s: collecting public dependencies, level %d", root->id, maxdepth);
eflags = pkgconf_queue_collect_dependencies_walk(client, &root->required, data, maxdepth);
if (eflags != PKGCONF_PKG_ERRF_OK)
return eflags;
PKGCONF_TRACE(client, "%s: finished, %s", root->id, (root->flags & PKGCONF_PKG_PROPF_VISITED_PRIVATE) ? "private" : "public");
return eflags;
}
static inline unsigned int
pkgconf_queue_collect_dependencies(pkgconf_client_t *client,
pkgconf_pkg_t *root,
void *data,
int maxdepth)
{
++client->serial;
return pkgconf_queue_collect_dependencies_main(client, root, data, maxdepth);
}
static inline unsigned int static inline unsigned int
pkgconf_queue_verify(pkgconf_client_t *client, pkgconf_pkg_t *world, pkgconf_list_t *list, int maxdepth) pkgconf_queue_verify(pkgconf_client_t *client, pkgconf_pkg_t *world, pkgconf_list_t *list, int maxdepth)
{ {
unsigned int result; if (!pkgconf_queue_compile(client, world, list))
const unsigned int saved_flags = client->flags;
pkgconf_pkg_t initial_world = {
.id = "user:request",
.realname = "virtual world package",
.flags = PKGCONF_PKG_PROPF_STATIC | PKGCONF_PKG_PROPF_VIRTUAL,
};
if (!pkgconf_queue_compile(client, &initial_world, list))
{
pkgconf_solution_free(client, &initial_world);
return PKGCONF_PKG_ERRF_DEPGRAPH_BREAK; return PKGCONF_PKG_ERRF_DEPGRAPH_BREAK;
}
PKGCONF_TRACE(client, "solving"); return pkgconf_pkg_verify_graph(client, world, maxdepth);
result = pkgconf_pkg_traverse(client, &initial_world, NULL, NULL, maxdepth, 0);
if (result != PKGCONF_PKG_ERRF_OK)
{
pkgconf_solution_free(client, &initial_world);
return result;
}
PKGCONF_TRACE(client, "flattening");
result = pkgconf_queue_collect_dependencies(client, &initial_world, world, maxdepth);
if (result != PKGCONF_PKG_ERRF_OK)
{
pkgconf_solution_free(client, &initial_world);
return result;
}
if (client->flags & PKGCONF_PKG_PKGF_SEARCH_PRIVATE)
{
PKGCONF_TRACE(client, "marking public deps");
client->flags &= ~PKGCONF_PKG_PKGF_SEARCH_PRIVATE;
client->flags |= PKGCONF_PKG_PKGF_SKIP_CONFLICTS;
result = pkgconf_pkg_traverse(client, &initial_world, pkgconf_queue_mark_public, &world->required, maxdepth, 0);
client->flags = saved_flags;
if (result != PKGCONF_PKG_ERRF_OK)
{
pkgconf_solution_free(client, &initial_world);
return result;
}
}
/* free the initial solution */
pkgconf_solution_free(client, &initial_world);
return PKGCONF_PKG_ERRF_OK;
}
/*
* !doc
*
* .. c:function:: void pkgconf_solution_free(pkgconf_client_t *client, pkgconf_pkg_t *world, int maxdepth)
*
* Removes references to package nodes contained in a solution.
*
* :param pkgconf_client_t* client: The pkgconf client object to use for dependency resolution.
* :param pkgconf_pkg_t* world: The root for the generated dependency graph. Should have PKGCONF_PKG_PROPF_VIRTUAL flag.
* :returns: nothing
*/
void
pkgconf_solution_free(pkgconf_client_t *client, pkgconf_pkg_t *world)
{
(void) client;
if (world->flags & PKGCONF_PKG_PROPF_VIRTUAL)
{
pkgconf_dependency_free(&world->required);
pkgconf_dependency_free(&world->requires_private);
}
}
/*
* !doc
*
* .. c:function:: bool pkgconf_queue_solve(pkgconf_client_t *client, pkgconf_list_t *list, pkgconf_pkg_t *world, int maxdepth)
*
* Solves and flattens the dependency graph for the supplied dependency list.
*
* :param pkgconf_client_t* client: The pkgconf client object to use for dependency resolution.
* :param pkgconf_list_t* list: The list of dependency requests to consider.
* :param pkgconf_pkg_t* world: The root for the generated dependency graph, provided by the caller. Should have PKGCONF_PKG_PROPF_VIRTUAL flag.
* :param int maxdepth: The maximum allowed depth for the dependency resolver. A depth of -1 means unlimited.
* :returns: true if the dependency resolver found a solution, otherwise false.
* :rtype: bool
*/
bool
pkgconf_queue_solve(pkgconf_client_t *client, pkgconf_list_t *list, pkgconf_pkg_t *world, int maxdepth)
{
/* if maxdepth is one, then we will not traverse deeper than our virtual package. */
if (!maxdepth)
maxdepth = -1;
return pkgconf_queue_verify(client, world, list, maxdepth) == PKGCONF_PKG_ERRF_OK;
} }
/* /*
@ -331,8 +124,6 @@ pkgconf_queue_solve(pkgconf_client_t *client, pkgconf_list_t *list, pkgconf_pkg_
* Attempt to compile a dependency resolution queue into a dependency resolution problem, then attempt to solve the problem and * Attempt to compile a dependency resolution queue into a dependency resolution problem, then attempt to solve the problem and
* feed the solution to a callback function if a complete dependency graph is found. * feed the solution to a callback function if a complete dependency graph is found.
* *
* This function should not be used in new code. Use pkgconf_queue_solve instead.
*
* :param pkgconf_client_t* client: The pkgconf client object to use for dependency resolution. * :param pkgconf_client_t* client: The pkgconf client object to use for dependency resolution.
* :param pkgconf_list_t* list: The list of dependency requests to consider. * :param pkgconf_list_t* list: The list of dependency requests to consider.
* :param pkgconf_queue_apply_func_t func: The callback function to call if a solution is found by the dependency resolver. * :param pkgconf_queue_apply_func_t func: The callback function to call if a solution is found by the dependency resolver.
@ -344,7 +135,6 @@ pkgconf_queue_solve(pkgconf_client_t *client, pkgconf_list_t *list, pkgconf_pkg_
bool bool
pkgconf_queue_apply(pkgconf_client_t *client, pkgconf_list_t *list, pkgconf_queue_apply_func_t func, int maxdepth, void *data) pkgconf_queue_apply(pkgconf_client_t *client, pkgconf_list_t *list, pkgconf_queue_apply_func_t func, int maxdepth, void *data)
{ {
bool ret = false;
pkgconf_pkg_t world = { pkgconf_pkg_t world = {
.id = "virtual:world", .id = "virtual:world",
.realname = "virtual world package", .realname = "virtual world package",
@ -355,18 +145,18 @@ pkgconf_queue_apply(pkgconf_client_t *client, pkgconf_list_t *list, pkgconf_queu
if (!maxdepth) if (!maxdepth)
maxdepth = -1; maxdepth = -1;
if (!pkgconf_queue_solve(client, list, &world, maxdepth)) if (pkgconf_queue_verify(client, &world, list, maxdepth) != PKGCONF_PKG_ERRF_OK)
goto cleanup; return false;
/* the world dependency set is flattened after it is returned from pkgconf_queue_verify */
if (!func(client, &world, data, maxdepth)) if (!func(client, &world, data, maxdepth))
goto cleanup; {
ret = true;
cleanup:
pkgconf_pkg_free(client, &world); pkgconf_pkg_free(client, &world);
return ret; return false;
}
pkgconf_pkg_free(client, &world);
return true;
} }
/* /*

View File

@ -59,7 +59,6 @@
# include <dirent.h> # include <dirent.h>
# include <unistd.h> # include <unistd.h>
# include <limits.h> # include <limits.h>
# include <strings.h>
# ifdef PATH_MAX # ifdef PATH_MAX
# define PKGCONF_ITEM_SIZE (PATH_MAX + 1024) # define PKGCONF_ITEM_SIZE (PATH_MAX + 1024)
# else # else

View File

@ -45,23 +45,7 @@
void void
pkgconf_tuple_add_global(pkgconf_client_t *client, const char *key, const char *value) pkgconf_tuple_add_global(pkgconf_client_t *client, const char *key, const char *value)
{ {
pkgconf_tuple_add(client, &client->global_vars, key, value, false, 0); pkgconf_tuple_add(client, &client->global_vars, key, value, false);
}
static pkgconf_tuple_t *
lookup_global_tuple(const pkgconf_client_t *client, const char *key)
{
pkgconf_node_t *node;
PKGCONF_FOREACH_LIST_ENTRY(client->global_vars.head, node)
{
pkgconf_tuple_t *tuple = node->data;
if (!strcmp(tuple->key, key))
return tuple;
}
return NULL;
} }
/* /*
@ -79,13 +63,17 @@ lookup_global_tuple(const pkgconf_client_t *client, const char *key)
char * char *
pkgconf_tuple_find_global(const pkgconf_client_t *client, const char *key) pkgconf_tuple_find_global(const pkgconf_client_t *client, const char *key)
{ {
pkgconf_tuple_t *tuple; pkgconf_node_t *node;
tuple = lookup_global_tuple(client, key); PKGCONF_FOREACH_LIST_ENTRY(client->global_vars.head, node)
if (tuple == NULL) {
return NULL; pkgconf_tuple_t *tuple = node->data;
if (!strcmp(tuple->key, key))
return tuple->value; return tuple->value;
}
return NULL;
} }
/* /*
@ -120,18 +108,13 @@ pkgconf_tuple_define_global(pkgconf_client_t *client, const char *kv)
{ {
char *workbuf = strdup(kv); char *workbuf = strdup(kv);
char *value; char *value;
pkgconf_tuple_t *tuple;
value = strchr(workbuf, '='); value = strchr(workbuf, '=');
if (value == NULL) if (value == NULL)
goto out; goto out;
*value++ = '\0'; *value++ = '\0';
pkgconf_tuple_add_global(client, workbuf, value);
tuple = pkgconf_tuple_add(client, &client->global_vars, workbuf, value, false, 0);
if (tuple != NULL)
tuple->flags = PKGCONF_PKG_TUPLEF_OVERRIDE;
out: out:
free(workbuf); free(workbuf);
} }
@ -156,7 +139,7 @@ pkgconf_tuple_find_delete(pkgconf_list_t *list, const char *key)
static char * static char *
dequote(const char *value) dequote(const char *value)
{ {
char *buf = calloc(1, (strlen(value) + 1) * 2); char *buf = calloc((strlen(value) + 1) * 2, 1);
char *bptr = buf; char *bptr = buf;
const char *i; const char *i;
char quote = 0; char quote = 0;
@ -178,45 +161,6 @@ dequote(const char *value)
return buf; return buf;
} }
static const char *
find_sysroot(const pkgconf_client_t *client, pkgconf_list_t *vars)
{
const char *sysroot_dir;
sysroot_dir = pkgconf_tuple_find(client, vars, "pc_sysrootdir");
if (sysroot_dir == NULL)
sysroot_dir = client->sysroot_dir;
return sysroot_dir;
}
static bool
should_rewrite_sysroot(const pkgconf_client_t *client, pkgconf_list_t *vars, const char *buf, unsigned int flags)
{
const char *sysroot_dir;
if (flags & PKGCONF_PKG_PROPF_UNINSTALLED && !(client->flags & PKGCONF_PKG_PKGF_FDO_SYSROOT_RULES))
return false;
sysroot_dir = find_sysroot(client, vars);
if (sysroot_dir == NULL)
return false;
if (*buf != '/')
return false;
if (!strcmp(sysroot_dir, "/"))
return false;
if (strlen(buf) <= strlen(sysroot_dir))
return false;
if (strstr(buf + strlen(sysroot_dir), sysroot_dir) == NULL)
return false;
return true;
}
/* /*
* !doc * !doc
* *
@ -233,23 +177,23 @@ should_rewrite_sysroot(const pkgconf_client_t *client, pkgconf_list_t *vars, con
* :rtype: pkgconf_tuple_t * * :rtype: pkgconf_tuple_t *
*/ */
pkgconf_tuple_t * pkgconf_tuple_t *
pkgconf_tuple_add(const pkgconf_client_t *client, pkgconf_list_t *list, const char *key, const char *value, bool parse, unsigned int flags) pkgconf_tuple_add(const pkgconf_client_t *client, pkgconf_list_t *list, const char *key, const char *value, bool parse)
{ {
char *dequote_value; char *dequote_value;
pkgconf_tuple_t *tuple = calloc(1, sizeof(pkgconf_tuple_t)); pkgconf_tuple_t *tuple = calloc(sizeof(pkgconf_tuple_t), 1);
pkgconf_tuple_find_delete(list, key); pkgconf_tuple_find_delete(list, key);
dequote_value = dequote(value); dequote_value = dequote(value);
PKGCONF_TRACE(client, "adding tuple to @%p: %s => %s (parsed? %d)", list, key, dequote_value, parse);
tuple->key = strdup(key); tuple->key = strdup(key);
if (parse) if (parse)
tuple->value = pkgconf_tuple_parse(client, list, dequote_value, flags); tuple->value = pkgconf_tuple_parse(client, list, dequote_value);
else else
tuple->value = strdup(dequote_value); tuple->value = strdup(dequote_value);
PKGCONF_TRACE(client, "adding tuple to @%p: %s => %s (parsed? %d)", list, key, tuple->value, parse);
pkgconf_node_insert(&tuple->iter, tuple, list); pkgconf_node_insert(&tuple->iter, tuple, list);
free(dequote_value); free(dequote_value);
@ -274,11 +218,10 @@ char *
pkgconf_tuple_find(const pkgconf_client_t *client, pkgconf_list_t *list, const char *key) pkgconf_tuple_find(const pkgconf_client_t *client, pkgconf_list_t *list, const char *key)
{ {
pkgconf_node_t *node; pkgconf_node_t *node;
pkgconf_tuple_t *global_tuple; char *res;
global_tuple = lookup_global_tuple(client, key); if ((res = pkgconf_tuple_find_global(client, key)) != NULL)
if (global_tuple != NULL && global_tuple->flags & PKGCONF_PKG_TUPLEF_OVERRIDE) return res;
return global_tuple->value;
PKGCONF_FOREACH_LIST_ENTRY(list->head, node) PKGCONF_FOREACH_LIST_ENTRY(list->head, node)
{ {
@ -288,35 +231,30 @@ pkgconf_tuple_find(const pkgconf_client_t *client, pkgconf_list_t *list, const c
return tuple->value; return tuple->value;
} }
if (global_tuple != NULL)
return global_tuple->value;
return NULL; return NULL;
} }
/* /*
* !doc * !doc
* *
* .. c:function:: char *pkgconf_tuple_parse(const pkgconf_client_t *client, pkgconf_list_t *vars, const char *value, unsigned int flags) * .. c:function:: char *pkgconf_tuple_parse(const pkgconf_client_t *client, pkgconf_list_t *vars, const char *value)
* *
* Parse an expression for variable substitution. * Parse an expression for variable substitution.
* *
* :param pkgconf_client_t* client: The pkgconf client object to access. * :param pkgconf_client_t* client: The pkgconf client object to access.
* :param pkgconf_list_t* list: The variable list to search for variables (along side the global variable list). * :param pkgconf_list_t* list: The variable list to search for variables (along side the global variable list).
* :param char* value: The ``key=value`` string to parse. * :param char* value: The ``key=value`` string to parse.
* :param uint flags: Any flags to consider while parsing.
* :return: the variable data with any variables substituted * :return: the variable data with any variables substituted
* :rtype: char * * :rtype: char *
*/ */
char * char *
pkgconf_tuple_parse(const pkgconf_client_t *client, pkgconf_list_t *vars, const char *value, unsigned int flags) pkgconf_tuple_parse(const pkgconf_client_t *client, pkgconf_list_t *vars, const char *value)
{ {
char buf[PKGCONF_BUFSIZE]; char buf[PKGCONF_BUFSIZE];
const char *ptr; const char *ptr;
char *bptr = buf; char *bptr = buf;
if (!(client->flags & PKGCONF_PKG_PKGF_FDO_SYSROOT_RULES) && if (!(client->flags & PKGCONF_PKG_PKGF_FDO_SYSROOT_RULES))
(!(flags & PKGCONF_PKG_PROPF_UNINSTALLED) || (client->flags & PKGCONF_PKG_PKGF_PKGCONF1_SYSROOT_RULES)))
{ {
if (*value == '/' && client->sysroot_dir != NULL && strncmp(value, client->sysroot_dir, strlen(client->sysroot_dir))) if (*value == '/' && client->sysroot_dir != NULL && strncmp(value, client->sysroot_dir, strlen(client->sysroot_dir)))
bptr += pkgconf_strlcpy(buf, client->sysroot_dir, sizeof buf); bptr += pkgconf_strlcpy(buf, client->sysroot_dir, sizeof buf);
@ -381,7 +319,7 @@ pkgconf_tuple_parse(const pkgconf_client_t *client, pkgconf_list_t *vars, const
{ {
size_t nlen; size_t nlen;
parsekv = pkgconf_tuple_parse(client, vars, kv, flags); parsekv = pkgconf_tuple_parse(client, vars, kv);
nlen = pkgconf_strlcpy(bptr, parsekv, remain); nlen = pkgconf_strlcpy(bptr, parsekv, remain);
free(parsekv); free(parsekv);
@ -415,15 +353,16 @@ pkgconf_tuple_parse(const pkgconf_client_t *client, pkgconf_list_t *vars, const
* safe to skip ahead in the string to scan for our sysroot dir. * safe to skip ahead in the string to scan for our sysroot dir.
* *
* Finally, we call pkgconf_path_relocate() to clean the path of spurious elements. * Finally, we call pkgconf_path_relocate() to clean the path of spurious elements.
*
* New in 1.9: Only attempt to rewrite the sysroot if we are not processing an uninstalled package.
*/ */
if (should_rewrite_sysroot(client, vars, buf, flags)) if (*buf == '/' &&
client->sysroot_dir != NULL &&
strcmp(client->sysroot_dir, "/") != 0 &&
strlen(buf) > strlen(client->sysroot_dir) &&
strstr(buf + strlen(client->sysroot_dir), client->sysroot_dir) != NULL)
{ {
char cleanpath[PKGCONF_ITEM_SIZE]; char cleanpath[PKGCONF_ITEM_SIZE];
const char *sysroot_dir = find_sysroot(client, vars);
pkgconf_strlcpy(cleanpath, buf + strlen(sysroot_dir), sizeof cleanpath); pkgconf_strlcpy(cleanpath, buf + strlen(client->sysroot_dir), sizeof cleanpath);
pkgconf_path_relocate(cleanpath, sizeof cleanpath); pkgconf_path_relocate(cleanpath, sizeof cleanpath);
return strdup(cleanpath); return strdup(cleanpath);
@ -471,6 +410,4 @@ pkgconf_tuple_free(pkgconf_list_t *list)
PKGCONF_FOREACH_LIST_ENTRY_SAFE(list->head, next, node) PKGCONF_FOREACH_LIST_ENTRY_SAFE(list->head, next, node)
pkgconf_tuple_free_entry(node->data, list); pkgconf_tuple_free_entry(node->data, list);
pkgconf_list_zero(list);
} }

File diff suppressed because it is too large Load Diff

View File

@ -29,12 +29,33 @@
# Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de> # Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de>
# Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com> # Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com>
# #
# Copying and distribution of this file, with or without modification, are # This program is free software: you can redistribute it and/or modify it
# permitted in any medium without royalty provided the copyright notice # under the terms of the GNU General Public License as published by the
# and this notice are preserved. This file is offered as-is, without any # Free Software Foundation, either version 3 of the License, or (at your
# warranty. # 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/>.
#
# As a special exception, the respective Autoconf Macro's copyright owner
# gives unlimited permission to copy, distribute and modify the configure
# scripts that are the output of Autoconf when processing the Macro. You
# need not follow the terms of the GNU General Public License when using
# or distributing such scripts, even though portions of the text of the
# Macro appear in them. The GNU General Public License (GPL) does govern
# all other use of the material that constitutes the Autoconf Macro.
#
# This special exception to the GPL applies to versions of the Autoconf
# Macro released by the Autoconf Archive. When you make and distribute a
# modified version of the Autoconf Macro, you may extend this special
# exception to the GPL to apply to your modified version as well.
#serial 6 #serial 5
AC_DEFUN([AX_CHECK_COMPILE_FLAG], AC_DEFUN([AX_CHECK_COMPILE_FLAG],
[AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_IF [AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_IF

View File

@ -99,9 +99,6 @@ These flags are always used, regardless of whether static compilation is request
.It Cflags.private .It Cflags.private
Required compiler flags for static compilation. Required compiler flags for static compilation.
(optional; fragment list; pkgconf extension) (optional; fragment list; pkgconf extension)
.It Copyright
A copyright attestation statement.
(optional; literal; pkgconf extension)
.It Libs .It Libs
Required linking flags for this package. Required linking flags for this package.
Libraries this package depends on for linking against it, which are not Libraries this package depends on for linking against it, which are not
@ -113,23 +110,15 @@ statically.
Libraries this package depends on for linking against it statically, which are Libraries this package depends on for linking against it statically, which are
not described as dependencies should be specified here. not described as dependencies should be specified here.
(optional; fragment list) (optional; fragment list)
.It License
The asserted SPDX license tag that should be applied to the given package.
(optional; literal; pkgconf extension)
.It Maintainer
The preferred contact for the maintainer. This should be in the format of a
name followed by an e-mail address or website.
(optional; literal; pkgconf extension)
.It Requires .It Requires
Required dependencies that must be met for the package to be usable. Required dependencies that must be met for the package to be usable.
All dependencies must be satisfied or the pkg-config implementation must not use All dependencies must be satisfied or the pkg-config implementation must not use
the package. the package.
(optional; dependency list) (optional; dependency list)
.It Requires.private .It Requires.private
Required dependencies that must be met for the package to be usable for header Required dependencies that must be met for the package to be usable for static linking.
inclusion and static linking.
All dependencies must be satisfied or the pkg-config implementation must not use All dependencies must be satisfied or the pkg-config implementation must not use
the package for header inclusion and static linking. the package for static linking.
(optional; dependency list) (optional; dependency list)
.It Conflicts .It Conflicts
Dependencies that must not be met for the package to be usable. Dependencies that must not be met for the package to be usable.
@ -162,9 +151,6 @@ includedir=${prefix}/include
Name: libfoo # human-readable name Name: libfoo # human-readable name
Description: an example library called libfoo # human-readable description Description: an example library called libfoo # human-readable description
Copyright: Copyright (c) 2022 pkgconf project authors
License: Apache-2.0
Maintainer: the pkgconf project <http://www.pkgconf.org>
Version: 1.0 Version: 1.0
URL: http://www.pkgconf.org URL: http://www.pkgconf.org
Requires: libbar > 2.0.0 Requires: libbar > 2.0.0

View File

@ -1,41 +1,23 @@
project('pkgconf', 'c', project('pkgconf', 'c',
version : '2.3.0', version : '1.8.1',
license : 'ISC', license : 'ISC',
meson_version : '>=0.49', meson_version : '>=0.47')
default_options : ['c_std=c99'],
)
cc = meson.get_compiler('c') cc = meson.get_compiler('c')
add_project_arguments(
'-D_BSD_SOURCE',
'-D_DEFAULT_SOURCE',
cc.get_supported_arguments(
'-Wimplicit-function-declaration',
'-Wmisleading-indentation',
),
language : 'c',
)
cdata = configuration_data() cdata = configuration_data()
check_functions = [ check_functions = [
['strlcat', 'string.h'], ['HAVE_STRLCAT', 'strlcat', 'string.h'],
['strlcpy', 'string.h'], ['HAVE_STRLCPY', 'strlcpy', 'string.h'],
['strndup', 'string.h'], ['HAVE_STRNDUP', 'strndup', 'string.h'],
['strdup', 'string.h'],
['strncasecmp', 'strings.h'],
['strcasecmp', 'strings.h'],
['reallocarray', 'stdlib.h'],
] ]
foreach f : check_functions foreach f : check_functions
name = f[0].to_upper().underscorify() if cc.has_function(f.get(1), prefix : '#include <' + f.get(2) + '>') and cc.has_header_symbol(f.get(2), f.get(1))
if cc.has_function(f[0], prefix : '#define _BSD_SOURCE\n#define _DEFAULT_SOURCE\n#include <@0@>'.format(f[1])) and cc.has_header_symbol(f[1], f[0], prefix : '#define _BSD_SOURCE\n#define _DEFAULT_SOURCE') cdata.set(f.get(0), 1)
cdata.set('HAVE_@0@'.format(name), 1)
cdata.set('HAVE_DECL_@0@'.format(name), 1)
else
cdata.set('HAVE_DECL_@0@'.format(name), 0)
endif endif
endforeach endforeach
@ -49,25 +31,15 @@ foreach f : ['libdir', 'datadir']
personality_path += [join_paths(get_option('prefix'), get_option(f), 'pkgconfig', 'personality.d')] personality_path += [join_paths(get_option('prefix'), get_option(f), 'pkgconfig', 'personality.d')]
endforeach endforeach
SYSTEM_LIBDIR = get_option('with-system-libdir') cdata.set_quoted('SYSTEM_LIBDIR', join_paths(get_option('prefix'), get_option('libdir')))
if SYSTEM_LIBDIR != '' cdata.set_quoted('SYSTEM_INCLUDEDIR', join_paths(get_option('prefix'), get_option('includedir')))
cdata.set_quoted('SYSTEM_LIBDIR', SYSTEM_LIBDIR)
else
cdata.set_quoted('SYSTEM_LIBDIR', join_paths(get_option('prefix'), get_option('libdir')))
endif
SYSTEM_INCLUDEDIR = get_option('with-system-includedir')
if SYSTEM_INCLUDEDIR != ''
cdata.set_quoted('SYSTEM_INCLUDEDIR', SYSTEM_INCLUDEDIR)
else
cdata.set_quoted('SYSTEM_INCLUDEDIR', join_paths(get_option('prefix'), get_option('includedir')))
endif
cdata.set_quoted('PKG_DEFAULT_PATH', ':'.join(default_path)) cdata.set_quoted('PKG_DEFAULT_PATH', ':'.join(default_path))
cdata.set_quoted('PERSONALITY_PATH', ':'.join(personality_path)) cdata.set_quoted('PERSONALITY_PATH', ':'.join(personality_path))
cdata.set_quoted('PACKAGE_NAME', meson.project_name()) cdata.set_quoted('PACKAGE_NAME', meson.project_name())
cdata.set_quoted('PACKAGE_VERSION', meson.project_version()) cdata.set_quoted('PACKAGE_VERSION', meson.project_version())
cdata.set_quoted('PACKAGE_BUGREPORT', 'https://todo.sr.ht/~kaniini/pkgconf') cdata.set_quoted('PACKAGE_BUGREPORT', 'https://todo.sr.ht/~kaniini/pkgconf')
cdata.set('abs_top_srcdir', meson.current_source_dir()) cdata.set('abs_top_srcdir', meson.source_root())
cdata.set('abs_top_builddir', meson.current_build_dir()) cdata.set('abs_top_builddir', meson.build_root())
subdir('libpkgconf') subdir('libpkgconf')
@ -96,22 +68,10 @@ libpkgconf = library('pkgconf',
'libpkgconf/tuple.c', 'libpkgconf/tuple.c',
c_args: ['-DLIBPKGCONF_EXPORT', build_static], c_args: ['-DLIBPKGCONF_EXPORT', build_static],
install : true, install : true,
version : '5.0.0', version : '3.0.0',
soversion : '5', soversion : '3',
) )
# For other projects using libpkgconfig as a subproject
dep_libpkgconf = declare_dependency(
link_with : libpkgconf,
include_directories : include_directories('.'),
)
# If we have a new enough meson override the dependency so that only
# `dependency('libpkgconf')` is required from the consumer
if meson.version().version_compare('>= 0.54.0')
meson.override_dependency('libpkgconf', dep_libpkgconf)
endif
pkg = import('pkgconfig') pkg = import('pkgconfig')
pkg.generate(libpkgconf, pkg.generate(libpkgconf,
name : 'libpkgconf', name : 'libpkgconf',
@ -131,12 +91,15 @@ pkgconf_exe = executable('pkgconf',
c_args: build_static, c_args: build_static,
install : true) install : true)
with_tests = get_option('tests') if get_option('tests')
kyua_exe = find_program('kyua', required : with_tests, disabler : true) kyua_exe = find_program('kyua')
atf_sh_exe = find_program('atf-sh', required : with_tests, disabler : true) atf_sh_exe = find_program('atf-sh')
kyuafile = configure_file(input : 'Kyuafile.in', output : 'Kyuafile', configuration : cdata) test('kyua', kyua_exe, args : ['--config=none', 'test', '--kyuafile=' + join_paths(meson.build_root(), 'Kyuafile'), '--build-root=' + meson.build_root()])
test('kyua', kyua_exe, args : ['--config=none', 'test', '--kyuafile', kyuafile, '--build-root', meson.current_build_dir()])
subdir('tests')
configure_file(input : 'Kyuafile.in', output : 'Kyuafile', configuration : cdata)
subdir('tests')
endif
install_man('man/pkgconf.1') install_man('man/pkgconf.1')
install_man('man/pkg.m4.7') install_man('man/pkg.m4.7')

View File

@ -1,19 +1,3 @@
option( option('tests', type: 'boolean', value: true,
'tests', description: 'Build tests which depends upon the kyua framework'
type: 'feature',
description: 'Build tests which depends upon the kyua framework',
)
option(
'with-system-libdir',
type: 'string',
value: '',
description: 'Specify the system library directory (default {prefix}/{libdir})'
)
option(
'with-system-includedir',
type: 'string',
value: '',
description: 'Specify the system include directory (default {prefix}/{includedir})'
) )

23
pkg.m4
View File

@ -1,5 +1,5 @@
# pkg.m4 - Macros to locate and use pkg-config. -*- Autoconf -*- # pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*-
# serial 12 (pkg-config-0.29.2) # serial 11 (pkg-config-0.29.1)
dnl Copyright © 2004 Scott James Remnant <scott@netsplit.com>. dnl Copyright © 2004 Scott James Remnant <scott@netsplit.com>.
dnl Copyright © 2012-2015 Dan Nicholson <dbn.lists@gmail.com> dnl Copyright © 2012-2015 Dan Nicholson <dbn.lists@gmail.com>
@ -41,13 +41,13 @@ dnl
dnl See the "Since" comment for each macro you use to see what version dnl See the "Since" comment for each macro you use to see what version
dnl of the macros you require. dnl of the macros you require.
m4_defun([PKG_PREREQ], m4_defun([PKG_PREREQ],
[m4_define([PKG_MACROS_VERSION], [0.29.2]) [m4_define([PKG_MACROS_VERSION], [0.29.1])
m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1, m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1,
[m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])]) [m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])])
])dnl PKG_PREREQ ])dnl PKG_PREREQ
dnl PKG_PROG_PKG_CONFIG([MIN-VERSION], [ACTION-IF-NOT-FOUND]) dnl PKG_PROG_PKG_CONFIG([MIN-VERSION])
dnl --------------------------------------------------------- dnl ----------------------------------
dnl Since: 0.16 dnl Since: 0.16
dnl dnl
dnl Search for the pkg-config tool and set the PKG_CONFIG variable to dnl Search for the pkg-config tool and set the PKG_CONFIG variable to
@ -55,12 +55,6 @@ dnl first found in the path. Checks that the version of pkg-config found
dnl is at least MIN-VERSION. If MIN-VERSION is not specified, 0.9.0 is dnl is at least MIN-VERSION. If MIN-VERSION is not specified, 0.9.0 is
dnl used since that's the first version where most current features of dnl used since that's the first version where most current features of
dnl pkg-config existed. dnl pkg-config existed.
dnl
dnl If pkg-config is not found or older than specified, it will result
dnl in an empty PKG_CONFIG variable. To avoid widespread issues with
dnl scripts not checking it, ACTION-IF-NOT-FOUND defaults to aborting.
dnl You can specify [PKG_CONFIG=false] as an action instead, which would
dnl result in pkg-config tests failing, but no bogus error messages.
AC_DEFUN([PKG_PROG_PKG_CONFIG], AC_DEFUN([PKG_PROG_PKG_CONFIG],
[m4_pattern_forbid([^_?PKG_[A-Z_]+$]) [m4_pattern_forbid([^_?PKG_[A-Z_]+$])
m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$]) m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$])
@ -81,9 +75,6 @@ if test -n "$PKG_CONFIG"; then
AC_MSG_RESULT([no]) AC_MSG_RESULT([no])
PKG_CONFIG="" PKG_CONFIG=""
fi fi
fi
if test -z "$PKG_CONFIG"; then
m4_default([$2], [AC_MSG_ERROR([pkg-config not found])])
fi[]dnl fi[]dnl
])dnl PKG_PROG_PKG_CONFIG ])dnl PKG_PROG_PKG_CONFIG
@ -95,7 +86,7 @@ dnl Check to see whether a particular set of modules exists. Similar to
dnl PKG_CHECK_MODULES(), but does not set variables or print errors. dnl PKG_CHECK_MODULES(), but does not set variables or print errors.
dnl dnl
dnl Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG]) dnl Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG])
dnl only at the first occurrence in configure.ac, so if the first place dnl only at the first occurence in configure.ac, so if the first place
dnl it's called might be skipped (such as if it is within an "if", you dnl it's called might be skipped (such as if it is within an "if", you
dnl have to call PKG_CHECK_EXISTS manually dnl have to call PKG_CHECK_EXISTS manually
AC_DEFUN([PKG_CHECK_EXISTS], AC_DEFUN([PKG_CHECK_EXISTS],
@ -151,7 +142,7 @@ AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl
AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl
pkg_failed=no pkg_failed=no
AC_MSG_CHECKING([for $2]) AC_MSG_CHECKING([for $1])
_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2]) _PKG_CONFIG([$1][_CFLAGS], [cflags], [$2])
_PKG_CONFIG([$1][_LIBS], [libs], [$2]) _PKG_CONFIG([$1][_LIBS], [libs], [$2])

View File

@ -11,7 +11,6 @@ tests_init \
libs_cflags_version_alt \ libs_cflags_version_alt \
libs_cflags_version_different \ libs_cflags_version_different \
libs_cflags_version_different_bad \ libs_cflags_version_different_bad \
libs_env \
exists_nonexitent \ exists_nonexitent \
nonexitent \ nonexitent \
exists_version \ exists_version \
@ -22,8 +21,6 @@ tests_init \
exists2 \ exists2 \
exists3 \ exists3 \
exists_version_alt \ exists_version_alt \
exists_cflags \
exists_cflags_env \
uninstalled_bad \ uninstalled_bad \
uninstalled \ uninstalled \
libs_intermediary \ libs_intermediary \
@ -32,19 +29,13 @@ tests_init \
libs_circular_directpc \ libs_circular_directpc \
libs_static \ libs_static \
libs_static_ordering \ libs_static_ordering \
libs_metapackage \
license_isc \
license_noassertion \
modversion_noflatten \
pkg_config_path \ pkg_config_path \
nolibs \ nolibs \
nocflags \ nocflags \
arbitary_path \ arbitary_path \
with_path \ with_path \
relocatable \ relocatable \
single_depth_selectors \ single_depth_selectors
print_variables_env \
variable_env
noargs_body() noargs_body()
{ {
@ -56,7 +47,7 @@ libs_body()
{ {
export PKG_CONFIG_PATH="${selfdir}/lib1" export PKG_CONFIG_PATH="${selfdir}/lib1"
atf_check \ atf_check \
-o inline:"-L/test/lib -lfoo\n" \ -o inline:"-L/test/lib -lfoo \n" \
pkgconf --libs foo pkgconf --libs foo
} }
@ -64,7 +55,7 @@ libs_cflags_body()
{ {
export PKG_CONFIG_PATH="${selfdir}/lib1" export PKG_CONFIG_PATH="${selfdir}/lib1"
atf_check \ atf_check \
-o inline:"-fPIC -I/test/include/foo -L/test/lib -lfoo\n" \ -o inline:"-fPIC -I/test/include/foo -L/test/lib -lfoo \n" \
pkgconf --cflags --libs foo pkgconf --cflags --libs foo
} }
@ -73,7 +64,7 @@ libs_cflags_version_body()
{ {
export PKG_CONFIG_PATH="${selfdir}/lib1" export PKG_CONFIG_PATH="${selfdir}/lib1"
atf_check \ atf_check \
-o inline:"-fPIC -I/test/include/foo -L/test/lib -lfoo\n" \ -o inline:"-fPIC -I/test/include/foo -L/test/lib -lfoo \n" \
pkgconf --cflags --libs 'foo > 1.2' pkgconf --cflags --libs 'foo > 1.2'
} }
@ -81,7 +72,7 @@ libs_cflags_version_multiple_body()
{ {
export PKG_CONFIG_PATH="${selfdir}/lib1" export PKG_CONFIG_PATH="${selfdir}/lib1"
atf_check \ atf_check \
-o inline:"-fPIC -I/test/include/foo -L/test/lib -lbar -lfoo\n" \ -o inline:"-I/test/include/foo -fPIC -L/test/lib -lbar -lfoo \n" \
pkgconf --cflags --libs 'foo > 1.2 bar >= 1.3' pkgconf --cflags --libs 'foo > 1.2 bar >= 1.3'
} }
@ -89,7 +80,7 @@ libs_cflags_version_multiple_coma_body()
{ {
export PKG_CONFIG_PATH="${selfdir}/lib1" export PKG_CONFIG_PATH="${selfdir}/lib1"
atf_check \ atf_check \
-o inline:"-fPIC -I/test/include/foo -L/test/lib -lbar -lfoo\n" \ -o inline:"-I/test/include/foo -fPIC -L/test/lib -lbar -lfoo \n" \
pkgconf --cflags --libs 'foo > 1.2,bar >= 1.3' pkgconf --cflags --libs 'foo > 1.2,bar >= 1.3'
} }
@ -97,7 +88,7 @@ libs_cflags_version_alt_body()
{ {
export PKG_CONFIG_PATH="${selfdir}/lib1" export PKG_CONFIG_PATH="${selfdir}/lib1"
atf_check \ atf_check \
-o inline:"-fPIC -I/test/include/foo -L/test/lib -lfoo\n" \ -o inline:"-fPIC -I/test/include/foo -L/test/lib -lfoo \n" \
pkgconf --cflags --libs 'foo' '>' '1.2' pkgconf --cflags --libs 'foo' '>' '1.2'
} }
@ -105,7 +96,7 @@ libs_cflags_version_different_body()
{ {
export PKG_CONFIG_PATH="${selfdir}/lib1" export PKG_CONFIG_PATH="${selfdir}/lib1"
atf_check \ atf_check \
-o inline:"-fPIC -I/test/include/foo -L/test/lib -lfoo\n" \ -o inline:"-fPIC -I/test/include/foo -L/test/lib -lfoo \n" \
pkgconf --cflags --libs 'foo' '!=' '1.3.0' pkgconf --cflags --libs 'foo' '!=' '1.3.0'
} }
@ -213,30 +204,30 @@ libs_intermediary_body()
{ {
export PKG_CONFIG_PATH="${selfdir}/lib1" export PKG_CONFIG_PATH="${selfdir}/lib1"
atf_check \ atf_check \
-o inline:"-lintermediary-1 -lintermediary-2 -lfoo -lbar -lbaz\n" \ -o inline:"-lintermediary-1 -lintermediary-2 -lfoo -lbar -lbaz \n" \
pkgconf --libs intermediary-1 intermediary-2 pkgconf --libs intermediary-1 intermediary-2
} }
libs_circular2_body()
{
export PKG_CONFIG_PATH="${selfdir}/lib1"
atf_check \
-o inline:"circular-1: breaking circular reference (circular-1 -> circular-2 -> circular-1)\n" \
pkgconf circular-2 --validate
}
libs_circular1_body() libs_circular1_body()
{ {
export PKG_CONFIG_PATH="${selfdir}/lib1" export PKG_CONFIG_PATH="${selfdir}/lib1"
atf_check \ atf_check \
-o inline:"circular-3: breaking circular reference (circular-3 -> circular-1 -> circular-3)\n" \ -o inline:"-lcircular-1 -lcircular-2 -lcircular-3 \n" \
pkgconf circular-1 --validate pkgconf --libs circular-1
}
libs_circular2_body()
{
export PKG_CONFIG_PATH="${selfdir}/lib1"
atf_check \
-o inline:"-lcircular-3 -lcircular-1 -lcircular-2 \n" \
pkgconf --libs circular-3
} }
libs_circular_directpc_body() libs_circular_directpc_body()
{ {
atf_check \ atf_check \
-o inline:"-lcircular-3 -lcircular-1 -lcircular-2\n" \ -o inline:"-lcircular-1 -lcircular-2 -lcircular-3 \n" \
pkgconf --libs ${selfdir}/lib1/circular-3.pc pkgconf --libs ${selfdir}/lib1/circular-3.pc
} }
@ -244,7 +235,7 @@ libs_static_body()
{ {
export PKG_CONFIG_PATH="${selfdir}/lib1" export PKG_CONFIG_PATH="${selfdir}/lib1"
atf_check \ atf_check \
-o inline:"/libfoo.a -pthread\n" \ -o inline:"/libfoo.a -pthread \n" \
pkgconf --libs static-archive-libs pkgconf --libs static-archive-libs
} }
@ -252,36 +243,28 @@ libs_static_ordering_body()
{ {
export PKG_CONFIG_PATH="${selfdir}/lib1" export PKG_CONFIG_PATH="${selfdir}/lib1"
atf_check \ atf_check \
-o inline:"-L/test/lib -lbar -lfoo\n" \ -o inline:"-L/test/lib -lbar -lfoo \n" \
pkgconf --libs foo bar pkgconf --libs foo bar
} }
libs_metapackage_body()
{
export PKG_CONFIG_PATH="${selfdir}/lib1"
atf_check \
-o inline:"-L/test/lib -lbar -lfoo\n" \
pkgconf --static --libs metapackage-3
}
pkg_config_path_body() pkg_config_path_body()
{ {
export PKG_CONFIG_PATH="${selfdir}/lib1${PATH_SEP}${selfdir}/lib2" export PKG_CONFIG_PATH="${selfdir}/lib1${PATH_SEP}${selfdir}/lib2"
atf_check \ atf_check \
-o inline:"-L/test/lib -lfoo\n" \ -o inline:"-L/test/lib -lfoo \n" \
pkgconf --libs foo pkgconf --libs foo
atf_check \ atf_check \
-o inline:"-L/test/lib -lbar -lfoo\n" \ -o inline:"-L/test/lib -lbar -lfoo \n" \
pkgconf --libs bar pkgconf --libs bar
} }
with_path_body() with_path_body()
{ {
atf_check \ atf_check \
-o inline:"-L/test/lib -lfoo\n" \ -o inline:"-L/test/lib -lfoo \n" \
pkgconf --with-path=${selfdir}/lib1 --with-path=${selfdir}/lib2 --libs foo pkgconf --with-path=${selfdir}/lib1 --with-path=${selfdir}/lib2 --libs foo
atf_check \ atf_check \
-o inline:"-L/test/lib -lbar -lfoo\n" \ -o inline:"-L/test/lib -lbar -lfoo \n" \
pkgconf --with-path=${selfdir}/lib1 --with-path=${selfdir}/lib2 --libs bar pkgconf --with-path=${selfdir}/lib1 --with-path=${selfdir}/lib2 --libs bar
} }
@ -305,7 +288,7 @@ arbitary_path_body()
{ {
cp ${selfdir}/lib1/foo.pc . cp ${selfdir}/lib1/foo.pc .
atf_check \ atf_check \
-o inline:"-L/test/lib -lfoo\n" \ -o inline:"-L/test/lib -lfoo \n" \
pkgconf --libs foo.pc pkgconf --libs foo.pc
} }
@ -324,60 +307,3 @@ single_depth_selectors_body()
-o inline:"foo\n" \ -o inline:"foo\n" \
pkgconf --with-path=${selfdir}/lib3 --print-requires bar pkgconf --with-path=${selfdir}/lib3 --print-requires bar
} }
license_isc_body()
{
atf_check \
-o inline:"foo: ISC\n" \
pkgconf --with-path=${selfdir}/lib1 --license foo
}
license_noassertion_body()
{
atf_check \
-o inline:"bar: NOASSERTION\nfoo: ISC\n" \
pkgconf --with-path=${selfdir}/lib1 --license bar
}
modversion_noflatten_body()
{
atf_check \
-o inline:"1.3\n" \
pkgconf --with-path=${selfdir}/lib1 --modversion bar
}
exists_cflags_body()
{
atf_check \
-o inline:"-DHAVE_FOO\n" \
pkgconf --with-path=${selfdir}/lib1 --cflags --exists-cflags --fragment-filter=D foo
}
exists_cflags_env_body()
{
atf_check \
-o inline:"FOO_CFLAGS='-DHAVE_FOO'\n" \
pkgconf --with-path=${selfdir}/lib1 --cflags --exists-cflags --fragment-filter=D --env=FOO foo
}
libs_env_body()
{
atf_check \
-o inline:"FOO_LIBS='-L/test/lib -lfoo'\n" \
pkgconf --with-path=${selfdir}/lib1 --libs --env=FOO foo
}
print_variables_env_body()
{
atf_check \
-o inline:"FOO_CFLAGS='-fPIC -I/test/include/foo'\nFOO_LIBS='-L/test/lib -lfoo'\nFOO_INCLUDEDIR='/test/include'\nFOO_LIBDIR='/test/lib'\nFOO_EXEC_PREFIX='/test'\nFOO_PREFIX='/test'\nFOO_PCFILEDIR='${selfdir}/lib1'\n" \
pkgconf --with-path=${selfdir}/lib1 --env=FOO --print-variables --cflags --libs foo
}
variable_env_body()
{
atf_check \
-o inline:"FOO_INCLUDEDIR='/test/include'\n" \
pkgconf --with-path=${selfdir}/lib1 --env=FOO --variable=includedir foo
}

View File

@ -10,7 +10,7 @@ libs_body()
{ {
export PKG_CONFIG_PATH="${selfdir}/lib1" export PKG_CONFIG_PATH="${selfdir}/lib1"
atf_check \ atf_check \
-o inline:"-L/test/lib -lconflicts\n" \ -o inline:"-L/test/lib -lconflicts \n" \
pkgconf --libs conflicts pkgconf --libs conflicts
} }
@ -18,6 +18,6 @@ ignore_body()
{ {
export PKG_CONFIG_PATH="${selfdir}/lib1" export PKG_CONFIG_PATH="${selfdir}/lib1"
atf_check \ atf_check \
-o inline:"-L/test/lib -lconflicts\n" \ -o inline:"-L/test/lib -lconflicts \n" \
pkgconf --ignore-conflicts --libs conflicts pkgconf --ignore-conflicts --libs conflicts
} }

View File

@ -9,12 +9,12 @@ libs_body()
{ {
export PKG_CONFIG_PATH="${selfdir}/lib1" export PKG_CONFIG_PATH="${selfdir}/lib1"
atf_check \ atf_check \
-o inline:"-F/test/lib -framework framework-1\n" \ -o inline:"-F/test/lib -framework framework-1 \n" \
pkgconf --libs framework-1 pkgconf --libs framework-1
atf_check \ atf_check \
-o inline:"-F/test/lib -framework framework-2 -framework framework-1\n" \ -o inline:"-F/test/lib -framework framework-2 -framework framework-1 \n" \
pkgconf --libs framework-2 pkgconf --libs framework-2
atf_check \ atf_check \
-o inline:"-F/test/lib -framework framework-2 -framework framework-1\n" \ -o inline:"-F/test/lib -framework framework-2 -framework framework-1 \n" \
pkgconf --libs framework-1 framework-2 pkgconf --libs framework-1 framework-2
} }

View File

@ -1,11 +0,0 @@
prefix=/usr
exec_prefix=/usr
libdir=${prefix}/lib64
includedir=${prefix}/include
Name: child-prefix-1
Description: child prefix 1 test data
Requires:
Version: 1.0
Libs: -L${libdir} -lchild-prefix-1
Cflags: -I${includedir}/child-prefix-1

View File

@ -9,4 +9,3 @@ Version: 1.2.3
Libs: -L${libdir} -lfoo Libs: -L${libdir} -lfoo
Cflags: -fPIC -I${includedir}/foo Cflags: -fPIC -I${includedir}/foo
Cflags.private: -DFOO_STATIC Cflags.private: -DFOO_STATIC
License: ISC

View File

@ -1,12 +0,0 @@
prefix=/test
exec_prefix=${prefix}
libdir=${prefix}/lib
includedir=${prefix}/include
Name: foobar
Description: A testing pkg-config file
Version: 3.2.1
Libs: -L${libdir} -lfoobar
Cflags: -fPIC -I${includedir}/foobar
Cflags.private: -DFOOBAR_STATIC
License: ISC

View File

@ -1,6 +0,0 @@
Name: metapackage-1
Version: 0.1
Description: metapackage for testing purposes
Requires.private: metapackage-2
Libs: -lmetapackage-1
Cflags: -I/metapackage-1

View File

@ -1,5 +0,0 @@
Name: metapackage-2
Version: 0.1
Description: metapackage for testing purposes
Libs: -lmetapackage-2
Cflags: -I/metapackage-2

View File

@ -1,4 +0,0 @@
Name: metapackage-3
Version: 0.1
Description: metapackage for testing purposes
Requires.private: bar

View File

@ -1,4 +0,0 @@
Name: metapackage
Version: 0.1
Description: metapackage for testing purposes
Requires: metapackage-1, metapackage-2

View File

@ -1,10 +0,0 @@
prefix=${pc_sysrootdir}/test
exec_prefix=${prefix}
libdir=${prefix}/lib
includedir=${prefix}/include
Name: omg-sysroot
Description: A testing pkg-config file
Version: 1.2.3
Libs: -L${libdir} -lomg
Cflags: -fPIC -I${includedir}/omg

View File

@ -7,4 +7,4 @@ Name: quotes
Description: A testing pkg-config file Description: A testing pkg-config file
Version: 1.2.3 Version: 1.2.3
Libs: -L${libdir} -lfoo Libs: -L${libdir} -lfoo
Cflags: -DQUOTED=\"bla\" -DA=\"escaped\ string\'\ \literal\" -DB="\1\$" -DC='bla' Cflags: -DQUOTED=\"bla\"

View File

@ -1,7 +0,0 @@
prefix=/test\ with\ spaces
includedir=${prefix}/include
Name: spaces-in-paths
Version: 1
Description: test package for properly expanding spaces in variables
Cflags: -I${includedir} -I${includedir}/subdir

View File

@ -1,7 +0,0 @@
prefix=${pc_sysrootdir}/usr
Name: sysroot-dir
Description: Package for testing whether sysroot dirs are repeated or not
Version: 1
CFlags: -I${prefix}/include
Libs: -L${prefix}/lib -lfoo

View File

@ -1,9 +0,0 @@
prefix=/sysroot/usr
includedir=${prefix}/include
libdir=${prefix}/lib
Name: sysroot-dir
Description: Package for testing whether sysroot dirs are repeated or not
Version: 1
CFlags: -I${includedir}
Libs: -L${libdir} -lfoo

View File

@ -1,9 +0,0 @@
prefix=${pc_sysrootdir}/usr
includedir=${prefix}/include
libdir=${prefix}/lib
Name: sysroot-dir
Description: Package for testing whether sysroot dirs are repeated or not
Version: 1
CFlags: -I${includedir}
Libs: -L${libdir} -lfoo

View File

@ -1,9 +0,0 @@
prefix=/sysroot/usr
includedir=${prefix}/include
libdir=${prefix}/lib
Name: sysroot-dir
Description: Package for testing whether sysroot dirs are repeated or not
Version: 1
CFlags: -I${includedir}
Libs: -L${libdir} -lfoo

View File

@ -1,11 +0,0 @@
prefix=/test
exec_prefix=${prefix}
libdir=${prefix}/lib
includedir=${prefix}/include
Name: unavailable_provider
Description: Provides an otherwise unavailable package
Version: 1.2.3
Provides: unavailable = 1.2.3
Libs: -lunavailable
Cflags:

View File

@ -1,10 +0,0 @@
prefix=/tëst
exec_prefix=${prefix}
libdir=${prefix}/lib
includedir=${prefix}/include
Name: utf8
Description: Library installed in a prefix with UTF-8
Version: 0
Libs: -L${libdir} -lutf8
Cflags: -I${includedir}

View File

@ -18,5 +18,5 @@ tests = [
# yuck # yuck
foreach test : tests foreach test : tests
test_file = configure_file(input: test + '.sh', output: test, copy: true) configure_file(input: test + '.sh', output: test, copy: true)
endforeach endforeach

View File

@ -41,7 +41,7 @@ comments_body()
{ {
export PKG_CONFIG_PATH="${selfdir}/lib1" export PKG_CONFIG_PATH="${selfdir}/lib1"
atf_check \ atf_check \
-o inline:"-lfoo\n" \ -o inline:"-lfoo \n" \
pkgconf --libs comments pkgconf --libs comments
} }
@ -49,7 +49,7 @@ comments_in_fields_body()
{ {
export PKG_CONFIG_PATH="${selfdir}/lib1" export PKG_CONFIG_PATH="${selfdir}/lib1"
atf_check \ atf_check \
-o inline:"-lfoo\n" \ -o inline:"-lfoo \n" \
pkgconf --libs comments-in-fields pkgconf --libs comments-in-fields
} }
@ -57,7 +57,7 @@ dos_body()
{ {
export PKG_CONFIG_PATH="${selfdir}/lib1" export PKG_CONFIG_PATH="${selfdir}/lib1"
atf_check \ atf_check \
-o inline:"-L/test/lib/dos-lineendings -ldos-lineendings\n" \ -o inline:"-L/test/lib/dos-lineendings -ldos-lineendings \n" \
pkgconf --libs dos-lineendings pkgconf --libs dos-lineendings
} }
@ -65,7 +65,7 @@ no_trailing_newline_body()
{ {
export PKG_CONFIG_PATH="${selfdir}/lib1" export PKG_CONFIG_PATH="${selfdir}/lib1"
atf_check \ atf_check \
-o inline:"-I/test/include/no-trailing-newline\n" \ -o inline:"-I/test/include/no-trailing-newline \n" \
pkgconf --cflags no-trailing-newline pkgconf --cflags no-trailing-newline
} }
@ -73,7 +73,7 @@ argv_parse_body()
{ {
export PKG_CONFIG_PATH="${selfdir}/lib1" export PKG_CONFIG_PATH="${selfdir}/lib1"
atf_check \ atf_check \
-o inline:"-llib-3 -llib-1 -llib-2 -lpthread\n" \ -o inline:"-llib-3 -llib-1 -llib-2 -lpthread \n" \
pkgconf --libs argv-parse pkgconf --libs argv-parse
} }
@ -90,7 +90,7 @@ argv_parse_3_body()
{ {
export PKG_CONFIG_PATH="${selfdir}/lib1" export PKG_CONFIG_PATH="${selfdir}/lib1"
atf_check \ atf_check \
-o inline:"-llib-1 -pthread /test/lib/lib2.so\n" \ -o inline:"-llib-1 -pthread /test/lib/lib2.so \n" \
pkgconf --libs argv-parse-3 pkgconf --libs argv-parse-3
} }
@ -98,10 +98,10 @@ tilde_quoting_body()
{ {
export PKG_CONFIG_PATH="${selfdir}/lib1" export PKG_CONFIG_PATH="${selfdir}/lib1"
atf_check \ atf_check \
-o inline:"-L~ -ltilde\n" \ -o inline:"-L~ -ltilde \n" \
pkgconf --libs tilde-quoting pkgconf --libs tilde-quoting
atf_check \ atf_check \
-o inline:"-I~\n" \ -o inline:"-I~ \n" \
pkgconf --cflags tilde-quoting pkgconf --cflags tilde-quoting
} }
@ -109,7 +109,7 @@ paren_quoting_body()
{ {
export PKG_CONFIG_PATH="${selfdir}/lib1" export PKG_CONFIG_PATH="${selfdir}/lib1"
atf_check \ atf_check \
-o inline:"-L\$(libdir) -ltilde\n" \ -o inline:"-L\$(libdir) -ltilde \n" \
pkgconf --libs paren-quoting pkgconf --libs paren-quoting
} }
@ -134,7 +134,7 @@ escaped_backslash_body()
{ {
atf_check \ atf_check \
-e ignore \ -e ignore \
-o inline:"-IC:\\\\\\\\A\n" \ -o inline:"-IC:\\\\\\\\A \n" \
pkgconf --with-path=${selfdir}/lib1 --cflags escaped-backslash pkgconf --with-path=${selfdir}/lib1 --cflags escaped-backslash
} }
@ -142,7 +142,7 @@ quoted_body()
{ {
export PKG_CONFIG_PATH="${selfdir}/lib1" export PKG_CONFIG_PATH="${selfdir}/lib1"
atf_check \ atf_check \
-o inline:"-DQUOTED=\\\"bla\\\" -DA=\\\"escaped\\ string\\\'\\ literal\\\" -DB=\\\\\\1\$ -DC=bla\n" \ -o inline:"-DQUOTED=\\\"bla\\\" \n" \
pkgconf --cflags quotes pkgconf --cflags quotes
} }
@ -150,7 +150,7 @@ flag_order_1_body()
{ {
export PKG_CONFIG_PATH="${selfdir}/lib1" export PKG_CONFIG_PATH="${selfdir}/lib1"
atf_check \ atf_check \
-o inline:"-L/test/lib -Bdynamic -lfoo -Bstatic -lbar\n" \ -o inline:"-L/test/lib -Bdynamic -lfoo -Bstatic -lbar \n" \
pkgconf --libs flag-order-1 pkgconf --libs flag-order-1
} }
@ -158,7 +158,7 @@ flag_order_2_body()
{ {
export PKG_CONFIG_PATH="${selfdir}/lib1" export PKG_CONFIG_PATH="${selfdir}/lib1"
atf_check \ atf_check \
-o inline:"-L/test/lib -Bdynamic -lfoo -Bstatic -lbar -lfoo\n" \ -o inline:"-L/test/lib -Bdynamic -lfoo -Bstatic -lbar -lfoo \n" \
pkgconf --libs flag-order-1 foo pkgconf --libs flag-order-1 foo
} }
@ -166,7 +166,7 @@ flag_order_3_body()
{ {
export PKG_CONFIG_PATH="${selfdir}/lib1" export PKG_CONFIG_PATH="${selfdir}/lib1"
atf_check \ atf_check \
-o inline:"-L/test/lib -Wl,--start-group -lfoo -lbar -Wl,--end-group\n" \ -o inline:"-L/test/lib -Wl,--start-group -lfoo -lbar -Wl,--end-group \n" \
pkgconf --libs flag-order-3 pkgconf --libs flag-order-3
} }
@ -174,7 +174,7 @@ flag_order_4_body()
{ {
export PKG_CONFIG_PATH="${selfdir}/lib1" export PKG_CONFIG_PATH="${selfdir}/lib1"
atf_check \ atf_check \
-o inline:"-L/test/lib -Wl,--start-group -lfoo -lbar -Wl,--end-group -lfoo\n" \ -o inline:"-L/test/lib -Wl,--start-group -lfoo -lbar -Wl,--end-group -lfoo \n" \
pkgconf --libs flag-order-3 foo pkgconf --libs flag-order-3 foo
} }
@ -182,7 +182,7 @@ variable_whitespace_body()
{ {
export PKG_CONFIG_PATH="${selfdir}/lib1" export PKG_CONFIG_PATH="${selfdir}/lib1"
atf_check \ atf_check \
-o inline:"-I/test/include\n" \ -o inline:"-I/test/include \n" \
pkgconf --cflags variable-whitespace pkgconf --cflags variable-whitespace
} }
@ -190,7 +190,7 @@ fragment_quoting_body()
{ {
export PKG_CONFIG_PATH="${selfdir}/lib1" export PKG_CONFIG_PATH="${selfdir}/lib1"
atf_check \ atf_check \
-o inline:"-fPIC -I/test/include/foo -DQUOTED=\\\"/test/share/doc\\\"\n" \ -o inline:"-fPIC -I/test/include/foo -DQUOTED=\\\"/test/share/doc\\\" \n" \
pkgconf --cflags fragment-quoting pkgconf --cflags fragment-quoting
} }
@ -198,7 +198,7 @@ fragment_quoting_2_body()
{ {
export PKG_CONFIG_PATH="${selfdir}/lib1" export PKG_CONFIG_PATH="${selfdir}/lib1"
atf_check \ atf_check \
-o inline:"-fPIC -I/test/include/foo -DQUOTED=/test/share/doc\n" \ -o inline:"-fPIC -I/test/include/foo -DQUOTED=/test/share/doc \n" \
pkgconf --cflags fragment-quoting-2 pkgconf --cflags fragment-quoting-2
} }
@ -206,7 +206,7 @@ fragment_quoting_3_body()
{ {
export PKG_CONFIG_PATH="${selfdir}/lib1" export PKG_CONFIG_PATH="${selfdir}/lib1"
atf_check \ atf_check \
-o inline:"-fPIC -I/test/include/foo -DQUOTED=\\\"/test/share/doc\\\"\n" \ -o inline:"-fPIC -I/test/include/foo -DQUOTED=\\\"/test/share/doc\\\" \n" \
pkgconf --cflags fragment-quoting-3 pkgconf --cflags fragment-quoting-3
} }
@ -214,7 +214,7 @@ fragment_quoting_5_body()
{ {
export PKG_CONFIG_PATH="${selfdir}/lib1" export PKG_CONFIG_PATH="${selfdir}/lib1"
atf_check \ atf_check \
-o inline:"-fPIC -I/test/include/foo -DQUOTED=/test/share/doc\n" \ -o inline:"-fPIC -I/test/include/foo -DQUOTED=/test/share/doc \n" \
pkgconf --cflags fragment-quoting-5 pkgconf --cflags fragment-quoting-5
} }
@ -222,28 +222,28 @@ fragment_quoting_7_body()
{ {
export PKG_CONFIG_PATH="${selfdir}/lib1" export PKG_CONFIG_PATH="${selfdir}/lib1"
atf_check \ atf_check \
-o inline:"-Dhello=10 -Dworld=+32 -DDEFINED_FROM_PKG_CONFIG=hello\\ world\n" \ -o inline:"-Dhello=10 -Dworld=+32 -DDEFINED_FROM_PKG_CONFIG=hello\\ world \n" \
pkgconf --cflags fragment-quoting-7 pkgconf --cflags fragment-quoting-7
} }
fragment_escaping_1_body() fragment_escaping_1_body()
{ {
atf_check \ atf_check \
-o inline:"-IC:\\\\\\\\D\\ E\n" \ -o inline:"-IC:\\\\\\\\D\\ E \n" \
pkgconf --with-path="${selfdir}/lib1" --cflags fragment-escaping-1 pkgconf --with-path="${selfdir}/lib1" --cflags fragment-escaping-1
} }
fragment_escaping_2_body() fragment_escaping_2_body()
{ {
atf_check \ atf_check \
-o inline:"-IC:\\\\\\\\D\\ E\n" \ -o inline:"-IC:\\\\\\\\D\\ E \n" \
pkgconf --with-path="${selfdir}/lib1" --cflags fragment-escaping-2 pkgconf --with-path="${selfdir}/lib1" --cflags fragment-escaping-2
} }
fragment_escaping_3_body() fragment_escaping_3_body()
{ {
atf_check \ atf_check \
-o inline:"-IC:\\\\\\\\D\\ E\n" \ -o inline:"-IC:\\\\\\\\D\\ E \n" \
pkgconf --with-path="${selfdir}/lib1" --cflags fragment-escaping-3 pkgconf --with-path="${selfdir}/lib1" --cflags fragment-escaping-3
} }
@ -269,7 +269,7 @@ fragment_quoting_7a_body()
fragment_comment_body() fragment_comment_body()
{ {
atf_check \ atf_check \
-o inline:'kuku=\#ttt\n' \ -o inline:'kuku=\#ttt \n' \
pkgconf --with-path="${selfdir}/lib1" --cflags fragment-comment pkgconf --with-path="${selfdir}/lib1" --cflags fragment-comment
} }
@ -292,7 +292,7 @@ msvc_fragment_render_cflags_body()
tuple_dequote_body() tuple_dequote_body()
{ {
atf_check \ atf_check \
-o inline:'-L/test/lib -lfoo\n' \ -o inline:'-L/test/lib -lfoo \n' \
pkgconf --with-path="${selfdir}/lib1" --libs tuple-quoting pkgconf --with-path="${selfdir}/lib1" --libs tuple-quoting
} }

View File

@ -27,7 +27,7 @@ provides = 1.2.3
-o inline:"${OUTPUT}" \ -o inline:"${OUTPUT}" \
pkgconf --print-provides provides pkgconf --print-provides provides
atf_check \ atf_check \
-o inline:"-lfoo\n" \ -o inline:"-lfoo \n" \
pkgconf --libs provides-request-simple pkgconf --libs provides-request-simple
atf_check \ atf_check \
-e ignore \ -e ignore \

View File

@ -8,7 +8,6 @@ tests_init \
depgraph_break_2 \ depgraph_break_2 \
depgraph_break_3 \ depgraph_break_3 \
define_variable \ define_variable \
define_variable_override \
variable \ variable \
keep_system_libs \ keep_system_libs \
libs \ libs \
@ -23,15 +22,6 @@ tests_init \
idirafter_munge_order \ idirafter_munge_order \
idirafter_munge_sysroot \ idirafter_munge_sysroot \
idirafter_ordering \ idirafter_ordering \
modversion_common_prefix \
modversion_fullpath \
modversion_provides \
modversion_uninstalled \
modversion_one_word_expression \
modversion_two_word_expression \
modversion_three_word_expression \
modversion_one_word_expression_no_space \
modversion_one_word_expression_no_space_zero \
pcpath \ pcpath \
virtual_variable \ virtual_variable \
fragment_collision \ fragment_collision \
@ -39,10 +29,7 @@ tests_init \
malformed_quoting \ malformed_quoting \
explicit_sysroot \ explicit_sysroot \
empty_tuple \ empty_tuple \
solver_requires_private_debounce \ billion_laughs
billion_laughs \
define_prefix_child_prefix_1 \
define_prefix_child_prefix_1_env
# sysroot_munge \ # sysroot_munge \
@ -85,13 +72,6 @@ define_variable_body()
pkgconf --variable=typelibdir --define-variable='libdir=\${libdir}' typelibdir pkgconf --variable=typelibdir --define-variable='libdir=\${libdir}' typelibdir
} }
define_variable_override_body()
{
export PKG_CONFIG_PATH="${selfdir}/lib1"
atf_check -o inline:"/test\n" \
pkgconf --variable=prefix --define-variable='prefix=/test' typelibdir
}
variable_body() variable_body()
{ {
export PKG_CONFIG_PATH="${selfdir}/lib1" export PKG_CONFIG_PATH="${selfdir}/lib1"
@ -109,7 +89,7 @@ keep_system_libs_body()
pkgconf --libs-only-L cflags-libs-only pkgconf --libs-only-L cflags-libs-only
atf_check \ atf_check \
-o inline:"-L/test/local/lib\n" \ -o inline:"-L/test/local/lib \n" \
pkgconf --libs-only-L --keep-system-libs cflags-libs-only pkgconf --libs-only-L --keep-system-libs cflags-libs-only
} }
@ -117,7 +97,7 @@ libs_body()
{ {
export PKG_CONFIG_PATH="${selfdir}/lib1" export PKG_CONFIG_PATH="${selfdir}/lib1"
atf_check \ atf_check \
-o inline:"-L/test/local/lib -lfoo\n" \ -o inline:"-L/test/local/lib -lfoo \n" \
pkgconf --libs cflags-libs-only pkgconf --libs cflags-libs-only
} }
@ -125,7 +105,7 @@ libs_only_body()
{ {
export PKG_CONFIG_PATH="${selfdir}/lib1" export PKG_CONFIG_PATH="${selfdir}/lib1"
atf_check \ atf_check \
-o inline:"-L/test/local/lib -lfoo\n" \ -o inline:"-L/test/local/lib -lfoo \n" \
pkgconf --libs-only-L --libs-only-l cflags-libs-only pkgconf --libs-only-L --libs-only-l cflags-libs-only
} }
@ -133,10 +113,10 @@ libs_never_mergeback_body()
{ {
export PKG_CONFIG_PATH="${selfdir}/lib1" export PKG_CONFIG_PATH="${selfdir}/lib1"
atf_check \ atf_check \
-o inline:"-L/test/bar/lib -lfoo1\n" \ -o inline:"-L/test/bar/lib -lfoo1 \n" \
pkgconf --libs prefix-foo1 pkgconf --libs prefix-foo1
atf_check \ atf_check \
-o inline:"-L/test/bar/lib -lfoo1 -lfoo2\n" \ -o inline:"-L/test/bar/lib -lfoo1 -lfoo2 \n" \
pkgconf --libs prefix-foo1 prefix-foo2 pkgconf --libs prefix-foo1 prefix-foo2
} }
@ -144,7 +124,7 @@ cflags_only_body()
{ {
export PKG_CONFIG_PATH="${selfdir}/lib1" export PKG_CONFIG_PATH="${selfdir}/lib1"
atf_check \ atf_check \
-o inline:"-I/test/local/include/foo\n" \ -o inline:"-I/test/local/include/foo \n" \
pkgconf --cflags-only-I --cflags-only-other cflags-libs-only pkgconf --cflags-only-I --cflags-only-other cflags-libs-only
} }
@ -152,7 +132,7 @@ cflags_never_mergeback_body()
{ {
export PKG_CONFIG_PATH="${selfdir}/lib1" export PKG_CONFIG_PATH="${selfdir}/lib1"
atf_check \ atf_check \
-o inline:"-I/test/bar/include/foo -DBAR -fPIC -DFOO\n" \ -o inline:"-I/test/bar/include/foo -DBAR -fPIC -DFOO \n" \
pkgconf --cflags prefix-foo1 prefix-foo2 pkgconf --cflags prefix-foo1 prefix-foo2
} }
@ -176,7 +156,7 @@ isystem_munge_order_body()
{ {
export PKG_CONFIG_PATH="${selfdir}/lib1" export PKG_CONFIG_PATH="${selfdir}/lib1"
atf_check \ atf_check \
-o inline:"-isystem /opt/bad/include -isystem /opt/bad2/include\n" \ -o inline:"-isystem /opt/bad/include -isystem /opt/bad2/include \n" \
pkgconf --cflags isystem pkgconf --cflags isystem
} }
@ -192,7 +172,7 @@ idirafter_munge_order_body()
{ {
export PKG_CONFIG_PATH="${selfdir}/lib1" export PKG_CONFIG_PATH="${selfdir}/lib1"
atf_check \ atf_check \
-o inline:"-idirafter /opt/bad/include -idirafter /opt/bad2/include\n" \ -o inline:"-idirafter /opt/bad/include -idirafter /opt/bad2/include \n" \
pkgconf --cflags idirafter pkgconf --cflags idirafter
} }
@ -208,7 +188,7 @@ idirafter_ordering_body()
{ {
export PKG_CONFIG_PATH="${selfdir}/lib1" export PKG_CONFIG_PATH="${selfdir}/lib1"
atf_check \ atf_check \
-o inline:"-I/opt/bad/include1 -idirafter -I/opt/bad/include2 -I/opt/bad/include3\n" \ -o inline:"-I/opt/bad/include1 -idirafter -I/opt/bad/include2 -I/opt/bad/include3 \n" \
pkgconf --cflags idirafter-ordering pkgconf --cflags idirafter-ordering
} }
@ -216,7 +196,7 @@ pcpath_body()
{ {
export PKG_CONFIG_PATH="${selfdir}/lib2" export PKG_CONFIG_PATH="${selfdir}/lib2"
atf_check \ atf_check \
-o inline:"-fPIC -I/test/include/foo\n" \ -o inline:"-fPIC -I/test/include/foo \n" \
pkgconf --cflags ${selfdir}/lib3/bar.pc pkgconf --cflags ${selfdir}/lib3/bar.pc
} }
@ -225,7 +205,7 @@ sysroot_munge_body()
sed "s|/sysroot/|${selfdir}/|g" ${selfdir}/lib1/sysroot-dir.pc > ${selfdir}/lib1/sysroot-dir-selfdir.pc sed "s|/sysroot/|${selfdir}/|g" ${selfdir}/lib1/sysroot-dir.pc > ${selfdir}/lib1/sysroot-dir-selfdir.pc
export PKG_CONFIG_PATH="${selfdir}/lib1" PKG_CONFIG_SYSROOT_DIR="${selfdir}" export PKG_CONFIG_PATH="${selfdir}/lib1" PKG_CONFIG_SYSROOT_DIR="${selfdir}"
atf_check \ atf_check \
-o inline:"-L${selfdir}/lib -lfoo\n" \ -o inline:"-L${selfdir}/lib -lfoo \n" \
pkgconf --libs sysroot-dir-selfdir pkgconf --libs sysroot-dir-selfdir
} }
@ -244,7 +224,7 @@ virtual_variable_body()
fragment_collision_body() fragment_collision_body()
{ {
atf_check -o inline:"-D_BAZ -D_BAR -D_FOO -D_THREAD_SAFE -pthread\n" \ atf_check -o inline:"-D_BAZ -D_BAR -D_FOO -D_THREAD_SAFE -pthread \n" \
pkgconf --with-path="${selfdir}/lib1" --cflags fragment-collision pkgconf --with-path="${selfdir}/lib1" --cflags fragment-collision
} }
@ -273,82 +253,8 @@ empty_tuple_body()
pkgconf --with-path="${selfdir}/lib1" --cflags empty-tuple pkgconf --with-path="${selfdir}/lib1" --cflags empty-tuple
} }
solver_requires_private_debounce_body()
{
atf_check -o inline:"-I/metapackage-1 -I/metapackage-2 -lmetapackage-1 -lmetapackage-2\n" \
pkgconf --with-path="${selfdir}/lib1" --cflags --libs metapackage
}
billion_laughs_body() billion_laughs_body()
{ {
atf_check -o inline:"warning: truncating very long variable to 64KB\nwarning: truncating very long variable to 64KB\nwarning: truncating very long variable to 64KB\nwarning: truncating very long variable to 64KB\nwarning: truncating very long variable to 64KB\n" \ atf_check -o inline:"warning: truncating very long variable to 64KB\nwarning: truncating very long variable to 64KB\nwarning: truncating very long variable to 64KB\nwarning: truncating very long variable to 64KB\nwarning: truncating very long variable to 64KB\n" \
pkgconf --with-path="${selfdir}/lib1" --validate billion-laughs pkgconf --with-path="${selfdir}/lib1" --validate billion-laughs
} }
modversion_common_prefix_body()
{
atf_check -o inline:"foo: 1.2.3\nfoobar: 3.2.1\n" \
pkgconf --with-path="${selfdir}/lib1" --modversion --verbose foo foobar
}
modversion_fullpath_body()
{
atf_check -o inline:"1.2.3\n" \
pkgconf --modversion "${selfdir}/lib1/foo.pc"
}
modversion_provides_body()
{
atf_check -o inline:"1.2.3\n" \
pkgconf --with-path="${selfdir}/lib1" --modversion unavailable
}
modversion_uninstalled_body()
{
atf_check -o inline:"1.2.3\n" \
pkgconf --with-path="${selfdir}/lib1" --modversion omg
}
modversion_one_word_expression_body()
{
atf_check -o inline:"1.2.3\n" \
pkgconf --with-path="${selfdir}/lib1" --modversion "foo > 1.0"
}
modversion_two_word_expression_body()
{
atf_check -o inline:"1.2.3\n" \
pkgconf --with-path="${selfdir}/lib1" --modversion foo "> 1.0"
}
modversion_three_word_expression_body()
{
atf_check -o inline:"1.2.3\n" \
pkgconf --with-path="${selfdir}/lib1" --modversion foo ">" 1.0
}
modversion_one_word_expression_no_space_body()
{
atf_check -o inline:"1.2.3\n" \
pkgconf --with-path="${selfdir}/lib1" --modversion "foo >1.0"
}
modversion_one_word_expression_no_space_zero_body()
{
atf_check -o inline:"1.2.3\n" \
pkgconf --with-path="${selfdir}/lib1" --modversion "foo >0.5"
}
define_prefix_child_prefix_1_body()
{
atf_check -o inline:"-I${selfdir}/lib1/include/child-prefix-1 -L${selfdir}/lib1/lib64 -lchild-prefix-1\n" \
pkgconf --with-path="${selfdir}/lib1/child-prefix/pkgconfig" --define-prefix --cflags --libs child-prefix-1
}
define_prefix_child_prefix_1_env_body()
{
export PKG_CONFIG_PATH="${selfdir}/lib1/child-prefix/pkgconfig"
export PKG_CONFIG_RELOCATE_PATHS=1
atf_check -o inline:"-I${selfdir}/lib1/include/child-prefix-1 -L${selfdir}/lib1/lib64 -lchild-prefix-1\n" \
pkgconf --cflags --libs child-prefix-1
}

View File

@ -10,10 +10,6 @@ tests_init \
argv_parse2 \ argv_parse2 \
static_cflags \ static_cflags \
private_duplication \ private_duplication \
private_duplication_digraph \
foo_bar \
bar_foo \
foo_metapackage_3 \
libs_static2 \ libs_static2 \
missing \ missing \
requires_internal \ requires_internal \
@ -25,7 +21,7 @@ libs_body()
{ {
export PKG_CONFIG_PATH="${selfdir}/lib1" export PKG_CONFIG_PATH="${selfdir}/lib1"
atf_check \ atf_check \
-o inline:"-L/test/lib -lbar -lfoo\n" \ -o inline:"-L/test/lib -lbar -lfoo \n" \
pkgconf --libs bar pkgconf --libs bar
} }
@ -33,7 +29,7 @@ libs_cflags_body()
{ {
export PKG_CONFIG_PATH="${selfdir}/lib1" export PKG_CONFIG_PATH="${selfdir}/lib1"
atf_check \ atf_check \
-o inline:"-fPIC -I/test/include/foo -L/test/lib -lbaz\n" \ -o inline:"-fPIC -I/test/include/foo -L/test/lib -lbaz \n" \
pkgconf --libs --cflags baz pkgconf --libs --cflags baz
} }
@ -41,7 +37,7 @@ libs_static_body()
{ {
export PKG_CONFIG_PATH="${selfdir}/lib1" export PKG_CONFIG_PATH="${selfdir}/lib1"
atf_check \ atf_check \
-o inline:"-L/test/lib -lbaz -L/test/lib -lzee -lfoo\n" \ -o inline:"-L/test/lib -lbaz -L/test/lib -lzee -L/test/lib -lfoo \n" \
pkgconf --static --libs baz pkgconf --static --libs baz
} }
@ -49,7 +45,7 @@ libs_static_pure_body()
{ {
export PKG_CONFIG_PATH="${selfdir}/lib1" export PKG_CONFIG_PATH="${selfdir}/lib1"
atf_check \ atf_check \
-o inline:"-L/test/lib -lbaz -lfoo\n" \ -o inline:"-L/test/lib -lbaz -L/test/lib -lfoo \n" \
pkgconf --static --pure --libs baz pkgconf --static --pure --libs baz
} }
@ -57,7 +53,7 @@ argv_parse2_body()
{ {
export PKG_CONFIG_PATH="${selfdir}/lib1" export PKG_CONFIG_PATH="${selfdir}/lib1"
atf_check \ atf_check \
-o inline:"-llib-1 -pthread /test/lib/lib2.so\n" \ -o inline:"-llib-1 -pthread /test/lib/lib2.so \n" \
pkgconf --static --libs argv-parse-2 pkgconf --static --libs argv-parse-2
} }
@ -65,7 +61,7 @@ static_cflags_body()
{ {
export PKG_CONFIG_PATH="${selfdir}/lib1" export PKG_CONFIG_PATH="${selfdir}/lib1"
atf_check \ atf_check \
-o inline:"-fPIC -I/test/include/foo -DFOO_STATIC\n" \ -o inline:"-fPIC -I/test/include/foo -DFOO_STATIC \n" \
pkgconf --static --cflags baz pkgconf --static --cflags baz
} }
@ -73,51 +69,15 @@ private_duplication_body()
{ {
export PKG_CONFIG_PATH="${selfdir}/lib1" export PKG_CONFIG_PATH="${selfdir}/lib1"
atf_check \ atf_check \
-o inline:"-lprivate -lbaz -lzee -lbar -lfoo\n" \ -o inline:"-lprivate -lfoo -lbaz -lzee -lbar -lfoo \n" \
pkgconf --static --libs-only-l private-libs-duplication pkgconf --static --libs-only-l private-libs-duplication
} }
private_duplication_digraph_body()
{
export PKG_CONFIG_PATH="${selfdir}/lib1"
atf_check \
-o 'match:"user:request" -> "private-libs-duplication"' \
-o 'match:"private-libs-duplication" -> "bar"' \
-o 'match:"private-libs-duplication" -> "baz"' \
-o 'match:"bar" -> "foo"' \
-o 'match:"baz" -> "foo"' \
pkgconf --static --libs-only-l private-libs-duplication --digraph
}
bar_foo_body()
{
export PKG_CONFIG_PATH="${selfdir}/lib1"
atf_check \
-o inline:"-lbar -lfoo\n" \
pkgconf --static --libs-only-l bar foo
}
foo_bar_body()
{
export PKG_CONFIG_PATH="${selfdir}/lib1"
atf_check \
-o inline:"-lbar -lfoo\n" \
pkgconf --static --libs-only-l foo bar
}
foo_metapackage_3_body()
{
export PKG_CONFIG_PATH="${selfdir}/lib1"
atf_check \
-o inline:"-lbar -lfoo\n" \
pkgconf --static --libs-only-l foo metapackage-3
}
libs_static2_body() libs_static2_body()
{ {
export PKG_CONFIG_PATH="${selfdir}/lib1" export PKG_CONFIG_PATH="${selfdir}/lib1"
atf_check \ atf_check \
-o inline:"-lbar -lbar-private -L/test/lib -lfoo\n" \ -o inline:"-lbar -lbar-private -L/test/lib -lfoo \n" \
pkgconf --static --libs static-libs pkgconf --static --libs static-libs
} }
@ -127,14 +87,14 @@ missing_body()
atf_check \ atf_check \
-s exit:1 \ -s exit:1 \
-e ignore \ -e ignore \
-o ignore \ -o inline:"\n" \
pkgconf --cflags missing-require pkgconf --cflags missing-require
} }
requires_internal_body() requires_internal_body()
{ {
atf_check \ atf_check \
-o inline:"-lbar -lbar-private -L/test/lib -lfoo\n" \ -o inline:"-lbar -lbar-private -L/test/lib -lfoo \n" \
pkgconf --with-path="${selfdir}/lib1" --static --libs requires-internal pkgconf --with-path="${selfdir}/lib1" --static --libs requires-internal
} }
@ -150,7 +110,7 @@ requires_internal_missing_body()
requires_internal_collision_body() requires_internal_collision_body()
{ {
atf_check \ atf_check \
-o inline:"-I/test/local/include/foo\n" \ -o inline:"-I/test/local/include/foo \n" \
pkgconf --with-path="${selfdir}/lib1" --cflags requires-internal-collision pkgconf --with-path="${selfdir}/lib1" --cflags requires-internal-collision
} }

View File

@ -6,18 +6,13 @@ tests_init \
cflags \ cflags \
variable \ variable \
do_not_eat_slash \ do_not_eat_slash \
do_not_duplicate_sysroot_dir \
uninstalled \
uninstalled_pkgconf1 \
uninstalled_fdo \
uninstalled_fdo_pc_sysrootdir
do_not_eat_slash_body() do_not_eat_slash_body()
{ {
export PKG_CONFIG_PATH="${selfdir}/lib1" export PKG_CONFIG_PATH="${selfdir}/lib1"
export PKG_CONFIG_SYSROOT_DIR="/" export PKG_CONFIG_SYSROOT_DIR="/"
atf_check \ atf_check \
-o inline:"-fPIC -I/test/include/foo\n" \ -o inline:"-fPIC -I/test/include/foo \n" \
pkgconf --cflags baz pkgconf --cflags baz
} }
@ -26,7 +21,7 @@ cflags_body()
export PKG_CONFIG_PATH="${selfdir}/lib1" export PKG_CONFIG_PATH="${selfdir}/lib1"
export PKG_CONFIG_SYSROOT_DIR="${SYSROOT_DIR}" export PKG_CONFIG_SYSROOT_DIR="${SYSROOT_DIR}"
atf_check \ atf_check \
-o inline:"-fPIC -I${SYSROOT_DIR}/test/include/foo\n" \ -o inline:"-fPIC -I${SYSROOT_DIR}/test/include/foo \n" \
pkgconf --cflags baz pkgconf --cflags baz
} }
@ -41,70 +36,3 @@ variable_body()
-o inline:"${SYSROOT_DIR}/test/include\n" \ -o inline:"${SYSROOT_DIR}/test/include\n" \
pkgconf --variable=includedir foo pkgconf --variable=includedir foo
} }
do_not_duplicate_sysroot_dir_body()
{
export PKG_CONFIG_PATH="${selfdir}/lib1"
export PKG_CONFIG_SYSROOT_DIR="/sysroot"
atf_check \
-o inline:"-I/sysroot/usr/include\n" \
pkgconf --cflags sysroot-dir-2
atf_check \
-o inline:"-I/sysroot/usr/include\n" \
pkgconf --cflags sysroot-dir-3
atf_check \
-o inline:"-I/sysroot/usr/include\n" \
pkgconf --cflags sysroot-dir-5
export PKG_CONFIG_SYSROOT_DIR="${SYSROOT_DIR}"
atf_check \
-o inline:"-I${SYSROOT_DIR}/usr/include\n" \
pkgconf --cflags sysroot-dir-4
}
uninstalled_body()
{
export PKG_CONFIG_PATH="${selfdir}/lib1"
export PKG_CONFIG_SYSROOT_DIR="/sysroot"
atf_check \
-o inline:"-L/test/lib -lomg\n" \
pkgconf --libs omg
}
uninstalled_pkgconf1_body()
{
export PKG_CONFIG_PATH="${selfdir}/lib1"
export PKG_CONFIG_SYSROOT_DIR="/sysroot"
export PKG_CONFIG_PKGCONF1_SYSROOT_RULES="1"
atf_check \
-o inline:"-L/sysroot/test/lib -lomg\n" \
pkgconf --libs omg
}
uninstalled_fdo_body()
{
export PKG_CONFIG_PATH="${selfdir}/lib1"
export PKG_CONFIG_SYSROOT_DIR="/sysroot"
export PKG_CONFIG_FDO_SYSROOT_RULES="1"
atf_check \
-o inline:"-L/test/lib -lomg\n" \
pkgconf --libs omg
}
uninstalled_fdo_pc_sysrootdir_body()
{
export PKG_CONFIG_PATH="${selfdir}/lib1"
export PKG_CONFIG_SYSROOT_DIR="/sysroot"
export PKG_CONFIG_FDO_SYSROOT_RULES="1"
atf_check \
-o inline:"-L/sysroot/test/lib -lomg\n" \
pkgconf --libs omg-sysroot
}