mirror of
https://github.com/pkgconf/pkgconf.git
synced 2026-01-27 01:44:34 +00:00
Compare commits
No commits in common. "master" and "pkgconf-2.1.0" have entirely different histories.
master
...
pkgconf-2.
4
.github/FUNDING.yml
vendored
4
.github/FUNDING.yml
vendored
@ -1 +1,3 @@
|
||||
open_collective: pkgconf
|
||||
github: kaniini
|
||||
patreon: kaniini
|
||||
liberapay: kaniini
|
||||
135
.github/workflows/release-tarballs.yml
vendored
135
.github/workflows/release-tarballs.yml
vendored
@ -1,135 +0,0 @@
|
||||
name: Generate and upload release artifacts
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'pkgconf-*'
|
||||
|
||||
jobs:
|
||||
tarball:
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: alpine:latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
repository: pkgconf/pkgconf
|
||||
|
||||
- name: Update system and add dependencies
|
||||
run: |
|
||||
apk update
|
||||
apk add kyua atf build-base autoconf automake libtool xz gzip tar openssh-client
|
||||
|
||||
- name: Bootstrap autotools
|
||||
run: |
|
||||
sh autogen.sh
|
||||
./configure
|
||||
|
||||
- name: Run tests and generate dist tarballs
|
||||
run: |
|
||||
make distcheck -j$(nproc)
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: tarball
|
||||
path: pkgconf-*.tar.*
|
||||
|
||||
msi:
|
||||
name: Build MSI
|
||||
runs-on: windows-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include: [
|
||||
{ msystem: MINGW64, arch: x86_64},
|
||||
]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: setup-msys2
|
||||
uses: msys2/setup-msys2@v2
|
||||
with:
|
||||
msystem: ${{ matrix.msystem }}
|
||||
update: true
|
||||
install: >-
|
||||
mingw-w64-${{ matrix.arch }}-meson
|
||||
mingw-w64-${{ matrix.arch }}-ninja
|
||||
mingw-w64-${{ matrix.arch }}-gcc
|
||||
mingw-w64-${{ matrix.arch }}-msitools
|
||||
|
||||
- name: Build
|
||||
shell: msys2 {0}
|
||||
run: |
|
||||
# the code assumes msvc style printf atm
|
||||
export CFLAGS=-D__USE_MINGW_ANSI_STDIO=0
|
||||
meson _build --buildtype=release -Dtests=disabled -Db_lto=true
|
||||
meson compile -C _build msi
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: msi
|
||||
path: _build/pkgconf-*.msi
|
||||
|
||||
release:
|
||||
name: Create Release
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write
|
||||
needs: [tarball, msi]
|
||||
steps:
|
||||
- name: Download tarball artifact
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: tarball
|
||||
path: dist
|
||||
- name: Download msi artifact
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: msi
|
||||
path: dist
|
||||
- name: Create Release
|
||||
uses: softprops/action-gh-release@v2
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
with:
|
||||
files: |
|
||||
dist/pkgconf-*.tar.*
|
||||
dist/pkgconf-*.msi
|
||||
|
||||
publish:
|
||||
name: Publish on distfiles.ariadne.space
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write
|
||||
needs: [tarball, msi]
|
||||
steps:
|
||||
- name: Download tarball artifact
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: tarball
|
||||
path: dist
|
||||
- name: Download msi artifact
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: msi
|
||||
path: dist
|
||||
- name: Upload dist tarballs to distfiles.ariadne.space
|
||||
env:
|
||||
DISTFILES_PRIVATE_KEY: ${{ secrets.DISTFILES_PRIVATE_KEY }}
|
||||
DISTFILES_HOST_KEYS: ${{ secrets.DISTFILES_HOST_KEYS }}
|
||||
run: |
|
||||
mkdir -p $HOME/.ssh
|
||||
|
||||
# Ensure the private key is read-only so SSH doesn't reject it.
|
||||
umask 277
|
||||
(echo "$DISTFILES_PRIVATE_KEY" | base64 -d) > $HOME/.ssh/id_ed25519
|
||||
|
||||
umask 077
|
||||
(echo "$DISTFILES_HOST_KEYS" | base64 -d) > $HOME/.ssh/known_hosts
|
||||
|
||||
# Upload the tarballs.
|
||||
scp -i "$HOME/.ssh/id_ed25519" -o "UserKnownHostsFile=$HOME/.ssh/known_hosts" dist/* kaniini@distfiles.ariadne.space:distfiles/pkgconf/
|
||||
|
||||
# Delete the key material.
|
||||
rm -rf $HOME/.ssh
|
||||
42
.github/workflows/test.yml
vendored
42
.github/workflows/test.yml
vendored
@ -13,6 +13,7 @@ jobs:
|
||||
matrix:
|
||||
include: [
|
||||
{ msystem: MINGW64, arch: x86_64},
|
||||
{ msystem: MINGW32, arch: i686}
|
||||
]
|
||||
steps:
|
||||
- name: Checkout code
|
||||
@ -27,7 +28,6 @@ jobs:
|
||||
mingw-w64-${{ matrix.arch }}-meson
|
||||
mingw-w64-${{ matrix.arch }}-ninja
|
||||
mingw-w64-${{ matrix.arch }}-gcc
|
||||
mingw-w64-${{ matrix.arch }}-msitools
|
||||
|
||||
- name: Build
|
||||
shell: msys2 {0}
|
||||
@ -35,22 +35,8 @@ jobs:
|
||||
# the code assumes msvc style printf atm
|
||||
export CFLAGS=-D__USE_MINGW_ANSI_STDIO=0
|
||||
|
||||
meson _build
|
||||
meson compile -C _build msi
|
||||
|
||||
- name: Run tests
|
||||
shell: msys2 {0}
|
||||
run: |
|
||||
meson test -v -C _build
|
||||
|
||||
- name: Upload Artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: build-output
|
||||
path: |
|
||||
_build/*.exe
|
||||
_build/*.dll
|
||||
_build/*.msi
|
||||
meson -Dtests=disabled _build
|
||||
meson compile -C _build
|
||||
|
||||
debian-meson:
|
||||
runs-on: ubuntu-latest
|
||||
@ -154,7 +140,7 @@ jobs:
|
||||
- name: Update system and add dependencies
|
||||
run: |
|
||||
apk update
|
||||
apk add kyua atf build-base autoconf automake libtool xz gzip tar
|
||||
apk add kyua atf build-base autoconf automake libtool xz gzip
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
@ -165,23 +151,3 @@ jobs:
|
||||
- name: Run tests
|
||||
run: |
|
||||
make distcheck
|
||||
|
||||
analysis:
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: alpine
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Update system and add dependencies
|
||||
run: |
|
||||
apk update
|
||||
apk add kyua atf build-base autoconf automake libtool xz gzip
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
export CFLAGS="-Wall -Werror -O2 -ggdb3 -fanalyzer"
|
||||
./autogen.sh
|
||||
./configure
|
||||
make -j9 CFLAGS="$CFLAGS"
|
||||
|
||||
50
.gitignore
vendored
50
.gitignore
vendored
@ -1,19 +1,13 @@
|
||||
Makefile
|
||||
Makefile.in
|
||||
.dirstamp
|
||||
stamp-h*
|
||||
*.h.in~
|
||||
*.o
|
||||
*.og
|
||||
*.op
|
||||
*.lo
|
||||
*.gcno
|
||||
*.gcda
|
||||
*.gcov
|
||||
core
|
||||
.gdb_history
|
||||
|
||||
.libs
|
||||
.deps
|
||||
|
||||
*.exe
|
||||
@ -22,8 +16,8 @@ core
|
||||
*.orig
|
||||
*.patch
|
||||
*.rej
|
||||
/tests/run.sh
|
||||
|
||||
# autoconf stuff
|
||||
/aclocal.m4
|
||||
/autom4te.cache/
|
||||
/buildsys.mk
|
||||
@ -32,48 +26,8 @@ core
|
||||
/config.log
|
||||
/config.status
|
||||
/configure
|
||||
/compile
|
||||
/config.guess
|
||||
/config.sub
|
||||
/depcomp
|
||||
/install-sh
|
||||
/missing
|
||||
|
||||
# programs
|
||||
/bomtool
|
||||
/pkgconf
|
||||
/pkgconf-gcov
|
||||
/pkgconf-profile
|
||||
|
||||
# libtool
|
||||
/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/symlink
|
||||
/tests/sysroot
|
||||
/tests/test_env.sh
|
||||
/tests/version
|
||||
Makefile
|
||||
|
||||
75
.woodpecker.yml
Normal file
75
.woodpecker.yml
Normal file
@ -0,0 +1,75 @@
|
||||
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
|
||||
262
Makefile.am
262
Makefile.am
@ -9,190 +9,17 @@ personality_dir = @PERSONALITY_PATH@
|
||||
pkgconfigdir = $(libdir)/pkgconfig
|
||||
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)\"
|
||||
|
||||
bin_PROGRAMS = pkgconf bomtool spdxtool
|
||||
bin_PROGRAMS = pkgconf bomtool
|
||||
lib_LTLIBRARIES = libpkgconf.la
|
||||
|
||||
EXTRA_DIST = pkg.m4 \
|
||||
meson.build \
|
||||
meson_options.txt \
|
||||
pkgconf.wxs.in \
|
||||
txt2rtf.py \
|
||||
libpkgconf/meson.build \
|
||||
libpkgconf/config.h.meson \
|
||||
libpkgconf/win-dirent.h \
|
||||
t/basic/arbitrary-path.test \
|
||||
t/basic/builtin-pkg-config-exists.test \
|
||||
t/basic/builtin-pkg-config-pc_path-variable.test \
|
||||
t/basic/builtin-pkgconf-exists.test \
|
||||
t/basic/builtin-pkgconf-pc_path-variable.test \
|
||||
t/basic/define-prefix.test \
|
||||
t/basic/define-prefix-child-prefix-env.test \
|
||||
t/basic/define-prefix-child-prefix.test \
|
||||
t/basic/direct-query-with-pkg_config_path.test \
|
||||
t/basic/env-tuple.test \
|
||||
t/basic/exists-cflags-env.test \
|
||||
t/basic/exists-cflags.test \
|
||||
t/basic/exists-nonexistent.test \
|
||||
t/basic/exists-version-greater-than-with-tilde.test \
|
||||
t/basic/exists-version-greater-than.test \
|
||||
t/basic/exists-version-less-than-with-tilde.test \
|
||||
t/basic/exists-version-malformed.test \
|
||||
t/basic/exists-version-minimum.test \
|
||||
t/basic/exists-version-with-tilde.test \
|
||||
t/basic/incomplete-cflags.test \
|
||||
t/basic/incomplete-libs.test \
|
||||
t/basic/keep-system-libs.test \
|
||||
t/basic/keep-system-libs-2.test \
|
||||
t/basic/libs.test \
|
||||
t/basic/libs-cflags.test \
|
||||
t/basic/libs-cflags-version.test \
|
||||
t/basic/libs-cflags-version-multiple.test \
|
||||
t/basic/libs-cflags-version-multiple-comma.test \
|
||||
t/basic/libs-cflags-version-not.test \
|
||||
t/basic/libs-cflags-version-not-provided.test \
|
||||
t/basic/libs-env.test \
|
||||
t/basic/libs-only.test \
|
||||
t/basic/malformed-empty-package.test \
|
||||
t/basic/modversion-fullpath.test \
|
||||
t/basic/modversion-noflatten.test \
|
||||
t/basic/modversion-uninstalled.test \
|
||||
t/basic/modversion-verbose-prefix.test \
|
||||
t/basic/noargs.test \
|
||||
t/basic/nocflags.test \
|
||||
t/basic/nolibs.test \
|
||||
t/basic/pkg-config-path.test \
|
||||
t/basic/print-variables-env.test \
|
||||
t/basic/single-depth-selectors.test \
|
||||
t/basic/static-archive-libs.test \
|
||||
t/basic/uninstalled-not.test \
|
||||
t/basic/uninstalled.test \
|
||||
t/basic/variable-env.test \
|
||||
t/basic/variable-no-recursion.test \
|
||||
t/basic/variable.test \
|
||||
t/basic/version-atleast-1.test \
|
||||
t/basic/version-atleast-2.test \
|
||||
t/basic/version-exact-1.test \
|
||||
t/basic/version-exact-2.test \
|
||||
t/basic/version-max-1.test \
|
||||
t/basic/version-max-2.test \
|
||||
t/ordering/cflags-never-mergeback.test \
|
||||
t/ordering/cflags-only.test \
|
||||
t/ordering/flag-order-1.test \
|
||||
t/ordering/flag-order-2.test \
|
||||
t/ordering/flag-order-3.test \
|
||||
t/ordering/flag-order-4.test \
|
||||
t/ordering/fragment-collision.test \
|
||||
t/ordering/framework-1.test \
|
||||
t/ordering/framework-2.test \
|
||||
t/ordering/framework-3.test \
|
||||
t/ordering/idirafter-munge-ordering.test \
|
||||
t/ordering/idirafter-ordering.test \
|
||||
t/ordering/isystem-munge-ordering.test \
|
||||
t/ordering/libs-never-mergeback.test \
|
||||
t/parser/argv-parse-1.test \
|
||||
t/parser/argv-parse-2.test \
|
||||
t/parser/argv-parse-3.test \
|
||||
t/parser/c-comments-should-warn.test \
|
||||
t/parser/comments-in-fields.test \
|
||||
t/parser/comments.test \
|
||||
t/parser/dos-lineendings.test \
|
||||
t/parser/escaped-backslashes-in-output.test \
|
||||
t/parser/fragment-comment.test \
|
||||
t/parser/fragment-groups-composite.test \
|
||||
t/parser/fragment-groups.test \
|
||||
t/parser/malformed-no-newlines.test \
|
||||
t/parser/malformed-quoting.test \
|
||||
t/parser/multiline-bogus-header.test \
|
||||
t/parser/multiline-field.test \
|
||||
t/parser/no-trailing-newline.test \
|
||||
t/parser/paren-quoting.test \
|
||||
t/parser/shell-quoted-output.test \
|
||||
t/parser/tilde-quoting-1.test \
|
||||
t/parser/tilde-quoting-2.test \
|
||||
t/parser/truncated-files-should-fail-to-parse.test \
|
||||
t/parser/tuple-dequote.test \
|
||||
t/parser/variable-whitespace.test \
|
||||
t/solver/circular-reference-1.test \
|
||||
t/solver/circular-reference-2.test \
|
||||
t/solver/circular-reference-directpc.test \
|
||||
t/solver/conflicts-solution-error.test \
|
||||
t/solver/conflicts-solution-ignore.test \
|
||||
t/solver/conflicts-solution-is-fine-standalone.test \
|
||||
t/solver/depgraph-break-1.test \
|
||||
t/solver/depgraph-break-2.test \
|
||||
t/solver/depgraph-break-3.test \
|
||||
t/solver/libs-intermediary.test \
|
||||
t/solver/libs-metapackage.test \
|
||||
t/solver/libs-static-ordering.test \
|
||||
t/solver/missing-required-dep.test \
|
||||
t/solver/modversion-provides.test \
|
||||
t/solver/private-libs-duplication-digraph.test \
|
||||
t/solver/private-libs-duplication.test \
|
||||
t/solver/provides-bar-any.test \
|
||||
t/solver/provides-bar-versioned-equal.test \
|
||||
t/solver/provides-bar-versioned-greater-than-equal.test \
|
||||
t/solver/provides-bar-versioned-greater-than.test \
|
||||
t/solver/provides-bar-versioned-less-than-equal.test \
|
||||
t/solver/provides-bar-versioned-less-than-new.test \
|
||||
t/solver/provides-bar-versioned-less-than-old.test \
|
||||
t/solver/provides-bar-versioned-not-equal-old.test \
|
||||
t/solver/provides-bar-versioned-not-equal.test \
|
||||
t/solver/provides-foo-any.test \
|
||||
t/solver/provides-foo-versioned-exact.test \
|
||||
t/solver/provides-foo-versioned-greater-than-equal.test \
|
||||
t/solver/provides-foo-versioned-greater-than.test \
|
||||
t/solver/provides-foo-versioned-less-than-equal.test \
|
||||
t/solver/provides-foo-versioned-less-than.test \
|
||||
t/solver/provides-foo-versioned-not-equal.test \
|
||||
t/solver/provides-indirect-dependency-versioned.test \
|
||||
t/solver/provides-indirect-dependency.test \
|
||||
t/solver/provides-print-simple.test \
|
||||
t/solver/provides-request-simple.test \
|
||||
t/solver/provides-request-simple-no-provides.test \
|
||||
t/solver/query-no-space-0.test \
|
||||
t/solver/query-no-space-1.test \
|
||||
t/solver/query-order-1.test \
|
||||
t/solver/query-order-2.test \
|
||||
t/solver/requires-internal-collision.test \
|
||||
t/solver/requires-internal-missing-nonstatic-cflags-libs.test \
|
||||
t/solver/requires-internal-missing-nonstatic.test \
|
||||
t/solver/requires-internal-missing-static-cflags.test \
|
||||
t/solver/requires-internal-missing.test \
|
||||
t/solver/requires-internal.test \
|
||||
t/solver/requires-private-debounce.test \
|
||||
t/solver/requires-private-missing.test \
|
||||
t/sbom/license-file-bar.test \
|
||||
t/sbom/license-file-foo.test \
|
||||
t/sbom/license-isc.test \
|
||||
t/sbom/license-noassertion.test \
|
||||
t/sbom/source-tag-bar.test \
|
||||
t/sbom/source-tag-foo.test \
|
||||
t/sysroot/cflags-rewriting.test \
|
||||
t/sysroot/idirafter-munge-sysroot.test \
|
||||
t/sysroot/isystem-munge-sysroot.test \
|
||||
t/sysroot/no-pc_sysrootdir-rewriting-2.test \
|
||||
t/sysroot/no-pc_sysrootdir-rewriting-3.test \
|
||||
t/sysroot/no-pc_sysrootdir-rewriting-4.test \
|
||||
t/sysroot/no-pc_sysrootdir-rewriting-5.test \
|
||||
t/sysroot/no-pc_sysrootdir-rewriting-variable.test \
|
||||
t/sysroot/skip-rewriting-when-sysroot-dir-is-root-dir.test \
|
||||
t/sysroot/undefined-pc_sysrootdir-should-be-empty.test \
|
||||
t/sysroot/uninstalled-rewriting-fdo-rules-with-pc_sysrootdir.test \
|
||||
t/sysroot/uninstalled-rewriting-fdo-rules.test \
|
||||
t/sysroot/uninstalled-rewriting-pkgconf-1-rules.test \
|
||||
t/sysroot/uninstalled-rewriting.test \
|
||||
t/sysroot/variable-rewriting-1.test \
|
||||
t/sysroot/variable-rewriting-2.test \
|
||||
t/tuple/billion-laughs.test \
|
||||
t/tuple/case-sensitivity-1.test \
|
||||
t/tuple/case-sensitivity-2.test \
|
||||
t/tuple/define-variable-override.test \
|
||||
t/tuple/define-variable.test \
|
||||
t/tuple/duplicate-upsert.test \
|
||||
t/tuple/empty-tuple.test \
|
||||
tests/lib-relocatable/lib/pkgconfig/foo.pc \
|
||||
tests/lib1/argv-parse-2.pc \
|
||||
tests/lib1/billion-laughs.pc \
|
||||
@ -262,11 +89,6 @@ EXTRA_DIST = pkg.m4 \
|
||||
tests/lib1/fragment-quoting-3.pc \
|
||||
tests/lib1/fragment-quoting-5.pc \
|
||||
tests/lib1/fragment-quoting-7.pc \
|
||||
tests/lib1/fragment-groups.pc \
|
||||
tests/lib1/fragment-groups-2.pc \
|
||||
tests/lib1/fragment-group-a.pc \
|
||||
tests/lib1/fragment-group-b.pc \
|
||||
tests/lib1/fragment-group-c.pc \
|
||||
tests/lib1/malformed-1.pc \
|
||||
tests/lib1/malformed-quoting.pc \
|
||||
tests/lib1/malformed-version.pc \
|
||||
@ -284,32 +106,10 @@ EXTRA_DIST = pkg.m4 \
|
||||
tests/lib1/tuple-quoting.pc \
|
||||
tests/lib1/empty-tuple.pc \
|
||||
tests/lib1/orphaned-requires-private.pc \
|
||||
tests/lib1/pcfiledir.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 \
|
||||
tests/lib1/cflags-libs-private-a.pc \
|
||||
tests/lib1/cflags-libs-private-b.pc \
|
||||
tests/lib1/cflags-libs-private-c.pc \
|
||||
tests/lib1/truncated.pc \
|
||||
tests/lib1/c-comment.pc \
|
||||
tests/lib1/duplicate-tuple.pc \
|
||||
tests/lib1/flag-whitespace.pc \
|
||||
tests/lib1/flag-whitespace-2.pc \
|
||||
tests/lib-sbom/meta_package.pc \
|
||||
tests/lib-sbom/test1.pc \
|
||||
tests/lib-sbom/test2.pc \
|
||||
tests/lib-sbom/test3.pc \
|
||||
tests/lib-sbom/test4.pc \
|
||||
tests/lib-sbom/test5.pc \
|
||||
tests/lib-sbom/test6.pc \
|
||||
tests/lib-sbom-files/basic.json \
|
||||
tests/lib-sbom-files/meta_package.json \
|
||||
tests/lib-sbom-files/with_dependency.json \
|
||||
tests/personality-data/i386-linux-gnu.personality \
|
||||
tests/meson.build \
|
||||
$(test_scripts) \
|
||||
doc/conf.py \
|
||||
doc/extract.py \
|
||||
@ -326,23 +126,26 @@ EXTRA_DIST = pkg.m4 \
|
||||
doc/libpkgconf-queue.rst \
|
||||
doc/libpkgconf-tuple.rst
|
||||
|
||||
test_scripts= \
|
||||
test_scripts= tests/meson.build \
|
||||
tests/basic.sh \
|
||||
tests/builtins.sh \
|
||||
tests/conflicts.sh \
|
||||
tests/framework.sh \
|
||||
tests/parser.sh \
|
||||
tests/personality.sh \
|
||||
tests/provides.sh \
|
||||
tests/regress.sh \
|
||||
tests/requires.sh \
|
||||
tests/spdxtool.sh \
|
||||
tests/symlink.sh
|
||||
tests/sysroot.sh \
|
||||
tests/version.sh
|
||||
|
||||
test_sh = $(test_scripts)
|
||||
check_SCRIPTS = ${test_sh:.sh=}
|
||||
test_sh = $(filter-out tests/meson.build, $(test_scripts))
|
||||
check_SCRIPTS = $(test_sh:.sh=)
|
||||
|
||||
SUFFIXES= .sh
|
||||
|
||||
nobase_pkginclude_HEADERS = libpkgconf/bsdstubs.h libpkgconf/iter.h libpkgconf/libpkgconf.h libpkgconf/stdinc.h libpkgconf/libpkgconf-api.h
|
||||
libpkgconf_la_SOURCES = \
|
||||
libpkgconf/audit.c \
|
||||
libpkgconf/buffer.c \
|
||||
libpkgconf/cache.c \
|
||||
libpkgconf/client.c \
|
||||
libpkgconf/pkg.c \
|
||||
@ -353,14 +156,12 @@ libpkgconf_la_SOURCES = \
|
||||
libpkgconf/tuple.c \
|
||||
libpkgconf/dependency.c \
|
||||
libpkgconf/queue.c \
|
||||
libpkgconf/output.c \
|
||||
libpkgconf/path.c \
|
||||
libpkgconf/personality.c \
|
||||
libpkgconf/parser.c
|
||||
libpkgconf_la_LDFLAGS = -no-undefined -version-info 7:0:0 -export-symbols-regex '^pkgconf_'
|
||||
libpkgconf_la_LDFLAGS = -no-undefined -version-info 4:0:0 -export-symbols-regex '^pkgconf_'
|
||||
|
||||
dist_man_MANS = \
|
||||
man/bomtool.1 \
|
||||
man/pkgconf.1 \
|
||||
man/pkg.m4.7 \
|
||||
man/pc.5 \
|
||||
@ -369,19 +170,12 @@ dist_man_MANS = \
|
||||
pkgconf_LDADD = libpkgconf.la
|
||||
pkgconf_SOURCES = \
|
||||
cli/main.c \
|
||||
cli/core.c \
|
||||
cli/getopt_long.c \
|
||||
cli/renderer-msvc.c
|
||||
pkgconf_CPPFLAGS = -I$(top_srcdir)/libpkgconf -I$(top_srcdir)/cli
|
||||
noinst_HEADERS = \
|
||||
cli/core.h \
|
||||
cli/getopt_long.h \
|
||||
cli/renderer-msvc.h \
|
||||
cli/spdxtool/core.h \
|
||||
cli/spdxtool/serialize.h \
|
||||
cli/spdxtool/simplelicensing.h \
|
||||
cli/spdxtool/software.h \
|
||||
cli/spdxtool/util.h
|
||||
cli/getopt_long.h \
|
||||
cli/renderer-msvc.h
|
||||
|
||||
bomtool_LDADD = libpkgconf.la
|
||||
bomtool_SOURCES = \
|
||||
@ -389,25 +183,6 @@ bomtool_SOURCES = \
|
||||
cli/getopt_long.c
|
||||
bomtool_CPPFLAGS = -I$(top_srcdir)/libpkgconf -I$(top_srcdir)/cli -I$(top_srcdir)/cli/bomtool
|
||||
|
||||
spdxtool_LDADD = libpkgconf.la
|
||||
spdxtool_SOURCES = \
|
||||
cli/spdxtool/main.c \
|
||||
cli/spdxtool/core.c \
|
||||
cli/spdxtool/software.c \
|
||||
cli/spdxtool/serialize.c \
|
||||
cli/spdxtool/simplelicensing.c \
|
||||
cli/spdxtool/util.c \
|
||||
cli/getopt_long.c
|
||||
spdxtool_CPPFLAGS = -I$(top_srcdir)/libpkgconf -I$(top_srcdir)/cli -I$(top_srcdir)/cli/spdxtool
|
||||
|
||||
noinst_PROGRAMS = test-runner
|
||||
test_runner_LDADD = libpkgconf.la
|
||||
test_runner_SOURCES = \
|
||||
cli/core.c \
|
||||
cli/getopt_long.c \
|
||||
cli/renderer-msvc.c \
|
||||
tests/test-runner.c
|
||||
|
||||
dist_doc_DATA = README.md AUTHORS
|
||||
|
||||
m4datadir = $(datadir)/aclocal
|
||||
@ -416,14 +191,7 @@ m4data_DATA = pkg.m4
|
||||
CLEANFILES = $(EXTRA_PROGRAMS) \
|
||||
$(check_SCRIPTS)
|
||||
|
||||
check: pkgconf test-runner $(check_SCRIPTS)
|
||||
$(builddir)/test-runner$(EXEEXT) --test-fixtures=$(top_srcdir)/tests $(top_srcdir)/t/basic
|
||||
$(builddir)/test-runner$(EXEEXT) --test-fixtures=$(top_srcdir)/tests $(top_srcdir)/t/ordering
|
||||
$(builddir)/test-runner$(EXEEXT) --test-fixtures=$(top_srcdir)/tests $(top_srcdir)/t/parser
|
||||
$(builddir)/test-runner$(EXEEXT) --test-fixtures=$(top_srcdir)/tests $(top_srcdir)/t/solver
|
||||
$(builddir)/test-runner$(EXEEXT) --test-fixtures=$(top_srcdir)/tests $(top_srcdir)/t/sbom
|
||||
$(builddir)/test-runner$(EXEEXT) --test-fixtures=$(top_srcdir)/tests $(top_srcdir)/t/sysroot
|
||||
$(builddir)/test-runner$(EXEEXT) --test-fixtures=$(top_srcdir)/tests $(top_srcdir)/t/tuple
|
||||
check: pkgconf $(check_SCRIPTS)
|
||||
kyua --config=none test --kyuafile='$(top_builddir)/Kyuafile' \
|
||||
--build-root='$(top_builddir)'
|
||||
|
||||
|
||||
@ -16,13 +16,11 @@ SRCS = \
|
||||
libpkgconf/argvsplit.c \
|
||||
libpkgconf/audit.c \
|
||||
libpkgconf/bsdstubs.c \
|
||||
libpkgconf/buffer.c \
|
||||
libpkgconf/cache.c \
|
||||
libpkgconf/client.c \
|
||||
libpkgconf/dependency.c \
|
||||
libpkgconf/fileio.c \
|
||||
libpkgconf/fragment.c \
|
||||
libpkgconf/output.c \
|
||||
libpkgconf/parser.c \
|
||||
libpkgconf/path.c \
|
||||
libpkgconf/personality.c \
|
||||
@ -30,8 +28,7 @@ SRCS = \
|
||||
libpkgconf/queue.c \
|
||||
libpkgconf/tuple.c \
|
||||
cli/getopt_long.c \
|
||||
cli/main.c \
|
||||
cli/core.c
|
||||
cli/main.c
|
||||
OBJS = ${SRCS:.c=.o}
|
||||
CFLAGS = ${STATIC} -DPKGCONF_LITE -I. -Ilibpkgconf -Icli -DSYSTEM_LIBDIR=\"${SYSTEM_LIBDIR}\" -DSYSTEM_INCLUDEDIR=\"${SYSTEM_INCLUDEDIR}\" -DPKG_DEFAULT_PATH=\"${PKG_DEFAULT_PATH}\"
|
||||
STATIC =
|
||||
@ -42,7 +39,7 @@ all: pkgconf-lite
|
||||
libpkgconf/config.h:
|
||||
@echo '#define PACKAGE_NAME "pkgconf-lite"' >> $@
|
||||
@echo '#define PACKAGE_BUGREPORT "https://git.dereferenced.org/pkgconf/pkgconf/issues"' >> $@
|
||||
@echo '#define PACKAGE_VERSION "2.5.1"' >> $@
|
||||
@echo '#define PACKAGE_VERSION "2.1.0"' >> $@
|
||||
@echo '#define PACKAGE PACKAGE_NAME " " PACKAGE_VERSION' >> $@
|
||||
@echo '#define HAVE_STRLCPY' >> $@
|
||||
@echo '#define HAVE_STRLCAT' >> $@
|
||||
|
||||
160
NEWS
160
NEWS
@ -1,164 +1,6 @@
|
||||
Changes from previous version of pkgconf
|
||||
========================================
|
||||
|
||||
Changes from 2.5.0 to 2.5.1:
|
||||
----------------------------
|
||||
|
||||
* Fix processing of empty dependency lists.
|
||||
|
||||
Changes from 2.4.3 to 2.5.0:
|
||||
----------------------------
|
||||
|
||||
* Added a manual page for bomtool.
|
||||
|
||||
* Add support for preloaded packages.
|
||||
These are modules which are preloaded into the package database
|
||||
and preferred over searching the module search path when present.
|
||||
|
||||
* Refactor Windows registry PKG_CONFIG_PATH support so that it
|
||||
augments the main directory search list instead of being treated
|
||||
as a special case.
|
||||
|
||||
* Processing of `--with-path` arguments by the pkgconf CLI is
|
||||
now deferred until libpkgconf is fully initialized, effectively
|
||||
aligning behavior with PKG_CONFIG_PATH processing.
|
||||
|
||||
* Fix several minor memory safety bugs which were identified by
|
||||
the GCC 15 static analyzer.
|
||||
|
||||
* Added support for pledge(2) and unveil(2) on systems where
|
||||
this functionality is available.
|
||||
|
||||
* Significant improvements to pkgconf's manual pages.
|
||||
Patches by Ingo Schwarze and Jonathan Gray (OpenBSD).
|
||||
|
||||
* Remove questionable default-static assumption on Windows that
|
||||
was inherited from the original pkg-config. Most distributions
|
||||
of pkgconf on Windows were already patching this out.
|
||||
Patch by Kai Pastor.
|
||||
|
||||
* Add -D_POSIX_C_SOURCE=200809L to the build definitions, which
|
||||
is needed for readlinkat on glibc.
|
||||
Patch by Filipe Laíns.
|
||||
|
||||
Changes from 2.4.2 to 2.4.3:
|
||||
----------------------------
|
||||
|
||||
* Fix additional logic errors relating to the new fragment trees
|
||||
functionality.
|
||||
|
||||
Changes from 2.4.1 to 2.4.2:
|
||||
----------------------------
|
||||
|
||||
* Fix several logic errors in the pkg-config file parser that were
|
||||
surfaced by recent refactoring work.
|
||||
|
||||
* Fix BSD make compatibility so that it generates the test data
|
||||
before running kyua on BSD make implementations.
|
||||
|
||||
Changes from 2.4.0 to 2.4.1:
|
||||
----------------------------
|
||||
|
||||
* Ensure the full DAG is solved for all query types.
|
||||
|
||||
Changes from 2.3.0 to 2.4.0:
|
||||
----------------------------
|
||||
|
||||
* Allow multiple package names in solution-based queries such as
|
||||
`--print-requires`, `--print-requires-private` and `--print-provides`.
|
||||
|
||||
* Use `_DEFAULT_SOURCE` where appropriate on Meson.
|
||||
|
||||
* Add an abstract buffer type and use it when loading files from disk
|
||||
instead of a 64KB buffer. This ensures large pkg-config files are
|
||||
not truncated.
|
||||
|
||||
* Disable graph recursion in `--variable` queries as it was generating
|
||||
duplicate output.
|
||||
|
||||
* Add infrastructure for tracking fragment group relations and convert
|
||||
storage of fragments to use a tree-like structure instead of string
|
||||
concatenation.
|
||||
|
||||
* Add support for tracking linker groups, e.g.
|
||||
|
||||
-Wl,--start-group -la -lb -lc -Wl,--end-group
|
||||
|
||||
as fragment groups.
|
||||
|
||||
* Properly contextualize the sysroot directory when processing package
|
||||
information, ensuring packages where ${pc_sysrootdir} does not match
|
||||
the default are properly processed.
|
||||
|
||||
Changes from 2.2.0 to 2.3.0:
|
||||
----------------------------
|
||||
|
||||
* 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:
|
||||
----------------------------
|
||||
|
||||
@ -167,7 +9,7 @@ Changes from 2.0.3 to 2.1.0:
|
||||
Patches by Kai Pastor.
|
||||
|
||||
* Fix warnings with GCC 14 -Walloc-size.
|
||||
Patch by Sam James.
|
||||
Patch by Sam Jones.
|
||||
|
||||
* Add --solution to the pkgconf CLI to dump the solver state.
|
||||
|
||||
|
||||
103
README.md
103
README.md
@ -1,75 +1,88 @@
|
||||
# pkgconf [](https://github.com/pkgconf/pkgconf/actions/workflows/test.yml)
|
||||
|
||||
`pkgconf` is a program which helps to configure compiler and linker flags for
|
||||
development libraries. It is a superset of the functionality provided by
|
||||
pkg-config from freedesktop.org, but does not provide bug-compatibility with
|
||||
the original pkg-config.
|
||||
development libraries. It is similar to pkg-config from freedesktop.org.
|
||||
|
||||
`libpkgconf` is a library which provides access to most of `pkgconf`'s functionality,
|
||||
to allow other tooling such as compilers and IDEs to discover and use libraries
|
||||
configured by pkgconf.
|
||||
|
||||
## release tarballs
|
||||
## using `pkgconf` with autotools
|
||||
|
||||
Release tarballs are available on [distfiles.ariadne.space][distfiles].
|
||||
Implementations of pkg-config, such as pkgconf, are typically used with the
|
||||
PKG_CHECK_MODULES autoconf macro. As far as we know, pkgconf is
|
||||
compatible with all known variations of this macro. pkgconf detects at
|
||||
runtime whether or not it was started as 'pkg-config', and if so, attempts
|
||||
to set program options such that its behaviour is similar.
|
||||
|
||||
[distfiles]: https://distfiles.ariadne.space/pkgconf/
|
||||
In terms of the autoconf macro, it is possible to specify the PKG_CONFIG
|
||||
environment variable, so that you can test pkgconf without overwriting your
|
||||
pkg-config binary. Some other build systems may also respect the PKG_CONFIG
|
||||
environment variable.
|
||||
|
||||
## build system setup
|
||||
To set the environment variable on the bourne shell and clones (i.e. bash), you
|
||||
can run:
|
||||
|
||||
If you would like to use the git sources directly, or a snapshot of the
|
||||
sources from GitHub, you will need to regenerate the autotools build
|
||||
system artifacts yourself, or use Meson instead. For example, on Alpine:
|
||||
$ export PKG_CONFIG=/usr/bin/pkgconf
|
||||
|
||||
$ apk add autoconf automake libtool build-base
|
||||
$ sh ./autogen.sh
|
||||
## comparison of `pkgconf` and `pkg-config` dependency resolvers
|
||||
|
||||
## pkgconf-lite
|
||||
pkgconf builds an acyclic directed dependency graph. This allows for the user
|
||||
to more conservatively link their binaries -- which may be helpful in some
|
||||
environments, such as when prelink(1) is being used. As a result of building
|
||||
a directed dependency graph designed for the specific problem domain provided
|
||||
by the user, more accurate dependencies can be determined.
|
||||
|
||||
If you only need the original pkg-config functionality, there is also pkgconf-lite,
|
||||
which builds the `pkgconf` frontend and relevant portions of `libpkgconf` functionality
|
||||
into a single binary:
|
||||
Current release versions of pkg-config, on the other hand, build a database of all
|
||||
known pkg-config files on the system before attempting to resolve dependencies, which
|
||||
is a considerably slower and less efficient design. Efforts have been made recently
|
||||
to improve this behaviour.
|
||||
|
||||
$ make -f Makefile.lite
|
||||
|
||||
## why `pkgconf` over original `pkg-config`?
|
||||
|
||||
pkgconf builds a flattened directed dependency graph, which allows for more insight
|
||||
into relationships between dependencies, allowing for some link-time dependency
|
||||
optimization, which allows for the user to more conservatively link their binaries,
|
||||
which may be helpful in some environments, such as when prelink(1) is being used.
|
||||
|
||||
The solver is also optimized to handle large dependency graphs with hundreds of
|
||||
thousands of edges, which can be seen in any project using the Abseil frameworks
|
||||
for example.
|
||||
|
||||
In addition, pkgconf has full support for virtual packages, while the original
|
||||
pkg-config does not, as well as fully supporting `Conflicts` at dependency
|
||||
resolution time, which is more efficient than checking for `Conflicts` while
|
||||
walking the dependency graph.
|
||||
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
|
||||
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,
|
||||
such as, for example, how `Conflicts` rules are processed.
|
||||
|
||||
## linker flags optimization
|
||||
|
||||
pkgconf, when used effectively, can make optimizations to avoid overlinking binaries.
|
||||
As previously mentioned, pkgconf makes optimizations to the linker flags in both the
|
||||
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.
|
||||
|
||||
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
|
||||
which have pkg-config metadata files installed.
|
||||
|
||||
The practice of using `Libs` and `Cflags` to describe unrelated dependencies is
|
||||
not recommended in [Dan Nicholson's pkg-config tutorial][fd-tut] for this reason.
|
||||
Doing so is discouraged by the [freedesktop tutorial][fd-tut] anyway.
|
||||
|
||||
[fd-tut]: http://people.freedesktop.org/~dbn/pkg-config-guide.html
|
||||
|
||||
## bug compatibility with original pkg-config
|
||||
## compatibility with pkg-config
|
||||
|
||||
In general, we do not provide bug-level compatibility with pkg-config.
|
||||
I really hate that I have to have this section, I like being a nice person, but we
|
||||
unfortunately have to say this because otherwise we get passive-aggressive people who
|
||||
try to argue with us about what pkg-config compatibility means.
|
||||
|
||||
We do not provide bug-level compatibility with pkg-config.
|
||||
|
||||
What that means is, if you feel that there is a legitimate regression versus pkg-config,
|
||||
do let us know, but also make sure that the .pc files are valid and follow the rules of
|
||||
the [pkg-config tutorial][fd-tut], as most likely fixing them to follow the specified
|
||||
rules will solve the problem.
|
||||
|
||||
Additionally, **we do not consider pkgconf doing what you tell it to do, in cases for
|
||||
which pkg-config fails to do so, to be a bug**.
|
||||
|
||||
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
|
||||
to those paths, it is not a `pkgconf` problem -- `pkgconf` is doing exactly what you told
|
||||
it to do.
|
||||
|
||||
We will reject bugs like this, and if someone insists on fixing such a non-bug, this
|
||||
constitutes a violation of our [Code of Conduct](CODE_OF_CONDUCT.md), which may be
|
||||
addressed by banning from this repository.
|
||||
|
||||
## debug output
|
||||
|
||||
Please use only the stable interfaces to query pkg-config. Do not screen-scrape the
|
||||
@ -101,16 +114,17 @@ flags like so:
|
||||
|
||||
## compiling `pkgconf` and `libpkgconf` with Meson (usually for Windows)
|
||||
|
||||
|
||||
pkgconf is compiled using [Meson](https://mesonbuild.com) on Windows. In theory, you could also use
|
||||
Meson to build on UNIX, but this is not recommended at this time as pkgconf is typically built
|
||||
Meson to build on UNIX, but this is not recommended at this time as it pkgconf is typically built
|
||||
much earlier than Meson.
|
||||
|
||||
$ meson setup build -Dtests=disabled
|
||||
$ meson compile -C build
|
||||
$ meson install -C build
|
||||
|
||||
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
|
||||
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
|
||||
on path relocation.
|
||||
|
||||
## pkg-config symlink
|
||||
@ -121,6 +135,11 @@ to make this determination themselves.
|
||||
|
||||
$ ln -sf pkgconf /usr/bin/pkg-config
|
||||
|
||||
## release tarballs
|
||||
|
||||
Release tarballs are available at <https://distfiles.ariadne.space/pkgconf/>.
|
||||
Please only use the tarballs from distfiles.ariadne.space.
|
||||
|
||||
## contacts
|
||||
|
||||
You can report bugs at <https://github.com/pkgconf/pkgconf/issues>.
|
||||
|
||||
@ -80,8 +80,8 @@ parse_options "$@"
|
||||
|
||||
cd $TOP_DIR
|
||||
|
||||
run_or_die $LIBTOOLIZE --install
|
||||
run_or_die $ACLOCAL
|
||||
run_or_die $AUTOHEADER
|
||||
run_or_die $AUTOCONF
|
||||
run_or_die $LIBTOOLIZE --install
|
||||
run_or_die $AUTOMAKE --add-missing
|
||||
|
||||
@ -31,15 +31,7 @@ static pkgconf_client_t pkg_client;
|
||||
static uint64_t want_flags;
|
||||
static size_t maximum_package_count = 0;
|
||||
static int maximum_traverse_depth = 2000;
|
||||
static FILE *error_msgout = NULL;
|
||||
|
||||
static const char *
|
||||
environ_lookup_handler(const pkgconf_client_t *client, const char *key)
|
||||
{
|
||||
(void) client;
|
||||
|
||||
return getenv(key);
|
||||
}
|
||||
FILE *error_msgout = NULL;
|
||||
|
||||
static bool
|
||||
error_handler(const char *msg, const pkgconf_client_t *client, void *data)
|
||||
@ -73,9 +65,6 @@ sbom_name(pkgconf_pkg_t *world)
|
||||
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;
|
||||
|
||||
@ -144,9 +133,6 @@ write_sbom_package(pkgconf_client_t *client, pkgconf_pkg_t *pkg, void *unused)
|
||||
if (pkg->description != NULL)
|
||||
printf("PackageSummary: <text>%s</text>\n", pkg->description);
|
||||
|
||||
if (pkg->source != NULL)
|
||||
printf("PackageDownloadLocation: %s\n", pkg->source);
|
||||
|
||||
printf("\n\n");
|
||||
}
|
||||
|
||||
@ -293,7 +279,7 @@ main(int argc, char *argv[])
|
||||
}
|
||||
}
|
||||
|
||||
pkgconf_client_init(&pkg_client, error_handler, NULL, personality, NULL, environ_lookup_handler);
|
||||
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);
|
||||
|
||||
1371
cli/core.c
1371
cli/core.c
File diff suppressed because it is too large
Load Diff
99
cli/core.h
99
cli/core.h
@ -1,99 +0,0 @@
|
||||
/*
|
||||
* core.h
|
||||
* core, printer functions
|
||||
*
|
||||
* Copyright (c) 2011-2025 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.
|
||||
*/
|
||||
|
||||
#ifndef __CLI_CORE_H
|
||||
#define __CLI_CORE_H
|
||||
|
||||
#define PKG_CFLAGS_ONLY_I (((uint64_t) 1) << 2)
|
||||
#define PKG_CFLAGS_ONLY_OTHER (((uint64_t) 1) << 3)
|
||||
#define PKG_CFLAGS (PKG_CFLAGS_ONLY_I|PKG_CFLAGS_ONLY_OTHER)
|
||||
#define PKG_LIBS_ONLY_LDPATH (((uint64_t) 1) << 5)
|
||||
#define PKG_LIBS_ONLY_LIBNAME (((uint64_t) 1) << 6)
|
||||
#define PKG_LIBS_ONLY_OTHER (((uint64_t) 1) << 7)
|
||||
#define PKG_LIBS (PKG_LIBS_ONLY_LDPATH|PKG_LIBS_ONLY_LIBNAME|PKG_LIBS_ONLY_OTHER)
|
||||
#define PKG_MODVERSION (((uint64_t) 1) << 8)
|
||||
#define PKG_REQUIRES (((uint64_t) 1) << 9)
|
||||
#define PKG_REQUIRES_PRIVATE (((uint64_t) 1) << 10)
|
||||
#define PKG_VARIABLES (((uint64_t) 1) << 11)
|
||||
#define PKG_DIGRAPH (((uint64_t) 1) << 12)
|
||||
#define PKG_KEEP_SYSTEM_CFLAGS (((uint64_t) 1) << 13)
|
||||
#define PKG_KEEP_SYSTEM_LIBS (((uint64_t) 1) << 14)
|
||||
#define PKG_VERSION (((uint64_t) 1) << 15)
|
||||
#define PKG_ABOUT (((uint64_t) 1) << 16)
|
||||
#define PKG_ENV_ONLY (((uint64_t) 1) << 17)
|
||||
#define PKG_ERRORS_ON_STDOUT (((uint64_t) 1) << 18)
|
||||
#define PKG_SILENCE_ERRORS (((uint64_t) 1) << 19)
|
||||
#define PKG_IGNORE_CONFLICTS (((uint64_t) 1) << 20)
|
||||
#define PKG_STATIC (((uint64_t) 1) << 21)
|
||||
#define PKG_NO_UNINSTALLED (((uint64_t) 1) << 22)
|
||||
#define PKG_UNINSTALLED (((uint64_t) 1) << 23)
|
||||
#define PKG_LIST (((uint64_t) 1) << 24)
|
||||
#define PKG_HELP (((uint64_t) 1) << 25)
|
||||
#define PKG_PRINT_ERRORS (((uint64_t) 1) << 26)
|
||||
#define PKG_SIMULATE (((uint64_t) 1) << 27)
|
||||
#define PKG_NO_CACHE (((uint64_t) 1) << 28)
|
||||
#define PKG_PROVIDES (((uint64_t) 1) << 29)
|
||||
#define PKG_VALIDATE (((uint64_t) 1) << 30)
|
||||
#define PKG_LIST_PACKAGE_NAMES (((uint64_t) 1) << 31)
|
||||
#define PKG_NO_PROVIDES (((uint64_t) 1) << 32)
|
||||
#define PKG_PURE (((uint64_t) 1) << 33)
|
||||
#define PKG_PATH (((uint64_t) 1) << 34)
|
||||
#define PKG_DEFINE_PREFIX (((uint64_t) 1) << 35)
|
||||
#define PKG_DONT_DEFINE_PREFIX (((uint64_t) 1) << 36)
|
||||
#define PKG_DONT_RELOCATE_PATHS (((uint64_t) 1) << 37)
|
||||
#define PKG_DEBUG (((uint64_t) 1) << 38)
|
||||
#define PKG_SHORT_ERRORS (((uint64_t) 1) << 39)
|
||||
#define PKG_EXISTS (((uint64_t) 1) << 40)
|
||||
#define PKG_MSVC_SYNTAX (((uint64_t) 1) << 41)
|
||||
#define PKG_INTERNAL_CFLAGS (((uint64_t) 1) << 42)
|
||||
#define PKG_DUMP_PERSONALITY (((uint64_t) 1) << 43)
|
||||
#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)
|
||||
#define PKG_FRAGMENT_TREE (((uint64_t) 1) << 48)
|
||||
#define PKG_DUMP_SOURCE (((uint64_t) 1) << 49)
|
||||
#define PKG_DUMP_LICENSE_FILE (((uint64_t) 1) << 50)
|
||||
#define PKG_NEWLINES (((uint64_t) 1) << 51)
|
||||
|
||||
typedef struct {
|
||||
pkgconf_client_t pkg_client;
|
||||
pkgconf_fragment_render_ops_t *want_render_ops;
|
||||
|
||||
uint64_t want_flags;
|
||||
int verbosity;
|
||||
int maximum_traverse_depth;
|
||||
size_t maximum_package_count;
|
||||
|
||||
const char *want_variable;
|
||||
const char *want_fragment_filter;
|
||||
const char *want_env_prefix;
|
||||
|
||||
char *required_pkgconfig_version;
|
||||
const char *required_exact_module_version;
|
||||
const char *required_max_module_version;
|
||||
const char *required_module_version;
|
||||
|
||||
FILE *error_msgout;
|
||||
FILE *logfile_out;
|
||||
|
||||
bool opened_error_msgout;
|
||||
} pkgconf_cli_state_t;
|
||||
|
||||
extern void path_list_to_buffer(const pkgconf_list_t *list, pkgconf_buffer_t *buffer, char delim);
|
||||
extern int pkgconf_cli_run(pkgconf_cli_state_t *state, int argc, char *argv[], int last_argc);
|
||||
extern void pkgconf_cli_state_reset(pkgconf_cli_state_t *state);
|
||||
|
||||
#endif
|
||||
1396
cli/main.c
1396
cli/main.c
File diff suppressed because it is too large
Load Diff
@ -30,7 +30,7 @@ fragment_should_quote(const pkgconf_fragment_t *frag)
|
||||
for (src = frag->data; *src; src++)
|
||||
{
|
||||
if (((*src < ' ') ||
|
||||
(*src >= (' ' + (frag->children.head != NULL ? 1 : 0)) && *src < '$') ||
|
||||
(*src >= (' ' + (frag->merged ? 1 : 0)) && *src < '$') ||
|
||||
(*src > '$' && *src < '(') ||
|
||||
(*src > ')' && *src < '+') ||
|
||||
(*src > ':' && *src < '=') ||
|
||||
@ -104,50 +104,68 @@ msvc_renderer_render_len(const pkgconf_list_t *list, bool escape)
|
||||
}
|
||||
|
||||
static void
|
||||
msvc_renderer_render_buf(const pkgconf_list_t *list, pkgconf_buffer_t *buf, bool escape, char delim)
|
||||
msvc_renderer_render_buf(const pkgconf_list_t *list, char *buf, size_t buflen, bool escape)
|
||||
{
|
||||
pkgconf_node_t *node;
|
||||
char *bptr = buf;
|
||||
|
||||
memset(buf, 0, buflen);
|
||||
|
||||
PKGCONF_FOREACH_LIST_ENTRY(list->head, node)
|
||||
{
|
||||
const pkgconf_fragment_t *frag = node->data;
|
||||
size_t buf_remaining = buflen - (bptr - buf);
|
||||
size_t cnt;
|
||||
|
||||
if (!allowed_fragment(frag))
|
||||
continue;
|
||||
|
||||
if (fragment_len(frag) > buf_remaining)
|
||||
break;
|
||||
|
||||
switch(frag->type) {
|
||||
case 'D':
|
||||
case 'I':
|
||||
pkgconf_buffer_append_fmt(buf, "/%c", frag->type);
|
||||
*bptr++ = '/';
|
||||
*bptr++ = frag->type;
|
||||
break;
|
||||
case 'L':
|
||||
pkgconf_buffer_append(buf, "/libpath:");
|
||||
cnt = pkgconf_strlcpy(bptr, "/libpath:", buf_remaining);
|
||||
bptr += cnt;
|
||||
buf_remaining -= cnt;
|
||||
break;
|
||||
}
|
||||
|
||||
escape = fragment_should_quote(frag);
|
||||
|
||||
if (escape)
|
||||
pkgconf_buffer_push_byte(buf, '"');
|
||||
*bptr++ = '"';
|
||||
|
||||
pkgconf_buffer_append(buf, frag->data);
|
||||
cnt = pkgconf_strlcpy(bptr, frag->data, buf_remaining);
|
||||
bptr += cnt;
|
||||
buf_remaining -= cnt;
|
||||
|
||||
if (frag->type == 'l')
|
||||
pkgconf_buffer_append(buf, ".lib");
|
||||
{
|
||||
cnt = pkgconf_strlcpy(bptr, ".lib", buf_remaining);
|
||||
bptr += cnt;
|
||||
}
|
||||
|
||||
if (escape)
|
||||
pkgconf_buffer_push_byte(buf, '"');
|
||||
*bptr++ = '"';
|
||||
|
||||
pkgconf_buffer_push_byte(buf, delim);
|
||||
*bptr++ = ' ';
|
||||
}
|
||||
|
||||
*bptr = '\0';
|
||||
}
|
||||
|
||||
static pkgconf_fragment_render_ops_t msvc_renderer_ops = {
|
||||
static const pkgconf_fragment_render_ops_t msvc_renderer_ops = {
|
||||
.render_len = msvc_renderer_render_len,
|
||||
.render_buf = msvc_renderer_render_buf
|
||||
};
|
||||
|
||||
pkgconf_fragment_render_ops_t *
|
||||
const pkgconf_fragment_render_ops_t *
|
||||
msvc_renderer_get(void)
|
||||
{
|
||||
return &msvc_renderer_ops;
|
||||
|
||||
@ -18,6 +18,6 @@
|
||||
|
||||
#include <libpkgconf/libpkgconf.h>
|
||||
|
||||
pkgconf_fragment_render_ops_t *msvc_renderer_get(void);
|
||||
const pkgconf_fragment_render_ops_t *msvc_renderer_get(void);
|
||||
|
||||
#endif
|
||||
|
||||
@ -1,690 +0,0 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*
|
||||
* Copyright (c) 2025 The FreeBSD Foundation
|
||||
*
|
||||
* Portions of this software were developed by
|
||||
* Tuukka Pasanen <tuukka.pasanen@ilmi.fi> under sponsorship from
|
||||
* the FreeBSD Foundation
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "util.h"
|
||||
#include "serialize.h"
|
||||
#include "core.h"
|
||||
#include "software.h"
|
||||
#include "simplelicensing.h"
|
||||
|
||||
/*
|
||||
* !doc
|
||||
*
|
||||
* .. c:function:: spdxtool_core_agent_t *spdxtool_core_agent_new(pkgconf_client_t *client, char *creation_info_id, char *name)
|
||||
*
|
||||
* Create new /Core/Agent struct
|
||||
*
|
||||
* :param pkgconf_client_t *client: The pkgconf client being accessed.
|
||||
* :param char *creation_info_id: CreationInfo spdxId
|
||||
* :param char *name: Name of agent
|
||||
* :return: NULL if some problem occurs and Agent struct if not
|
||||
*/
|
||||
spdxtool_core_agent_t *
|
||||
spdxtool_core_agent_new(pkgconf_client_t *client, char *creation_info_id, char *name)
|
||||
{
|
||||
char spdx_id_name[1024];
|
||||
char *spdx_id = NULL;
|
||||
spdxtool_core_agent_t *agent_struct = NULL;
|
||||
|
||||
if(!client || !creation_info_id || !name)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
agent_struct = calloc(1, sizeof(spdxtool_core_agent_t));
|
||||
|
||||
if(!agent_struct)
|
||||
{
|
||||
pkgconf_error(client, "Memory exhausted! Can't create agent struct.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
agent_struct->type = "Agent";
|
||||
memset(spdx_id_name, 0x00, 1024);
|
||||
strncpy(spdx_id_name, name, 1023);
|
||||
spdxtool_util_string_correction(spdx_id_name);
|
||||
spdx_id = spdxtool_util_get_spdx_id_string(client, agent_struct->type, spdx_id_name);
|
||||
|
||||
agent_struct->creation_info = creation_info_id;
|
||||
agent_struct->spdx_id = spdx_id;
|
||||
agent_struct->name = name;
|
||||
return agent_struct;
|
||||
}
|
||||
|
||||
/*
|
||||
* !doc
|
||||
*
|
||||
* .. c:function:: void spdxtool_core_agent_free(spdxtool_core_agent_t *agent_struct)
|
||||
*
|
||||
* Free /Core/Agent struct
|
||||
*
|
||||
* :param spdxtool_core_agent_t *agent_struct: Agent struct to be freed.
|
||||
* :return: nothing
|
||||
*/
|
||||
void
|
||||
spdxtool_core_agent_free(spdxtool_core_agent_t *agent_struct)
|
||||
{
|
||||
if(!agent_struct)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if(agent_struct->creation_info)
|
||||
{
|
||||
free(agent_struct->creation_info);
|
||||
agent_struct->creation_info = NULL;
|
||||
}
|
||||
|
||||
if(agent_struct->spdx_id)
|
||||
{
|
||||
free(agent_struct->spdx_id);
|
||||
agent_struct->spdx_id = NULL;
|
||||
}
|
||||
|
||||
if(agent_struct->name)
|
||||
{
|
||||
free(agent_struct->name);
|
||||
agent_struct->name = NULL;
|
||||
}
|
||||
|
||||
free(agent_struct);
|
||||
}
|
||||
|
||||
/*
|
||||
* !doc
|
||||
*
|
||||
* .. c:function:: void spdxtool_core_agent_serialize(pkgconf_client_t *client, pkgconf_buffer_t *buffer, spdxtool_core_agent_t *agent_struct, bool last)
|
||||
*
|
||||
* Serialize /Core/Agent struct to JSON
|
||||
*
|
||||
* :param pkgconf_client_t *client: The pkgconf client being accessed.
|
||||
* :param pkgconf_buffer_t *buffer: Buffer where struct is serialized
|
||||
* :param spdxtool_core_agent_t *agent_struct: Agent struct to be serialized
|
||||
* :param bool last: Is this last Agent struct or does it need comma at the end. True comma False not
|
||||
* :return: nothing
|
||||
*/
|
||||
void
|
||||
spdxtool_core_agent_serialize(pkgconf_client_t *client, pkgconf_buffer_t *buffer, spdxtool_core_agent_t *agent_struct, bool last)
|
||||
{
|
||||
(void) client;
|
||||
spdxtool_serialize_obj_start(buffer, 2);
|
||||
spdxtool_serialize_parm_and_string(buffer, "@type", agent_struct->type, 3, 1);
|
||||
spdxtool_serialize_parm_and_string(buffer, "creationInfo", agent_struct->creation_info, 3, 1);
|
||||
spdxtool_serialize_parm_and_string(buffer, "spdxId", agent_struct->spdx_id, 3, 1);
|
||||
spdxtool_serialize_parm_and_string(buffer, "name", agent_struct->name, 3, 0);
|
||||
spdxtool_serialize_obj_end(buffer, 2, last);
|
||||
}
|
||||
|
||||
/*
|
||||
* !doc
|
||||
*
|
||||
* .. c:function:: spdxtool_core_creation_info_t *spdxtool_core_creation_info_new(pkgconf_client_t *client, char *agent_id, char *id)
|
||||
*
|
||||
* Create new /Core/CreationInfo struct
|
||||
*
|
||||
* :param pkgconf_client_t *client: The pkgconf client being accessed.
|
||||
* :param char *agent_id: Agent spdxId
|
||||
* :param char *id: Id for creation info
|
||||
* :param char *time: If NULL current time is used if not then
|
||||
* this time string is used. Time string should be
|
||||
* in ISO8601 format: YYYY-MM-DDTHH:MM:SSZ
|
||||
* :return: NULL if some problem occurs and CreationInfo struct if not
|
||||
*/
|
||||
spdxtool_core_creation_info_t *
|
||||
spdxtool_core_creation_info_new(pkgconf_client_t *client, char *agent_id, char *id, char *time)
|
||||
{
|
||||
spdxtool_core_creation_info_t *creation_struct = NULL;
|
||||
|
||||
if(!client || !agent_id || !id)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
creation_struct = calloc(1, sizeof(spdxtool_core_creation_info_t));
|
||||
if(!creation_struct)
|
||||
{
|
||||
pkgconf_error(client, "Memory exhausted! Can't create agent struct.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
creation_struct->type = "CreationInfo";
|
||||
creation_struct->id = id;
|
||||
if(!time)
|
||||
{
|
||||
creation_struct->created = spdxtool_util_get_current_iso8601_time();
|
||||
}
|
||||
else
|
||||
{
|
||||
creation_struct->created = time;
|
||||
}
|
||||
creation_struct->created_by = agent_id;
|
||||
creation_struct->created_using="pkgconf spdxtool";
|
||||
creation_struct->spec_version = spdxtool_util_get_spdx_version(client);
|
||||
return creation_struct;
|
||||
}
|
||||
|
||||
/*
|
||||
* !doc
|
||||
*
|
||||
* .. c:function:: void spdxtool_core_creation_info_free(spdxtool_core_creation_info_t *creation_struct)
|
||||
*
|
||||
* Free /Core/CreationInfo struct
|
||||
*
|
||||
* :param spdxtool_core_creation_info_t *creation_struct: CreationInfo struct to be freed.
|
||||
* :return: nothing
|
||||
*/
|
||||
void
|
||||
spdxtool_core_creation_info_free(spdxtool_core_creation_info_t *creation_struct)
|
||||
{
|
||||
if(!creation_struct)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if(creation_struct->id)
|
||||
{
|
||||
free(creation_struct->id);
|
||||
creation_struct->id = NULL;
|
||||
}
|
||||
|
||||
if(creation_struct->created)
|
||||
{
|
||||
free(creation_struct->created);
|
||||
creation_struct->created = NULL;
|
||||
}
|
||||
|
||||
if(creation_struct->created_by)
|
||||
{
|
||||
free(creation_struct->created_by);
|
||||
creation_struct->created_by = NULL;
|
||||
}
|
||||
|
||||
|
||||
free(creation_struct);
|
||||
}
|
||||
|
||||
/*
|
||||
* !doc
|
||||
*
|
||||
* .. c:function:: void spdxtool_core_creation_info_serialize(pkgconf_client_t *client, pkgconf_buffer_t *buffer, spdxtool_core_creation_info_t *creation_struct, bool last)
|
||||
*
|
||||
* Serialize /Core/CreationInfo struct to JSON
|
||||
*
|
||||
* :param pkgconf_client_t *client: The pkgconf client being accessed.
|
||||
* :param pkgconf_buffer_t *buffer: Buffer where struct is serialized
|
||||
* :param spdxtool_core_creation_info_t *creation_struct: CreationInfo struct to be serialized
|
||||
* :param bool last: Is this last CreationInfo struct or does it need comma at the end. True comma False not
|
||||
* :return: nothing
|
||||
*/
|
||||
void
|
||||
spdxtool_core_creation_info_serialize(pkgconf_client_t *client, pkgconf_buffer_t *buffer, spdxtool_core_creation_info_t *creation_struct, bool last)
|
||||
{
|
||||
(void) client;
|
||||
|
||||
spdxtool_serialize_obj_start(buffer, 2);
|
||||
spdxtool_serialize_parm_and_string(buffer, "@type", creation_struct->type, 3, true);
|
||||
spdxtool_serialize_parm_and_string(buffer, "@id", creation_struct->id, 3, true);
|
||||
spdxtool_serialize_parm_and_string(buffer, "created", creation_struct->created, 3, true);
|
||||
spdxtool_serialize_parm_and_char(buffer, "createdBy", '[', 3, false);
|
||||
spdxtool_serialize_string(buffer, creation_struct->created_by, 4, false);
|
||||
spdxtool_serialize_array_end(buffer, 3, true);
|
||||
spdxtool_serialize_parm_and_string(buffer, "specVersion", (char *)creation_struct->spec_version, 3, false);
|
||||
spdxtool_serialize_obj_end(buffer, 2, last);
|
||||
}
|
||||
|
||||
/*
|
||||
* !doc
|
||||
*
|
||||
* .. c:function:: spdxtool_core_creation_info_t *spdxtool_core_creation_info_new(pkgconf_client_t *client, char *agent_id, char *id)
|
||||
*
|
||||
* Create new /Core/SpdxDocument struct
|
||||
* In SPDX Lite SBOM there can be only one SpdxDocument
|
||||
*
|
||||
* :param pkgconf_client_t *client: The pkgconf client being accessed.
|
||||
* :param char *spdx_id: Id of this SpdxDocument
|
||||
* :param char *creation_id: Id for creation info
|
||||
* :return: NULL if some problem occurs and SpdxDocument struct if not
|
||||
*/
|
||||
spdxtool_core_spdx_document_t *
|
||||
spdxtool_core_spdx_document_new(pkgconf_client_t *client, char *spdx_id, char *creation_id)
|
||||
{
|
||||
spdxtool_core_spdx_document_t *spdx_struct = NULL;
|
||||
|
||||
if(!client || !spdx_id || !creation_id)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
(void)client;
|
||||
|
||||
spdx_struct = calloc(1, sizeof(spdxtool_core_spdx_document_t));
|
||||
|
||||
if(!spdx_struct)
|
||||
{
|
||||
pkgconf_error(client, "Memory exhausted! Can't create spdx_document struct.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
spdx_struct->type = "SpdxDocument";
|
||||
spdx_struct->spdx_id = spdx_id;
|
||||
spdx_struct->creation_info = creation_id;
|
||||
return spdx_struct;
|
||||
}
|
||||
|
||||
/*
|
||||
* !doc
|
||||
*
|
||||
* .. c:function:: void spdxtool_core_spdx_document_free(spdxtool_core_spdx_document_t *spdx_struct)
|
||||
*
|
||||
* Free /Core/SpdxDocument struct
|
||||
*
|
||||
* :param spdxtool_core_spdx_document_t *spdx_struct: SpdxDocument struct to be freed.
|
||||
* :return: nothing
|
||||
*/
|
||||
void
|
||||
spdxtool_core_spdx_document_free(spdxtool_core_spdx_document_t *spdx_struct)
|
||||
{
|
||||
pkgconf_node_t *iter = NULL;
|
||||
pkgconf_node_t *iter_last = NULL;
|
||||
|
||||
if(!spdx_struct)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if(spdx_struct->spdx_id)
|
||||
{
|
||||
free(spdx_struct->spdx_id);
|
||||
spdx_struct->spdx_id = NULL;
|
||||
}
|
||||
|
||||
if(spdx_struct->creation_info)
|
||||
{
|
||||
free(spdx_struct->creation_info);
|
||||
spdx_struct->creation_info = NULL;
|
||||
}
|
||||
|
||||
if(spdx_struct->agent)
|
||||
{
|
||||
free(spdx_struct->agent);
|
||||
spdx_struct->agent = NULL;
|
||||
}
|
||||
|
||||
iter_last = NULL;
|
||||
PKGCONF_FOREACH_LIST_ENTRY(spdx_struct->rootElement.head, iter)
|
||||
{
|
||||
if(iter_last)
|
||||
{
|
||||
free(iter_last);
|
||||
iter_last = NULL;
|
||||
}
|
||||
|
||||
spdxtool_software_sbom_t *sbom = iter->data;
|
||||
spdxtool_software_sbom_free(sbom);
|
||||
iter->data = NULL;
|
||||
iter_last = iter;
|
||||
}
|
||||
|
||||
if(iter_last)
|
||||
{
|
||||
free(iter_last);
|
||||
iter_last = NULL;
|
||||
}
|
||||
|
||||
|
||||
iter_last = NULL;
|
||||
PKGCONF_FOREACH_LIST_ENTRY(spdx_struct->element.head, iter)
|
||||
{
|
||||
if(iter_last)
|
||||
{
|
||||
free(iter_last);
|
||||
iter_last = NULL;
|
||||
}
|
||||
|
||||
free(iter->data);
|
||||
iter_last = iter;
|
||||
}
|
||||
|
||||
if(iter_last)
|
||||
{
|
||||
free(iter_last);
|
||||
iter_last = NULL;
|
||||
}
|
||||
|
||||
|
||||
iter_last = NULL;
|
||||
PKGCONF_FOREACH_LIST_ENTRY(spdx_struct->licenses.head, iter)
|
||||
{
|
||||
if(iter_last)
|
||||
{
|
||||
free(iter_last);
|
||||
iter_last = NULL;
|
||||
}
|
||||
spdxtool_simplelicensing_license_expression_t *expression = iter->data;
|
||||
spdxtool_simplelicensing_licenseExpression_free(expression);
|
||||
iter->data = NULL;
|
||||
iter_last = iter;
|
||||
}
|
||||
|
||||
if(iter_last)
|
||||
{
|
||||
free(iter_last);
|
||||
iter_last = NULL;
|
||||
}
|
||||
|
||||
free(spdx_struct);
|
||||
}
|
||||
|
||||
/*
|
||||
* !doc
|
||||
*
|
||||
* .. c:function:: bool spdxtool_core_spdx_document_is_license(pkgconf_client_t *client, spdxtool_core_spdx_document_t *spdx_struct, char *license)
|
||||
*
|
||||
* Find out if specific license is already there.
|
||||
*
|
||||
* :param pkgconf_client_t *client: The pkgconf client being accessed.
|
||||
* :param spdxtool_core_spdx_document_t *spdx_struct: SpdxDocument struct being used.
|
||||
* :param char *license: SPDX name of license
|
||||
* :return: true is license is there and false if not
|
||||
*/
|
||||
bool
|
||||
spdxtool_core_spdx_document_is_license(pkgconf_client_t *client, spdxtool_core_spdx_document_t *spdx_struct, char *license)
|
||||
{
|
||||
pkgconf_node_t *iter = NULL;
|
||||
spdxtool_simplelicensing_license_expression_t *expression = NULL;
|
||||
|
||||
(void) client;
|
||||
|
||||
|
||||
if(!license)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
PKGCONF_FOREACH_LIST_ENTRY(spdx_struct->licenses.head, iter)
|
||||
{
|
||||
expression = iter->data;
|
||||
if (!strcmp(expression->license_expression, license))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* !doc
|
||||
*
|
||||
* .. c:function:: void spdxtool_core_spdx_document_add_license(pkgconf_client_t *client, spdxtool_core_spdx_document_t *spdx_struct, char *license)
|
||||
*
|
||||
* Add license to SpdxDocument and make sure that specific license is not already there.
|
||||
*
|
||||
* :param pkgconf_client_t *client: The pkgconf client being accessed.
|
||||
* :param spdxtool_core_spdx_document_t *spdx_struct: SpdxDocument struct being used.
|
||||
* :param char *license: SPDX name of license
|
||||
* :return: nothing
|
||||
*/
|
||||
void
|
||||
spdxtool_core_spdx_document_add_license(pkgconf_client_t *client, spdxtool_core_spdx_document_t *spdx_struct, char *license)
|
||||
{
|
||||
pkgconf_node_t *node = NULL;
|
||||
|
||||
|
||||
if(!license)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if(spdxtool_core_spdx_document_is_license(client, spdx_struct, license))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
node = calloc(1, sizeof(pkgconf_node_t));
|
||||
if(!node)
|
||||
{
|
||||
pkgconf_error(client, "Memory exhausted! Cant't add license to spdx_document.");
|
||||
return;
|
||||
}
|
||||
spdxtool_simplelicensing_license_expression_t *expression = spdxtool_simplelicensing_licenseExpression_new(client, license);
|
||||
pkgconf_node_insert_tail(node, expression, &spdx_struct->licenses);
|
||||
}
|
||||
|
||||
/*
|
||||
* !doc
|
||||
*
|
||||
* .. c:function:: void spdxtool_core_spdx_document_add_element(pkgconf_client_t *client, spdxtool_core_spdx_document_t *spdx_struct, char *element)
|
||||
*
|
||||
* Add element spdxId to SpdxDocument
|
||||
*
|
||||
* :param pkgconf_client_t *client: The pkgconf client being accessed.
|
||||
* :param spdxtool_core_spdx_document_t *spdx_struct: SpdxDocument struct being used.
|
||||
* :param char *element: spdxId of element
|
||||
* :return: nothing
|
||||
*/
|
||||
void
|
||||
spdxtool_core_spdx_document_add_element(pkgconf_client_t *client, spdxtool_core_spdx_document_t *spdx_struct, char *element)
|
||||
{
|
||||
pkgconf_node_t *node = NULL;
|
||||
|
||||
(void) client;
|
||||
|
||||
if(!element)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
node = calloc(1, sizeof(pkgconf_node_t));
|
||||
if(!node)
|
||||
{
|
||||
pkgconf_error(NULL, "Memory exhausted! Can't add spdx_id's to spdx_document.");
|
||||
return;
|
||||
}
|
||||
pkgconf_node_insert_tail(node, element, &spdx_struct->element);
|
||||
}
|
||||
|
||||
/*
|
||||
* !doc
|
||||
*
|
||||
* .. c:function:: void spdxtool_core_creation_info_serialize(pkgconf_client_t *client, pkgconf_buffer_t *buffer, spdxtool_core_creation_info_t *creation_struct, bool last)
|
||||
*
|
||||
* Serialize /Core/SpdxDocument struct to JSON
|
||||
*
|
||||
* :param pkgconf_client_t *client: The pkgconf client being accessed.
|
||||
* :param pkgconf_buffer_t *buffer: Buffer where struct is serialized
|
||||
* :param spdxtool_core_spdx_document_t *spdx_struct: SpdxDocument struct to be serialized
|
||||
* :param bool last: Is this last CreationInfo struct or does it need comma at the end. True comma False not
|
||||
* :return: nothing
|
||||
*/
|
||||
void
|
||||
spdxtool_core_spdx_document_serialize(pkgconf_client_t *client, pkgconf_buffer_t *buffer, spdxtool_core_spdx_document_t *spdx_struct, bool last)
|
||||
{
|
||||
pkgconf_node_t *iter = NULL;
|
||||
bool is_next = false;
|
||||
|
||||
PKGCONF_FOREACH_LIST_ENTRY(spdx_struct->rootElement.head, iter)
|
||||
{
|
||||
spdxtool_software_sbom_t *sbom = NULL;
|
||||
sbom = iter->data;
|
||||
spdxtool_software_sbom_serialize(client, buffer, sbom, true);
|
||||
}
|
||||
|
||||
spdxtool_serialize_obj_start(buffer, 2);
|
||||
spdxtool_serialize_parm_and_string(buffer, "@type", spdx_struct->type, 3, true);
|
||||
spdxtool_serialize_parm_and_string(buffer, "creationInfo", spdx_struct->creation_info, 3, true);
|
||||
spdxtool_serialize_parm_and_string(buffer, "spdxId", spdx_struct->spdx_id, 3, true);
|
||||
spdxtool_serialize_parm_and_char(buffer, "rootElement", '[', 3, false);
|
||||
PKGCONF_FOREACH_LIST_ENTRY(spdx_struct->rootElement.head, iter)
|
||||
{
|
||||
spdxtool_software_sbom_t *sbom = NULL;
|
||||
sbom = iter->data;
|
||||
is_next = false;
|
||||
if(iter->next)
|
||||
{
|
||||
is_next = true;
|
||||
}
|
||||
spdxtool_serialize_string(buffer, sbom->spdx_id, 4, is_next);
|
||||
}
|
||||
spdxtool_serialize_array_end(buffer, 3, true);
|
||||
spdxtool_serialize_parm_and_char(buffer, "element", '[', 3, false);
|
||||
spdxtool_serialize_string(buffer, spdx_struct->agent, 4, true);
|
||||
|
||||
PKGCONF_FOREACH_LIST_ENTRY(spdx_struct->element.head, iter)
|
||||
{
|
||||
char *spdx_id = NULL;
|
||||
spdx_id = iter->data;
|
||||
spdxtool_serialize_string(buffer, spdx_id, 4, true);
|
||||
}
|
||||
|
||||
PKGCONF_FOREACH_LIST_ENTRY(spdx_struct->rootElement.head, iter)
|
||||
{
|
||||
spdxtool_software_sbom_t *sbom = NULL;
|
||||
sbom = iter->data;
|
||||
is_next = false;
|
||||
if(iter->next)
|
||||
{
|
||||
is_next = true;
|
||||
}
|
||||
spdxtool_serialize_string(buffer, sbom->spdx_id, 4, true);
|
||||
spdxtool_serialize_string(buffer, pkgconf_tuple_find(client, &sbom->rootElement->vars, "spdxId"), 4, is_next);
|
||||
}
|
||||
|
||||
spdxtool_serialize_array_end(buffer, 3, false);
|
||||
spdxtool_serialize_obj_end(buffer, 2, last);
|
||||
}
|
||||
|
||||
/*
|
||||
* !doc
|
||||
*
|
||||
* .. c:function:: spdxtool_core_relationship_t *spdxtool_core_relationship_new(pkgconf_client_t *client, char *creation_info_id, char *spdx_id, char *from, char *to, char *relationship_type)
|
||||
*
|
||||
* Create new /Core/Relationship struct
|
||||
*
|
||||
* :param pkgconf_client_t *client: The pkgconf client being accessed.
|
||||
* :param char *creation_id: Id for creation info
|
||||
* :param char *spdx_id: Id of this SpdxDocument
|
||||
* :param char *from: from spdxId
|
||||
* :param char *to: to spdxId
|
||||
* :param char *relationship_type: These can be found on SPDX documentation
|
||||
* :return: NULL if some problem occurs and SpdxDocument struct if not
|
||||
*/
|
||||
spdxtool_core_relationship_t *
|
||||
spdxtool_core_relationship_new(pkgconf_client_t *client, char *creation_info_id, char *spdx_id, char *from, char *to, char *relationship_type)
|
||||
{
|
||||
spdxtool_core_relationship_t *relationship = NULL;
|
||||
|
||||
if(!client || !creation_info_id || !spdx_id || !from || !to || !relationship_type)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
(void) client;
|
||||
|
||||
relationship = calloc(1, sizeof(spdxtool_core_relationship_t));
|
||||
|
||||
if(!relationship)
|
||||
{
|
||||
pkgconf_error(client, "Memory exhausted! Can't create relationship struct.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
relationship->type = "Relationship";
|
||||
relationship->creation_info = creation_info_id;
|
||||
relationship->spdx_id = spdx_id;
|
||||
relationship->from = from;
|
||||
relationship->to = to;
|
||||
relationship->relationship_type = relationship_type;
|
||||
|
||||
return relationship;
|
||||
}
|
||||
|
||||
/*
|
||||
* !doc
|
||||
*
|
||||
* .. c:function:: void spdxtool_core_relationship_free(spdxtool_core_relationship_t *relationship_struct)
|
||||
*
|
||||
* Free /Core/Relationship struct
|
||||
*
|
||||
* :param spdxtool_core_relationship_t *relationship_struct: Relationship struct to be freed.
|
||||
* :return: nothing
|
||||
*/
|
||||
void
|
||||
spdxtool_core_relationship_free(spdxtool_core_relationship_t *relationship_struct)
|
||||
{
|
||||
if(!relationship_struct)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if(relationship_struct->spdx_id)
|
||||
{
|
||||
free(relationship_struct->spdx_id);
|
||||
relationship_struct->spdx_id = NULL;
|
||||
}
|
||||
|
||||
if(relationship_struct->creation_info)
|
||||
{
|
||||
free(relationship_struct->creation_info);
|
||||
relationship_struct->creation_info = NULL;
|
||||
}
|
||||
|
||||
if(relationship_struct->from)
|
||||
{
|
||||
free(relationship_struct->from);
|
||||
relationship_struct->from = NULL;
|
||||
}
|
||||
|
||||
if(relationship_struct->to)
|
||||
{
|
||||
free(relationship_struct->to);
|
||||
relationship_struct->to = NULL;
|
||||
}
|
||||
|
||||
if(relationship_struct->relationship_type)
|
||||
{
|
||||
free(relationship_struct->relationship_type);
|
||||
relationship_struct->relationship_type = NULL;
|
||||
}
|
||||
|
||||
free(relationship_struct);
|
||||
}
|
||||
|
||||
/*
|
||||
* !doc
|
||||
*
|
||||
* .. c:function:: void spdxtool_core_creation_info_serialize(pkgconf_client_t *client, pkgconf_buffer_t *buffer, spdxtool_core_creation_info_t *creation_struct, bool last)
|
||||
*
|
||||
* Serialize /Core/Relationship struct to JSON
|
||||
*
|
||||
* :param pkgconf_client_t *client: The pkgconf client being accessed.
|
||||
* :param pkgconf_buffer_t *buffer: Buffer where struct is serialized
|
||||
* :param spdxtool_core_relationship_t *relationship_struct: Relationship struct to be serialized
|
||||
* :param bool last: Is this last CreationInfo struct or does it need comma at the end. True comma False not
|
||||
* :return: nothing
|
||||
*/
|
||||
void
|
||||
spdxtool_core_relationship_serialize(pkgconf_client_t *client, pkgconf_buffer_t *buffer, spdxtool_core_relationship_t *relationship_struct, bool last)
|
||||
{
|
||||
(void) client;
|
||||
|
||||
spdxtool_serialize_obj_start(buffer, 2);
|
||||
spdxtool_serialize_parm_and_string(buffer, "@type", relationship_struct->type, 3, true);
|
||||
spdxtool_serialize_parm_and_string(buffer, "creationInfo", relationship_struct->creation_info, 3, true);
|
||||
spdxtool_serialize_parm_and_string(buffer, "spdxId", relationship_struct->spdx_id, 3, true);
|
||||
spdxtool_serialize_parm_and_string(buffer, "from", relationship_struct->from, 3, true);
|
||||
spdxtool_serialize_parm_and_char(buffer, "to", '[', 3, false);
|
||||
spdxtool_serialize_string(buffer, relationship_struct->to, 4, false);
|
||||
spdxtool_serialize_array_end(buffer, 3, true);
|
||||
spdxtool_serialize_parm_and_string(buffer, "relationshipType", relationship_struct->relationship_type, 3, false);
|
||||
spdxtool_serialize_obj_end(buffer, 2, last);
|
||||
}
|
||||
@ -1,73 +0,0 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*
|
||||
* Copyright (c) 2025 The FreeBSD Foundation
|
||||
*
|
||||
* Portions of this software were developed by
|
||||
* Tuukka Pasanen <tuukka.pasanen@ilmi.fi> under sponsorship from
|
||||
* the FreeBSD Foundation
|
||||
*/
|
||||
|
||||
#ifndef CLI__SPDXTOOL__CORE_H
|
||||
#define CLI__SPDXTOOL__CORE_H
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "util.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
spdxtool_core_agent_t *
|
||||
spdxtool_core_agent_new(pkgconf_client_t *client, char *creation_id, char *name);
|
||||
|
||||
void
|
||||
spdxtool_core_agent_free(spdxtool_core_agent_t *agent_struct);
|
||||
|
||||
void
|
||||
spdxtool_core_agent_serialize(pkgconf_client_t *client, pkgconf_buffer_t *buffer, spdxtool_core_agent_t *agent_struct, bool last);
|
||||
|
||||
spdxtool_core_creation_info_t *
|
||||
spdxtool_core_creation_info_new(pkgconf_client_t *client, char *agent_id, char *id, char *time);
|
||||
|
||||
void
|
||||
spdxtool_core_creation_info_free(spdxtool_core_creation_info_t *creation_struct);
|
||||
|
||||
void
|
||||
spdxtool_core_creation_info_serialize(pkgconf_client_t *client, pkgconf_buffer_t *buffer, spdxtool_core_creation_info_t *creation_struct, bool last);
|
||||
|
||||
spdxtool_core_spdx_document_t *
|
||||
spdxtool_core_spdx_document_new(pkgconf_client_t *client, char *spdx_id, char *creation_id);
|
||||
|
||||
bool
|
||||
spdxtool_core_spdx_document_is_license(pkgconf_client_t *client, spdxtool_core_spdx_document_t *spdx_struct, char *license);
|
||||
|
||||
|
||||
void
|
||||
spdxtool_core_spdx_document_add_license(pkgconf_client_t *client, spdxtool_core_spdx_document_t *spdx_struct, char *license);
|
||||
|
||||
void
|
||||
spdxtool_core_spdx_document_add_element(pkgconf_client_t *client, spdxtool_core_spdx_document_t *spdx_struct, char *element);
|
||||
|
||||
|
||||
void
|
||||
spdxtool_core_spdx_document_free(spdxtool_core_spdx_document_t *spdx_struct);
|
||||
|
||||
void
|
||||
spdxtool_core_spdx_document_serialize(pkgconf_client_t *client, pkgconf_buffer_t *buffer, spdxtool_core_spdx_document_t *spdx_struct, bool last);
|
||||
|
||||
|
||||
spdxtool_core_relationship_t *
|
||||
spdxtool_core_relationship_new(pkgconf_client_t *client, char *creation_info_id, char *spdx_id, char *from, char *to, char *relationship_type);
|
||||
|
||||
void
|
||||
spdxtool_core_relationship_free(spdxtool_core_relationship_t *relationship_struct);
|
||||
|
||||
void
|
||||
spdxtool_core_relationship_serialize(pkgconf_client_t *client, pkgconf_buffer_t *buffer, spdxtool_core_relationship_t *relationship_struct, bool last);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@ -1,356 +0,0 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*
|
||||
* Copyright (c) 2025 The FreeBSD Foundation
|
||||
*
|
||||
* Portions of this software were developed by
|
||||
* Tuukka Pasanen <tuukka.pasanen@ilmi.fi> under sponsorship from
|
||||
* the FreeBSD Foundation
|
||||
*/
|
||||
|
||||
#include "libpkgconf/config.h"
|
||||
#include <libpkgconf/stdinc.h>
|
||||
#include <libpkgconf/libpkgconf.h>
|
||||
#include "getopt_long.h"
|
||||
#include "util.h"
|
||||
#include "core.h"
|
||||
#include "software.h"
|
||||
#include "serialize.h"
|
||||
#include "simplelicensing.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 = "3.0.1";
|
||||
static const char *bom_license = "CC0-1.0";
|
||||
static const char *xsd_any_uri_default_base = "https://github.com/pkgconf/pkgconf";
|
||||
static int maximum_traverse_depth = 2000;
|
||||
|
||||
static pkgconf_client_t pkg_client;
|
||||
static uint64_t want_flags;
|
||||
static size_t maximum_package_count = 0;
|
||||
// static int maximum_traverse_depth = 2000;
|
||||
static FILE *error_msgout = NULL;
|
||||
|
||||
static const char *
|
||||
environ_lookup_handler(const pkgconf_client_t *client, const char *key)
|
||||
{
|
||||
(void) client;
|
||||
|
||||
return getenv(key);
|
||||
}
|
||||
|
||||
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 void
|
||||
write_jsonld_end(pkgconf_client_t *client, pkgconf_pkg_t *world, pkgconf_buffer_t *buffer)
|
||||
{
|
||||
(void) client;
|
||||
(void) world;
|
||||
|
||||
spdxtool_serialize_array_end(buffer, 1, false);
|
||||
spdxtool_serialize_obj_end(buffer, 0, false);
|
||||
}
|
||||
|
||||
static void
|
||||
write_jsonld_header(pkgconf_client_t *client, pkgconf_pkg_t *world, pkgconf_buffer_t *buffer)
|
||||
{
|
||||
(void) client;
|
||||
(void) world;
|
||||
|
||||
spdxtool_serialize_obj_start(buffer, 0);
|
||||
spdxtool_serialize_parm_and_string(buffer, "@context", "https://spdx.org/rdf/3.0.1/spdx-context.jsonld", 1, true);
|
||||
|
||||
spdxtool_serialize_parm_and_char(buffer, "@graph", '[', 1, false);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
generate_spdx_package(pkgconf_client_t *client, pkgconf_pkg_t *pkg, void *ptr)
|
||||
{
|
||||
(void) client;
|
||||
pkgconf_node_t *node = NULL;
|
||||
spdxtool_core_spdx_document_t *document = (spdxtool_core_spdx_document_t *)ptr;
|
||||
char *package_spdx = NULL;
|
||||
char spdx_id_name[1024];
|
||||
|
||||
|
||||
if (pkg->flags & PKGCONF_PKG_PROPF_VIRTUAL)
|
||||
return;
|
||||
|
||||
spdxtool_software_sbom_t *sbom = spdxtool_software_sbom_new(client, spdxtool_util_get_spdx_id_string(client, "software_Sbom", pkg->realname), strdup(document->creation_info), strdup("build"));
|
||||
sbom->spdx_document = document;
|
||||
sbom->rootElement = pkg;
|
||||
|
||||
package_spdx = spdxtool_util_get_spdx_id_string(client, "Package", pkg->realname);
|
||||
|
||||
pkgconf_tuple_add(client, &pkg->vars, "spdxId", package_spdx, false, 0);
|
||||
free(package_spdx);
|
||||
package_spdx = NULL;
|
||||
|
||||
pkgconf_tuple_add(client, &pkg->vars, "creationInfo", document->creation_info, false, 0);
|
||||
pkgconf_tuple_add(client, &pkg->vars, "agent", document->agent, false, 0);
|
||||
|
||||
if (pkg->license != NULL)
|
||||
{
|
||||
snprintf(spdx_id_name, 1024, "%s/hasDeclaredLicense", pkg->realname);
|
||||
package_spdx = spdxtool_util_get_spdx_id_string(client, "Relationship", spdx_id_name);
|
||||
pkgconf_tuple_add(client, &pkg->vars, "hasDeclaredLicense", package_spdx, false, 0);
|
||||
free(package_spdx);
|
||||
package_spdx = NULL;
|
||||
|
||||
snprintf(spdx_id_name, 1024, "%s/hasConcludedLicense", pkg->realname);
|
||||
package_spdx = spdxtool_util_get_spdx_id_string(client, "Relationship", spdx_id_name);
|
||||
pkgconf_tuple_add(client, &pkg->vars, "hasConcludedLicense", package_spdx, false, 0);
|
||||
free(package_spdx);
|
||||
package_spdx = NULL;
|
||||
|
||||
spdxtool_core_spdx_document_add_license(client, document, pkg->license);
|
||||
}
|
||||
|
||||
node = calloc(1, sizeof(pkgconf_node_t));
|
||||
|
||||
if(!node)
|
||||
{
|
||||
pkgconf_error(NULL, "Memory exhausted!");
|
||||
return;
|
||||
}
|
||||
pkgconf_node_insert_tail(node, sbom, &document->rootElement);
|
||||
}
|
||||
|
||||
static bool
|
||||
generate_spdx(pkgconf_client_t *client, pkgconf_pkg_t *world, char *creation_time, char *creation_id, char *agent_name)
|
||||
{
|
||||
int eflag;
|
||||
pkgconf_buffer_t buffer = PKGCONF_BUFFER_INITIALIZER;
|
||||
|
||||
char *agent_name_string = "Default";
|
||||
char *creation_id_string = "_:creationinfo_1";
|
||||
char *creation_time_string = NULL;
|
||||
|
||||
|
||||
if(agent_name)
|
||||
{
|
||||
agent_name_string = agent_name;
|
||||
}
|
||||
|
||||
if(creation_time)
|
||||
{
|
||||
creation_time_string = strdup(creation_time);
|
||||
}
|
||||
|
||||
if(creation_id)
|
||||
{
|
||||
creation_id_string = creation_id;
|
||||
}
|
||||
|
||||
spdxtool_core_agent_t *agent = spdxtool_core_agent_new(client, strdup(creation_id_string), strdup(agent_name_string));
|
||||
spdxtool_core_creation_info_t *creation = spdxtool_core_creation_info_new(&pkg_client, strdup(agent->spdx_id), strdup(creation_id_string), creation_time_string);
|
||||
spdxtool_core_spdx_document_t *document = spdxtool_core_spdx_document_new(&pkg_client, spdxtool_util_get_spdx_id_int(&pkg_client, "spdxDocument"), strdup(creation_id_string));
|
||||
|
||||
document->agent = strdup(agent->spdx_id);
|
||||
|
||||
eflag = pkgconf_pkg_traverse(client, world, generate_spdx_package, document, maximum_traverse_depth, 0);
|
||||
if (eflag != PKGCONF_PKG_ERRF_OK)
|
||||
return false;
|
||||
|
||||
write_jsonld_header(client, world, &buffer);
|
||||
|
||||
spdxtool_core_agent_serialize(client, &buffer, agent, true);
|
||||
spdxtool_core_creation_info_serialize(client, &buffer, creation, true);
|
||||
|
||||
spdxtool_simplelicensing_licenseExpression_serialize(client, &buffer, document, true);
|
||||
|
||||
spdxtool_core_spdx_document_serialize(client, &buffer, document, false);
|
||||
|
||||
write_jsonld_end(client, world, &buffer);
|
||||
|
||||
spdxtool_core_spdx_document_free(document);
|
||||
spdxtool_core_agent_free(agent);
|
||||
spdxtool_core_creation_info_free(creation);
|
||||
|
||||
printf("%s\n", pkgconf_buffer_str(&buffer));
|
||||
|
||||
pkgconf_buffer_finalize(&buffer);
|
||||
return true;
|
||||
}
|
||||
|
||||
static int
|
||||
version(void)
|
||||
{
|
||||
printf("spdxtool %s\n", PACKAGE_VERSION);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
static int
|
||||
about(void)
|
||||
{
|
||||
printf("spdxtool (%s %s)\n\n", PACKAGE_NAME, PACKAGE_VERSION);
|
||||
printf("SPDX-License-Identifier: BSD-2-Clause\n\n");
|
||||
printf("Copyright (c) 2025 The FreeBSD Foundation\n\n");
|
||||
printf("Portions of this software were developed by\n");
|
||||
printf("Tuukka Pasanen <tuukka.pasanen@ilmi.fi> under sponsorship from\n");
|
||||
printf("the FreeBSD Foundation\n\n");
|
||||
printf("Report bugs at <%s>.\n", PACKAGE_BUGREPORT);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
static int
|
||||
usage(void)
|
||||
{
|
||||
printf("usage: spdxtool [modules]\n");
|
||||
|
||||
printf("\nOptions:\n");
|
||||
|
||||
printf(" --agent-name Set agent name [default: 'Default']\n");
|
||||
printf(" --creation-time Use string as creation time (Should be in ISO8601 format) [default: current time]\n");
|
||||
printf(" --creation-id Use string as creation id [default: '_:creationinfo_1']\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();
|
||||
char *creation_time = NULL;
|
||||
char *creation_id = NULL;
|
||||
char *agent_name = NULL;
|
||||
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[] =
|
||||
{
|
||||
{ "agent-name", required_argument, NULL, 100, },
|
||||
{ "creation-time", required_argument, NULL, 101, },
|
||||
{ "creation-id", required_argument, NULL, 102, },
|
||||
{ "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 100:
|
||||
agent_name = pkg_optarg;
|
||||
break;
|
||||
case 101:
|
||||
creation_time = pkg_optarg;
|
||||
break;
|
||||
case 102:
|
||||
creation_id = pkg_optarg;
|
||||
break;
|
||||
case '?':
|
||||
case ':':
|
||||
return EXIT_FAILURE;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
pkgconf_client_init(&pkg_client, error_handler, NULL, personality, NULL, environ_lookup_handler);
|
||||
|
||||
/* 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 (!pkgconf_queue_solve(&pkg_client, &pkgq, &world, maximum_traverse_depth))
|
||||
{
|
||||
ret = EXIT_FAILURE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
spdxtool_util_set_uri_root(&pkg_client, xsd_any_uri_default_base);
|
||||
spdxtool_util_set_spdx_license(&pkg_client, bom_license);
|
||||
spdxtool_util_set_spdx_version(&pkg_client, spdx_version);
|
||||
|
||||
if (!generate_spdx(&pkg_client, &world, creation_time, creation_id, agent_name))
|
||||
{
|
||||
ret = EXIT_FAILURE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = EXIT_SUCCESS;
|
||||
|
||||
out:
|
||||
pkgconf_solution_free(&pkg_client, &world);
|
||||
pkgconf_queue_free(&pkgq);
|
||||
pkgconf_cross_personality_deinit(personality);
|
||||
pkgconf_client_deinit(&pkg_client);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -1,206 +0,0 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*
|
||||
* Copyright (c) 2025 The FreeBSD Foundation
|
||||
*
|
||||
* Portions of this software were developed by
|
||||
* Tuukka Pasanen <tuukka.pasanen@ilmi.fi> under sponsorship from
|
||||
* the FreeBSD Foundation
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "util.h"
|
||||
#include "core.h"
|
||||
|
||||
static inline void
|
||||
serialize_add_indent(pkgconf_buffer_t *buffer, unsigned int level)
|
||||
{
|
||||
for (; level; level--)
|
||||
pkgconf_buffer_append(buffer, " ");
|
||||
}
|
||||
|
||||
static inline void
|
||||
serialize_next_line(pkgconf_buffer_t *buffer, bool more)
|
||||
{
|
||||
if (more)
|
||||
pkgconf_buffer_push_byte(buffer, ',');
|
||||
|
||||
pkgconf_buffer_push_byte(buffer, '\n');
|
||||
}
|
||||
|
||||
static inline void
|
||||
serialize_begin_object(pkgconf_buffer_t *buffer, char ch, unsigned int level)
|
||||
{
|
||||
serialize_add_indent(buffer, level);
|
||||
pkgconf_buffer_push_byte(buffer, ch);
|
||||
serialize_next_line(buffer, false);
|
||||
}
|
||||
|
||||
static inline void
|
||||
serialize_end_object(pkgconf_buffer_t *buffer, char ch, unsigned int level, bool more)
|
||||
{
|
||||
serialize_add_indent(buffer, level);
|
||||
pkgconf_buffer_push_byte(buffer, ch);
|
||||
serialize_next_line(buffer, more);
|
||||
}
|
||||
|
||||
/*
|
||||
* !doc
|
||||
*
|
||||
* .. c:function:: void spdxtool_serialize_parm_and_string(pkgconf_buffer_t *buffer, char *parm, char *string, unsigned int level, bool more)
|
||||
*
|
||||
* Add paramter, string and optional comma to buffer
|
||||
*
|
||||
* :param pkgconf_buffer_t *buffer: Buffer to add.
|
||||
* :param char *param: Parameter name
|
||||
* :param char *string: String to add
|
||||
* :param unsigned int level: Indent level
|
||||
* :param bool more: true if more fields are expected, else false
|
||||
* :return: nothing
|
||||
*/
|
||||
void
|
||||
spdxtool_serialize_parm_and_string(pkgconf_buffer_t *buffer, char *parm, char *string, unsigned int level, bool more)
|
||||
{
|
||||
serialize_add_indent(buffer, level);
|
||||
pkgconf_buffer_append_fmt(buffer, "\"%s\": \"%s\"", parm, string);
|
||||
serialize_next_line(buffer, more);
|
||||
}
|
||||
|
||||
/*
|
||||
* !doc
|
||||
*
|
||||
* .. c:function:: void spdxtool_serialize_parm_and_char(pkgconf_buffer_t *buffer, char *parm, char ch, unsigned int level, bool more)
|
||||
*
|
||||
* Add paramter, char and optional comma to buffer
|
||||
*
|
||||
* :param pkgconf_buffer_t *buffer: Buffer to add.
|
||||
* :param char *param: Parameter name
|
||||
* :param char ch: Char to add
|
||||
* :param unsigned int level: Indent level
|
||||
* :param bool more: true if more fields are expected, else false
|
||||
* :return: nothing
|
||||
*/
|
||||
void
|
||||
spdxtool_serialize_parm_and_char(pkgconf_buffer_t *buffer, char *parm, char ch, unsigned int level, bool more)
|
||||
{
|
||||
serialize_add_indent(buffer, level);
|
||||
pkgconf_buffer_append_fmt(buffer, "\"%s\": %c", parm, ch);
|
||||
serialize_next_line(buffer, more);
|
||||
}
|
||||
|
||||
/*
|
||||
* !doc
|
||||
*
|
||||
* .. c:function:: void spdxtool_serialize_parm_and_int(pkgconf_buffer_t *buffer, char *parm, int integer, unsigned int level, bool more)
|
||||
*
|
||||
* Add paramter, integer and optional comma to buffer
|
||||
*
|
||||
* :param pkgconf_buffer_t *buffer: Buffer to add.
|
||||
* :param char *param: Parameter name
|
||||
* :param int integer: Int to add
|
||||
* :param unsigned int level: Indent level
|
||||
* :param bool more: true if more fields are expected, else false
|
||||
* :return: nothing
|
||||
*/
|
||||
void
|
||||
spdxtool_serialize_parm_and_int(pkgconf_buffer_t *buffer, char *parm, int integer, unsigned int level, bool more)
|
||||
{
|
||||
serialize_add_indent(buffer, level);
|
||||
pkgconf_buffer_append_fmt(buffer, "\"%s\": %d", parm, integer);
|
||||
serialize_next_line(buffer, more);
|
||||
}
|
||||
|
||||
/*
|
||||
* !doc
|
||||
*
|
||||
* .. c:function:: void spdxtool_serialize_string(pkgconf_buffer_t *buffer, char *string, unsigned int level, bool more)
|
||||
*
|
||||
* Add just string.
|
||||
*
|
||||
* :param pkgconf_buffer_t *buffer: Buffer to add.
|
||||
* :param char *param: Parameter name
|
||||
* :param char *ch: String to add
|
||||
* :param unsigned int: level Indent level
|
||||
* :param bool more: true if more fields are expected, else false
|
||||
* :return: nothing
|
||||
*/
|
||||
void
|
||||
spdxtool_serialize_string(pkgconf_buffer_t *buffer, char *string, unsigned int level, bool more)
|
||||
{
|
||||
serialize_add_indent(buffer, level);
|
||||
pkgconf_buffer_push_byte(buffer, '"');
|
||||
pkgconf_buffer_append(buffer, string);
|
||||
pkgconf_buffer_push_byte(buffer, '"');
|
||||
serialize_next_line(buffer, more);
|
||||
}
|
||||
|
||||
/*
|
||||
* !doc
|
||||
*
|
||||
* .. c:function:: void spdxtool_serialize_obj_start(pkgconf_buffer_t *buffer, unsigned int level)
|
||||
*
|
||||
* Start JSON object to buffer
|
||||
*
|
||||
* :param pkgconf_buffer_t *buffer: Buffer to add.
|
||||
* :param unsigned int level: Indent level
|
||||
* :return: nothing
|
||||
*/
|
||||
void
|
||||
spdxtool_serialize_obj_start(pkgconf_buffer_t *buffer, unsigned int level)
|
||||
{
|
||||
serialize_begin_object(buffer, '{', level);
|
||||
}
|
||||
|
||||
/*
|
||||
* !doc
|
||||
*
|
||||
* .. c:function:: void spdxtool_serialize_obj_end(pkgconf_buffer_t *buffer, unsigned int level, bool more)
|
||||
*
|
||||
* End JSON object to buffer
|
||||
*
|
||||
* :param pkgconf_buffer_t *buffer: Buffer to add.
|
||||
* :param unsigned int level: Level which is added
|
||||
* :param bool more: true if more fields are expected, else false
|
||||
* :return: nothing
|
||||
*/
|
||||
void
|
||||
spdxtool_serialize_obj_end(pkgconf_buffer_t *buffer, unsigned int level, bool more)
|
||||
{
|
||||
serialize_end_object(buffer, '}', level, more);
|
||||
}
|
||||
|
||||
/*
|
||||
* !doc
|
||||
*
|
||||
* .. c:function:: void spdxtool_serialize_obj_start(pkgconf_buffer_t *buffer, unsigned int level)
|
||||
*
|
||||
* Start JSON array to buffer
|
||||
*
|
||||
* :param pkgconf_buffer_t *buffer: Buffer to add.
|
||||
* :param unsigned int level: Level which is added
|
||||
* :return: nothing
|
||||
*/
|
||||
void
|
||||
spdxtool_serialize_array_start(pkgconf_buffer_t *buffer, unsigned int level)
|
||||
{
|
||||
serialize_begin_object(buffer, '[', level);
|
||||
}
|
||||
|
||||
/*
|
||||
* !doc
|
||||
*
|
||||
* .. c:function:: void spdxtool_serialize_array_end(pkgconf_buffer_t *buffer, unsigned int level, bool more)
|
||||
*
|
||||
* End JSON array to buffer
|
||||
*
|
||||
* :param pkgconf_buffer_t *buffer: Buffer to add.
|
||||
* :param unsigned int level: Level which is added
|
||||
* :param bool more: true if more fields are expected, else false
|
||||
* :return: nothing
|
||||
*/
|
||||
void
|
||||
spdxtool_serialize_array_end(pkgconf_buffer_t *buffer, unsigned int level, bool more)
|
||||
{
|
||||
serialize_end_object(buffer, ']', level, more);
|
||||
}
|
||||
@ -1,50 +0,0 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*
|
||||
* Copyright (c) 2025 The FreeBSD Foundation
|
||||
*
|
||||
* Portions of this software were developed by
|
||||
* Tuukka Pasanen <tuukka.pasanen@ilmi.fi> under sponsorship from
|
||||
* the FreeBSD Foundation
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "util.h"
|
||||
|
||||
#ifndef CLI__SPDXTOOL__SERIALIZE_H
|
||||
#define CLI__SPDXTOOL__SERIALIZE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void
|
||||
spdxtool_serialize_parm_and_string(pkgconf_buffer_t *buffer, char *parm, char *string, unsigned int level, bool comma);
|
||||
|
||||
void
|
||||
spdxtool_serialize_parm_and_char(pkgconf_buffer_t *buffer, char *parm, char ch, unsigned int level, bool comma);
|
||||
|
||||
void
|
||||
spdxtool_serialize_parm_and_int(pkgconf_buffer_t *buffer, char *parm, int integer, unsigned int level, bool comma);
|
||||
|
||||
void
|
||||
spdxtool_serialize_string(pkgconf_buffer_t *buffer, char *string, unsigned int level, bool comma);
|
||||
|
||||
void
|
||||
spdxtool_serialize_obj_start(pkgconf_buffer_t *buffer, unsigned int level);
|
||||
|
||||
void
|
||||
spdxtool_serialize_obj_end(pkgconf_buffer_t *buffer, unsigned int level, bool comma);
|
||||
|
||||
void
|
||||
spdxtool_serialize_array_start(pkgconf_buffer_t *buffer, unsigned int level);
|
||||
|
||||
void
|
||||
spdxtool_serialize_array_end(pkgconf_buffer_t *buffer, unsigned int level, bool comma);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@ -1,120 +0,0 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*
|
||||
* Copyright (c) 2025 The FreeBSD Foundation
|
||||
*
|
||||
* Portions of this software were developed by
|
||||
* Tuukka Pasanen <tuukka.pasanen@ilmi.fi> under sponsorship from
|
||||
* the FreeBSD Foundation
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "util.h"
|
||||
#include "serialize.h"
|
||||
#include "software.h"
|
||||
#include "core.h"
|
||||
|
||||
/*
|
||||
* !doc
|
||||
*
|
||||
* .. c:function:: spdxtool_simplelicensing_license_expression_t *spdxtool_simplelicensing_licenseExpression_new(pkgconf_client_t *client, char *license)
|
||||
*
|
||||
* Create new /SimpleLicensing/SimpleLicensingText struct
|
||||
*
|
||||
* :param pkgconf_client_t *client: The pkgconf client being accessed.
|
||||
* :param char *license: SPDX name of license
|
||||
* :return: NULL if some problem occurs and SimpleLicensingText struct if not
|
||||
*/
|
||||
spdxtool_simplelicensing_license_expression_t *
|
||||
spdxtool_simplelicensing_licenseExpression_new(pkgconf_client_t *client, char *license)
|
||||
{
|
||||
spdxtool_simplelicensing_license_expression_t *expression = NULL;
|
||||
|
||||
if(!client || !license)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
expression = calloc(1, sizeof(spdxtool_simplelicensing_license_expression_t));
|
||||
|
||||
if(!expression)
|
||||
{
|
||||
pkgconf_error(client, "Memory exhausted! Can't create simplelicense_expression struct!");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
expression->type = "simplelicensing_LicenseExpression";
|
||||
expression->license_expression = strdup(license);
|
||||
expression->spdx_id = spdxtool_util_get_spdx_id_string(client, expression->type, license);
|
||||
|
||||
return expression;
|
||||
}
|
||||
|
||||
/*
|
||||
* !doc
|
||||
*
|
||||
* .. c:function:: void spdxtool_simplelicensing_licenseExpression_free(spdxtool_simplelicensing_license_expression_t *expression_struct)
|
||||
*
|
||||
* Free /SimpleLicensing/SimpleLicensingText struct
|
||||
*
|
||||
* :param spdxtool_simplelicensing_license_expression_t *expression_struct: SimpleLicensingText struct to be freed.
|
||||
* :return: nothing
|
||||
*/
|
||||
void
|
||||
spdxtool_simplelicensing_licenseExpression_free(spdxtool_simplelicensing_license_expression_t *expression_struct)
|
||||
{
|
||||
if(!expression_struct)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if(expression_struct->spdx_id)
|
||||
{
|
||||
free(expression_struct->spdx_id);
|
||||
expression_struct->spdx_id = NULL;
|
||||
}
|
||||
|
||||
if(expression_struct->license_expression)
|
||||
{
|
||||
free(expression_struct->license_expression);
|
||||
expression_struct->license_expression = NULL;
|
||||
}
|
||||
|
||||
free(expression_struct);
|
||||
}
|
||||
|
||||
/*
|
||||
* !doc
|
||||
*
|
||||
* .. c:function:: void spdxtool_simplelicensing_licenseExpression_serialize(pkgconf_client_t *client, pkgconf_buffer_t *buffer, spdxtool_core_spdx_document_t *spdx_struct, bool last)
|
||||
*
|
||||
* Serialize /SimpleLicensing/SimpleLicensingText struct to JSON
|
||||
*
|
||||
* :param pkgconf_client_t *client: The pkgconf client being accessed.
|
||||
* :param pkgconf_buffer_t *buffer: Buffer where struct is serialized
|
||||
* :param spdxtool_core_spdx_document_t *spdx_struct: SimpleLicensingText struct to be serialized
|
||||
* :param bool last: Is this last CreationInfo struct or does it need comma at the end. True comma False not
|
||||
* :return: nothing
|
||||
*/
|
||||
void
|
||||
spdxtool_simplelicensing_licenseExpression_serialize(pkgconf_client_t *client, pkgconf_buffer_t *buffer, spdxtool_core_spdx_document_t *spdx_struct, bool last)
|
||||
{
|
||||
pkgconf_node_t *iter = NULL;
|
||||
|
||||
(void) last;
|
||||
|
||||
PKGCONF_FOREACH_LIST_ENTRY(spdx_struct->licenses.head, iter)
|
||||
{
|
||||
spdxtool_simplelicensing_license_expression_t *expression = iter->data;
|
||||
|
||||
spdxtool_serialize_obj_start(buffer, 2);
|
||||
spdxtool_serialize_parm_and_string(buffer, "@type", "simplelicensing_LicenseExpression", 3, true);
|
||||
spdxtool_serialize_parm_and_string(buffer, "creationInfo", spdx_struct->creation_info, 3, true);
|
||||
spdxtool_serialize_parm_and_string(buffer, "spdxId",expression->spdx_id, 3, true);
|
||||
spdxtool_serialize_parm_and_string(buffer, "simplelicensing_licenseExpression", expression->license_expression, 3, false);
|
||||
spdxtool_serialize_obj_end(buffer, 2, true);
|
||||
|
||||
spdxtool_core_spdx_document_add_element(client, spdx_struct, strdup(expression->spdx_id));
|
||||
}
|
||||
}
|
||||
@ -1,38 +0,0 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*
|
||||
* Copyright (c) 2025 The FreeBSD Foundation
|
||||
*
|
||||
* Portions of this software were developed by
|
||||
* Tuukka Pasanen <tuukka.pasanen@ilmi.fi> under sponsorship from
|
||||
* the FreeBSD Foundation
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "util.h"
|
||||
|
||||
#ifndef CLI__SPDXTOOL__SIMPLELICENSING_H
|
||||
#define CLI__SPDXTOOL__SIMPLELICENSING_H
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
spdxtool_simplelicensing_license_expression_t *
|
||||
spdxtool_simplelicensing_licenseExpression_new(pkgconf_client_t *client, char *license);
|
||||
|
||||
void
|
||||
spdxtool_simplelicensing_licenseExpression_free(spdxtool_simplelicensing_license_expression_t *expression_struct);
|
||||
|
||||
|
||||
void
|
||||
spdxtool_simplelicensing_licenseExpression_serialize(pkgconf_client_t *client, pkgconf_buffer_t *buffer, spdxtool_core_spdx_document_t *spdx_struct, bool last);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@ -1,241 +0,0 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*
|
||||
* Copyright (c) 2025 The FreeBSD Foundation
|
||||
*
|
||||
* Portions of this software were developed by
|
||||
* Tuukka Pasanen <tuukka.pasanen@ilmi.fi> under sponsorship from
|
||||
* the FreeBSD Foundation
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "util.h"
|
||||
#include "serialize.h"
|
||||
#include "software.h"
|
||||
#include "core.h"
|
||||
|
||||
/*
|
||||
* !doc
|
||||
*
|
||||
* .. c:function:: spdxtool_software_sbom_t *spdxtool_software_sbom_new(pkgconf_client_t *client, char *spdx_id, char *creation_id, char *sbom_type)
|
||||
*
|
||||
* Create new /Software/Sbom struct
|
||||
*
|
||||
* :param pkgconf_client_t *client: The pkgconf client being accessed.
|
||||
* :param char *spdx_id: spdxId for this SBOM element
|
||||
* :param char *creation_id: id for CreationInfo
|
||||
* :param char *sbom_type: Sbom types can be found SPDX documention
|
||||
* :return: NULL if some problem occurs and Sbom struct if not
|
||||
*/
|
||||
spdxtool_software_sbom_t *
|
||||
spdxtool_software_sbom_new(pkgconf_client_t *client, char *spdx_id, char *creation_id, char *sbom_type)
|
||||
{
|
||||
spdxtool_software_sbom_t *sbom_struct = NULL;
|
||||
|
||||
if(!client || !spdx_id || !creation_id || !sbom_type)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
(void)client;
|
||||
|
||||
sbom_struct = calloc(1, sizeof(spdxtool_software_sbom_t));
|
||||
|
||||
if(!sbom_struct)
|
||||
{
|
||||
pkgconf_error(client, "Memory exhausted! Can't create sbom struct.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sbom_struct->type="software_Sbom";
|
||||
sbom_struct->spdx_id = spdx_id;
|
||||
sbom_struct->creation_info = creation_id;
|
||||
sbom_struct->sbom_type = sbom_type;
|
||||
return sbom_struct;
|
||||
}
|
||||
|
||||
/*
|
||||
* !doc
|
||||
*
|
||||
* .. c:function:: void spdxtool_software_sbom_free(spdxtool_software_sbom_t *sbom_struct)
|
||||
*
|
||||
* Free /Software/Sbom struct
|
||||
*
|
||||
* :param spdxtool_software_sbom_t *sbom_struct: Sbom struct to be freed.
|
||||
* :return: nothing
|
||||
*/
|
||||
void
|
||||
spdxtool_software_sbom_free(spdxtool_software_sbom_t *sbom_struct)
|
||||
{
|
||||
|
||||
if(!sbom_struct)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if(sbom_struct->spdx_id)
|
||||
{
|
||||
free(sbom_struct->spdx_id);
|
||||
sbom_struct->spdx_id = NULL;
|
||||
}
|
||||
|
||||
if(sbom_struct->creation_info)
|
||||
{
|
||||
free(sbom_struct->creation_info);
|
||||
sbom_struct->creation_info = NULL;
|
||||
}
|
||||
|
||||
if(sbom_struct->sbom_type)
|
||||
{
|
||||
free(sbom_struct->sbom_type);
|
||||
sbom_struct->sbom_type = NULL;
|
||||
}
|
||||
|
||||
free(sbom_struct);
|
||||
}
|
||||
|
||||
/*
|
||||
* !doc
|
||||
*
|
||||
* .. c:function:: void spdxtool_software_sbom_serialize(pkgconf_client_t *client, pkgconf_buffer_t *buffer, spdxtool_software_sbom_t *sbom_struct, bool last)
|
||||
*
|
||||
* Serialize /Software/Sbom struct to JSON
|
||||
*
|
||||
* :param pkgconf_client_t *client: The pkgconf client being accessed.
|
||||
* :param pkgconf_buffer_t *buffer: Buffer where struct is serialized
|
||||
* :param spdxtool_software_sbom_t *sbom_struct: SimpleLicensingText struct to be serialized
|
||||
* :param bool last: Is this last CreationInfo struct or does it need comma at the end. True comma False not
|
||||
* :return: nothing
|
||||
*/
|
||||
void
|
||||
spdxtool_software_sbom_serialize(pkgconf_client_t *client, pkgconf_buffer_t *buffer, spdxtool_software_sbom_t *sbom_struct, bool last)
|
||||
{
|
||||
pkgconf_node_t *node = NULL;
|
||||
char *value;
|
||||
|
||||
spdxtool_serialize_obj_start(buffer, 2);
|
||||
spdxtool_serialize_parm_and_string(buffer, "@type", sbom_struct->type, 3, true);
|
||||
spdxtool_serialize_parm_and_string(buffer, "creationInfo", sbom_struct->creation_info, 3, true);
|
||||
spdxtool_serialize_parm_and_string(buffer, "spdxId", sbom_struct->spdx_id, 3, true);
|
||||
spdxtool_serialize_parm_and_char(buffer, "software_sbomType", '[', 3, false);
|
||||
spdxtool_serialize_string(buffer, sbom_struct->sbom_type, 4, false);
|
||||
spdxtool_serialize_array_end(buffer, 3, true);
|
||||
spdxtool_serialize_parm_and_char(buffer, "rootElement", '[', 3, false);
|
||||
spdxtool_serialize_string(buffer, pkgconf_tuple_find(client, &sbom_struct->rootElement->vars, "spdxId"), 4, false);
|
||||
spdxtool_serialize_array_end(buffer, 3, true);
|
||||
spdxtool_serialize_parm_and_char(buffer, "element", '[', 3, false);
|
||||
PKGCONF_FOREACH_LIST_ENTRY(sbom_struct->rootElement->required.head, node)
|
||||
{
|
||||
pkgconf_dependency_t *dep = node->data;
|
||||
pkgconf_pkg_t *match = dep->match;
|
||||
char *spdx_id_relation = NULL;
|
||||
char tmp_str[1024];
|
||||
|
||||
// New relation spdxId
|
||||
snprintf(tmp_str, 1024, "%s/dependsOn/%s", sbom_struct->rootElement->realname, match->realname);
|
||||
|
||||
spdx_id_relation = spdxtool_util_get_spdx_id_string(client, "Releationship", tmp_str);
|
||||
|
||||
spdxtool_serialize_string(buffer, spdx_id_relation, 4, true);
|
||||
|
||||
spdxtool_core_spdx_document_add_element(client, sbom_struct->spdx_document, strdup(spdx_id_relation));
|
||||
|
||||
free(spdx_id_relation);
|
||||
}
|
||||
|
||||
value = pkgconf_tuple_find(client, &sbom_struct->rootElement->vars, "hasDeclaredLicense");
|
||||
if (value != NULL)
|
||||
{
|
||||
spdxtool_serialize_string(buffer, value, 4, true);
|
||||
spdxtool_core_spdx_document_add_element(client, sbom_struct->spdx_document, strdup(value));
|
||||
}
|
||||
|
||||
value = pkgconf_tuple_find(client, &sbom_struct->rootElement->vars, "hasConcludedLicense");
|
||||
if (value != NULL)
|
||||
{
|
||||
spdxtool_serialize_string(buffer, value, 4, false);
|
||||
spdxtool_core_spdx_document_add_element(client, sbom_struct->spdx_document, strdup(value));
|
||||
}
|
||||
|
||||
spdxtool_serialize_array_end(buffer, 3, false);
|
||||
spdxtool_serialize_obj_end(buffer, 2, last);
|
||||
|
||||
spdxtool_software_package_serialize(client, buffer, sbom_struct->rootElement, false);
|
||||
}
|
||||
|
||||
/*
|
||||
* !doc
|
||||
*
|
||||
* .. c:function:: void spdxtool_software_sbom_serialize(pkgconf_client_t *client, pkgconf_buffer_t *buffer, spdxtool_software_sbom_t *sbom_struct, bool last)
|
||||
*
|
||||
* Serialize /Software/Package struct to JSON
|
||||
* This is bit special case as it takes pkgconf pkg struct and serializes that one
|
||||
* There is not new or free for this stype
|
||||
*
|
||||
* :param pkgconf_client_t *client: The pkgconf client being accessed.
|
||||
* :param pkgconf_buffer_t *buffer: Buffer where struct is serialized
|
||||
* :param pkgconf_pkg_t *pkg: Pkgconf package
|
||||
* :param bool last: Is this last CreationInfo struct or does it need comma at the end. True comma False not
|
||||
* :return: nothing
|
||||
*/
|
||||
void
|
||||
spdxtool_software_package_serialize(pkgconf_client_t *client, pkgconf_buffer_t *buffer, pkgconf_pkg_t *pkg, bool last)
|
||||
{
|
||||
spdxtool_core_relationship_t *relationship_struct = NULL;
|
||||
char *spdx_id_license = NULL, *tuple_license;
|
||||
pkgconf_node_t *node = NULL;
|
||||
|
||||
(void) last;
|
||||
|
||||
spdxtool_serialize_obj_start(buffer, 2);
|
||||
spdxtool_serialize_parm_and_string(buffer, "@type", "software_Package", 3, true);
|
||||
spdxtool_serialize_parm_and_string(buffer, "creationInfo", pkgconf_tuple_find(client, &pkg->vars, "creationInfo"), 3, true);
|
||||
spdxtool_serialize_parm_and_string(buffer, "spdxId", pkgconf_tuple_find(client, &pkg->vars, "spdxId"), 3, true);
|
||||
spdxtool_serialize_parm_and_string(buffer, "name", pkg->realname, 3, true);
|
||||
spdxtool_serialize_parm_and_char(buffer, "originatedBy", '[', 3, false);
|
||||
spdxtool_serialize_string(buffer, pkgconf_tuple_find(client, &pkg->vars, "agent"), 4, false);
|
||||
spdxtool_serialize_array_end(buffer, 3, true);
|
||||
spdxtool_serialize_parm_and_string(buffer, "software_copyrightText", "NOASSERTION", 3, true);
|
||||
spdxtool_serialize_parm_and_string(buffer, "software_packageVersion", pkg->version, 3, false);
|
||||
spdxtool_serialize_obj_end(buffer, 2, true);
|
||||
|
||||
/* These are must so add them right a way */
|
||||
spdx_id_license = spdxtool_util_get_spdx_id_string(client, "simplelicensing_LicenseExpression", pkg->license);
|
||||
|
||||
tuple_license = pkgconf_tuple_find(client, &pkg->vars, "hasDeclaredLicense");
|
||||
if (tuple_license != NULL)
|
||||
{
|
||||
relationship_struct = spdxtool_core_relationship_new(client, strdup(pkgconf_tuple_find(client, &pkg->vars, "creationInfo")), strdup(tuple_license), strdup(pkgconf_tuple_find(client, &pkg->vars, "spdxId")), strdup(spdx_id_license), strdup("hasDeclaredLicense"));
|
||||
spdxtool_core_relationship_serialize(client, buffer, relationship_struct, true);
|
||||
spdxtool_core_relationship_free(relationship_struct);
|
||||
}
|
||||
|
||||
tuple_license = pkgconf_tuple_find(client, &pkg->vars, "hasConcludedLicense");
|
||||
if (tuple_license != NULL)
|
||||
{
|
||||
relationship_struct = spdxtool_core_relationship_new(client, strdup(pkgconf_tuple_find(client, &pkg->vars, "creationInfo")), strdup(tuple_license), strdup(pkgconf_tuple_find(client, &pkg->vars, "spdxId")), spdx_id_license, strdup("hasConcludedLicense"));
|
||||
spdxtool_core_relationship_serialize(client, buffer, relationship_struct, true);
|
||||
spdxtool_core_relationship_free(relationship_struct);
|
||||
}
|
||||
|
||||
PKGCONF_FOREACH_LIST_ENTRY(pkg->required.head, node)
|
||||
{
|
||||
pkgconf_dependency_t *dep = node->data;
|
||||
pkgconf_pkg_t *match = dep->match;
|
||||
char *spdx_id_relation = NULL;
|
||||
char *spdx_id_package = NULL;
|
||||
char tmp_str[1024];
|
||||
|
||||
// New relation spdxId
|
||||
snprintf(tmp_str, 1024, "%s/dependsOn/%s", pkg->realname, match->realname);
|
||||
spdx_id_relation = spdxtool_util_get_spdx_id_string(client, "Releationship", tmp_str);
|
||||
|
||||
// new package spdxId which will be hopefully come later on
|
||||
spdx_id_package = spdxtool_util_get_spdx_id_string(client, "Package", match->realname);
|
||||
|
||||
relationship_struct = spdxtool_core_relationship_new(client, strdup(pkgconf_tuple_find(client, &pkg->vars, "creationInfo")), spdx_id_relation, strdup(pkgconf_tuple_find(client, &pkg->vars, "spdxId")), spdx_id_package, strdup("dependsOn"));
|
||||
spdxtool_core_relationship_serialize(client, buffer, relationship_struct, true);
|
||||
spdxtool_core_relationship_free(relationship_struct);
|
||||
}
|
||||
}
|
||||
@ -1,37 +0,0 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*
|
||||
* Copyright (c) 2025 The FreeBSD Foundation
|
||||
*
|
||||
* Portions of this software were developed by
|
||||
* Tuukka Pasanen <tuukka.pasanen@ilmi.fi> under sponsorship from
|
||||
* the FreeBSD Foundation
|
||||
*/
|
||||
|
||||
#ifndef CLI__SPDXTOOL_SOFTWARE_H
|
||||
#define CLI__SPDXTOOL_SOFTWARE_H
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "util.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
spdxtool_software_sbom_t *
|
||||
spdxtool_software_sbom_new(pkgconf_client_t *client, char *spdx_id, char *creation_id, char *sbom_type);
|
||||
|
||||
void
|
||||
spdxtool_software_sbom_free(spdxtool_software_sbom_t *sbom_struct);
|
||||
|
||||
void
|
||||
spdxtool_software_sbom_serialize(pkgconf_client_t *client, pkgconf_buffer_t *buffer, spdxtool_software_sbom_t *sbom_struct, bool last);
|
||||
|
||||
void
|
||||
spdxtool_software_package_serialize(pkgconf_client_t *client, pkgconf_buffer_t *buffer, pkgconf_pkg_t *pkg, bool last);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@ -1,255 +0,0 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*
|
||||
* Copyright (c) 2025 The FreeBSD Foundation
|
||||
*
|
||||
* Portions of this software were developed by
|
||||
* Tuukka Pasanen <tuukka.pasanen@ilmi.fi> under sponsorship from
|
||||
* the FreeBSD Foundation
|
||||
*/
|
||||
|
||||
#include <libpkgconf/libpkgconf.h>
|
||||
#include <libpkgconf/stdinc.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <ctype.h>
|
||||
|
||||
/*
|
||||
* !doc
|
||||
*
|
||||
* .. c:function:: void spdxtool_util_set_key(pkgconf_client_t *client, const char *key, const char *key_value, const char *key_default)
|
||||
*
|
||||
* Set key wit default value. Default value is used if key is NULL
|
||||
*
|
||||
* :param pkgconf_client_t* client: The pkgconf client being accessed.
|
||||
* :param const char *key: Key to be preserved
|
||||
* :param const char *key_value: Value for key
|
||||
* :param const char *key_default: Default value if key_value is NULL
|
||||
* :return: nothing
|
||||
*/
|
||||
void
|
||||
spdxtool_util_set_key(pkgconf_client_t *client, const char *key, const char *key_value, const char *key_default)
|
||||
{
|
||||
PKGCONF_TRACE(client, "set uri_root to: %s", key_value != NULL ? key_value : key_default);
|
||||
pkgconf_tuple_add_global(client, key, key_value != NULL ? key_value : key_default);
|
||||
}
|
||||
|
||||
/*
|
||||
* !doc
|
||||
*
|
||||
* .. c:function:: void spdxtool_util_set_uri_root(pkgconf_client_t *client, const char *uri_root)
|
||||
*
|
||||
* Set URI/URL root for spdxId. Type for this is 'xsd:anyURI' which means
|
||||
* it can they may be absolute or relative.
|
||||
*
|
||||
* :param pkgconf_client_t* client: The pkgconf client being accessed.
|
||||
* :param const char *uri_root: URI root.
|
||||
* :return: nothing
|
||||
*/
|
||||
void
|
||||
spdxtool_util_set_uri_root(pkgconf_client_t *client, const char *uri_root)
|
||||
{
|
||||
spdxtool_util_set_key(client, "spdx_uri_root", uri_root, "https://github.com/pkgconf/pkgconf");
|
||||
}
|
||||
|
||||
/*
|
||||
* !doc
|
||||
*
|
||||
* .. c:function:: const char *spdxtool_util_get_uri_root(pkgconf_client_t *client)
|
||||
*
|
||||
* Get current URI
|
||||
*
|
||||
* :param pkgconf_client_t* client: The pkgconf client being accessed.
|
||||
* :return: URI or NULL
|
||||
*/
|
||||
const char *
|
||||
spdxtool_util_get_uri_root(pkgconf_client_t *client)
|
||||
{
|
||||
return pkgconf_tuple_find_global(client, "spdx_uri_root");
|
||||
}
|
||||
|
||||
/*
|
||||
* !doc
|
||||
*
|
||||
* .. c:function:: void spdxtool_util_set_spdx_version(pkgconf_client_t *client, const char *spdx_version)
|
||||
*
|
||||
* Set current SPDX SBOM Spec version. If not set it's 3.0.1
|
||||
*
|
||||
* :param pkgconf_client_t* client: The pkgconf client being accessed.
|
||||
* :param char* spdx_version: SPDX specification version.
|
||||
* :return: nothing
|
||||
*/
|
||||
void
|
||||
spdxtool_util_set_spdx_version(pkgconf_client_t *client, const char *spdx_version)
|
||||
{
|
||||
spdxtool_util_set_key(client, "spdx_version", spdx_version, "3.0.1");
|
||||
}
|
||||
|
||||
/*
|
||||
* !doc
|
||||
*
|
||||
* .. c:function:: const char *spdxtool_util_get_spdx_version(pkgconf_client_t *client)
|
||||
*
|
||||
* Get SPDX SBOM specification version in use
|
||||
*
|
||||
* :param pkgconf_client_t* client: The pkgconf client being accessed.
|
||||
* :return: Spec version
|
||||
*/
|
||||
const char *
|
||||
spdxtool_util_get_spdx_version(pkgconf_client_t *client)
|
||||
{
|
||||
return pkgconf_tuple_find_global(client, "spdx_version");
|
||||
}
|
||||
|
||||
/*
|
||||
* !doc
|
||||
*
|
||||
* .. c:function:: void spdxtool_util_set_spdx_license(pkgconf_client_t *client, const char *spdx_license)
|
||||
*
|
||||
* Under which license SBOM is released. License string should be in
|
||||
* SPDX style. Something like: FreeBSD-DOC, CC0-1.0 or MIT
|
||||
*
|
||||
* :param pkgconf_client_t* client: The pkgconf client being accessed.
|
||||
* :param const char *spdx_license: SPDX compatible license
|
||||
* :return: nothing
|
||||
*/
|
||||
void
|
||||
spdxtool_util_set_spdx_license(pkgconf_client_t *client, const char *spdx_license)
|
||||
{
|
||||
spdxtool_util_set_key(client, "spdx_license", spdx_license, "CC0-1.0");
|
||||
}
|
||||
|
||||
/*
|
||||
* !doc
|
||||
*
|
||||
* .. c:function:: const char *spdxtool_util_get_spdx_license(pkgconf_client_t *client)
|
||||
*
|
||||
* Get license which SBOM is release in
|
||||
*
|
||||
* :param pkgconf_client_t* client: The pkgconf client being accessed.
|
||||
* :return: SPDX license
|
||||
*/
|
||||
const char *
|
||||
spdxtool_util_get_spdx_license(pkgconf_client_t *client)
|
||||
{
|
||||
return pkgconf_tuple_find_global(client, "spdx_license");
|
||||
}
|
||||
|
||||
static size_t last_id = 0;
|
||||
|
||||
/*
|
||||
* !doc
|
||||
*
|
||||
* .. c:function:: char *spdxtool_util_get_spdx_id_int(pkgconf_client_t *client, char *part)
|
||||
*
|
||||
* Get spdxId with current URI.
|
||||
* URI is lookg like https://test/part/1
|
||||
*
|
||||
* :param pkgconf_client_t* client: The pkgconf client being accessed.
|
||||
* :param char *part: Addition subdir part before number
|
||||
* :return: URI
|
||||
*/
|
||||
char *
|
||||
spdxtool_util_get_spdx_id_int(pkgconf_client_t *client, char *part)
|
||||
{
|
||||
const char *global_xsd_any_uri = spdxtool_util_get_uri_root(client);
|
||||
pkgconf_buffer_t current_uri = PKGCONF_BUFFER_INITIALIZER;
|
||||
|
||||
pkgconf_buffer_join(¤t_uri, '/', global_xsd_any_uri, part, NULL);
|
||||
pkgconf_buffer_append_fmt(¤t_uri, "/" SIZE_FMT_SPECIFIER, ++last_id);
|
||||
|
||||
return pkgconf_buffer_freeze(¤t_uri);
|
||||
}
|
||||
|
||||
/*
|
||||
* !doc
|
||||
*
|
||||
* .. c:function:: char *spdxtool_util_get_spdx_id_string(pkgconf_client_t *client, char *part, char *string_id)
|
||||
*
|
||||
* Get string id URI
|
||||
* looks something like: https://test/part/string_id
|
||||
*
|
||||
* :param pkgconf_client_t* client: The pkgconf client being accessed.
|
||||
* :param char* part: subdir part of URI.
|
||||
* :param char* string_id: String ID.
|
||||
* :return: URI
|
||||
*/
|
||||
char *
|
||||
spdxtool_util_get_spdx_id_string(pkgconf_client_t *client, char *part, char *string_id)
|
||||
{
|
||||
const char *global_xsd_any_uri = spdxtool_util_get_uri_root(client);
|
||||
pkgconf_buffer_t current_uri = PKGCONF_BUFFER_INITIALIZER;
|
||||
|
||||
pkgconf_buffer_join(¤t_uri, '/', global_xsd_any_uri, part, string_id, NULL);
|
||||
|
||||
return pkgconf_buffer_freeze(¤t_uri);
|
||||
}
|
||||
|
||||
/*
|
||||
* !doc
|
||||
*
|
||||
* .. c:function:: char *spdxtool_util_get_iso8601_time(time_t *wanted_time)
|
||||
*
|
||||
* Get ISO8601 time string
|
||||
*
|
||||
* :param time_t *wanted_time: Time to be converted
|
||||
* :return: Time string in ISO8601 format
|
||||
*/
|
||||
char *
|
||||
spdxtool_util_get_iso8601_time(time_t *wanted_time)
|
||||
{
|
||||
char buf[PKGCONF_ITEM_SIZE];
|
||||
struct tm *tm_info = gmtime(wanted_time);
|
||||
|
||||
if(!wanted_time)
|
||||
return NULL;
|
||||
|
||||
/* ISO8601 time with Z at the end */
|
||||
strftime(buf, sizeof buf, "%Y-%m-%dT%H:%M:%SZ", tm_info);
|
||||
return strdup(buf);
|
||||
}
|
||||
|
||||
/*
|
||||
* !doc
|
||||
*
|
||||
* .. c:function:: char *spdxtool_util_get_current_iso8601_time()
|
||||
*
|
||||
* Get ISO8601 current timestamp
|
||||
*
|
||||
* :return: Time string in ISO8601 format
|
||||
*/
|
||||
char *
|
||||
spdxtool_util_get_current_iso8601_time()
|
||||
{
|
||||
time_t now;
|
||||
time(&now);
|
||||
return spdxtool_util_get_iso8601_time(&now);
|
||||
}
|
||||
|
||||
/*
|
||||
* !doc
|
||||
*
|
||||
* .. c:function:: char *spdxtool_util_string_correction(char *str)
|
||||
*
|
||||
* Lowercase string and change spaces to '_'
|
||||
*
|
||||
* :param char *str: String to be converted
|
||||
* :return: Converted string
|
||||
*/
|
||||
char *
|
||||
spdxtool_util_string_correction(char *str)
|
||||
{
|
||||
char *ptr = str;
|
||||
/* Lowecase string and make spaces '_' */
|
||||
for ( ; *ptr; ++ptr)
|
||||
{
|
||||
*ptr = tolower(*ptr);
|
||||
if(isspace((unsigned char) *ptr))
|
||||
{
|
||||
*ptr = '_';
|
||||
}
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
@ -1,123 +0,0 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*
|
||||
* Copyright (c) 2025 The FreeBSD Foundation
|
||||
*
|
||||
* Portions of this software were developed by
|
||||
* Tuukka Pasanen <tuukka.pasanen@ilmi.fi> under sponsorship from
|
||||
* the FreeBSD Foundation
|
||||
*/
|
||||
|
||||
#ifndef CLI__SPDXTOOL__UTIL_H
|
||||
#define CLI__SPDXTOOL__UTIL_H
|
||||
|
||||
#include <libpkgconf/libpkgconf.h>
|
||||
#include <time.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct spdxtool_core_agent_
|
||||
{
|
||||
int refcount;
|
||||
char *spdx_id;
|
||||
char *type;
|
||||
char *creation_info;
|
||||
char *name;
|
||||
} spdxtool_core_agent_t;
|
||||
|
||||
typedef struct spdxtool_core_creation_info_
|
||||
{
|
||||
int refcount;
|
||||
char *id;
|
||||
char *type;
|
||||
char *created;
|
||||
char *created_by;
|
||||
char *created_using;
|
||||
const char *spec_version;
|
||||
} spdxtool_core_creation_info_t;
|
||||
|
||||
typedef struct spdxtool_core_spdx_document
|
||||
{
|
||||
int refcount;
|
||||
char *type;
|
||||
char *spdx_id;
|
||||
char *creation_info;
|
||||
char *agent;
|
||||
pkgconf_list_t licenses;
|
||||
pkgconf_list_t element;
|
||||
pkgconf_list_t rootElement;
|
||||
} spdxtool_core_spdx_document_t;
|
||||
|
||||
typedef struct spdxtool_software_sbom_
|
||||
{
|
||||
int refcount;
|
||||
char *spdx_id;
|
||||
char *type;
|
||||
char *creation_info;
|
||||
char *sbom_type;
|
||||
spdxtool_core_spdx_document_t *spdx_document;
|
||||
pkgconf_pkg_t *rootElement;
|
||||
} spdxtool_software_sbom_t;
|
||||
|
||||
typedef struct spdxtool_simplelicensing_license_expression_
|
||||
{
|
||||
int refcount;
|
||||
char *type;
|
||||
char *spdx_id;
|
||||
char *license_expression;
|
||||
} spdxtool_simplelicensing_license_expression_t;
|
||||
|
||||
typedef struct spdxtool_core_relationship_
|
||||
{
|
||||
int refcount;
|
||||
char *type;
|
||||
char *spdx_id;
|
||||
char *creation_info;
|
||||
char *from;
|
||||
char *to;
|
||||
char *relationship_type;
|
||||
} spdxtool_core_relationship_t;
|
||||
|
||||
void
|
||||
spdxtool_util_set_key(pkgconf_client_t *client, const char *key, const char *key_value, const char *key_default);
|
||||
|
||||
void
|
||||
spdxtool_util_set_uri_root(pkgconf_client_t *client, const char *uri_root);
|
||||
|
||||
const char *
|
||||
spdxtool_util_get_uri_root(pkgconf_client_t *client);
|
||||
|
||||
void
|
||||
spdxtool_util_set_spdx_version(pkgconf_client_t *client, const char *spdx_version);
|
||||
|
||||
const char *
|
||||
spdxtool_util_get_spdx_version(pkgconf_client_t *client);
|
||||
|
||||
void
|
||||
spdxtool_util_set_spdx_license(pkgconf_client_t *client, const char *spdx_license);
|
||||
|
||||
const char *
|
||||
spdxtool_util_get_spdx_license(pkgconf_client_t *client);
|
||||
|
||||
char *
|
||||
spdxtool_util_get_spdx_id_int(pkgconf_client_t *client, char *part);
|
||||
|
||||
char *
|
||||
spdxtool_util_get_spdx_id_string(pkgconf_client_t *client, char *part, char *string_id);
|
||||
|
||||
char *
|
||||
spdxtool_util_get_iso8601_time(time_t *wanted_time);
|
||||
|
||||
char *
|
||||
spdxtool_util_get_current_iso8601_time();
|
||||
|
||||
char *
|
||||
spdxtool_util_string_correction(char *str);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
29
configure.ac
29
configure.ac
@ -12,7 +12,7 @@ dnl implied. In no event shall the authors be liable for any damages arising
|
||||
dnl from the use of this software.
|
||||
|
||||
AC_PREREQ([2.71])
|
||||
AC_INIT([pkgconf],[2.5.1],[https://github.com/pkgconf/pkgconf/issues/new])
|
||||
AC_INIT([pkgconf],[2.1.0],[https://github.com/pkgconf/pkgconf/issues/new])
|
||||
AC_CONFIG_SRCDIR([cli/main.c])
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
AX_CHECK_COMPILE_FLAG([-Wall], [CFLAGS="$CFLAGS -Wall"])
|
||||
@ -23,9 +23,7 @@ AX_CHECK_COMPILE_FLAG([-std=gnu99], [CFLAGS="$CFLAGS -std=gnu99"], [
|
||||
])
|
||||
AC_CONFIG_HEADERS([libpkgconf/config.h])
|
||||
AC_CHECK_DECLS([strlcpy, strlcat, strndup], [], [], [[#include <string.h>]])
|
||||
AC_CHECK_DECLS([pledge, unveil], [], [], [[#include <unistd.h>]])
|
||||
AC_CHECK_DECLS([readlinkat], [], [], [[#include <unistd.h>]])
|
||||
AC_CHECK_DECLS([reallocarray], [], [], [[#include <stdlib.h>]])
|
||||
AC_CHECK_DECLS([reallocarray])
|
||||
AC_CHECK_HEADERS([sys/stat.h])
|
||||
AM_INIT_AUTOMAKE([foreign dist-xz subdir-objects])
|
||||
AM_SILENT_RULES([yes])
|
||||
@ -48,21 +46,13 @@ AC_SUBST([PKG_DEFAULT_PATH])
|
||||
|
||||
AC_ARG_WITH([system-libdir],[AS_HELP_STRING([--with-system-libdir],[specify the
|
||||
system library directory (default LIBDIR)])],
|
||||
[SYSTEM_LIBDIR="$withval"], [
|
||||
AC_MSG_WARN([--with-system-libdir is not set, assuming ${libdir}])
|
||||
AC_MSG_WARN([It is important that this value be properly set for correct behavior!])
|
||||
SYSTEM_LIBDIR="${libdir}"
|
||||
])
|
||||
SYSTEM_LIBDIR="$withval", SYSTEM_LIBDIR="${libdir}")
|
||||
|
||||
AC_SUBST([SYSTEM_LIBDIR])
|
||||
|
||||
AC_ARG_WITH([system-includedir],[AS_HELP_STRING([--with-system-includedir],[specify the
|
||||
system include directory (default INCLUDEDIR)])],
|
||||
[SYSTEM_INCLUDEDIR="$withval"], [
|
||||
AC_MSG_WARN([--with-system-includedir is not set, assuming ${includedir}])
|
||||
AC_MSG_WARN([It is important that this value be properly set for correct behavior!])
|
||||
SYSTEM_INCLUDEDIR="${includedir}"
|
||||
])
|
||||
SYSTEM_INCLUDEDIR="$withval", SYSTEM_INCLUDEDIR="${includedir}")
|
||||
|
||||
AC_SUBST([SYSTEM_INCLUDEDIR])
|
||||
|
||||
@ -73,14 +63,3 @@ AC_PROG_LN_S
|
||||
|
||||
AC_CONFIG_FILES([Makefile Kyuafile libpkgconf.pc tests/Kyuafile tests/test_env.sh])
|
||||
AC_OUTPUT
|
||||
|
||||
cat << EOF
|
||||
Build configuration:
|
||||
|
||||
Default personality search paths: ${PERSONALITY_PATH}
|
||||
Default package search paths: ${PKG_DEFAULT_PATH}
|
||||
Default include search paths: ${SYSTEM_INCLUDEDIR}
|
||||
Default library search paths: ${SYSTEM_LIBDIR}
|
||||
|
||||
Incorrect paths may result in unexpected behavior from pkgconf.
|
||||
EOF
|
||||
|
||||
@ -51,7 +51,7 @@ The `dependency` module provides support for building `dependency lists` (the ba
|
||||
|
||||
.. 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.
|
||||
:return: nothing
|
||||
|
||||
@ -7,8 +7,6 @@ Name: libpkgconf
|
||||
Description: a library for accessing and manipulating development framework configuration
|
||||
URL: https://gitea.treehouse.systems/ariadne/pkgconf
|
||||
License: ISC
|
||||
License.file: https://raw.githubusercontent.com/pkgconf/pkgconf/refs/heads/master/COPYING
|
||||
Source: https://github.com/pkgconf/pkgconf
|
||||
Version: @PACKAGE_VERSION@
|
||||
CFlags: -I${includedir}/pkgconf
|
||||
Libs: -L${libdir} -lpkgconf
|
||||
|
||||
@ -59,10 +59,7 @@ pkgconf_argv_free(char **argv)
|
||||
int
|
||||
pkgconf_argv_split(const char *src, int *argc, char ***argv)
|
||||
{
|
||||
char *buf = calloc(1, strlen(src) + 1);
|
||||
if (buf == NULL)
|
||||
return -1;
|
||||
|
||||
char *buf = malloc(strlen(src) + 1);
|
||||
const char *src_iter;
|
||||
char *dst_iter;
|
||||
int argc_count = 0;
|
||||
@ -73,13 +70,9 @@ pkgconf_argv_split(const char *src, int *argc, char ***argv)
|
||||
src_iter = src;
|
||||
dst_iter = buf;
|
||||
|
||||
*argv = calloc(argv_size, sizeof (void *));
|
||||
if (*argv == NULL)
|
||||
{
|
||||
free(buf);
|
||||
return -1;
|
||||
}
|
||||
memset(buf, 0, strlen(src) + 1);
|
||||
|
||||
*argv = calloc(argv_size, sizeof (void *));
|
||||
(*argv)[argc_count] = dst_iter;
|
||||
|
||||
while (*src_iter)
|
||||
|
||||
@ -17,7 +17,11 @@
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <libpkgconf/stdinc.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <libpkgconf/bsdstubs.h>
|
||||
#include <libpkgconf/config.h>
|
||||
|
||||
@ -117,28 +121,6 @@ strndup(const char *src, size_t len)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !HAVE_DECL_PLEDGE
|
||||
static inline int
|
||||
pledge(const char *promises, const char *execpromises)
|
||||
{
|
||||
(void) promises;
|
||||
(void) execpromises;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !HAVE_DECL_UNVEIL
|
||||
static inline int
|
||||
unveil(const char *path, const char *permissions)
|
||||
{
|
||||
(void) path;
|
||||
(void) permissions;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
size_t
|
||||
pkgconf_strlcpy(char *dst, const char *src, size_t siz)
|
||||
{
|
||||
@ -176,15 +158,3 @@ pkgconf_reallocarray(void *ptr, size_t m, size_t n)
|
||||
{
|
||||
return reallocarray(ptr, m, n);
|
||||
}
|
||||
|
||||
int
|
||||
pkgconf_pledge(const char *promises, const char *execpromises)
|
||||
{
|
||||
return pledge(promises, execpromises);
|
||||
}
|
||||
|
||||
int
|
||||
pkgconf_unveil(const char *path, const char *permissions)
|
||||
{
|
||||
return unveil(path, permissions);
|
||||
}
|
||||
|
||||
@ -26,8 +26,6 @@ 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 char *pkgconf_strndup(const char *src, size_t len);
|
||||
PKGCONF_API extern void *pkgconf_reallocarray(void *ptr, size_t m, size_t n);
|
||||
PKGCONF_API extern int pkgconf_pledge(const char *promises, const char *execpromises);
|
||||
PKGCONF_API extern int pkgconf_unveil(const char *path, const char *permissions);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@ -1,246 +0,0 @@
|
||||
/*
|
||||
* buffer.c
|
||||
* dynamically-managed buffers
|
||||
*
|
||||
* Copyright (c) 2024 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/stdinc.h>
|
||||
#include <libpkgconf/libpkgconf.h>
|
||||
|
||||
/*
|
||||
* !doc
|
||||
*
|
||||
* libpkgconf `buffer` module
|
||||
* ==========================
|
||||
*
|
||||
* The libpkgconf `buffer` module contains the functions related to managing
|
||||
* dynamically-allocated buffers.
|
||||
*/
|
||||
|
||||
static inline size_t
|
||||
target_allocation_size(size_t target_size)
|
||||
{
|
||||
return 4096 + (4096 * (target_size / 4096));
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void
|
||||
buffer_debug(pkgconf_buffer_t *buffer)
|
||||
{
|
||||
for (char *c = buffer->base; c <= buffer->end; c++) {
|
||||
fprintf(stderr, "%02x ", (unsigned char) *c);
|
||||
}
|
||||
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
pkgconf_buffer_append(pkgconf_buffer_t *buffer, const char *text)
|
||||
{
|
||||
size_t needed = strlen(text) + 1;
|
||||
size_t newsize = pkgconf_buffer_len(buffer) + needed;
|
||||
|
||||
char *newbase = realloc(buffer->base, target_allocation_size(newsize));
|
||||
|
||||
/* XXX: silently failing here is antisocial */
|
||||
if (newbase == NULL)
|
||||
return;
|
||||
|
||||
char *newend = newbase + pkgconf_buffer_len(buffer);
|
||||
pkgconf_strlcpy(newend, text, needed);
|
||||
|
||||
buffer->base = newbase;
|
||||
buffer->end = newend + (needed - 1);
|
||||
|
||||
*buffer->end = '\0';
|
||||
}
|
||||
|
||||
void
|
||||
pkgconf_buffer_append_vfmt(pkgconf_buffer_t *buffer, const char *fmt, va_list src_va)
|
||||
{
|
||||
va_list va;
|
||||
char *buf;
|
||||
size_t needed;
|
||||
|
||||
va_copy(va, src_va);
|
||||
needed = vsnprintf(NULL, 0, fmt, va) + 1;
|
||||
va_end(va);
|
||||
|
||||
buf = malloc(needed);
|
||||
|
||||
va_copy(va, src_va);
|
||||
vsnprintf(buf, needed, fmt, va);
|
||||
va_end(va);
|
||||
|
||||
pkgconf_buffer_append(buffer, buf);
|
||||
|
||||
free(buf);
|
||||
}
|
||||
|
||||
void
|
||||
pkgconf_buffer_append_fmt(pkgconf_buffer_t *buffer, const char *fmt, ...)
|
||||
{
|
||||
va_list va;
|
||||
|
||||
va_start(va, fmt);
|
||||
pkgconf_buffer_append_vfmt(buffer, fmt, va);
|
||||
va_end(va);
|
||||
}
|
||||
|
||||
void
|
||||
pkgconf_buffer_push_byte(pkgconf_buffer_t *buffer, char byte)
|
||||
{
|
||||
size_t newsize = pkgconf_buffer_len(buffer) + 1;
|
||||
char *newbase = realloc(buffer->base, target_allocation_size(newsize));
|
||||
|
||||
/* XXX: silently failing here remains antisocial */
|
||||
if (newbase == NULL)
|
||||
return;
|
||||
|
||||
char *newend = newbase + newsize;
|
||||
*(newend - 1) = byte;
|
||||
*newend = '\0';
|
||||
|
||||
buffer->base = newbase;
|
||||
buffer->end = newend;
|
||||
}
|
||||
|
||||
void
|
||||
pkgconf_buffer_trim_byte(pkgconf_buffer_t *buffer)
|
||||
{
|
||||
size_t newsize = pkgconf_buffer_len(buffer) - 1;
|
||||
char *newbase = realloc(buffer->base, target_allocation_size(newsize));
|
||||
|
||||
buffer->base = newbase;
|
||||
buffer->end = newbase + newsize;
|
||||
*(buffer->end) = '\0';
|
||||
}
|
||||
|
||||
void
|
||||
pkgconf_buffer_finalize(pkgconf_buffer_t *buffer)
|
||||
{
|
||||
free(buffer->base);
|
||||
buffer->base = buffer->end = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
pkgconf_buffer_fputs(pkgconf_buffer_t *buffer, FILE *out)
|
||||
{
|
||||
if (pkgconf_buffer_len(buffer) != 0)
|
||||
fputs(pkgconf_buffer_str(buffer), out);
|
||||
|
||||
fputc('\n', out);
|
||||
}
|
||||
|
||||
void
|
||||
pkgconf_buffer_vjoin(pkgconf_buffer_t *buffer, char delim, va_list src_va)
|
||||
{
|
||||
va_list va;
|
||||
const char *arg;
|
||||
|
||||
va_copy(va, src_va);
|
||||
|
||||
while ((arg = va_arg(va, const char *)) != NULL)
|
||||
{
|
||||
if (pkgconf_buffer_str(buffer) != NULL)
|
||||
pkgconf_buffer_push_byte(buffer, delim);
|
||||
|
||||
pkgconf_buffer_append(buffer, arg);
|
||||
}
|
||||
|
||||
va_end(va);
|
||||
}
|
||||
|
||||
// NOTE: due to C's rules regarding promotion in variable args and permissible variables, delim must
|
||||
// be an int here.
|
||||
void
|
||||
pkgconf_buffer_join(pkgconf_buffer_t *buffer, int delim, ...)
|
||||
{
|
||||
va_list va;
|
||||
|
||||
va_start(va, delim);
|
||||
pkgconf_buffer_vjoin(buffer, (char)delim, va);
|
||||
va_end(va);
|
||||
}
|
||||
|
||||
bool
|
||||
pkgconf_buffer_contains(const pkgconf_buffer_t *haystack, const pkgconf_buffer_t *needle)
|
||||
{
|
||||
const char *haystack_str = pkgconf_buffer_str_or_empty(haystack);
|
||||
const char *needle_str = pkgconf_buffer_str_or_empty(needle);
|
||||
|
||||
return strstr(haystack_str, needle_str) != NULL;
|
||||
}
|
||||
|
||||
bool
|
||||
pkgconf_buffer_contains_byte(const pkgconf_buffer_t *haystack, char needle)
|
||||
{
|
||||
const char *haystack_str = pkgconf_buffer_str_or_empty(haystack);
|
||||
return strchr(haystack_str, needle) != NULL;
|
||||
}
|
||||
|
||||
bool
|
||||
pkgconf_buffer_match(const pkgconf_buffer_t *haystack, const pkgconf_buffer_t *needle)
|
||||
{
|
||||
const char *haystack_str = pkgconf_buffer_str_or_empty(haystack);
|
||||
const char *needle_str = pkgconf_buffer_str_or_empty(needle);
|
||||
|
||||
if (pkgconf_buffer_len(haystack) != pkgconf_buffer_len(needle))
|
||||
return false;
|
||||
|
||||
return memcmp(haystack_str, needle_str, pkgconf_buffer_len(haystack)) == 0;
|
||||
}
|
||||
|
||||
void
|
||||
pkgconf_buffer_subst(pkgconf_buffer_t *dest, const pkgconf_buffer_t *src, const char *pattern, const char *value)
|
||||
{
|
||||
const char *iter = src->base;
|
||||
size_t pattern_len = strlen(pattern);
|
||||
|
||||
if (!pkgconf_buffer_len(src))
|
||||
return;
|
||||
|
||||
if (!pattern_len)
|
||||
{
|
||||
pkgconf_buffer_append(dest, pkgconf_buffer_str(src));
|
||||
return;
|
||||
}
|
||||
|
||||
while (iter < src->end)
|
||||
{
|
||||
if ((size_t)(src->end - iter) >= pattern_len && !memcmp(iter, pattern, pattern_len))
|
||||
{
|
||||
pkgconf_buffer_append(dest, value);
|
||||
iter += pattern_len;
|
||||
}
|
||||
else
|
||||
pkgconf_buffer_push_byte(dest, *iter++);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
pkgconf_buffer_escape(pkgconf_buffer_t *dest, const pkgconf_buffer_t *src, const pkgconf_span_t *spans, size_t nspans)
|
||||
{
|
||||
const char *p = pkgconf_buffer_str(src);
|
||||
|
||||
if (!pkgconf_buffer_len(src))
|
||||
return;
|
||||
|
||||
for (; *p; p++)
|
||||
{
|
||||
if (pkgconf_span_contains((unsigned char) *p, spans, nspans))
|
||||
pkgconf_buffer_push_byte(dest, '\\');
|
||||
|
||||
pkgconf_buffer_push_byte(dest, *p);
|
||||
}
|
||||
}
|
||||
@ -60,22 +60,17 @@ trace_path_list(const pkgconf_client_t *client, const char *desc, pkgconf_list_t
|
||||
void
|
||||
pkgconf_client_dir_list_build(pkgconf_client_t *client, const pkgconf_cross_personality_t *personality)
|
||||
{
|
||||
pkgconf_path_build_from_environ(client, "PKG_CONFIG_PATH", NULL, &client->dir_list, true);
|
||||
pkgconf_path_build_from_environ("PKG_CONFIG_PATH", NULL, &client->dir_list, true);
|
||||
|
||||
if (!(client->flags & PKGCONF_PKG_PKGF_ENV_ONLY))
|
||||
{
|
||||
pkgconf_list_t dir_list = PKGCONF_LIST_INITIALIZER;
|
||||
const pkgconf_list_t *prepend_list = &personality->dir_list;
|
||||
|
||||
#ifdef _WIN32
|
||||
(void) pkgconf_path_build_from_registry(HKEY_CURRENT_USER, &client->dir_list, true);
|
||||
(void) pkgconf_path_build_from_registry(HKEY_LOCAL_MACHINE, &client->dir_list, true);
|
||||
#endif
|
||||
|
||||
if (pkgconf_client_getenv(client, "PKG_CONFIG_LIBDIR") != NULL)
|
||||
if (getenv("PKG_CONFIG_LIBDIR") != NULL)
|
||||
{
|
||||
/* PKG_CONFIG_LIBDIR= should empty the search path entirely. */
|
||||
(void) pkgconf_path_build_from_environ(client, "PKG_CONFIG_LIBDIR", NULL, &dir_list, true);
|
||||
(void) pkgconf_path_build_from_environ("PKG_CONFIG_LIBDIR", NULL, &dir_list, true);
|
||||
prepend_list = &dir_list;
|
||||
}
|
||||
|
||||
@ -87,7 +82,7 @@ pkgconf_client_dir_list_build(pkgconf_client_t *client, const pkgconf_cross_pers
|
||||
/*
|
||||
* !doc
|
||||
*
|
||||
* .. 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, void *client_data, pkgconf_environ_lookup_handler_func_t environ_lookup_handler)
|
||||
* .. 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.
|
||||
*
|
||||
@ -95,16 +90,11 @@ pkgconf_client_dir_list_build(pkgconf_client_t *client, const pkgconf_cross_pers
|
||||
* :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 pkgconf_cross_personality_t* personality: the cross-compile personality to use for defaults
|
||||
* :param void* client_data: user data associated with the client
|
||||
* :param pkgconf_environ_lookup_handler_func_t environ_lookup_handler: the lookup handler to use for environment variables
|
||||
* :return: nothing
|
||||
*/
|
||||
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, void *client_data, pkgconf_environ_lookup_handler_func_t environ_lookup_handler)
|
||||
pkgconf_client_init(pkgconf_client_t *client, pkgconf_error_handler_func_t error_handler, void *error_handler_data, const pkgconf_cross_personality_t *personality)
|
||||
{
|
||||
client->personality = personality;
|
||||
client->client_data = client_data;
|
||||
client->environ_lookup_handler = environ_lookup_handler;
|
||||
client->error_handler_data = error_handler_data;
|
||||
client->error_handler = error_handler;
|
||||
client->auditf = NULL;
|
||||
@ -116,9 +106,6 @@ pkgconf_client_init(pkgconf_client_t *client, pkgconf_error_handler_func_t error
|
||||
pkgconf_client_set_trace_handler(client, NULL, NULL);
|
||||
#endif
|
||||
|
||||
if (client->unveil_handler == NULL)
|
||||
pkgconf_client_set_unveil_handler(client, NULL);
|
||||
|
||||
pkgconf_client_set_error_handler(client, error_handler, error_handler_data);
|
||||
pkgconf_client_set_warn_handler(client, NULL, NULL);
|
||||
|
||||
@ -126,38 +113,36 @@ pkgconf_client_init(pkgconf_client_t *client, pkgconf_error_handler_func_t error
|
||||
pkgconf_client_set_buildroot_dir(client, NULL);
|
||||
pkgconf_client_set_prefix_varname(client, NULL);
|
||||
|
||||
if(pkgconf_client_getenv(client, "PKG_CONFIG_SYSTEM_LIBRARY_PATH") == NULL)
|
||||
if(getenv("PKG_CONFIG_SYSTEM_LIBRARY_PATH") == NULL)
|
||||
pkgconf_path_copy_list(&client->filter_libdirs, &personality->filter_libdirs);
|
||||
else
|
||||
pkgconf_path_build_from_environ(client, "PKG_CONFIG_SYSTEM_LIBRARY_PATH", NULL, &client->filter_libdirs, false);
|
||||
pkgconf_path_build_from_environ("PKG_CONFIG_SYSTEM_LIBRARY_PATH", NULL, &client->filter_libdirs, false);
|
||||
|
||||
if(pkgconf_client_getenv(client, "PKG_CONFIG_SYSTEM_INCLUDE_PATH") == NULL)
|
||||
if(getenv("PKG_CONFIG_SYSTEM_INCLUDE_PATH") == NULL)
|
||||
pkgconf_path_copy_list(&client->filter_includedirs, &personality->filter_includedirs);
|
||||
else
|
||||
pkgconf_path_build_from_environ(client, "PKG_CONFIG_SYSTEM_INCLUDE_PATH", NULL, &client->filter_includedirs, false);
|
||||
pkgconf_path_build_from_environ("PKG_CONFIG_SYSTEM_INCLUDE_PATH", NULL, &client->filter_includedirs, false);
|
||||
|
||||
/* GCC uses these environment variables to define system include paths, so we should check them. */
|
||||
#ifdef __HAIKU__
|
||||
pkgconf_path_build_from_environ(client, "BELIBRARIES", NULL, &client->filter_libdirs, false);
|
||||
pkgconf_path_build_from_environ("BELIBRARIES", NULL, &client->filter_libdirs, false);
|
||||
#else
|
||||
pkgconf_path_build_from_environ(client, "LIBRARY_PATH", NULL, &client->filter_libdirs, false);
|
||||
pkgconf_path_build_from_environ("LIBRARY_PATH", NULL, &client->filter_libdirs, false);
|
||||
#endif
|
||||
pkgconf_path_build_from_environ(client, "CPATH", NULL, &client->filter_includedirs, false);
|
||||
pkgconf_path_build_from_environ(client, "C_INCLUDE_PATH", NULL, &client->filter_includedirs, false);
|
||||
pkgconf_path_build_from_environ(client, "CPLUS_INCLUDE_PATH", NULL, &client->filter_includedirs, false);
|
||||
pkgconf_path_build_from_environ(client, "OBJC_INCLUDE_PATH", NULL, &client->filter_includedirs, false);
|
||||
pkgconf_path_build_from_environ("CPATH", NULL, &client->filter_includedirs, false);
|
||||
pkgconf_path_build_from_environ("C_INCLUDE_PATH", NULL, &client->filter_includedirs, false);
|
||||
pkgconf_path_build_from_environ("CPLUS_INCLUDE_PATH", NULL, &client->filter_includedirs, false);
|
||||
pkgconf_path_build_from_environ("OBJC_INCLUDE_PATH", NULL, &client->filter_includedirs, false);
|
||||
|
||||
#ifdef _WIN32
|
||||
/* also use the path lists that MSVC uses on windows */
|
||||
pkgconf_path_build_from_environ(client, "INCLUDE", NULL, &client->filter_includedirs, false);
|
||||
pkgconf_path_build_from_environ("INCLUDE", NULL, &client->filter_includedirs, false);
|
||||
#endif
|
||||
|
||||
PKGCONF_TRACE(client, "initialized client @%p", client);
|
||||
|
||||
trace_path_list(client, "filtered library paths", &client->filter_libdirs);
|
||||
trace_path_list(client, "filtered include paths", &client->filter_includedirs);
|
||||
|
||||
client->output = pkgconf_output_default();
|
||||
}
|
||||
|
||||
/*
|
||||
@ -170,34 +155,17 @@ pkgconf_client_init(pkgconf_client_t *client, pkgconf_error_handler_func_t error
|
||||
* :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 pkgconf_cross_personality_t* personality: cross-compile personality to use
|
||||
* :param void* client_data: user data associated with the client
|
||||
* :param pkgconf_environ_lookup_handler_func_t environ_lookup_handler: the lookup handler to use for environment variables
|
||||
* :return: A pkgconf client object.
|
||||
* :rtype: 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, void *client_data, pkgconf_environ_lookup_handler_func_t environ_lookup_handler)
|
||||
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));
|
||||
if (out == NULL)
|
||||
return NULL;
|
||||
|
||||
pkgconf_client_init(out, error_handler, error_handler_data, personality, client_data, environ_lookup_handler);
|
||||
pkgconf_client_init(out, error_handler, error_handler_data, personality);
|
||||
return out;
|
||||
}
|
||||
|
||||
static void
|
||||
unref_preload_list(pkgconf_client_t *client)
|
||||
{
|
||||
pkgconf_node_t *n, *tn;
|
||||
|
||||
PKGCONF_FOREACH_LIST_ENTRY_SAFE(client->preloaded_pkgs.head, tn, n)
|
||||
{
|
||||
pkgconf_pkg_t *pkg = n->data;
|
||||
pkgconf_pkg_unref(client, pkg);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* !doc
|
||||
*
|
||||
@ -213,8 +181,6 @@ pkgconf_client_deinit(pkgconf_client_t *client)
|
||||
{
|
||||
PKGCONF_TRACE(client, "deinit @%p", client);
|
||||
|
||||
unref_preload_list(client);
|
||||
|
||||
if (client->prefix_varname != NULL)
|
||||
free(client->prefix_varname);
|
||||
|
||||
@ -230,8 +196,6 @@ pkgconf_client_deinit(pkgconf_client_t *client)
|
||||
pkgconf_tuple_free_global(client);
|
||||
pkgconf_path_free(&client->dir_list);
|
||||
pkgconf_cache_free(client);
|
||||
|
||||
memset(client, '\0', sizeof(*client));
|
||||
}
|
||||
|
||||
/*
|
||||
@ -292,7 +256,7 @@ pkgconf_client_set_sysroot_dir(pkgconf_client_t *client, const char *sysroot_dir
|
||||
|
||||
PKGCONF_TRACE(client, "set sysroot_dir to: %s", client->sysroot_dir != NULL ? client->sysroot_dir : "<default>");
|
||||
|
||||
pkgconf_tuple_add_global(client, "pc_sysrootdir", client->sysroot_dir != NULL ? client->sysroot_dir : "");
|
||||
pkgconf_tuple_add_global(client, "pc_sysrootdir", client->sysroot_dir != NULL ? client->sysroot_dir : "/");
|
||||
}
|
||||
|
||||
/*
|
||||
@ -354,32 +318,14 @@ pkgconf_client_set_buildroot_dir(pkgconf_client_t *client, const char *buildroot
|
||||
bool
|
||||
pkgconf_error(const pkgconf_client_t *client, const char *format, ...)
|
||||
{
|
||||
char *errbuf;
|
||||
ssize_t msgsize = 0;
|
||||
bool ret;
|
||||
char errbuf[PKGCONF_BUFSIZE];
|
||||
va_list va;
|
||||
|
||||
va_start(va, format);
|
||||
msgsize = vsnprintf(NULL, 0, format, va);
|
||||
vsnprintf(errbuf, sizeof errbuf, format, va);
|
||||
va_end(va);
|
||||
|
||||
if (msgsize < 0)
|
||||
return false;
|
||||
|
||||
msgsize++;
|
||||
|
||||
errbuf = calloc(1, msgsize);
|
||||
if (errbuf == NULL)
|
||||
return false;
|
||||
|
||||
va_start(va, format);
|
||||
vsnprintf(errbuf, msgsize, format, va);
|
||||
va_end(va);
|
||||
|
||||
ret = client->error_handler(errbuf, client, client->error_handler_data);
|
||||
free(errbuf);
|
||||
|
||||
return ret;
|
||||
return client->error_handler(errbuf, client, client->error_handler_data);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -397,32 +343,14 @@ pkgconf_error(const pkgconf_client_t *client, const char *format, ...)
|
||||
bool
|
||||
pkgconf_warn(const pkgconf_client_t *client, const char *format, ...)
|
||||
{
|
||||
char *errbuf;
|
||||
ssize_t msgsize = 0;
|
||||
bool ret;
|
||||
char errbuf[PKGCONF_BUFSIZE];
|
||||
va_list va;
|
||||
|
||||
va_start(va, format);
|
||||
msgsize = vsnprintf(NULL, 0, format, va);
|
||||
vsnprintf(errbuf, sizeof errbuf, format, va);
|
||||
va_end(va);
|
||||
|
||||
if (msgsize < 0)
|
||||
return false;
|
||||
|
||||
msgsize++;
|
||||
|
||||
errbuf = calloc(1, msgsize);
|
||||
if (errbuf == NULL)
|
||||
return false;
|
||||
|
||||
va_start(va, format);
|
||||
vsnprintf(errbuf, msgsize, format, va);
|
||||
va_end(va);
|
||||
|
||||
ret = client->warn_handler(errbuf, client, client->warn_handler_data);
|
||||
free(errbuf);
|
||||
|
||||
return ret;
|
||||
return client->warn_handler(errbuf, client, client->warn_handler_data);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -443,56 +371,22 @@ pkgconf_warn(const pkgconf_client_t *client, const char *format, ...)
|
||||
bool
|
||||
pkgconf_trace(const pkgconf_client_t *client, const char *filename, size_t lineno, const char *funcname, const char *format, ...)
|
||||
{
|
||||
char prefix[PKGCONF_ITEM_SIZE];
|
||||
char *errbuf = NULL;
|
||||
ssize_t errlen;
|
||||
char *finalbuf = NULL;
|
||||
ssize_t finallen;
|
||||
bool ret;
|
||||
char errbuf[PKGCONF_BUFSIZE];
|
||||
size_t len;
|
||||
va_list va;
|
||||
|
||||
if (client == NULL || client->trace_handler == NULL)
|
||||
return false;
|
||||
|
||||
snprintf(prefix, sizeof prefix, "%s:" SIZE_FMT_SPECIFIER " [%s]:", filename, lineno, funcname);
|
||||
len = snprintf(errbuf, sizeof errbuf, "%s:" SIZE_FMT_SPECIFIER " [%s]: ", filename, lineno, funcname);
|
||||
|
||||
va_start(va, format);
|
||||
errlen = vsnprintf(NULL, 0, format, va);
|
||||
vsnprintf(errbuf + len, sizeof(errbuf) - len, format, va);
|
||||
va_end(va);
|
||||
|
||||
if (errlen < 0)
|
||||
return false;
|
||||
pkgconf_strlcat(errbuf, "\n", sizeof errbuf);
|
||||
|
||||
errlen++;
|
||||
errbuf = calloc(1, errlen);
|
||||
if (errbuf == NULL)
|
||||
return false;
|
||||
|
||||
va_start(va, format);
|
||||
vsnprintf(errbuf, errlen, format, va);
|
||||
va_end(va);
|
||||
|
||||
finallen = snprintf(NULL, 0, "%s %s\n", prefix, errbuf);
|
||||
if (finallen < 0)
|
||||
{
|
||||
free(errbuf);
|
||||
return false;
|
||||
}
|
||||
|
||||
finallen++;
|
||||
finalbuf = calloc(1, finallen);
|
||||
if (finalbuf == NULL)
|
||||
{
|
||||
free(errbuf);
|
||||
return false;
|
||||
}
|
||||
|
||||
snprintf(finalbuf, finallen, "%s %s\n", prefix, errbuf);
|
||||
ret = client->trace_handler(finalbuf, client, client->trace_handler_data);
|
||||
free(errbuf);
|
||||
free(finalbuf);
|
||||
|
||||
return ret;
|
||||
return client->trace_handler(errbuf, client, client->trace_handler_data);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -518,14 +412,6 @@ pkgconf_default_error_handler(const char *msg, const pkgconf_client_t *client, v
|
||||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
default_unveil_handler(const pkgconf_client_t *client, const char *path, const char *permissions)
|
||||
{
|
||||
(void) client;
|
||||
(void) path;
|
||||
(void) permissions;
|
||||
}
|
||||
|
||||
/*
|
||||
* !doc
|
||||
*
|
||||
@ -685,45 +571,6 @@ pkgconf_client_set_error_handler(pkgconf_client_t *client, pkgconf_error_handler
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* !doc
|
||||
*
|
||||
* .. c:function:: pkgconf_client_get_unveil_handler(const pkgconf_client_t *client)
|
||||
*
|
||||
* Returns the unveil handler if one is set, else ``NULL``.
|
||||
*
|
||||
* :param pkgconf_client_t* client: The client object to get the unveil handler from.
|
||||
* :return: a function pointer to the error handler or ``NULL``
|
||||
*/
|
||||
pkgconf_unveil_handler_func_t
|
||||
pkgconf_client_get_unveil_handler(const pkgconf_client_t *client)
|
||||
{
|
||||
return client->unveil_handler;
|
||||
}
|
||||
|
||||
/*
|
||||
* !doc
|
||||
*
|
||||
* .. c:function:: pkgconf_client_set_unveil_handler(pkgconf_client_t *client, pkgconf_unveil_handler_func_t unveil_handler)
|
||||
*
|
||||
* Sets an unveil handler on a client object or uninstalls one if set to ``NULL``.
|
||||
*
|
||||
* :param pkgconf_client_t* client: The client object to set the error handler on.
|
||||
* :param pkgconf_unveil_handler_func_t unveil_handler: The unveil handler to set.
|
||||
* :return: nothing
|
||||
*/
|
||||
void
|
||||
pkgconf_client_set_unveil_handler(pkgconf_client_t *client, pkgconf_unveil_handler_func_t unveil_handler)
|
||||
{
|
||||
client->unveil_handler = unveil_handler;
|
||||
|
||||
if (client->unveil_handler == NULL)
|
||||
{
|
||||
PKGCONF_TRACE(client, "installing default unveil handler");
|
||||
client->unveil_handler = default_unveil_handler;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef PKGCONF_LITE
|
||||
/*
|
||||
* !doc
|
||||
@ -766,131 +613,3 @@ pkgconf_client_set_trace_handler(pkgconf_client_t *client, pkgconf_error_handler
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* !doc
|
||||
*
|
||||
* .. c:function:: bool pkgconf_client_preload_one(pkgconf_client_t *client, pkgconf_pkg_t *pkg)
|
||||
*
|
||||
* Adds a package to the preloaded packages set.
|
||||
*
|
||||
* :param pkgconf_client_t* client: The client object for preloading.
|
||||
* :param pkgconf_pkg_t* pkg: The package to preload.
|
||||
* :return: true on success, false on error
|
||||
* :rtype: bool
|
||||
*/
|
||||
bool
|
||||
pkgconf_client_preload_one(pkgconf_client_t *client, pkgconf_pkg_t *pkg)
|
||||
{
|
||||
PKGCONF_TRACE(client, "preloading pkg %s@%p", pkg->id, pkg);
|
||||
|
||||
pkg->flags |= PKGCONF_PKG_PROPF_PRELOADED;
|
||||
|
||||
pkgconf_pkg_ref(client, pkg);
|
||||
pkgconf_node_insert_tail(&pkg->preload_node, pkg, &client->preloaded_pkgs);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* !doc
|
||||
*
|
||||
* .. c:function:: bool pkgconf_client_preload_path(pkgconf_client_t *client, const char *path)
|
||||
*
|
||||
* Loads a pkg-config file into the preloaded packages set.
|
||||
*
|
||||
* :param pkgconf_client_t* client: The client object for preloading.
|
||||
* :param char* path: The path to the pkg-config file to preload.
|
||||
* :return: true on success, false on error
|
||||
* :rtype: bool
|
||||
*/
|
||||
bool
|
||||
pkgconf_client_preload_path(pkgconf_client_t *client, const char *path)
|
||||
{
|
||||
pkgconf_pkg_t *pkg = pkgconf_pkg_new_from_path(client, path, PKGCONF_PKG_PROPF_PRELOADED);
|
||||
if (pkg == NULL)
|
||||
return false;
|
||||
|
||||
return pkgconf_client_preload_one(client, pkg);
|
||||
}
|
||||
|
||||
/*
|
||||
* !doc
|
||||
*
|
||||
* .. c:function:: bool pkgconf_client_preload_from_environ(pkgconf_client_t *client, const char *env)
|
||||
*
|
||||
* Loads zero or more pkg-config files specified in the given environmental
|
||||
* variable.
|
||||
*
|
||||
* :param pkgconf_client_t* client: The client object for preloading.
|
||||
* :param char* environ: The environment variable to use for preloading.
|
||||
* :return: true on success, false on error
|
||||
* :rtype: bool
|
||||
*/
|
||||
bool
|
||||
pkgconf_client_preload_from_environ(pkgconf_client_t *client, const char *env)
|
||||
{
|
||||
const char *data;
|
||||
pkgconf_list_t pathlist = PKGCONF_LIST_INITIALIZER;
|
||||
pkgconf_node_t *n;
|
||||
bool ret = true;
|
||||
|
||||
data = getenv(env);
|
||||
if (data == NULL)
|
||||
return true;
|
||||
|
||||
pkgconf_path_split(data, &pathlist, true);
|
||||
|
||||
PKGCONF_FOREACH_LIST_ENTRY(pathlist.head, n)
|
||||
{
|
||||
pkgconf_path_t *pn = n->data;
|
||||
|
||||
ret = pkgconf_client_preload_path(client, pn->path);
|
||||
if (!ret)
|
||||
break;
|
||||
}
|
||||
|
||||
pkgconf_path_free(&pathlist);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* !doc
|
||||
*
|
||||
* .. c:function:: void pkgconf_client_set_output(pkgconf_client_t *client, pkgconf_output_t *output)
|
||||
*
|
||||
* Sets the client's output object. This is mainly a convenience function for clients
|
||||
* to use.
|
||||
*
|
||||
* :param pkgconf_client_t* client: The client object to set the output object for.
|
||||
* :param pkgconf_output_t* output: The output object to use.
|
||||
* :return: nothing
|
||||
*/
|
||||
void
|
||||
pkgconf_client_set_output(pkgconf_client_t *client, pkgconf_output_t *output)
|
||||
{
|
||||
client->output = output;
|
||||
}
|
||||
|
||||
/*
|
||||
* !doc
|
||||
*
|
||||
* .. c:function:: const char *pkgconf_client_getenv(const pkgconf_client_t *client, const char *key)
|
||||
*
|
||||
* Looks up an environmental variable which may be mocked, otherwise fetches
|
||||
* from the main environment.
|
||||
*
|
||||
* :param pkgconf_client_t* client: yhe client object to use for looking up environmental variables.
|
||||
* :param char* key: the environmental variable to look up.
|
||||
* :return: the environmental variable contents else NULL
|
||||
* :rtype: const char*
|
||||
*/
|
||||
const char *
|
||||
pkgconf_client_getenv(const pkgconf_client_t *client, const char *key)
|
||||
{
|
||||
if (client != NULL && client->environ_lookup_handler != NULL)
|
||||
return client->environ_lookup_handler(client, key);
|
||||
|
||||
return getenv(key);
|
||||
}
|
||||
|
||||
@ -24,12 +24,6 @@
|
||||
/* Define to 1 if you have the `reallocarray' function. */
|
||||
#mesondefine HAVE_DECL_REALLOCARRAY
|
||||
|
||||
/* Define to 1 if you have the `pledge' function. */
|
||||
#mesondefine HAVE_DECL_PLEDGE
|
||||
|
||||
/* Define to 1 if you have the `unveil' function. */
|
||||
#mesondefine HAVE_DECL_UNVEIL
|
||||
|
||||
/* Name of package */
|
||||
#mesondefine PACKAGE
|
||||
|
||||
@ -72,8 +66,3 @@
|
||||
#mesondefine SYSTEM_INCLUDEDIR
|
||||
#mesondefine SYSTEM_LIBDIR
|
||||
#mesondefine PERSONALITY_PATH
|
||||
|
||||
/* Enable Solaris extensions. */
|
||||
#ifndef __EXTENSIONS__
|
||||
# define __EXTENSIONS__ 1
|
||||
#endif
|
||||
|
||||
@ -131,9 +131,6 @@ pkgconf_dependency_addraw(pkgconf_client_t *client, pkgconf_list_t *list, const
|
||||
pkgconf_dependency_t *dep;
|
||||
|
||||
dep = calloc(1, sizeof(pkgconf_dependency_t));
|
||||
if (dep == NULL)
|
||||
return NULL;
|
||||
|
||||
dep->package = pkgconf_strndup(package, package_sz);
|
||||
|
||||
if (version_sz != 0)
|
||||
@ -211,9 +208,6 @@ pkgconf_dependency_free_one(pkgconf_dependency_t *dep)
|
||||
if (dep->version != NULL)
|
||||
free(dep->version);
|
||||
|
||||
if (dep->why != NULL)
|
||||
free(dep->why);
|
||||
|
||||
free(dep);
|
||||
}
|
||||
|
||||
@ -268,7 +262,7 @@ pkgconf_dependency_unref(pkgconf_client_t *client, pkgconf_dependency_t *dep)
|
||||
*
|
||||
* .. 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.
|
||||
* :return: nothing
|
||||
@ -310,29 +304,19 @@ pkgconf_dependency_parse_str(pkgconf_client_t *client, pkgconf_list_t *deplist_h
|
||||
parse_state_t state = OUTSIDE_MODULE;
|
||||
pkgconf_pkg_comparator_t compare = PKGCONF_CMP_ANY;
|
||||
char cmpname[PKGCONF_ITEM_SIZE];
|
||||
size_t package_sz = 0, version_sz = 0, buf_sz = 0;
|
||||
char *buf;
|
||||
char *start = NULL;
|
||||
char *ptr = NULL;
|
||||
char buf[PKGCONF_BUFSIZE];
|
||||
size_t package_sz = 0, version_sz = 0;
|
||||
char *start = buf;
|
||||
char *ptr = buf;
|
||||
char *vstart = NULL;
|
||||
char *package = NULL, *version = NULL;
|
||||
char *cnameptr = cmpname;
|
||||
char *cnameend = cmpname + PKGCONF_ITEM_SIZE - 1;
|
||||
|
||||
if (!*depends)
|
||||
return;
|
||||
|
||||
memset(cmpname, '\0', sizeof cmpname);
|
||||
|
||||
buf_sz = (strlen(depends) * 2) + 1;
|
||||
buf = calloc(1, buf_sz);
|
||||
if (buf == NULL)
|
||||
return;
|
||||
|
||||
pkgconf_strlcpy(buf, depends, buf_sz);
|
||||
pkgconf_strlcat(buf, " ", buf_sz);
|
||||
|
||||
start = ptr = buf;
|
||||
pkgconf_strlcpy(buf, depends, sizeof buf);
|
||||
pkgconf_strlcat(buf, " ", sizeof buf);
|
||||
|
||||
while (*ptr)
|
||||
{
|
||||
@ -402,16 +386,15 @@ pkgconf_dependency_parse_str(pkgconf_client_t *client, pkgconf_list_t *deplist_h
|
||||
break;
|
||||
|
||||
case INSIDE_OPERATOR:
|
||||
if (PKGCONF_IS_OPERATOR_CHAR(*ptr))
|
||||
if (!PKGCONF_IS_OPERATOR_CHAR(*ptr))
|
||||
{
|
||||
if (cnameptr < cnameend)
|
||||
*cnameptr++ = *ptr;
|
||||
break;
|
||||
state = AFTER_OPERATOR;
|
||||
compare = pkgconf_pkg_comparator_lookup_by_name(cmpname);
|
||||
}
|
||||
else if (cnameptr < cnameend)
|
||||
*cnameptr++ = *ptr;
|
||||
|
||||
state = AFTER_OPERATOR;
|
||||
compare = pkgconf_pkg_comparator_lookup_by_name(cmpname);
|
||||
// fallthrough
|
||||
break;
|
||||
|
||||
case AFTER_OPERATOR:
|
||||
if (!isspace((unsigned char)*ptr))
|
||||
@ -443,8 +426,6 @@ pkgconf_dependency_parse_str(pkgconf_client_t *client, pkgconf_list_t *deplist_h
|
||||
|
||||
ptr++;
|
||||
}
|
||||
|
||||
free(buf);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -489,9 +470,6 @@ pkgconf_dependency_copy(pkgconf_client_t *client, const pkgconf_dependency_t *de
|
||||
pkgconf_dependency_t *new_dep;
|
||||
|
||||
new_dep = calloc(1, sizeof(pkgconf_dependency_t));
|
||||
if (new_dep == NULL)
|
||||
return NULL;
|
||||
|
||||
new_dep->package = strdup(dep->package);
|
||||
|
||||
if (dep->version != NULL)
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
* fileio.c
|
||||
* File reading utilities
|
||||
*
|
||||
* Copyright (c) 2012, 2025 pkgconf authors (see AUTHORS).
|
||||
* Copyright (c) 2012 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
|
||||
@ -16,13 +16,18 @@
|
||||
#include <libpkgconf/stdinc.h>
|
||||
#include <libpkgconf/libpkgconf.h>
|
||||
|
||||
bool
|
||||
pkgconf_fgetline(pkgconf_buffer_t *buffer, FILE *stream)
|
||||
char *
|
||||
pkgconf_fgetline(char *line, size_t size, FILE *stream)
|
||||
{
|
||||
char *s = line;
|
||||
char *end = line + size - 2;
|
||||
bool quoted = false;
|
||||
int c = '\0', c2;
|
||||
|
||||
while ((c = getc(stream)) != EOF)
|
||||
if (s == NULL)
|
||||
return NULL;
|
||||
|
||||
while (s < end && (c = getc(stream)) != EOF)
|
||||
{
|
||||
if (c == '\\' && !quoted)
|
||||
{
|
||||
@ -36,11 +41,11 @@ pkgconf_fgetline(pkgconf_buffer_t *buffer, FILE *stream)
|
||||
do {
|
||||
c = getc(stream);
|
||||
} while (c != '\n' && c != EOF);
|
||||
pkgconf_buffer_push_byte(buffer, c);
|
||||
*s++ = c;
|
||||
break;
|
||||
}
|
||||
else
|
||||
pkgconf_buffer_push_byte(buffer, c);
|
||||
*s++ = c;
|
||||
|
||||
quoted = false;
|
||||
continue;
|
||||
@ -61,14 +66,14 @@ pkgconf_fgetline(pkgconf_buffer_t *buffer, FILE *stream)
|
||||
}
|
||||
else
|
||||
{
|
||||
pkgconf_buffer_push_byte(buffer, c);
|
||||
*s++ = c;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
else if (c == '\r')
|
||||
{
|
||||
pkgconf_buffer_push_byte(buffer, '\n');
|
||||
*s++ = '\n';
|
||||
|
||||
if ((c2 = getc(stream)) == '\n')
|
||||
{
|
||||
@ -94,20 +99,26 @@ pkgconf_fgetline(pkgconf_buffer_t *buffer, FILE *stream)
|
||||
else
|
||||
{
|
||||
if (quoted) {
|
||||
pkgconf_buffer_push_byte(buffer, '\\');
|
||||
*s++ = '\\';
|
||||
quoted = false;
|
||||
}
|
||||
pkgconf_buffer_push_byte(buffer, c);
|
||||
*s++ = c;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (c == EOF && (s == line || ferror(stream)))
|
||||
return NULL;
|
||||
|
||||
*s = '\0';
|
||||
|
||||
/* Remove newline character. */
|
||||
if (pkgconf_buffer_lastc(buffer) == '\n')
|
||||
pkgconf_buffer_trim_byte(buffer);
|
||||
if (s > line && *(--s) == '\n') {
|
||||
*s = '\0';
|
||||
|
||||
if (pkgconf_buffer_lastc(buffer) == '\r')
|
||||
pkgconf_buffer_trim_byte(buffer);
|
||||
if (s > line && *(--s) == '\r')
|
||||
*s = '\0';
|
||||
}
|
||||
|
||||
return !(c == EOF || ferror(stream));
|
||||
return line;
|
||||
}
|
||||
|
||||
@ -32,31 +32,6 @@ struct pkgconf_fragment_check {
|
||||
size_t len;
|
||||
};
|
||||
|
||||
static inline bool
|
||||
pkgconf_fragment_is_greedy(const char *string)
|
||||
{
|
||||
static const struct pkgconf_fragment_check check_fragments[] = {
|
||||
{"-F", 2},
|
||||
{"-I", 2},
|
||||
{"-L", 2},
|
||||
{"-D", 2},
|
||||
{"-l", 2},
|
||||
};
|
||||
|
||||
if (*string != '-')
|
||||
return false;
|
||||
|
||||
for (size_t i = 0; i < PKGCONF_ARRAY_SIZE(check_fragments); i++)
|
||||
if (!strncmp(string, check_fragments[i].token, check_fragments[i].len))
|
||||
{
|
||||
/* if it is the bare flag, then we want the next token to be the data */
|
||||
if (!*(string + check_fragments[i].len))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
pkgconf_fragment_is_unmergeable(const char *string)
|
||||
{
|
||||
@ -77,7 +52,6 @@ pkgconf_fragment_is_unmergeable(const char *string)
|
||||
{"-nostdinc", 9},
|
||||
{"-nostdlibinc", 12},
|
||||
{"-nobuiltininc", 13},
|
||||
{"-nodefaultlibs", 14},
|
||||
};
|
||||
|
||||
if (*string != '-')
|
||||
@ -106,38 +80,6 @@ pkgconf_fragment_should_munge(const char *string, const char *sysroot_dir)
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
pkgconf_fragment_is_groupable(const char *string)
|
||||
{
|
||||
static const struct pkgconf_fragment_check check_fragments[] = {
|
||||
{"-Wl,--start-group", 17},
|
||||
{"-framework", 10},
|
||||
{"-isystem", 8},
|
||||
{"-idirafter", 10},
|
||||
{"-include", 8},
|
||||
};
|
||||
|
||||
for (size_t i = 0; i < PKGCONF_ARRAY_SIZE(check_fragments); i++)
|
||||
if (!strncmp(string, check_fragments[i].token, check_fragments[i].len))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
pkgconf_fragment_is_terminus(const char *string)
|
||||
{
|
||||
static const struct pkgconf_fragment_check check_fragments[] = {
|
||||
{"-Wl,--end-group", 15},
|
||||
};
|
||||
|
||||
for (size_t i = 0; i < PKGCONF_ARRAY_SIZE(check_fragments); i++)
|
||||
if (!strncmp(string, check_fragments[i].token, check_fragments[i].len))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
pkgconf_fragment_is_special(const char *string)
|
||||
{
|
||||
@ -178,38 +120,6 @@ pkgconf_fragment_copy_munged(const pkgconf_client_t *client, const char *source,
|
||||
return strdup(mungebuf);
|
||||
}
|
||||
|
||||
/*
|
||||
* !doc
|
||||
*
|
||||
* .. c:function:: void pkgconf_fragment_insert(const pkgconf_client_t *client, pkgconf_list_t *list, char type, const char *data, bool tail)
|
||||
*
|
||||
* 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
|
||||
*
|
||||
@ -226,41 +136,15 @@ pkgconf_fragment_insert(const pkgconf_client_t *client, pkgconf_list_t *list, ch
|
||||
void
|
||||
pkgconf_fragment_add(const pkgconf_client_t *client, pkgconf_list_t *list, const char *string, unsigned int flags)
|
||||
{
|
||||
pkgconf_list_t *target = list;
|
||||
pkgconf_fragment_t *frag;
|
||||
|
||||
if (*string == '\0')
|
||||
return;
|
||||
|
||||
if (list->tail != NULL && list->tail->data != NULL &&
|
||||
!(client->flags & PKGCONF_PKG_PKGF_DONT_MERGE_SPECIAL_FRAGMENTS))
|
||||
{
|
||||
pkgconf_fragment_t *parent = list->tail->data;
|
||||
|
||||
/* only attempt to merge 'special' fragments together */
|
||||
if (!parent->type && parent->data != NULL &&
|
||||
pkgconf_fragment_is_unmergeable(parent->data) &&
|
||||
!(parent->flags & PKGCONF_PKG_FRAGF_TERMINATED))
|
||||
{
|
||||
if (pkgconf_fragment_is_groupable(parent->data))
|
||||
target = &parent->children;
|
||||
|
||||
if (pkgconf_fragment_is_terminus(string))
|
||||
parent->flags |= PKGCONF_PKG_FRAGF_TERMINATED;
|
||||
|
||||
PKGCONF_TRACE(client, "adding fragment as child to list @%p", target);
|
||||
}
|
||||
}
|
||||
|
||||
frag = calloc(1, sizeof(pkgconf_fragment_t));
|
||||
if (frag == NULL)
|
||||
{
|
||||
PKGCONF_TRACE(client, "failed to add new fragment due to allocation failure to list @%p", target);
|
||||
return;
|
||||
}
|
||||
|
||||
if (strlen(string) > 1 && !pkgconf_fragment_is_special(string))
|
||||
{
|
||||
frag = calloc(1, sizeof(pkgconf_fragment_t));
|
||||
|
||||
frag->type = *(string + 1);
|
||||
frag->data = pkgconf_fragment_copy_munged(client, string + 2, flags);
|
||||
|
||||
@ -268,13 +152,55 @@ pkgconf_fragment_add(const pkgconf_client_t *client, pkgconf_list_t *list, const
|
||||
}
|
||||
else
|
||||
{
|
||||
frag->type = 0;
|
||||
frag->data = pkgconf_fragment_copy_munged(client, string, flags);
|
||||
char mungebuf[PKGCONF_ITEM_SIZE];
|
||||
|
||||
PKGCONF_TRACE(client, "created special fragment {'%s'} in list @%p", frag->data, target);
|
||||
if (list->tail != NULL && list->tail->data != NULL &&
|
||||
!(client->flags & PKGCONF_PKG_PKGF_DONT_MERGE_SPECIAL_FRAGMENTS))
|
||||
{
|
||||
pkgconf_fragment_t *parent = list->tail->data;
|
||||
|
||||
/* only attempt to merge 'special' fragments together */
|
||||
if (!parent->type && parent->data != NULL && pkgconf_fragment_is_unmergeable(parent->data))
|
||||
{
|
||||
size_t len;
|
||||
char *newdata;
|
||||
|
||||
pkgconf_fragment_munge(client, mungebuf, sizeof mungebuf, string, NULL, flags);
|
||||
|
||||
len = strlen(parent->data) + strlen(mungebuf) + 2;
|
||||
newdata = malloc(len);
|
||||
|
||||
pkgconf_strlcpy(newdata, parent->data, len);
|
||||
pkgconf_strlcat(newdata, " ", len);
|
||||
pkgconf_strlcat(newdata, mungebuf, len);
|
||||
|
||||
PKGCONF_TRACE(client, "merging '%s' to '%s' to form fragment {'%s'} in list @%p", mungebuf, parent->data, newdata, list);
|
||||
|
||||
free(parent->data);
|
||||
parent->data = newdata;
|
||||
parent->merged = true;
|
||||
|
||||
/* use a copy operation to force a dedup */
|
||||
pkgconf_node_delete(&parent->iter, list);
|
||||
pkgconf_fragment_copy(client, list, parent, false);
|
||||
|
||||
/* the fragment list now (maybe) has the copied node, so free the original */
|
||||
free(parent->data);
|
||||
free(parent);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
frag = calloc(1, sizeof(pkgconf_fragment_t));
|
||||
|
||||
frag->type = 0;
|
||||
frag->data = strdup(string);
|
||||
|
||||
PKGCONF_TRACE(client, "created special fragment {'%s'} in list @%p", frag->data, list);
|
||||
}
|
||||
|
||||
pkgconf_node_insert_tail(&frag->iter, frag, target);
|
||||
pkgconf_node_insert_tail(&frag->iter, frag, list);
|
||||
}
|
||||
|
||||
static inline pkgconf_fragment_t *
|
||||
@ -327,9 +253,6 @@ pkgconf_fragment_can_merge(const pkgconf_fragment_t *base, unsigned int flags, b
|
||||
if (is_private)
|
||||
return false;
|
||||
|
||||
if (base->children.head != NULL)
|
||||
return false;
|
||||
|
||||
return pkgconf_fragment_is_unmergeable(base->data);
|
||||
}
|
||||
|
||||
@ -433,7 +356,7 @@ pkgconf_fragment_copy(const pkgconf_client_t *client, pkgconf_list_t *list, cons
|
||||
frag = calloc(1, sizeof(pkgconf_fragment_t));
|
||||
|
||||
frag->type = base->type;
|
||||
pkgconf_fragment_copy_list(client, &frag->children, &base->children);
|
||||
frag->merged = base->merged;
|
||||
if (base->data != NULL)
|
||||
frag->data = strdup(base->data);
|
||||
|
||||
@ -494,27 +417,49 @@ pkgconf_fragment_filter(const pkgconf_client_t *client, pkgconf_list_t *dest, pk
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
fragment_quote(pkgconf_buffer_t *out, const pkgconf_fragment_t *frag)
|
||||
static inline char *
|
||||
fragment_quote(const pkgconf_fragment_t *frag)
|
||||
{
|
||||
const char *src = frag->data;
|
||||
ssize_t outlen = strlen(src) + 10;
|
||||
char *out, *dst;
|
||||
|
||||
if (frag->data == NULL)
|
||||
return;
|
||||
return NULL;
|
||||
|
||||
const pkgconf_buffer_t *src = PKGCONF_BUFFER_FROM_STR(frag->data);
|
||||
const pkgconf_span_t quote_spans[] = {
|
||||
{ 0x00, 0x1f },
|
||||
{ (unsigned char)' ', (unsigned char)'#' },
|
||||
{ (unsigned char)'%', (unsigned char)'\'' },
|
||||
{ (unsigned char)'*', (unsigned char)'*' },
|
||||
{ (unsigned char)';', (unsigned char)'<' },
|
||||
{ (unsigned char)'>', (unsigned char)'?' },
|
||||
{ (unsigned char)'[', (unsigned char)']' },
|
||||
{ (unsigned char)'`', (unsigned char)'`' },
|
||||
{ (unsigned char)'{', (unsigned char)'}' },
|
||||
{ 0x7f, 0xff },
|
||||
};
|
||||
out = dst = calloc(1, outlen);
|
||||
|
||||
pkgconf_buffer_escape(out, src, quote_spans, PKGCONF_ARRAY_SIZE(quote_spans));
|
||||
for (; *src; src++)
|
||||
{
|
||||
if (((*src < ' ') ||
|
||||
(*src >= (' ' + (frag->merged ? 1 : 0)) && *src < '$') ||
|
||||
(*src > '$' && *src < '(') ||
|
||||
(*src > ')' && *src < '+') ||
|
||||
(*src > ':' && *src < '=') ||
|
||||
(*src > '=' && *src < '@') ||
|
||||
(*src > 'Z' && *src < '\\') ||
|
||||
#ifndef _WIN32
|
||||
(*src == '\\') ||
|
||||
#endif
|
||||
(*src > '\\' && *src < '^') ||
|
||||
(*src == '`') ||
|
||||
(*src > 'z' && *src < '~') ||
|
||||
(*src > '~')))
|
||||
*dst++ = '\\';
|
||||
|
||||
*dst++ = *src;
|
||||
|
||||
if ((ptrdiff_t)(dst - out) + 2 > outlen)
|
||||
{
|
||||
ptrdiff_t offset = dst - out;
|
||||
outlen *= 2;
|
||||
out = realloc(out, outlen);
|
||||
dst = out + offset;
|
||||
}
|
||||
}
|
||||
|
||||
*dst = 0;
|
||||
return out;
|
||||
}
|
||||
|
||||
static inline size_t
|
||||
@ -527,18 +472,9 @@ pkgconf_fragment_len(const pkgconf_fragment_t *frag)
|
||||
|
||||
if (frag->data != NULL)
|
||||
{
|
||||
pkgconf_node_t *iter;
|
||||
|
||||
pkgconf_buffer_t quoted = PKGCONF_BUFFER_INITIALIZER;
|
||||
fragment_quote("ed, frag);
|
||||
len += pkgconf_buffer_len("ed);
|
||||
pkgconf_buffer_finalize("ed);
|
||||
|
||||
PKGCONF_FOREACH_LIST_ENTRY(frag->children.head, iter)
|
||||
{
|
||||
const pkgconf_fragment_t *child_frag = iter->data;
|
||||
len += pkgconf_fragment_len(child_frag) + 1;
|
||||
}
|
||||
char *quoted = fragment_quote(frag);
|
||||
len += strlen(quoted);
|
||||
free(quoted);
|
||||
}
|
||||
|
||||
return len;
|
||||
@ -561,46 +497,45 @@ fragment_render_len(const pkgconf_list_t *list, bool escape)
|
||||
return out;
|
||||
}
|
||||
|
||||
static inline size_t
|
||||
fragment_render_item(const pkgconf_fragment_t *frag, pkgconf_buffer_t *buf, char delim)
|
||||
{
|
||||
const pkgconf_node_t *iter;
|
||||
pkgconf_buffer_t quoted = PKGCONF_BUFFER_INITIALIZER;
|
||||
|
||||
fragment_quote("ed, frag);
|
||||
|
||||
if (frag->type)
|
||||
pkgconf_buffer_append_fmt(buf, "-%c", frag->type);
|
||||
|
||||
pkgconf_buffer_append(buf, pkgconf_buffer_str_or_empty("ed));
|
||||
pkgconf_buffer_finalize("ed);
|
||||
|
||||
PKGCONF_FOREACH_LIST_ENTRY(frag->children.head, iter)
|
||||
{
|
||||
const pkgconf_fragment_t *child_frag = iter->data;
|
||||
|
||||
pkgconf_buffer_push_byte(buf, delim);
|
||||
fragment_render_item(child_frag, buf, delim);
|
||||
}
|
||||
|
||||
return pkgconf_buffer_len(buf);
|
||||
}
|
||||
|
||||
static void
|
||||
fragment_render_buf(const pkgconf_list_t *list, pkgconf_buffer_t *buf, bool escape, char delim)
|
||||
fragment_render_buf(const pkgconf_list_t *list, char *buf, size_t buflen, bool escape)
|
||||
{
|
||||
(void) escape;
|
||||
|
||||
pkgconf_node_t *node;
|
||||
char *bptr = buf;
|
||||
|
||||
memset(buf, 0, buflen);
|
||||
|
||||
PKGCONF_FOREACH_LIST_ENTRY(list->head, node)
|
||||
{
|
||||
const pkgconf_fragment_t *frag = node->data;
|
||||
fragment_render_item(frag, buf, delim);
|
||||
size_t buf_remaining = buflen - (bptr - buf);
|
||||
char *quoted = fragment_quote(frag);
|
||||
|
||||
if (strlen(quoted) > buf_remaining)
|
||||
{
|
||||
free(quoted);
|
||||
break;
|
||||
}
|
||||
|
||||
if (frag->type)
|
||||
{
|
||||
*bptr++ = '-';
|
||||
*bptr++ = frag->type;
|
||||
}
|
||||
|
||||
if (quoted != NULL)
|
||||
{
|
||||
bptr += pkgconf_strlcpy(bptr, quoted, buf_remaining);
|
||||
free(quoted);
|
||||
}
|
||||
|
||||
if (node->next != NULL)
|
||||
pkgconf_buffer_push_byte(buf, delim);
|
||||
*bptr++ = ' ';
|
||||
}
|
||||
|
||||
*bptr = '\0';
|
||||
}
|
||||
|
||||
static const pkgconf_fragment_render_ops_t default_render_ops = {
|
||||
@ -633,7 +568,7 @@ pkgconf_fragment_render_len(const pkgconf_list_t *list, bool escape, const pkgco
|
||||
/*
|
||||
* !doc
|
||||
*
|
||||
* .. c:function:: void pkgconf_fragment_render_buf(const pkgconf_list_t *list, char *buf, size_t buflen, bool escape, const pkgconf_fragment_render_ops_t *ops, char delim)
|
||||
* .. c:function:: void pkgconf_fragment_render_buf(const pkgconf_list_t *list, char *buf, size_t buflen, bool escape, const pkgconf_fragment_render_ops_t *ops)
|
||||
*
|
||||
* Renders a `fragment list` into a buffer.
|
||||
*
|
||||
@ -642,16 +577,41 @@ pkgconf_fragment_render_len(const pkgconf_list_t *list, bool escape, const pkgco
|
||||
* :param size_t buflen: The length of the buffer.
|
||||
* :param bool escape: Whether or not to escape special shell characters (deprecated).
|
||||
* :param pkgconf_fragment_render_ops_t* ops: An optional ops structure to use for custom renderers, else ``NULL``.
|
||||
* :param char delim: The delimiter to use between fragments.
|
||||
* :return: nothing
|
||||
*/
|
||||
void
|
||||
pkgconf_fragment_render_buf(const pkgconf_list_t *list, pkgconf_buffer_t *buf, bool escape, const pkgconf_fragment_render_ops_t *ops, char delim)
|
||||
pkgconf_fragment_render_buf(const pkgconf_list_t *list, char *buf, size_t buflen, bool escape, const pkgconf_fragment_render_ops_t *ops)
|
||||
{
|
||||
(void) escape;
|
||||
|
||||
ops = ops != NULL ? ops : &default_render_ops;
|
||||
ops->render_buf(list, buf, true, delim);
|
||||
ops->render_buf(list, buf, buflen, true);
|
||||
}
|
||||
|
||||
/*
|
||||
* !doc
|
||||
*
|
||||
* .. c:function:: char *pkgconf_fragment_render(const pkgconf_list_t *list)
|
||||
*
|
||||
* Allocate memory and render a `fragment list` into it.
|
||||
*
|
||||
* :param pkgconf_list_t* list: The `fragment list` being rendered.
|
||||
* :param bool escape: Whether or not to escape special shell characters (deprecated).
|
||||
* :param pkgconf_fragment_render_ops_t* ops: An optional ops structure to use for custom renderers, else ``NULL``.
|
||||
* :return: An allocated string containing the rendered `fragment list`.
|
||||
* :rtype: char *
|
||||
*/
|
||||
char *
|
||||
pkgconf_fragment_render(const pkgconf_list_t *list, bool escape, const pkgconf_fragment_render_ops_t *ops)
|
||||
{
|
||||
(void) escape;
|
||||
|
||||
size_t buflen = pkgconf_fragment_render_len(list, true, ops);
|
||||
char *buf = calloc(1, buflen);
|
||||
|
||||
pkgconf_fragment_render_buf(list, buf, buflen, true, ops);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -693,7 +653,6 @@ pkgconf_fragment_free(pkgconf_list_t *list)
|
||||
{
|
||||
pkgconf_fragment_t *frag = node->data;
|
||||
|
||||
pkgconf_fragment_free(&frag->children);
|
||||
free(frag->data);
|
||||
free(frag);
|
||||
}
|
||||
@ -732,6 +691,8 @@ pkgconf_fragment_parse(const pkgconf_client_t *client, pkgconf_list_t *list, pkg
|
||||
|
||||
for (i = 0; i < argc; i++)
|
||||
{
|
||||
PKGCONF_TRACE(client, "processing %s", argv[i]);
|
||||
|
||||
if (argv[i] == NULL)
|
||||
{
|
||||
PKGCONF_TRACE(client, "parsed fragment string is inconsistent: argc = %d while argv[%d] == NULL", argc, i);
|
||||
@ -740,24 +701,7 @@ pkgconf_fragment_parse(const pkgconf_client_t *client, pkgconf_list_t *list, pkg
|
||||
return false;
|
||||
}
|
||||
|
||||
bool greedy = pkgconf_fragment_is_greedy(argv[i]);
|
||||
|
||||
PKGCONF_TRACE(client, "processing [%s] greedy=%d", argv[i], greedy);
|
||||
|
||||
if (greedy && i + 1 < argc)
|
||||
{
|
||||
pkgconf_buffer_t greedybuf = PKGCONF_BUFFER_INITIALIZER;
|
||||
|
||||
pkgconf_buffer_append(&greedybuf, argv[i]);
|
||||
pkgconf_buffer_append(&greedybuf, argv[i + 1]);
|
||||
pkgconf_fragment_add(client, list, pkgconf_buffer_str(&greedybuf), flags);
|
||||
pkgconf_buffer_finalize(&greedybuf);
|
||||
|
||||
/* skip over next arg as we combined them */
|
||||
i++;
|
||||
}
|
||||
else
|
||||
pkgconf_fragment_add(client, list, argv[i], flags);
|
||||
pkgconf_fragment_add(client, list, argv[i], flags);
|
||||
}
|
||||
|
||||
pkgconf_argv_free(argv);
|
||||
|
||||
@ -22,7 +22,6 @@
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <libpkgconf/libpkgconf-api.h>
|
||||
#include <libpkgconf/iter.h>
|
||||
#include <libpkgconf/bsdstubs.h>
|
||||
@ -31,6 +30,23 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* pkg-config uses ';' on win32 as ':' is part of path */
|
||||
#ifdef _WIN32
|
||||
#define PKG_CONFIG_PATH_SEP_S ";"
|
||||
#else
|
||||
#define PKG_CONFIG_PATH_SEP_S ":"
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#define PKG_DIR_SEP_S '\\'
|
||||
#else
|
||||
#define PKG_DIR_SEP_S '/'
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#define realpath(N,R) _fullpath((R),(N),_MAX_PATH)
|
||||
#endif
|
||||
|
||||
#define PKGCONF_BUFSIZE (65535)
|
||||
|
||||
typedef enum {
|
||||
@ -48,14 +64,11 @@ typedef enum {
|
||||
typedef struct pkgconf_pkg_ pkgconf_pkg_t;
|
||||
typedef struct pkgconf_dependency_ pkgconf_dependency_t;
|
||||
typedef struct pkgconf_tuple_ pkgconf_tuple_t;
|
||||
typedef struct pkgconf_buffer_ pkgconf_buffer_t;
|
||||
typedef struct pkgconf_span_ pkgconf_span_t;
|
||||
typedef struct pkgconf_fragment_ pkgconf_fragment_t;
|
||||
typedef struct pkgconf_path_ pkgconf_path_t;
|
||||
typedef struct pkgconf_client_ pkgconf_client_t;
|
||||
typedef struct pkgconf_cross_personality_ pkgconf_cross_personality_t;
|
||||
typedef struct pkgconf_queue_ pkgconf_queue_t;
|
||||
typedef struct pkgconf_output_ pkgconf_output_t;
|
||||
|
||||
#define PKGCONF_ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x)))
|
||||
|
||||
@ -68,14 +81,12 @@ typedef struct pkgconf_output_ pkgconf_output_t;
|
||||
#define PKGCONF_FOREACH_LIST_ENTRY_REVERSE(tail, value) \
|
||||
for ((value) = (tail); (value) != NULL; (value) = (value)->prev)
|
||||
|
||||
#define LIBPKGCONF_VERSION 20501
|
||||
#define LIBPKGCONF_VERSION_STR "2.5.1"
|
||||
#define LIBPKGCONF_VERSION 20003
|
||||
#define LIBPKGCONF_VERSION_STR "2.0.3"
|
||||
|
||||
struct pkgconf_queue_ {
|
||||
pkgconf_node_t iter;
|
||||
char *package;
|
||||
|
||||
unsigned int flags;
|
||||
};
|
||||
|
||||
struct pkgconf_fragment_ {
|
||||
@ -84,12 +95,9 @@ struct pkgconf_fragment_ {
|
||||
char type;
|
||||
char *data;
|
||||
|
||||
pkgconf_list_t children;
|
||||
unsigned int flags;
|
||||
bool merged;
|
||||
};
|
||||
|
||||
#define PKGCONF_PKG_FRAGF_TERMINATED 0x1
|
||||
|
||||
struct pkgconf_dependency_ {
|
||||
pkgconf_node_t iter;
|
||||
|
||||
@ -103,8 +111,6 @@ struct pkgconf_dependency_ {
|
||||
|
||||
int refcount;
|
||||
pkgconf_client_t *owner;
|
||||
|
||||
char *why;
|
||||
};
|
||||
|
||||
struct pkgconf_tuple_ {
|
||||
@ -116,11 +122,6 @@ struct pkgconf_tuple_ {
|
||||
unsigned int flags;
|
||||
};
|
||||
|
||||
struct pkgconf_buffer_ {
|
||||
char *base;
|
||||
char *end;
|
||||
};
|
||||
|
||||
#define PKGCONF_PKG_TUPLEF_OVERRIDE 0x1
|
||||
|
||||
struct pkgconf_path_ {
|
||||
@ -129,8 +130,6 @@ struct pkgconf_path_ {
|
||||
char *path;
|
||||
void *handle_path;
|
||||
void *handle_device;
|
||||
|
||||
unsigned int flags;
|
||||
};
|
||||
|
||||
#define PKGCONF_PKG_PROPF_NONE 0x00
|
||||
@ -138,9 +137,6 @@ struct pkgconf_path_ {
|
||||
#define PKGCONF_PKG_PROPF_CACHED 0x02
|
||||
#define PKGCONF_PKG_PROPF_UNINSTALLED 0x08
|
||||
#define PKGCONF_PKG_PROPF_VIRTUAL 0x10
|
||||
#define PKGCONF_PKG_PROPF_ANCESTOR 0x20
|
||||
#define PKGCONF_PKG_PROPF_VISITED_PRIVATE 0x40
|
||||
#define PKGCONF_PKG_PROPF_PRELOADED 0x80
|
||||
|
||||
struct pkgconf_pkg_ {
|
||||
int refcount;
|
||||
@ -154,8 +150,6 @@ struct pkgconf_pkg_ {
|
||||
char *license;
|
||||
char *maintainer;
|
||||
char *copyright;
|
||||
char *source;
|
||||
char *license_file;
|
||||
char *why;
|
||||
|
||||
pkgconf_list_t libs;
|
||||
@ -182,16 +176,12 @@ struct pkgconf_pkg_ {
|
||||
|
||||
uint64_t serial;
|
||||
uint64_t identifier;
|
||||
|
||||
pkgconf_node_t preload_node;
|
||||
};
|
||||
|
||||
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 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 void (*pkgconf_unveil_handler_func_t)(const pkgconf_client_t *client, const char *path, const char *permissions);
|
||||
typedef const char *(*pkgconf_environ_lookup_handler_func_t)(const pkgconf_client_t *client, const char *variable);
|
||||
|
||||
struct pkgconf_client_ {
|
||||
pkgconf_list_t dir_list;
|
||||
@ -201,7 +191,6 @@ struct pkgconf_client_ {
|
||||
|
||||
pkgconf_list_t global_vars;
|
||||
|
||||
void *client_data;
|
||||
void *error_handler_data;
|
||||
void *warn_handler_data;
|
||||
void *trace_handler_data;
|
||||
@ -210,8 +199,6 @@ struct pkgconf_client_ {
|
||||
pkgconf_error_handler_func_t warn_handler;
|
||||
pkgconf_error_handler_func_t trace_handler;
|
||||
|
||||
pkgconf_environ_lookup_handler_func_t environ_lookup_handler;
|
||||
|
||||
FILE *auditf;
|
||||
|
||||
char *sysroot_dir;
|
||||
@ -228,18 +215,10 @@ struct pkgconf_client_ {
|
||||
|
||||
pkgconf_pkg_t **cache_table;
|
||||
size_t cache_count;
|
||||
|
||||
pkgconf_unveil_handler_func_t unveil_handler;
|
||||
|
||||
pkgconf_list_t preloaded_pkgs;
|
||||
|
||||
pkgconf_output_t *output;
|
||||
|
||||
const pkgconf_cross_personality_t *personality;
|
||||
};
|
||||
|
||||
struct pkgconf_cross_personality_ {
|
||||
char *name;
|
||||
const char *name;
|
||||
|
||||
pkgconf_list_t dir_list;
|
||||
|
||||
@ -253,8 +232,8 @@ struct pkgconf_cross_personality_ {
|
||||
};
|
||||
|
||||
/* client.c */
|
||||
PKGCONF_API 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, void *client_data, pkgconf_environ_lookup_handler_func_t environ_lookup_handler);
|
||||
PKGCONF_API pkgconf_client_t * pkgconf_client_new(pkgconf_error_handler_func_t error_handler, void *error_handler_data, const pkgconf_cross_personality_t *personality, void *client_data, pkgconf_environ_lookup_handler_func_t environ_lookup_handler);
|
||||
PKGCONF_API 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);
|
||||
PKGCONF_API pkgconf_client_t * pkgconf_client_new(pkgconf_error_handler_func_t error_handler, void *error_handler_data, const pkgconf_cross_personality_t *personality);
|
||||
PKGCONF_API void pkgconf_client_deinit(pkgconf_client_t *client);
|
||||
PKGCONF_API void pkgconf_client_free(pkgconf_client_t *client);
|
||||
PKGCONF_API const char *pkgconf_client_get_sysroot_dir(const pkgconf_client_t *client);
|
||||
@ -271,14 +250,7 @@ PKGCONF_API pkgconf_error_handler_func_t pkgconf_client_get_error_handler(const
|
||||
PKGCONF_API void pkgconf_client_set_error_handler(pkgconf_client_t *client, pkgconf_error_handler_func_t error_handler, void *error_handler_data);
|
||||
PKGCONF_API pkgconf_error_handler_func_t pkgconf_client_get_trace_handler(const pkgconf_client_t *client);
|
||||
PKGCONF_API void pkgconf_client_set_trace_handler(pkgconf_client_t *client, pkgconf_error_handler_func_t trace_handler, void *trace_handler_data);
|
||||
PKGCONF_API pkgconf_unveil_handler_func_t pkgconf_client_get_unveil_handler(const pkgconf_client_t *client);
|
||||
PKGCONF_API void pkgconf_client_set_unveil_handler(pkgconf_client_t *client, pkgconf_unveil_handler_func_t unveil_handler);
|
||||
PKGCONF_API void pkgconf_client_dir_list_build(pkgconf_client_t *client, const pkgconf_cross_personality_t *personality);
|
||||
PKGCONF_API bool pkgconf_client_preload_one(pkgconf_client_t *client, pkgconf_pkg_t *pkg);
|
||||
PKGCONF_API bool pkgconf_client_preload_path(pkgconf_client_t *client, const char *path);
|
||||
PKGCONF_API bool pkgconf_client_preload_from_environ(pkgconf_client_t *client, const char *env);
|
||||
PKGCONF_API void pkgconf_client_set_output(pkgconf_client_t *client, pkgconf_output_t *output);
|
||||
PKGCONF_API const char *pkgconf_client_getenv(const pkgconf_client_t *client, const char *key);
|
||||
|
||||
/* personality.c */
|
||||
PKGCONF_API pkgconf_cross_personality_t *pkgconf_cross_personality_default(void);
|
||||
@ -306,11 +278,10 @@ PKGCONF_API void pkgconf_cross_personality_deinit(pkgconf_cross_personality_t *p
|
||||
#define PKGCONF_PKG_PKGF_DONT_MERGE_SPECIAL_FRAGMENTS 0x4000
|
||||
#define PKGCONF_PKG_PKGF_FDO_SYSROOT_RULES 0x8000
|
||||
#define PKGCONF_PKG_PKGF_PKGCONF1_SYSROOT_RULES 0x10000
|
||||
#define PKGCONF_PKG_PKGF_REQUIRE_INTERNAL 0x20000
|
||||
#define PKGCONF_PKG_PKGF_ANCESTOR 0x20000
|
||||
|
||||
#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_PACKAGE_NOT_FOUND 0x1
|
||||
@ -318,23 +289,21 @@ PKGCONF_API void pkgconf_cross_personality_deinit(pkgconf_cross_personality_t *p
|
||||
#define PKGCONF_PKG_ERRF_PACKAGE_CONFLICT 0x4
|
||||
#define PKGCONF_PKG_ERRF_DEPGRAPH_BREAK 0x8
|
||||
|
||||
#if __GNUC__ >= 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)
|
||||
# define PRINTFLIKE(fmtarg, firstvararg) \
|
||||
__attribute__((__format__ (gnu_printf, fmtarg, firstvararg)))
|
||||
#elif defined(__clang__) || defined(__INTEL_COMPILER) || __GNUC__ > 2 || (_GNUC__ == 2 && __GNUC_MINOR__ >= 5)
|
||||
# define PRINTFLIKE(fmtarg, firstvararg) \
|
||||
__attribute__((__format__ (__printf__, fmtarg, firstvararg)))
|
||||
#if defined(__GNUC__) || defined(__INTEL_COMPILER)
|
||||
#define PRINTFLIKE(fmtarg, firstvararg) \
|
||||
__attribute__((__format__ (__printf__, fmtarg, firstvararg)))
|
||||
#define DEPRECATED \
|
||||
__attribute__((deprecated))
|
||||
#else
|
||||
# define PRINTFLIKE(fmtarg, firstvararg)
|
||||
#endif
|
||||
#define PRINTFLIKE(fmtarg, firstvararg)
|
||||
#define DEPRECATED
|
||||
#endif /* defined(__INTEL_COMPILER) || defined(__GNUC__) */
|
||||
|
||||
#if defined(__clang__) || defined(__INTEL_COMPILER) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
|
||||
# define DEPRECATED __attribute__((deprecated))
|
||||
#elif defined(_MSC_VER)
|
||||
# define DEPRECATED __declspec(deprecated)
|
||||
#else
|
||||
# define DEPRECATED
|
||||
#endif
|
||||
/* parser.c */
|
||||
typedef void (*pkgconf_parser_operand_func_t)(void *data, const size_t lineno, const char *key, const char *value);
|
||||
typedef void (*pkgconf_parser_warn_func_t)(void *data, const char *fmt, ...);
|
||||
|
||||
PKGCONF_API void pkgconf_parser_parse(FILE *f, void *data, const pkgconf_parser_operand_func_t *ops, const pkgconf_parser_warn_func_t warnfunc, const char *filename);
|
||||
|
||||
/* pkg.c */
|
||||
PKGCONF_API bool pkgconf_error(const pkgconf_client_t *client, const char *format, ...) PRINTFLIKE(2, 3);
|
||||
@ -361,19 +330,19 @@ PKGCONF_API void pkgconf_pkg_unref(pkgconf_client_t *client, pkgconf_pkg_t *pkg)
|
||||
PKGCONF_API void pkgconf_pkg_free(pkgconf_client_t *client, pkgconf_pkg_t *pkg);
|
||||
PKGCONF_API pkgconf_pkg_t *pkgconf_pkg_find(pkgconf_client_t *client, const char *name);
|
||||
PKGCONF_API 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);
|
||||
PKGCONF_API unsigned int pkgconf_pkg_walk_conflicts_list(pkgconf_client_t *client, pkgconf_pkg_t *root, pkgconf_list_t *deplist);
|
||||
PKGCONF_API unsigned int pkgconf_pkg_verify_graph(pkgconf_client_t *client, pkgconf_pkg_t *root, int depth);
|
||||
PKGCONF_API pkgconf_pkg_t *pkgconf_pkg_verify_dependency(pkgconf_client_t *client, pkgconf_dependency_t *pkgdep, unsigned int *eflags);
|
||||
PKGCONF_API const char *pkgconf_pkg_get_comparator(const pkgconf_dependency_t *pkgdep);
|
||||
PKGCONF_API unsigned int pkgconf_pkg_cflags(pkgconf_client_t *client, pkgconf_pkg_t *root, pkgconf_list_t *list, int maxdepth);
|
||||
PKGCONF_API unsigned int pkgconf_pkg_libs(pkgconf_client_t *client, pkgconf_pkg_t *root, pkgconf_list_t *list, int maxdepth);
|
||||
PKGCONF_API pkgconf_pkg_comparator_t pkgconf_pkg_comparator_lookup_by_name(const char *name);
|
||||
PKGCONF_API pkgconf_pkg_t *pkgconf_builtin_pkg_get(const char *name);
|
||||
|
||||
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);
|
||||
|
||||
/* parse.c */
|
||||
PKGCONF_API pkgconf_pkg_t *pkgconf_pkg_new_from_path(pkgconf_client_t *client, const char *path, unsigned int flags);
|
||||
PKGCONF_API pkgconf_pkg_t *pkgconf_pkg_new_from_file(pkgconf_client_t *client, const char *path, FILE *f, unsigned int flags);
|
||||
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(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);
|
||||
@ -391,12 +360,11 @@ PKGCONF_API void pkgconf_argv_free(char **argv);
|
||||
/* fragment.c */
|
||||
typedef struct pkgconf_fragment_render_ops_ {
|
||||
size_t (*render_len)(const pkgconf_list_t *list, bool escape);
|
||||
void (*render_buf)(const pkgconf_list_t *list, pkgconf_buffer_t *buf, bool escape, char delim);
|
||||
void (*render_buf)(const pkgconf_list_t *list, char *buf, size_t len, bool escape);
|
||||
} pkgconf_fragment_render_ops_t;
|
||||
|
||||
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 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, 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_list(const pkgconf_client_t *client, pkgconf_list_t *list, const pkgconf_list_t *base);
|
||||
@ -404,9 +372,13 @@ PKGCONF_API void pkgconf_fragment_delete(pkgconf_list_t *list, pkgconf_fragment_
|
||||
PKGCONF_API void pkgconf_fragment_free(pkgconf_list_t *list);
|
||||
PKGCONF_API void pkgconf_fragment_filter(const pkgconf_client_t *client, pkgconf_list_t *dest, pkgconf_list_t *src, pkgconf_fragment_filter_func_t filter_func, void *data);
|
||||
PKGCONF_API size_t pkgconf_fragment_render_len(const pkgconf_list_t *list, bool escape, const pkgconf_fragment_render_ops_t *ops);
|
||||
PKGCONF_API void pkgconf_fragment_render_buf(const pkgconf_list_t *list, pkgconf_buffer_t *buf, bool escape, const pkgconf_fragment_render_ops_t *ops, char delim);
|
||||
PKGCONF_API void pkgconf_fragment_render_buf(const pkgconf_list_t *list, char *buf, size_t len, bool escape, const pkgconf_fragment_render_ops_t *ops);
|
||||
PKGCONF_API char *pkgconf_fragment_render(const pkgconf_list_t *list, bool escape, const pkgconf_fragment_render_ops_t *ops);
|
||||
PKGCONF_API bool pkgconf_fragment_has_system_dir(const pkgconf_client_t *client, const pkgconf_fragment_t *frag);
|
||||
|
||||
/* fileio.c */
|
||||
PKGCONF_API char *pkgconf_fgetline(char *line, size_t size, FILE *stream);
|
||||
|
||||
/* 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 char *pkgconf_tuple_find(const pkgconf_client_t *client, pkgconf_list_t *list, const char *key);
|
||||
@ -420,7 +392,6 @@ PKGCONF_API void pkgconf_tuple_define_global(pkgconf_client_t *client, const cha
|
||||
|
||||
/* queue.c */
|
||||
PKGCONF_API void pkgconf_queue_push(pkgconf_list_t *list, const char *package);
|
||||
PKGCONF_API void pkgconf_queue_push_dependency(pkgconf_list_t *list, const pkgconf_dependency_t *dep);
|
||||
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);
|
||||
@ -443,113 +414,11 @@ PKGCONF_API void pkgconf_audit_log_dependency(pkgconf_client_t *client, const pk
|
||||
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_build_from_environ(const pkgconf_client_t *client, const char *envvarname, const char *fallback, pkgconf_list_t *dirlist, bool filter);
|
||||
#ifdef _WIN32
|
||||
PKGCONF_API size_t pkgconf_path_build_from_registry(/* HKEY -> HANDLE -> PVOID */ void *hKey, pkgconf_list_t *dirlist, bool filter);
|
||||
#endif
|
||||
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 void pkgconf_path_free(pkgconf_list_t *dirlist);
|
||||
PKGCONF_API bool pkgconf_path_relocate(char *buf, size_t buflen);
|
||||
PKGCONF_API void pkgconf_path_copy_list(pkgconf_list_t *dst, const pkgconf_list_t *src);
|
||||
PKGCONF_API void pkgconf_path_prepend_list(pkgconf_list_t *dst, const pkgconf_list_t *src);
|
||||
|
||||
/* buffer.c */
|
||||
struct pkgconf_span_ {
|
||||
unsigned char lo;
|
||||
unsigned char hi; /* inclusive */
|
||||
};
|
||||
|
||||
static inline bool pkgconf_span_contains(unsigned char c, const pkgconf_span_t *spans, size_t nspans) {
|
||||
for (size_t i = 0; i < nspans; i++)
|
||||
if (c >= spans[i].lo && c <= spans[i].hi)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
PKGCONF_API void pkgconf_buffer_append(pkgconf_buffer_t *buffer, const char *text);
|
||||
PKGCONF_API void pkgconf_buffer_append_fmt(pkgconf_buffer_t *buffer, const char *fmt, ...) PRINTFLIKE(2, 3);
|
||||
PKGCONF_API void pkgconf_buffer_append_vfmt(pkgconf_buffer_t *buffer, const char *fmt, va_list va);
|
||||
PKGCONF_API void pkgconf_buffer_push_byte(pkgconf_buffer_t *buffer, char byte);
|
||||
PKGCONF_API void pkgconf_buffer_trim_byte(pkgconf_buffer_t *buffer);
|
||||
PKGCONF_API void pkgconf_buffer_finalize(pkgconf_buffer_t *buffer);
|
||||
PKGCONF_API void pkgconf_buffer_fputs(pkgconf_buffer_t *buffer, FILE *out);
|
||||
PKGCONF_API void pkgconf_buffer_vjoin(pkgconf_buffer_t *buffer, char delim, va_list va);
|
||||
PKGCONF_API void pkgconf_buffer_join(pkgconf_buffer_t *buffer, int delim, ...);
|
||||
PKGCONF_API bool pkgconf_buffer_contains(const pkgconf_buffer_t *haystack, const pkgconf_buffer_t *needle);
|
||||
PKGCONF_API bool pkgconf_buffer_contains_byte(const pkgconf_buffer_t *haystack, char needle);
|
||||
PKGCONF_API bool pkgconf_buffer_match(const pkgconf_buffer_t *haystack, const pkgconf_buffer_t *needle);
|
||||
PKGCONF_API void pkgconf_buffer_subst(pkgconf_buffer_t *dest, const pkgconf_buffer_t *src, const char *pattern, const char *value);
|
||||
PKGCONF_API void pkgconf_buffer_escape(pkgconf_buffer_t *dest, const pkgconf_buffer_t *src, const pkgconf_span_t *spans, size_t nspans);
|
||||
static inline const char *pkgconf_buffer_str(const pkgconf_buffer_t *buffer) {
|
||||
return buffer->base;
|
||||
}
|
||||
|
||||
static inline const char *pkgconf_buffer_str_or_empty(const pkgconf_buffer_t *buffer) {
|
||||
return buffer->base != NULL ? buffer->base : "";
|
||||
}
|
||||
|
||||
static inline size_t pkgconf_buffer_len(const pkgconf_buffer_t *buffer) {
|
||||
return (size_t)(ptrdiff_t)(buffer->end - buffer->base);
|
||||
}
|
||||
|
||||
static inline char pkgconf_buffer_lastc(const pkgconf_buffer_t *buffer) {
|
||||
if (buffer->base == buffer->end)
|
||||
return '\0';
|
||||
|
||||
return *(buffer->end - 1);
|
||||
}
|
||||
|
||||
#define PKGCONF_BUFFER_INITIALIZER { NULL, NULL }
|
||||
#define PKGCONF_BUFFER_FROM_STR(str) &(const pkgconf_buffer_t){ .base = str, .end = str + strlen(str) }
|
||||
|
||||
static inline void pkgconf_buffer_reset(pkgconf_buffer_t *buffer) {
|
||||
pkgconf_buffer_finalize(buffer);
|
||||
buffer->base = buffer->end = NULL;
|
||||
}
|
||||
|
||||
static inline char *pkgconf_buffer_freeze(pkgconf_buffer_t *buffer) {
|
||||
if (buffer->base == NULL)
|
||||
return NULL;
|
||||
|
||||
char *out = strdup(pkgconf_buffer_str(buffer));
|
||||
pkgconf_buffer_reset(buffer);
|
||||
return out;
|
||||
}
|
||||
|
||||
static inline void pkgconf_buffer_copy(pkgconf_buffer_t *buffer, pkgconf_buffer_t *newptr)
|
||||
{
|
||||
pkgconf_buffer_reset(newptr);
|
||||
pkgconf_buffer_append(newptr, pkgconf_buffer_str(buffer));
|
||||
}
|
||||
|
||||
/* fileio.c */
|
||||
PKGCONF_API bool pkgconf_fgetline(pkgconf_buffer_t *buffer, FILE *stream);
|
||||
|
||||
/* parser.c */
|
||||
typedef void (*pkgconf_parser_operand_func_t)(void *data, const char *warnprefix, const char *key, const char *value);
|
||||
typedef void (*pkgconf_parser_warn_func_t)(void *data, const char *fmt, ...);
|
||||
|
||||
PKGCONF_API void pkgconf_parser_parse_buffer(void *data, const pkgconf_parser_operand_func_t *ops, const pkgconf_parser_warn_func_t warnfunc, pkgconf_buffer_t *buffer, const char *warnprefix);
|
||||
PKGCONF_API void pkgconf_parser_parse(FILE *f, void *data, const pkgconf_parser_operand_func_t *ops, const pkgconf_parser_warn_func_t warnfunc, const char *filename);
|
||||
|
||||
/* output.c */
|
||||
typedef enum {
|
||||
PKGCONF_OUTPUT_STDOUT,
|
||||
PKGCONF_OUTPUT_STDERR,
|
||||
} pkgconf_output_stream_t;
|
||||
|
||||
struct pkgconf_output_ {
|
||||
void *privdata;
|
||||
|
||||
bool (*write)(pkgconf_output_t *output, pkgconf_output_stream_t stream, const pkgconf_buffer_t *buffer);
|
||||
};
|
||||
|
||||
PKGCONF_API bool pkgconf_output_putbuf(pkgconf_output_t *output, pkgconf_output_stream_t stream, const pkgconf_buffer_t *buffer, bool newline);
|
||||
PKGCONF_API bool pkgconf_output_puts(pkgconf_output_t *output, pkgconf_output_stream_t stream, const char *str);
|
||||
PKGCONF_API bool pkgconf_output_fmt(pkgconf_output_t *output, pkgconf_output_stream_t stream, const char *fmt, ...);
|
||||
PKGCONF_API bool pkgconf_output_vfmt(pkgconf_output_t *output, pkgconf_output_stream_t stream, const char *fmt, va_list va);
|
||||
PKGCONF_API pkgconf_output_t *pkgconf_output_default(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@ -1,110 +0,0 @@
|
||||
/*
|
||||
* output.c
|
||||
* I/O abstraction layer
|
||||
*
|
||||
* Copyright (c) 2025 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/stdinc.h>
|
||||
#include <libpkgconf/libpkgconf.h>
|
||||
|
||||
bool
|
||||
pkgconf_output_putbuf(pkgconf_output_t *output, pkgconf_output_stream_t stream, const pkgconf_buffer_t *buffer, bool newline)
|
||||
{
|
||||
bool ret;
|
||||
pkgconf_buffer_t buf = PKGCONF_BUFFER_INITIALIZER;
|
||||
|
||||
if (pkgconf_buffer_len(buffer) != 0)
|
||||
pkgconf_buffer_append(&buf, pkgconf_buffer_str(buffer));
|
||||
|
||||
if (newline)
|
||||
pkgconf_buffer_push_byte(&buf, '\n');
|
||||
|
||||
ret = output->write(output, stream, &buf);
|
||||
pkgconf_buffer_finalize(&buf);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool
|
||||
pkgconf_output_puts(pkgconf_output_t *output, pkgconf_output_stream_t stream, const char *str)
|
||||
{
|
||||
bool ret;
|
||||
pkgconf_buffer_t buf = PKGCONF_BUFFER_INITIALIZER;
|
||||
|
||||
pkgconf_buffer_append(&buf, str);
|
||||
pkgconf_buffer_push_byte(&buf, '\n');
|
||||
ret = output->write(output, stream, &buf);
|
||||
pkgconf_buffer_finalize(&buf);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool
|
||||
pkgconf_output_fmt(pkgconf_output_t *output, pkgconf_output_stream_t stream, const char *fmt, ...)
|
||||
{
|
||||
bool ret;
|
||||
va_list va;
|
||||
|
||||
va_start(va, fmt);
|
||||
ret = pkgconf_output_vfmt(output, stream, fmt, va);
|
||||
va_end(va);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool
|
||||
pkgconf_output_vfmt(pkgconf_output_t *output, pkgconf_output_stream_t stream, const char *fmt, va_list src_va)
|
||||
{
|
||||
va_list va;
|
||||
bool ret;
|
||||
pkgconf_buffer_t buf = PKGCONF_BUFFER_INITIALIZER;
|
||||
|
||||
va_copy(va, src_va);
|
||||
pkgconf_buffer_append_vfmt(&buf, fmt, va);
|
||||
va_end(va);
|
||||
|
||||
ret = output->write(output, stream, &buf);
|
||||
pkgconf_buffer_finalize(&buf);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool
|
||||
pkgconf_output_stdio_write(pkgconf_output_t *output, pkgconf_output_stream_t stream, const pkgconf_buffer_t *buffer)
|
||||
{
|
||||
(void) output;
|
||||
|
||||
FILE *target = stream == PKGCONF_OUTPUT_STDERR ? stderr : stdout;
|
||||
|
||||
if (buffer != NULL)
|
||||
{
|
||||
const char *str = pkgconf_buffer_str(buffer);
|
||||
size_t size = pkgconf_buffer_len(buffer);
|
||||
|
||||
if (size > 0 && !fwrite(str, size, 1, target))
|
||||
return false;
|
||||
}
|
||||
|
||||
fflush(target);
|
||||
return true;
|
||||
}
|
||||
|
||||
static pkgconf_output_t pkgconf_default_output = {
|
||||
.privdata = NULL,
|
||||
.write = pkgconf_output_stdio_write,
|
||||
};
|
||||
|
||||
pkgconf_output_t *
|
||||
pkgconf_output_default(void)
|
||||
{
|
||||
return &pkgconf_default_output;
|
||||
}
|
||||
@ -2,7 +2,7 @@
|
||||
* parser.c
|
||||
* rfc822 message parser
|
||||
*
|
||||
* Copyright (c) 2018, 2025 pkgconf authors (see AUTHORS).
|
||||
* Copyright (c) 2018 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
|
||||
@ -17,84 +17,90 @@
|
||||
#include <libpkgconf/stdinc.h>
|
||||
#include <libpkgconf/libpkgconf.h>
|
||||
|
||||
void
|
||||
pkgconf_parser_parse_buffer(void *data, const pkgconf_parser_operand_func_t *ops, const pkgconf_parser_warn_func_t warnfunc, pkgconf_buffer_t *buffer, const char *warnprefix)
|
||||
{
|
||||
char op, *p, *key, *value;
|
||||
|
||||
p = buffer->base;
|
||||
if (p == NULL)
|
||||
return;
|
||||
while (*p && isspace((unsigned char)*p))
|
||||
p++;
|
||||
if (*p && p != buffer->base)
|
||||
{
|
||||
warnfunc(data, "%s: warning: whitespace encountered while parsing key section\n",
|
||||
warnprefix);
|
||||
}
|
||||
key = p;
|
||||
while (*p && (isalpha((unsigned char)*p) || isdigit((unsigned char)*p) || *p == '_' || *p == '.'))
|
||||
p++;
|
||||
|
||||
if (!isalpha((unsigned char)*key) &&
|
||||
!isdigit((unsigned char)*p))
|
||||
return;
|
||||
|
||||
while (*p && isspace((unsigned char)*p))
|
||||
{
|
||||
warnfunc(data, "%s: warning: whitespace encountered while parsing key section\n",
|
||||
warnprefix);
|
||||
|
||||
/* set to null to avoid trailing spaces in key */
|
||||
*p = '\0';
|
||||
p++;
|
||||
}
|
||||
|
||||
op = *p;
|
||||
if (*p != '\0')
|
||||
{
|
||||
*p = '\0';
|
||||
p++;
|
||||
}
|
||||
|
||||
while (*p && isspace((unsigned char)*p))
|
||||
p++;
|
||||
|
||||
value = p;
|
||||
p = value + (strlen(value) - 1);
|
||||
while (*p && isspace((unsigned char) *p) && p > value)
|
||||
{
|
||||
if (op == '=')
|
||||
{
|
||||
warnfunc(data, "%s: warning: trailing whitespace encountered while parsing value section\n",
|
||||
warnprefix);
|
||||
}
|
||||
|
||||
*p = '\0';
|
||||
p--;
|
||||
}
|
||||
if (ops[(unsigned char) op])
|
||||
ops[(unsigned char) op](data, warnprefix, key, value);
|
||||
}
|
||||
|
||||
/*
|
||||
* !doc
|
||||
*
|
||||
* .. 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.
|
||||
*
|
||||
* :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 FILE* f: The file object to read from.
|
||||
* :returns: A ``pkgconf_pkg_t`` object which contains the package data.
|
||||
* :rtype: pkgconf_pkg_t *
|
||||
*/
|
||||
void
|
||||
pkgconf_parser_parse(FILE *f, void *data, const pkgconf_parser_operand_func_t *ops, const pkgconf_parser_warn_func_t warnfunc, const char *filename)
|
||||
{
|
||||
pkgconf_buffer_t readbuf = PKGCONF_BUFFER_INITIALIZER;
|
||||
char readbuf[PKGCONF_BUFSIZE];
|
||||
size_t lineno = 0;
|
||||
bool continue_reading = true;
|
||||
|
||||
while (continue_reading)
|
||||
while (pkgconf_fgetline(readbuf, PKGCONF_BUFSIZE, f) != NULL)
|
||||
{
|
||||
char warnprefix[PKGCONF_ITEM_SIZE];
|
||||
char op, *p, *key, *value;
|
||||
bool warned_key_whitespace = false, warned_value_whitespace = false;
|
||||
|
||||
continue_reading = pkgconf_fgetline(&readbuf, f);
|
||||
lineno++;
|
||||
|
||||
snprintf(warnprefix, sizeof warnprefix, "%s:" SIZE_FMT_SPECIFIER, filename, lineno);
|
||||
pkgconf_parser_parse_buffer(data, ops, warnfunc, &readbuf, warnprefix);
|
||||
pkgconf_buffer_reset(&readbuf);
|
||||
p = readbuf;
|
||||
while (*p && isspace((unsigned char)*p))
|
||||
p++;
|
||||
if (*p && p != readbuf)
|
||||
{
|
||||
warnfunc(data, "%s:" SIZE_FMT_SPECIFIER ": warning: whitespace encountered while parsing key section\n",
|
||||
filename, lineno);
|
||||
warned_key_whitespace = true;
|
||||
}
|
||||
key = p;
|
||||
while (*p && (isalpha((unsigned char)*p) || isdigit((unsigned char)*p) || *p == '_' || *p == '.'))
|
||||
p++;
|
||||
|
||||
if (!isalpha((unsigned char)*key) &&
|
||||
!isdigit((unsigned char)*p))
|
||||
continue;
|
||||
|
||||
while (*p && isspace((unsigned char)*p))
|
||||
{
|
||||
if (!warned_key_whitespace)
|
||||
{
|
||||
warnfunc(data, "%s:" SIZE_FMT_SPECIFIER ": warning: whitespace encountered while parsing key section\n",
|
||||
filename, lineno);
|
||||
warned_key_whitespace = true;
|
||||
}
|
||||
|
||||
/* set to null to avoid trailing spaces in key */
|
||||
*p = '\0';
|
||||
p++;
|
||||
}
|
||||
|
||||
op = *p;
|
||||
if (*p != '\0')
|
||||
{
|
||||
*p = '\0';
|
||||
p++;
|
||||
}
|
||||
|
||||
while (*p && isspace((unsigned char)*p))
|
||||
p++;
|
||||
|
||||
value = p;
|
||||
p = value + (strlen(value) - 1);
|
||||
while (*p && isspace((unsigned char) *p) && p > value)
|
||||
{
|
||||
if (!warned_value_whitespace && op == '=')
|
||||
{
|
||||
warnfunc(data, "%s:" SIZE_FMT_SPECIFIER ": warning: trailing whitespace encountered while parsing value section\n",
|
||||
filename, lineno);
|
||||
warned_value_whitespace = true;
|
||||
}
|
||||
|
||||
*p = '\0';
|
||||
p--;
|
||||
}
|
||||
if (ops[(unsigned char) op])
|
||||
ops[(unsigned char) op](data, lineno, key, value);
|
||||
}
|
||||
|
||||
pkgconf_buffer_finalize(&readbuf);
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
@ -91,9 +91,6 @@ prepare_path_node(const char *text, pkgconf_list_t *dirlist, bool filter)
|
||||
#endif
|
||||
|
||||
node = calloc(1, sizeof(pkgconf_path_t));
|
||||
if (node == NULL)
|
||||
return NULL;
|
||||
|
||||
node->path = strdup(path);
|
||||
|
||||
#ifdef PKGCONF_CACHE_INODES
|
||||
@ -192,7 +189,6 @@ pkgconf_path_split(const char *text, pkgconf_list_t *dirlist, bool filter)
|
||||
* 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.
|
||||
*
|
||||
* :param pkgconf_client_t* client: The client to use for environmental variable lookup (can be NULL).
|
||||
* :param char* envvarname: The environment variable to look up.
|
||||
* :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.
|
||||
@ -201,11 +197,11 @@ pkgconf_path_split(const char *text, pkgconf_list_t *dirlist, bool filter)
|
||||
* :rtype: size_t
|
||||
*/
|
||||
size_t
|
||||
pkgconf_path_build_from_environ(const pkgconf_client_t *client, const char *envvarname, const char *fallback, pkgconf_list_t *dirlist, bool filter)
|
||||
pkgconf_path_build_from_environ(const char *envvarname, const char *fallback, pkgconf_list_t *dirlist, bool filter)
|
||||
{
|
||||
const char *data;
|
||||
|
||||
data = pkgconf_client_getenv(client, envvarname);
|
||||
data = getenv(envvarname);
|
||||
if (data != NULL)
|
||||
return pkgconf_path_split(data, dirlist, filter);
|
||||
|
||||
@ -271,9 +267,6 @@ pkgconf_path_copy_list(pkgconf_list_t *dst, const pkgconf_list_t *src)
|
||||
pkgconf_path_t *srcpath = n->data, *path;
|
||||
|
||||
path = calloc(1, sizeof(pkgconf_path_t));
|
||||
if (path == NULL)
|
||||
continue;
|
||||
|
||||
path->path = strdup(srcpath->path);
|
||||
|
||||
#ifdef PKGCONF_CACHE_INODES
|
||||
@ -285,41 +278,6 @@ pkgconf_path_copy_list(pkgconf_list_t *dst, const pkgconf_list_t *src)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* !doc
|
||||
*
|
||||
* .. c:function:: void pkgconf_path_prepend_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
|
||||
*/
|
||||
void
|
||||
pkgconf_path_prepend_list(pkgconf_list_t *dst, const pkgconf_list_t *src)
|
||||
{
|
||||
pkgconf_node_t *n;
|
||||
|
||||
PKGCONF_FOREACH_LIST_ENTRY(src->head, n)
|
||||
{
|
||||
pkgconf_path_t *srcpath = n->data, *path;
|
||||
|
||||
path = calloc(1, sizeof(pkgconf_path_t));
|
||||
if (path == NULL)
|
||||
continue;
|
||||
|
||||
path->path = strdup(srcpath->path);
|
||||
|
||||
#ifdef PKGCONF_CACHE_INODES
|
||||
path->handle_path = srcpath->handle_path;
|
||||
path->handle_device = srcpath->handle_device;
|
||||
#endif
|
||||
|
||||
pkgconf_node_insert(&path->lnode, path, dst);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* !doc
|
||||
*
|
||||
@ -388,6 +346,10 @@ normpath(const char *path)
|
||||
bool
|
||||
pkgconf_path_relocate(char *buf, size_t buflen)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
char *ti;
|
||||
#endif
|
||||
|
||||
char *tmpbuf;
|
||||
|
||||
if ((tmpbuf = normpath(buf)) != NULL)
|
||||
@ -405,53 +367,3 @@ pkgconf_path_relocate(char *buf, size_t buflen)
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
#define PKG_CONFIG_REG_KEY "Software\\pkgconfig\\PKG_CONFIG_PATH"
|
||||
/*
|
||||
* !doc
|
||||
*
|
||||
* .. c:function:: void pkgconf_path_build_from_registry(HKEY hKey, pkgconf_list_t *dir_list, bool filter)
|
||||
*
|
||||
* Adds paths to a directory list discovered from a given registry key.
|
||||
*
|
||||
* :param HKEY hKey: The registry key to enumerate.
|
||||
* :param pkgconf_list_t* dir_list: The directory list to append enumerated paths to.
|
||||
* :param bool filter: Whether duplicate paths should be filtered.
|
||||
* :return: number of path nodes added to the list
|
||||
* :rtype: size_t
|
||||
*/
|
||||
size_t
|
||||
pkgconf_path_build_from_registry(void *hKey, pkgconf_list_t *dir_list, bool filter)
|
||||
{
|
||||
HKEY key;
|
||||
int i = 0;
|
||||
size_t added = 0;
|
||||
|
||||
char buf[16384]; /* per registry limits */
|
||||
DWORD bufsize = sizeof buf;
|
||||
if (RegOpenKeyEx(hKey, PKG_CONFIG_REG_KEY,
|
||||
0, KEY_READ, &key) != ERROR_SUCCESS)
|
||||
return 0;
|
||||
|
||||
while (RegEnumValue(key, i++, buf, &bufsize, NULL, NULL, NULL, NULL)
|
||||
== ERROR_SUCCESS)
|
||||
{
|
||||
char pathbuf[PKGCONF_ITEM_SIZE];
|
||||
DWORD type;
|
||||
DWORD pathbuflen = sizeof pathbuf;
|
||||
|
||||
if (RegQueryValueEx(key, buf, NULL, &type, (LPBYTE) pathbuf, &pathbuflen)
|
||||
== ERROR_SUCCESS && type == REG_SZ)
|
||||
{
|
||||
pkgconf_path_add(pathbuf, dir_list, filter);
|
||||
added++;
|
||||
}
|
||||
|
||||
bufsize = sizeof buf;
|
||||
}
|
||||
|
||||
RegCloseKey(key);
|
||||
return added;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -24,6 +24,10 @@
|
||||
* =========================
|
||||
*/
|
||||
|
||||
#ifdef _WIN32
|
||||
# define strcasecmp _stricmp
|
||||
#endif
|
||||
|
||||
/*
|
||||
* 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
|
||||
@ -33,6 +37,10 @@ static unsigned default_personality_init = 0;
|
||||
|
||||
static pkgconf_cross_personality_t default_personality = {
|
||||
.name = "default",
|
||||
#ifdef _WIN32
|
||||
.want_default_static = true,
|
||||
.want_default_pure = true,
|
||||
#endif
|
||||
};
|
||||
|
||||
static inline void
|
||||
@ -79,7 +87,7 @@ build_default_search_path(pkgconf_list_t* dirlist)
|
||||
paths = NULL;
|
||||
}
|
||||
#else
|
||||
pkgconf_path_split(PKG_DEFAULT_PATH, dirlist, false);
|
||||
pkgconf_path_split(PKG_DEFAULT_PATH, dirlist, true);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -117,8 +125,7 @@ pkgconf_cross_personality_default(void)
|
||||
*
|
||||
* .. c:function:: void pkgconf_cross_personality_deinit(pkgconf_cross_personality_t *)
|
||||
*
|
||||
* Destroys a cross personality object and/or decreases the reference count on the
|
||||
* default cross personality object.
|
||||
* Decrements the count of default cross personality instances.
|
||||
*
|
||||
* Not thread safe.
|
||||
*
|
||||
@ -127,28 +134,11 @@ pkgconf_cross_personality_default(void)
|
||||
void
|
||||
pkgconf_cross_personality_deinit(pkgconf_cross_personality_t *personality)
|
||||
{
|
||||
/* allow NULL parameter for API backwards compatibility */
|
||||
if (personality == NULL)
|
||||
return;
|
||||
|
||||
/* XXX: this hack is rather ugly, but it works for now... */
|
||||
if (personality == &default_personality && --default_personality_init > 0)
|
||||
return;
|
||||
|
||||
pkgconf_path_free(&personality->dir_list);
|
||||
pkgconf_path_free(&personality->filter_libdirs);
|
||||
pkgconf_path_free(&personality->filter_includedirs);
|
||||
|
||||
if (personality->sysroot_dir != NULL)
|
||||
free(personality->sysroot_dir);
|
||||
|
||||
if (personality == &default_personality)
|
||||
return;
|
||||
|
||||
if (personality->name != NULL)
|
||||
free(personality->name);
|
||||
|
||||
free(personality);
|
||||
if (--default_personality_init == 0) {
|
||||
pkgconf_path_free(&personality->dir_list);
|
||||
pkgconf_path_free(&personality->filter_libdirs);
|
||||
pkgconf_path_free(&personality->filter_includedirs);
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef PKGCONF_LITE
|
||||
@ -164,7 +154,7 @@ valid_triplet(const char *triplet)
|
||||
return true;
|
||||
}
|
||||
|
||||
typedef void (*personality_keyword_func_t)(pkgconf_cross_personality_t *p, const char *keyword, const char *warnprefix, const ptrdiff_t offset, char *value);
|
||||
typedef void (*personality_keyword_func_t)(pkgconf_cross_personality_t *p, const char *keyword, const size_t lineno, const ptrdiff_t offset, char *value);
|
||||
typedef struct {
|
||||
const char *keyword;
|
||||
const personality_keyword_func_t func;
|
||||
@ -172,30 +162,30 @@ typedef struct {
|
||||
} personality_keyword_pair_t;
|
||||
|
||||
static void
|
||||
personality_bool_func(pkgconf_cross_personality_t *p, const char *keyword, const char *warnprefix, const ptrdiff_t offset, char *value)
|
||||
personality_bool_func(pkgconf_cross_personality_t *p, const char *keyword, const size_t lineno, const ptrdiff_t offset, char *value)
|
||||
{
|
||||
(void) keyword;
|
||||
(void) warnprefix;
|
||||
(void) lineno;
|
||||
|
||||
bool *dest = (bool *)((char *) p + offset);
|
||||
*dest = strcasecmp(value, "true") || strcasecmp(value, "yes") || *value == '1';
|
||||
}
|
||||
|
||||
static void
|
||||
personality_copy_func(pkgconf_cross_personality_t *p, const char *keyword, const char *warnprefix, const ptrdiff_t offset, char *value)
|
||||
personality_copy_func(pkgconf_cross_personality_t *p, const char *keyword, const size_t lineno, const ptrdiff_t offset, char *value)
|
||||
{
|
||||
(void) keyword;
|
||||
(void) warnprefix;
|
||||
(void) lineno;
|
||||
|
||||
char **dest = (char **)((char *) p + offset);
|
||||
*dest = strdup(value);
|
||||
}
|
||||
|
||||
static void
|
||||
personality_fragment_func(pkgconf_cross_personality_t *p, const char *keyword, const char *warnprefix, const ptrdiff_t offset, char *value)
|
||||
personality_fragment_func(pkgconf_cross_personality_t *p, const char *keyword, const size_t lineno, const ptrdiff_t offset, char *value)
|
||||
{
|
||||
(void) keyword;
|
||||
(void) warnprefix;
|
||||
(void) lineno;
|
||||
|
||||
pkgconf_list_t *dest = (pkgconf_list_t *)((char *) p + offset);
|
||||
pkgconf_path_split(value, dest, false);
|
||||
@ -220,7 +210,7 @@ personality_keyword_pair_cmp(const void *key, const void *ptr)
|
||||
}
|
||||
|
||||
static void
|
||||
personality_keyword_set(pkgconf_cross_personality_t *p, const char *warnprefix, const char *keyword, char *value)
|
||||
personality_keyword_set(pkgconf_cross_personality_t *p, const size_t lineno, const char *keyword, char *value)
|
||||
{
|
||||
const personality_keyword_pair_t *pair = bsearch(keyword,
|
||||
personality_keyword_pairs, PKGCONF_ARRAY_SIZE(personality_keyword_pairs),
|
||||
@ -229,7 +219,7 @@ personality_keyword_set(pkgconf_cross_personality_t *p, const char *warnprefix,
|
||||
if (pair == NULL || pair->func == NULL)
|
||||
return;
|
||||
|
||||
pair->func(p, keyword, warnprefix, pair->offset, value);
|
||||
pair->func(p, keyword, lineno, pair->offset, value);
|
||||
}
|
||||
|
||||
static const pkgconf_parser_operand_func_t personality_parser_ops[256] = {
|
||||
@ -265,19 +255,13 @@ load_personality_with_path(const char *path, const char *triplet, bool datadir)
|
||||
else
|
||||
snprintf(pathbuf, sizeof pathbuf, "%s/%s.personality", path, triplet);
|
||||
|
||||
p = calloc(1, sizeof(pkgconf_cross_personality_t));
|
||||
if (p == NULL)
|
||||
f = fopen(pathbuf, "r");
|
||||
if (f == NULL)
|
||||
return NULL;
|
||||
|
||||
p = calloc(1, sizeof(pkgconf_cross_personality_t));
|
||||
if (triplet != NULL)
|
||||
p->name = strdup(triplet);
|
||||
|
||||
f = fopen(pathbuf, "r");
|
||||
if (f == NULL) {
|
||||
pkgconf_cross_personality_deinit(p);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pkgconf_parser_parse(f, p, personality_parser_ops, personality_warn_func, pathbuf);
|
||||
|
||||
return p;
|
||||
@ -324,7 +308,7 @@ pkgconf_cross_personality_find(const char *triplet)
|
||||
}
|
||||
}
|
||||
|
||||
pkgconf_path_build_from_environ(NULL, "XDG_DATA_DIRS", "/usr/local/share" PKG_CONFIG_PATH_SEP_S "/usr/share", &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)
|
||||
{
|
||||
|
||||
648
libpkgconf/pkg.c
648
libpkgconf/pkg.c
File diff suppressed because it is too large
Load Diff
@ -29,32 +29,6 @@
|
||||
* Using the `queue` module functions is the recommended way of working with dependency graphs.
|
||||
*/
|
||||
|
||||
/*
|
||||
* !doc
|
||||
*
|
||||
* .. c:function:: void pkgconf_queue_push_dependency(pkgconf_list_t *list, const pkgconf_dependency_t *dep)
|
||||
*
|
||||
* Pushes a requested dependency onto the dependency resolver's queue which is described by
|
||||
* a pkgconf_dependency_t node.
|
||||
*
|
||||
* :param pkgconf_list_t* list: the dependency resolution queue to add the package request to.
|
||||
* :param pkgconf_dependency_t* dep: the dependency requested
|
||||
* :return: nothing
|
||||
*/
|
||||
void
|
||||
pkgconf_queue_push_dependency(pkgconf_list_t *list, const pkgconf_dependency_t *dep)
|
||||
{
|
||||
pkgconf_buffer_t depbuf = PKGCONF_BUFFER_INITIALIZER;
|
||||
pkgconf_queue_t *pkgq = calloc(1, sizeof(pkgconf_queue_t));
|
||||
|
||||
pkgconf_buffer_append(&depbuf, dep->package);
|
||||
if (dep->version != NULL)
|
||||
pkgconf_buffer_append_fmt(&depbuf, " %s %s", pkgconf_pkg_get_comparator(dep), dep->version);
|
||||
|
||||
pkgq->package = pkgconf_buffer_freeze(&depbuf);
|
||||
pkgconf_node_insert_tail(&pkgq->iter, pkgq, list);
|
||||
}
|
||||
|
||||
/*
|
||||
* !doc
|
||||
*
|
||||
@ -98,7 +72,7 @@ pkgconf_queue_compile(pkgconf_client_t *client, pkgconf_pkg_t *world, pkgconf_li
|
||||
pkgconf_queue_t *pkgq;
|
||||
|
||||
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);
|
||||
@ -129,169 +103,134 @@ pkgconf_queue_free(pkgconf_list_t *list)
|
||||
}
|
||||
|
||||
static void
|
||||
pkgconf_queue_mark_public(pkgconf_client_t *client, pkgconf_pkg_t *pkg, void *data)
|
||||
pkgconf_queue_collect_dependents(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)
|
||||
if (pkg == world)
|
||||
return;
|
||||
|
||||
PKGCONF_FOREACH_LIST_ENTRY(pkg->required.head, node)
|
||||
{
|
||||
pkgconf_dependency_t *parent_dep = node->data;
|
||||
pkgconf_dependency_t *flattened_dep;
|
||||
|
||||
flattened_dep = pkgconf_dependency_copy(client, parent_dep);
|
||||
|
||||
if ((client->flags & PKGCONF_PKG_PKGF_ITER_PKG_IS_PRIVATE) != PKGCONF_PKG_PKGF_ITER_PKG_IS_PRIVATE)
|
||||
pkgconf_node_insert(&flattened_dep->iter, flattened_dep, &world->required);
|
||||
else
|
||||
pkgconf_node_insert(&flattened_dep->iter, flattened_dep, &world->requires_private);
|
||||
}
|
||||
|
||||
if (client->flags & PKGCONF_PKG_PKGF_SEARCH_PRIVATE)
|
||||
{
|
||||
PKGCONF_FOREACH_LIST_ENTRY(pkg->requires_private.head, node)
|
||||
{
|
||||
pkgconf_dependency_t *parent_dep = node->data;
|
||||
pkgconf_dependency_t *flattened_dep;
|
||||
|
||||
flattened_dep = pkgconf_dependency_copy(client, parent_dep);
|
||||
|
||||
pkgconf_node_insert(&flattened_dep->iter, flattened_dep, &world->requires_private);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
dep_sort_cmp(const void *a, const void *b)
|
||||
{
|
||||
const pkgconf_dependency_t *depA = *(void **) a;
|
||||
const pkgconf_dependency_t *depB = *(void **) b;
|
||||
|
||||
return depB->match->identifier - depA->match->identifier;
|
||||
}
|
||||
|
||||
static inline void
|
||||
flatten_dependency_set(pkgconf_client_t *client, pkgconf_list_t *list)
|
||||
{
|
||||
pkgconf_node_t *node, *next;
|
||||
pkgconf_dependency_t **deps = NULL;
|
||||
size_t dep_count = 0, i;
|
||||
|
||||
PKGCONF_FOREACH_LIST_ENTRY_SAFE(list->head, next, node)
|
||||
{
|
||||
pkgconf_dependency_t *dep = node->data;
|
||||
pkgconf_dependency_t *flattened_dep;
|
||||
pkgconf_pkg_t *pkg = dep->match;
|
||||
|
||||
if (*dep->package == '\0')
|
||||
continue;
|
||||
pkgconf_pkg_t *pkg = pkgconf_pkg_verify_dependency(client, dep, NULL);
|
||||
|
||||
if (pkg == NULL)
|
||||
{
|
||||
PKGCONF_TRACE(client, "WTF: unmatched dependency %p <%s>", dep, dep->package);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (pkg->serial == client->serial)
|
||||
continue;
|
||||
{
|
||||
pkgconf_node_delete(node, list);
|
||||
pkgconf_dependency_unref(client, dep);
|
||||
goto next;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
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
|
||||
pkgconf_queue_collect_conflicts(pkgconf_client_t *client,
|
||||
pkgconf_pkg_t *root,
|
||||
pkgconf_pkg_t *world,
|
||||
int maxdepth)
|
||||
{
|
||||
unsigned int eflags = PKGCONF_PKG_ERRF_OK;
|
||||
pkgconf_node_t *node;
|
||||
|
||||
PKGCONF_TRACE(client, "%s: collecting conflicts, level %d", root->id, maxdepth);
|
||||
|
||||
PKGCONF_FOREACH_LIST_ENTRY(root->required.head, node)
|
||||
{
|
||||
pkgconf_dependency_t *dep = node->data;
|
||||
pkgconf_pkg_t *pkg = dep->match;
|
||||
pkgconf_node_t *cnode;
|
||||
|
||||
if (*dep->package == '\0')
|
||||
continue;
|
||||
|
||||
if (pkg == NULL)
|
||||
if (dep->match == NULL)
|
||||
{
|
||||
PKGCONF_TRACE(client, "WTF: unmatched dependency %p <%s>", dep, dep->package);
|
||||
continue;
|
||||
abort();
|
||||
}
|
||||
|
||||
PKGCONF_FOREACH_LIST_ENTRY(pkg->conflicts.head, cnode)
|
||||
/* for virtuals, we need to check to see if there are dupes */
|
||||
for (i = 0; i < dep_count; i++)
|
||||
{
|
||||
pkgconf_dependency_t *conflict = cnode->data;
|
||||
pkgconf_dependency_t *flattened_conflict = pkgconf_dependency_copy(client, conflict);
|
||||
pkgconf_dependency_t *other_dep = deps[i];
|
||||
|
||||
flattened_conflict->why = strdup(pkg->id);
|
||||
pkgconf_node_insert(&flattened_conflict->iter, flattened_conflict, &world->conflicts);
|
||||
PKGCONF_TRACE(client, "dedup %s = %s?", dep->package, other_dep->package);
|
||||
|
||||
if (!strcmp(dep->package, other_dep->package))
|
||||
{
|
||||
PKGCONF_TRACE(client, "skipping, "SIZE_FMT_SPECIFIER" deps", dep_count);
|
||||
goto next;
|
||||
}
|
||||
}
|
||||
|
||||
pkg->serial = client->serial;
|
||||
|
||||
/* copy to the deps table */
|
||||
dep_count++;
|
||||
deps = pkgconf_reallocarray(deps, dep_count, sizeof (void *));
|
||||
deps[dep_count - 1] = dep;
|
||||
|
||||
PKGCONF_TRACE(client, "added %s to dep table", dep->package);
|
||||
next:
|
||||
pkgconf_pkg_unref(client, pkg);
|
||||
}
|
||||
|
||||
return eflags;
|
||||
if (deps == NULL)
|
||||
return;
|
||||
|
||||
qsort(deps, dep_count, sizeof (void *), dep_sort_cmp);
|
||||
|
||||
/* zero the list and start readding */
|
||||
pkgconf_list_zero(list);
|
||||
|
||||
for (i = 0; i < dep_count; i++)
|
||||
{
|
||||
pkgconf_dependency_t *dep = deps[i];
|
||||
|
||||
if (dep->match == NULL)
|
||||
continue;
|
||||
|
||||
memset(&dep->iter, '\0', sizeof (dep->iter));
|
||||
pkgconf_node_insert(&dep->iter, dep, list);
|
||||
|
||||
PKGCONF_TRACE(client, "slot "SIZE_FMT_SPECIFIER": dep %s matched to %p<%s> id %"PRIu64, i, dep->package, dep->match, dep->match->id, dep->match->identifier);
|
||||
}
|
||||
|
||||
free(deps);
|
||||
}
|
||||
|
||||
static inline unsigned int
|
||||
pkgconf_queue_verify(pkgconf_client_t *client, pkgconf_pkg_t *world, pkgconf_list_t *list, int maxdepth)
|
||||
{
|
||||
unsigned int result;
|
||||
const unsigned int saved_flags = client->flags;
|
||||
pkgconf_pkg_t initial_world = {
|
||||
.id = "user:request",
|
||||
.id = "virtual:world",
|
||||
.realname = "virtual world package",
|
||||
.flags = PKGCONF_PKG_PROPF_STATIC | PKGCONF_PKG_PROPF_VIRTUAL,
|
||||
};
|
||||
@ -302,58 +241,31 @@ pkgconf_queue_verify(pkgconf_client_t *client, pkgconf_pkg_t *world, pkgconf_lis
|
||||
return PKGCONF_PKG_ERRF_DEPGRAPH_BREAK;
|
||||
}
|
||||
|
||||
PKGCONF_TRACE(client, "solving");
|
||||
result = pkgconf_pkg_traverse(client, &initial_world, NULL, NULL, maxdepth, 0);
|
||||
/* collect all the dependencies */
|
||||
result = pkgconf_pkg_traverse(client, &initial_world, pkgconf_queue_collect_dependents, world, 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;
|
||||
}
|
||||
|
||||
result = pkgconf_queue_collect_conflicts(client, 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;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(client->flags & PKGCONF_PKG_PKGF_SKIP_CONFLICTS))
|
||||
{
|
||||
PKGCONF_TRACE(client, "checking for conflicts");
|
||||
|
||||
result = pkgconf_pkg_walk_conflicts_list(client, world, &world->conflicts);
|
||||
if (result != PKGCONF_PKG_ERRF_OK)
|
||||
{
|
||||
pkgconf_solution_free(client, &initial_world);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/* free the initial solution */
|
||||
pkgconf_solution_free(client, &initial_world);
|
||||
|
||||
/* flatten the dependency set using serials.
|
||||
* we copy the dependencies to a vector, and then erase the list.
|
||||
* then we copy them back to the list.
|
||||
*/
|
||||
++client->serial;
|
||||
|
||||
PKGCONF_TRACE(client, "flattening requires deps");
|
||||
flatten_dependency_set(client, &world->required);
|
||||
|
||||
++client->serial;
|
||||
|
||||
PKGCONF_TRACE(client, "flattening requires.private deps");
|
||||
flatten_dependency_set(client, &world->requires_private);
|
||||
|
||||
return PKGCONF_PKG_ERRF_OK;
|
||||
}
|
||||
|
||||
@ -377,7 +289,6 @@ pkgconf_solution_free(pkgconf_client_t *client, pkgconf_pkg_t *world)
|
||||
{
|
||||
pkgconf_dependency_free(&world->required);
|
||||
pkgconf_dependency_free(&world->requires_private);
|
||||
pkgconf_dependency_free(&world->conflicts);
|
||||
}
|
||||
}
|
||||
|
||||
@ -402,13 +313,7 @@ pkgconf_queue_solve(pkgconf_client_t *client, pkgconf_list_t *list, pkgconf_pkg_
|
||||
if (!maxdepth)
|
||||
maxdepth = -1;
|
||||
|
||||
unsigned int flags = client->flags;
|
||||
client->flags |= PKGCONF_PKG_PKGF_SEARCH_PRIVATE;
|
||||
|
||||
unsigned int ret = pkgconf_queue_verify(client, world, list, maxdepth);
|
||||
client->flags = flags;
|
||||
|
||||
return ret == PKGCONF_PKG_ERRF_OK;
|
||||
return pkgconf_queue_verify(client, world, list, maxdepth) == PKGCONF_PKG_ERRF_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@ -25,21 +25,14 @@
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <stdint.h>
|
||||
#include <errno.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
# define WIN32_LEAN_AND_MEAN
|
||||
# include <windows.h>
|
||||
# include <malloc.h>
|
||||
# include <io.h> /* for _setmode() */
|
||||
# include <fcntl.h>
|
||||
# define PATH_DEV_NULL "nul"
|
||||
# ifdef _WIN64
|
||||
# ifndef __MINGW32__
|
||||
# define SIZE_FMT_SPECIFIER "%I64u"
|
||||
# else
|
||||
# define SIZE_FMT_SPECIFIER "%llu"
|
||||
# endif
|
||||
# define SIZE_FMT_SPECIFIER "%I64u"
|
||||
# else
|
||||
# define SIZE_FMT_SPECIFIER "%u"
|
||||
# endif
|
||||
@ -54,14 +47,9 @@
|
||||
# ifndef __MINGW32__
|
||||
# include "win-dirent.h"
|
||||
# else
|
||||
# include <dirent.h>
|
||||
# include <dirent.h>
|
||||
# endif
|
||||
# define PKGCONF_ITEM_SIZE (_MAX_PATH + 1024)
|
||||
# define PKG_CONFIG_PATH_SEP_S ";"
|
||||
# define PKG_DIR_SEP_S '\\'
|
||||
# define strcasecmp _stricmp
|
||||
# define strncasecmp _strnicmp
|
||||
# define realpath(N,R) _fullpath((R),(N),_MAX_PATH)
|
||||
#else
|
||||
# define PATH_DEV_NULL "/dev/null"
|
||||
# define SIZE_FMT_SPECIFIER "%zu"
|
||||
@ -72,18 +60,11 @@
|
||||
# include <unistd.h>
|
||||
# include <limits.h>
|
||||
# include <strings.h>
|
||||
# include <fcntl.h> // open
|
||||
# include <libgen.h> // basename/dirname
|
||||
# include <sys/stat.h> // lstat, S_ISLNK
|
||||
# include <unistd.h> // close, readlinkat
|
||||
# include <string.h>
|
||||
# ifdef PATH_MAX
|
||||
# define PKGCONF_ITEM_SIZE (PATH_MAX + 1024)
|
||||
# else
|
||||
# define PKGCONF_ITEM_SIZE (4096 + 1024)
|
||||
# endif
|
||||
# define PKG_CONFIG_PATH_SEP_S ":"
|
||||
# define PKG_DIR_SEP_S '/'
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@ -199,7 +199,7 @@ should_rewrite_sysroot(const pkgconf_client_t *client, pkgconf_list_t *vars, con
|
||||
return false;
|
||||
|
||||
sysroot_dir = find_sysroot(client, vars);
|
||||
if (sysroot_dir == NULL || !*sysroot_dir)
|
||||
if (sysroot_dir == NULL)
|
||||
return false;
|
||||
|
||||
if (*buf != '/')
|
||||
@ -238,6 +238,8 @@ pkgconf_tuple_add(const pkgconf_client_t *client, pkgconf_list_t *list, const ch
|
||||
char *dequote_value;
|
||||
pkgconf_tuple_t *tuple = calloc(1, sizeof(pkgconf_tuple_t));
|
||||
|
||||
pkgconf_tuple_find_delete(list, key);
|
||||
|
||||
dequote_value = dequote(value);
|
||||
|
||||
tuple->key = strdup(key);
|
||||
@ -248,8 +250,6 @@ pkgconf_tuple_add(const pkgconf_client_t *client, pkgconf_list_t *list, const ch
|
||||
|
||||
PKGCONF_TRACE(client, "adding tuple to @%p: %s => %s (parsed? %d)", list, key, tuple->value, parse);
|
||||
|
||||
pkgconf_tuple_find_delete(list, key);
|
||||
|
||||
pkgconf_node_insert(&tuple->iter, tuple, list);
|
||||
|
||||
free(dequote_value);
|
||||
@ -314,13 +314,12 @@ pkgconf_tuple_parse(const pkgconf_client_t *client, pkgconf_list_t *vars, const
|
||||
char buf[PKGCONF_BUFSIZE];
|
||||
const char *ptr;
|
||||
char *bptr = buf;
|
||||
const char *sysroot_dir = find_sysroot(client, vars);
|
||||
|
||||
if (!(client->flags & PKGCONF_PKG_PKGF_FDO_SYSROOT_RULES) &&
|
||||
(!(flags & PKGCONF_PKG_PROPF_UNINSTALLED) || (client->flags & PKGCONF_PKG_PKGF_PKGCONF1_SYSROOT_RULES)))
|
||||
{
|
||||
if (*value == '/' && sysroot_dir != NULL && *sysroot_dir && strncmp(value, sysroot_dir, strlen(sysroot_dir)))
|
||||
bptr += pkgconf_strlcpy(buf, sysroot_dir, sizeof buf);
|
||||
if (*value == '/' && client->sysroot_dir != NULL && strncmp(value, client->sysroot_dir, strlen(client->sysroot_dir)))
|
||||
bptr += pkgconf_strlcpy(buf, client->sysroot_dir, sizeof buf);
|
||||
}
|
||||
|
||||
for (ptr = value; *ptr != '\0' && bptr - buf < PKGCONF_BUFSIZE; ptr++)
|
||||
@ -422,6 +421,7 @@ pkgconf_tuple_parse(const pkgconf_client_t *client, pkgconf_list_t *vars, const
|
||||
if (should_rewrite_sysroot(client, vars, buf, flags))
|
||||
{
|
||||
char cleanpath[PKGCONF_ITEM_SIZE];
|
||||
const char *sysroot_dir = find_sysroot(client, vars);
|
||||
|
||||
pkgconf_strlcpy(cleanpath, buf + strlen(sysroot_dir), sizeof cleanpath);
|
||||
pkgconf_path_relocate(cleanpath, sizeof cleanpath);
|
||||
|
||||
100
man/bomtool.1
100
man/bomtool.1
@ -1,100 +0,0 @@
|
||||
.\" Copyright (c) 2025 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.
|
||||
.Dd June 4, 2025
|
||||
.Dt BOMTOOL 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm bomtool
|
||||
.Nd a tool for generating SPDX-based software bills of material
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Ar options
|
||||
.Ar module ...
|
||||
.Sh DESCRIPTION
|
||||
.Nm
|
||||
is a program which generates a textual SPDX 2.0 software bill of
|
||||
materials (SBOM) for a given set of pkg-config modules.
|
||||
The output of this tool can then be translated into other SBOM
|
||||
formats as necessary.
|
||||
.Pp
|
||||
The
|
||||
.Ar options
|
||||
are as follows:
|
||||
.Bl -tag -width indent
|
||||
.It Fl -about
|
||||
Print the version number, the Copyright notice, and the license of the
|
||||
.Nm
|
||||
program to standard output and exit.
|
||||
Most other options and all command line arguments are ignored.
|
||||
.It Fl -version
|
||||
Print the version number of the
|
||||
.Nm
|
||||
program to standard output and exit.
|
||||
Most other options and all command line arguments are ignored.
|
||||
.El
|
||||
.Sh ENVIRONMENT
|
||||
.Bl -tag -width indent
|
||||
.It Ev PKG_CONFIG_DEBUG_SPEW
|
||||
If set, print debugging messages to stderr.
|
||||
.It Ev PKG_CONFIG_IGNORE_CONFLICTS
|
||||
If set, ignore
|
||||
.Ic Conflicts
|
||||
rules in modules.
|
||||
Has the same effect as the
|
||||
.Fl -ignore-conflicts
|
||||
option in
|
||||
.Xr pkgconf 1
|
||||
.
|
||||
.It Ev PKG_CONFIG_LIBDIR
|
||||
A colon-separated list of low-priority directories where
|
||||
.Xr pc 5
|
||||
files are looked up.
|
||||
The module search path is constructed by appending this list to
|
||||
.Ev PKG_CONFIG_PATH ,
|
||||
which enjoys higher priority.
|
||||
If
|
||||
.Ev PKG_CONFIG_LIBDIR
|
||||
is not defined, the default list compiled into the
|
||||
.Nm
|
||||
program from the
|
||||
.Dv PKG_DEFAULT_PATH
|
||||
preprocessor macro is appended instead.
|
||||
If
|
||||
.Ev PKG_CONFIG_LIBDIR
|
||||
is defined but empty, nothing is appended.
|
||||
.It Ev PKG_CONFIG_MAXIMUM_TRAVERSE_DEPTH
|
||||
Impose a limit on the allowed depth in the dependency graph.
|
||||
.It Ev PKG_CONFIG_PATH
|
||||
A colon-separated list of high-priority directories where
|
||||
.Xr pc 5
|
||||
files are looked up.
|
||||
.It Ev PKG_CONFIG_PRELOADED_FILES
|
||||
Colon-separated list of
|
||||
.Xr pc 5
|
||||
files which are loaded before any other pkg-config files.
|
||||
These packages are given highest priority over any other
|
||||
.Xr pc 5
|
||||
files that would otherwise provide a given package.
|
||||
.El
|
||||
.Sh EXIT STATUS
|
||||
.Ex -std
|
||||
.Sh EXAMPLES
|
||||
Generating an SBOM for the package named foo:
|
||||
.Dl $ bomtool foo
|
||||
.Dl SPDXVersion: SPDX-2.2
|
||||
.Dl DataLicense: CC0-1.0
|
||||
.Dl SPDXID: SPDXRef-DOCUMENT
|
||||
.Dl DocumentName: SBOM-SPDX-fooC641.2.3
|
||||
.Dl DocumentNamespace: https://spdx.org/spdxdocs/bomtool-2.4.3
|
||||
.Dl Creator: Tool: bomtool 2.4.3
|
||||
.Dl [...]
|
||||
.Sh SEE ALSO
|
||||
.Xr pc 5 ,
|
||||
.Xr pkgconf 1
|
||||
21
man/pc.5
21
man/pc.5
@ -116,36 +116,19 @@ not described as dependencies should be specified here.
|
||||
.It License
|
||||
The asserted SPDX license tag that should be applied to the given package.
|
||||
(optional; literal; pkgconf extension)
|
||||
.It License.file
|
||||
License file location for whole license text.
|
||||
(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 Source
|
||||
The asserted SPDX downloadLocation tag that should be applied to the given package.
|
||||
Source should be URI contain tarball with exact version or Repository that contains
|
||||
tag with version same as mentioned in version tag. It can be also be URI with hash
|
||||
that is exact release point of the source.
|
||||
(optional; literal; pkgconf extension)
|
||||
.It Requires
|
||||
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
|
||||
the package.
|
||||
(optional; dependency list)
|
||||
.It Requires.internal
|
||||
Required dependencies that must be met for the package to be usable for
|
||||
static linking.
|
||||
The main differences verses Requires.private are that CFLAGS will not be
|
||||
included and the solver will not consider the dependency when solving for
|
||||
CFLAGS only.
|
||||
(optional; dependency list; pkgconf extension)
|
||||
.It Requires.private
|
||||
Required dependencies that must be met for the package to be usable for header
|
||||
inclusion and static linking.
|
||||
Required dependencies that must be met for the package to be usable for static linking.
|
||||
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)
|
||||
.It Conflicts
|
||||
Dependencies that must not be met for the package to be usable.
|
||||
|
||||
873
man/pkgconf.1
873
man/pkgconf.1
@ -16,745 +16,212 @@
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Ar options
|
||||
.Ar module ...
|
||||
.Op Ar list of modules
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
program retrieves configuration information related to the
|
||||
.Ar module
|
||||
arguments from
|
||||
.Xr pc 5
|
||||
files installed on the system and prints parts of the retrieved
|
||||
information depending on the specified
|
||||
.Ar options .
|
||||
The most common use is printing the compiler and linker flags needed
|
||||
to build software that uses the libraries given by the
|
||||
.Ar module
|
||||
arguments.
|
||||
.Pp
|
||||
The
|
||||
.Xr pc 5
|
||||
files are searched for along a path constructed from the
|
||||
.Fl -with-path
|
||||
option, the
|
||||
.Ev PKG_CONFIG_PATH
|
||||
and
|
||||
.Ev PKG_CONFIG_LIBDIR
|
||||
environment variables, and some compiled-in default directories.
|
||||
The
|
||||
.Ar module
|
||||
arguments correspond to the file names, but without the
|
||||
.Pa .pc
|
||||
filename extension.
|
||||
.Pp
|
||||
Several of the
|
||||
.Ar options
|
||||
cause immediate exit.
|
||||
If multiple of these options are given, only the option with the
|
||||
highest priority takes effect and those with lower priority are
|
||||
silently ignored.
|
||||
These options are, ordered by descending priority:
|
||||
.Bl -enum
|
||||
.It
|
||||
No-module options:
|
||||
.Fl -relocate ,
|
||||
.Fl -dump-personality ,
|
||||
.Fl -about ,
|
||||
.Fl -version ,
|
||||
.Fl -help ,
|
||||
.Fl -atleast-pkgconfig-version ,
|
||||
.Fl -list-all ,
|
||||
and
|
||||
.Fl -list-package-names :
|
||||
These options cause all arguments to be ignored.
|
||||
.It
|
||||
Argument-only options:
|
||||
.Fl -atleast-version ,
|
||||
.Fl -exact-version ,
|
||||
and
|
||||
.Fl -max-version :
|
||||
These options only inspect modules explicitly specified on the
|
||||
command line and do not look at dependencies.
|
||||
.It
|
||||
Limited-output options:
|
||||
.Fl -validate ,
|
||||
.Fl -license ,
|
||||
.Fl -license-file ,
|
||||
.Fl -source ,
|
||||
.Fl -uninstalled ,
|
||||
and
|
||||
.Fl -env :
|
||||
These options perform dependency resolution, but exit after printing
|
||||
the information requested by the highest-priority option,
|
||||
ignoring other output options that may have been specified.
|
||||
.El
|
||||
.Pp
|
||||
Several other options require at least one
|
||||
.Ar module
|
||||
argument, produce output, do not cause early exit, can be combined
|
||||
with each other, but override and disable all
|
||||
.Fl -cflags
|
||||
and
|
||||
.Fl -libs
|
||||
options:
|
||||
.Bl -enum
|
||||
.It
|
||||
Single-module output options:
|
||||
.Fl -path ,
|
||||
.Fl -print-variables ,
|
||||
.Fl -variable :
|
||||
If any of these options is specified, only the first
|
||||
.Ar module
|
||||
argument is used, all other arguments are silently ignored,
|
||||
and no dependency resolution is attempted.
|
||||
.It
|
||||
Depth-one output options:
|
||||
.Fl -print-provides ,
|
||||
.Fl -modversion ,
|
||||
.Fl -print-requires ,
|
||||
and
|
||||
.Fl -print-requires-private :
|
||||
If any of these options is specified, only modules
|
||||
explicitly specified on the command line are inspected
|
||||
and no dependency resolution is attempted.
|
||||
.It
|
||||
General output options:
|
||||
.Fl -simulate ,
|
||||
.Fl -digraph ,
|
||||
.Fl -solution ,
|
||||
.Fl -fragment-tree ,
|
||||
.Fl -newlines :
|
||||
These options do not limit dependency resolution.
|
||||
.El
|
||||
.Pp
|
||||
The most important output options
|
||||
.Fl -cflags
|
||||
and
|
||||
.Fl -libs
|
||||
can be combined with each other, but are overridden and ignored if
|
||||
any of the options listed above are specified.
|
||||
.Pp
|
||||
The complete list of
|
||||
.Ar options
|
||||
is as follows:
|
||||
is a program which helps to configure compiler and linker flags for
|
||||
development libraries.
|
||||
This allows build systems to detect other dependencies and use them with the
|
||||
system toolchain.
|
||||
.Sh GENERAL OPTIONS
|
||||
.Bl -tag -width indent
|
||||
.It Fl -about
|
||||
Print the version number, the Copyright notice, and the license of the
|
||||
.Nm
|
||||
program to standard output and exit.
|
||||
Most other options and all command line arguments are ignored.
|
||||
.It Fl -atleast-pkgconfig-version Ns = Ns Ar version
|
||||
Exit with error if the requested
|
||||
.Ar version
|
||||
number is greater than the version number of the
|
||||
.Nm
|
||||
program, or with success otherwise.
|
||||
Most other options and all command line arguments are ignored.
|
||||
.It Fl -atleast-version Ns = Ns Ar version
|
||||
Check the
|
||||
.Ar module
|
||||
arguments in the given order.
|
||||
Exit with error as soon as a
|
||||
.Ar module
|
||||
does not exist, and exit with success as soon as the version number of a
|
||||
.Ar module
|
||||
is greater than or equal to the requested
|
||||
.Ar version
|
||||
number.
|
||||
Exit with error if the version number of each
|
||||
.Ar module
|
||||
is less than the requested
|
||||
.Ar version
|
||||
number.
|
||||
.It Fl -cflags , Fl -cflags-only-I , Fl -cflags-only-other
|
||||
Print all compiler flags required to compile against the
|
||||
.Ar module ,
|
||||
or only the include path
|
||||
.Pq Fl I
|
||||
flags, or only the compiler flags that are not include path flags,
|
||||
respectively.
|
||||
These options imply
|
||||
.Fl -print-errors .
|
||||
.It Fl -debug
|
||||
Print some non-fatal warning messages to standard error output
|
||||
that would otherwise silently be ignored.
|
||||
This option also implies
|
||||
.Fl -print-errors .
|
||||
If
|
||||
.Nm
|
||||
was compiled without defining the preprocessor macro
|
||||
.Dv PKGCONF_LITE ,
|
||||
this option also prints many debugging messages to standard error output.
|
||||
.It Fl -define-prefix
|
||||
Attempts to determine the prefix variable to use for CFLAGS and LIBS entry relocations.
|
||||
This is mainly useful for platforms where framework SDKs are relocatable, such as Windows.
|
||||
.It Fl -define-variable Ns = Ns Ar varname Ns = Ns Ar value
|
||||
Define
|
||||
.Ar varname
|
||||
as
|
||||
.Ar value .
|
||||
Variables are used in query output, and some modules' results may change based
|
||||
on the presence of a variable definition.
|
||||
.It Fl -digraph
|
||||
Dump the dependency resolver's solution as a graphviz
|
||||
.Sq dot
|
||||
file.
|
||||
This can be used with graphviz to visualize module interdependencies.
|
||||
This option is only available if the preprocessor macro
|
||||
.Dv PKGCONF_LITE
|
||||
was not defined during compilation.
|
||||
.It Fl -dont-define-prefix
|
||||
Disables the
|
||||
.Sq define-prefix
|
||||
feature.
|
||||
.It Fl -dont-relocate-paths
|
||||
Disables the path relocation feature.
|
||||
.It Fl -dump-personality
|
||||
Print some default settings to standard output, in particular
|
||||
the default module search path that is used when
|
||||
.Ev PKG_CONFIG_LIBDIR
|
||||
is not defined, the default list of include paths that are filtered out when
|
||||
.Ev PKG_CONFIG_SYSTEM_INCLUDE_PATH
|
||||
is not defined,
|
||||
and the default list of library paths that are filtered out when
|
||||
.Ev PKG_CONFIG_SYSTEM_LIBRARY_PATH
|
||||
is not defined, and exit.
|
||||
Most other options and all command line arguments are ignored.
|
||||
This option is only available if the preprocessor macro
|
||||
.Dv PKGCONF_LITE
|
||||
was not defined during compilation.
|
||||
.It Fl -env Ns = Ns Ar varname
|
||||
Print the requested values as variable declarations in a similar format as the
|
||||
.Xr env 1
|
||||
command.
|
||||
.It Fl -env-only
|
||||
Initialize the module search path from
|
||||
.Fl -with-path
|
||||
and
|
||||
.Ev PKG_CONFIG_PATH
|
||||
only, ignoring
|
||||
.Ev PKG_CONFIG_LIBDIR
|
||||
and the compiled-in default directories.
|
||||
.It Fl -version
|
||||
Display the supported pkg-config version and exit.
|
||||
.It Fl -atleast-pkgconfig-version Ns = Ns Ar VERSION
|
||||
Exit with error if we do not support the requested pkg-config version.
|
||||
.It Fl -errors-to-stdout
|
||||
Print all error, warning, and debugging messages to standard output
|
||||
instead of to standard error output.
|
||||
.It Fl -exact-version Ns = Ns Ar version
|
||||
Check the
|
||||
.Ar module
|
||||
arguments in the given order.
|
||||
Exit with error as soon as a
|
||||
.Ar module
|
||||
does not exist, and exit with success as soon as the version number of a
|
||||
.Ar module
|
||||
is exactly the requested
|
||||
.Ar version
|
||||
number.
|
||||
Exit with error if the version number of each
|
||||
.Ar module
|
||||
differs from the requested
|
||||
.Ar version
|
||||
number.
|
||||
.It Fl -exists
|
||||
Exit with a non-zero exit status
|
||||
if the dependency resolver is unable to find all of the requested
|
||||
.Ar module Ns s .
|
||||
This option is active by default and cannot be disabled.
|
||||
However, various other options cause
|
||||
.Nm
|
||||
to exit and report success or failure before all arguments have been inspected.
|
||||
.It Fl -fragment-filter Ns = Ns Ar types
|
||||
Filter the fragment lists for the specified
|
||||
.Ar types .
|
||||
.It Fl -help
|
||||
Print a usage summary on standard output and exit.
|
||||
Most other options and all command line arguments are ignored.
|
||||
Print all errors on the main output stream instead of the error output stream.
|
||||
.It Fl -silence-errors
|
||||
Do not display any errors at all.
|
||||
.It Fl -list-all
|
||||
Walk all directories listed in the
|
||||
.Va PKG_CONFIG_PATH
|
||||
environmental variable and display information on packages which have registered
|
||||
information there.
|
||||
.It Fl -simulate
|
||||
Simulates resolving a dependency graph based on the requested modules on the
|
||||
command line.
|
||||
Dumps a series of trees denoting pkgconf's resolver state.
|
||||
.It Fl -no-cache
|
||||
Skip caching packages when they are loaded into the internal resolver.
|
||||
This may result in an alternate dependency graph being computed.
|
||||
.It Fl -ignore-conflicts
|
||||
Ignore
|
||||
.Sq Conflicts
|
||||
rules in modules.
|
||||
.It Fl -keep-system-cflags , Fl -keep-system-libs
|
||||
Keep CFLAGS or linker flag fragments that would be filtered due to being
|
||||
included by default in the compiler.
|
||||
.It Fl -libs , Fl -libs-only-L , Fl -libs-only-l , Fl -libs-only-other
|
||||
Print all linker flags required to link against the
|
||||
.Ar module ,
|
||||
or only the library path
|
||||
.Pq Fl L
|
||||
flags, or only the library
|
||||
.Pq Fl l
|
||||
flags, or only the linker flags that are neither library path
|
||||
nor library flags, respectively.
|
||||
These options imply
|
||||
.Fl -print-errors .
|
||||
.It Fl -list-all
|
||||
Walk the module search path in the order of descending priority.
|
||||
For each
|
||||
.Xr pc 5
|
||||
file found, print one line to standard output,
|
||||
containing the basename of the file without the extension, the
|
||||
.Ic Name
|
||||
property, a dash
|
||||
.Pq Sq \- ,
|
||||
and the
|
||||
.Ic Description
|
||||
property.
|
||||
This option implies
|
||||
.Fl -print-errors .
|
||||
All command line arguments are ignored.
|
||||
.It Fl -list-package-names
|
||||
Perform the same search as
|
||||
.Fl -list-all ,
|
||||
but only print the basename of each
|
||||
.Xr pc 5
|
||||
file without the extension, not the module name and the description.
|
||||
This option implies
|
||||
.Fl -print-errors .
|
||||
All command line arguments are ignored.
|
||||
.It Fl -log-file Ns = Ns Ar file
|
||||
Set the name of the output
|
||||
.Ar file
|
||||
where information about selected modules is logged,
|
||||
both about those selected by arguments and as dependencies.
|
||||
For each selected module, one line is printed,
|
||||
containing the basename of the
|
||||
.Xr pc 5
|
||||
file without the extension, optionally an operator and version number
|
||||
describing the desired range of versions, and either the actual version
|
||||
number in square brackets or the string
|
||||
.Qq NOT-FOUND .
|
||||
If this option is not provided, the name of the output file
|
||||
is instead taken from the
|
||||
.Ev PKG_CONFIG_LOG
|
||||
environment variable, and if that is not provided either,
|
||||
this kind of logging is disabled.
|
||||
.It Fl -max-version Ns = Ns Ar version
|
||||
Check the
|
||||
.Ar module
|
||||
arguments in the given order.
|
||||
Exit with error as soon as a
|
||||
.Ar module
|
||||
does not exist, and exit with success as soon as the version number of a
|
||||
.Ar module
|
||||
is less than or equal to the requested
|
||||
.Ar version
|
||||
number.
|
||||
Exit with error if the version number of each
|
||||
.Ar module
|
||||
is greater than the requested
|
||||
.Ar version
|
||||
number.
|
||||
.It Fl -maximum-traverse-depth Ns = Ns Ar depth
|
||||
.It Fl -env-only
|
||||
Learn about pkgconf's configuration strictly from environmental variables.
|
||||
.It Fl -validate Ar package ...
|
||||
Validate specific
|
||||
.Sq .pc
|
||||
files for correctness.
|
||||
.It Fl -maximum-traverse-depth Ns = Ns Ar DEPTH
|
||||
Impose a limit on the allowed depth in the dependency graph.
|
||||
For example, a
|
||||
.Ar depth
|
||||
of 2 restricts the resolver from acting on child
|
||||
For example, a depth of 2 will restrict the resolver from acting on child
|
||||
dependencies of modules added to the resolver's solution.
|
||||
This option is overridden by the
|
||||
.Ev PKG_CONFIG_MAXIMUM_TRAVERSE_DEPTH
|
||||
environment variable and by the options
|
||||
.Fl -modversion ,
|
||||
.Fl -path ,
|
||||
.Fl -print-provides ,
|
||||
.Fl -print-requires ,
|
||||
.Fl -print-requires-private ,
|
||||
.Fl -print-variables ,
|
||||
and
|
||||
.Fl -variable .
|
||||
.It Fl -modversion
|
||||
For each specified
|
||||
.Ar module ,
|
||||
print the version number to standard output.
|
||||
If the
|
||||
.Fl -verbose
|
||||
option is also specified, the name of the respective
|
||||
.Ar module
|
||||
and a colon is printed before each version number.
|
||||
This option implies
|
||||
.Fl -print-errors
|
||||
and
|
||||
.Fl -maximum-traverse-depth Ns =1
|
||||
and overrides and disables all
|
||||
.Fl -cflags
|
||||
and
|
||||
.Fl -libs
|
||||
flags.
|
||||
.It Fl -msvc-syntax
|
||||
Use MSVC syntax for
|
||||
.Fl -cflags ,
|
||||
.Fl -env ,
|
||||
and
|
||||
.Fl -libs
|
||||
output.
|
||||
This option is only available if the preprocessor macro
|
||||
.Dv PKGCONF_LITE
|
||||
was not defined during compilation.
|
||||
.It Fl -newlines
|
||||
Use newlines to separate individual CFLAGS or linker flag fragments
|
||||
instead of spaces.
|
||||
.It Fl -no-cache
|
||||
Skip caching packages when they are loaded into the internal resolver.
|
||||
This may result in an alternate dependency graph being computed.
|
||||
.It Fl -static
|
||||
Compute a deeper dependency graph and use compiler/linker flags intended for
|
||||
static linking.
|
||||
.It Fl -shared
|
||||
Compute a simple dependency graph that is only suitable for shared linking.
|
||||
.It Fl -pure
|
||||
Treats the computed dependency graph as if it were pure.
|
||||
This is mainly intended for use with the
|
||||
.Fl -static
|
||||
flag.
|
||||
.It Fl -no-provides
|
||||
Ignore
|
||||
.Sq Provides
|
||||
rules in modules when resolving dependencies.
|
||||
.It Fl -no-uninstalled
|
||||
Forbids the dependency resolver from considering 'uninstalled' modules as part
|
||||
of a solution.
|
||||
.It Fl -path
|
||||
For the first
|
||||
.Ar module
|
||||
given on the command line, let the dependency resolver find the
|
||||
.Xr pc 5
|
||||
file describing that module, print the absolute pathname of that file
|
||||
to standard output, and exit immediately,
|
||||
ignoring most other options and all other arguments.
|
||||
.It Fl -prefix-variable Ns = Ns Ar variable
|
||||
.It Fl -with-path Ns = Ns Ar PATH
|
||||
Adds a new module search path to pkgconf's dependency resolver.
|
||||
Paths added in this way are given preference before other paths.
|
||||
.It Fl -define-prefix
|
||||
Attempts to determine the prefix variable to use for CFLAGS and LIBS entry relocations.
|
||||
This is mainly useful for platforms where framework SDKs are relocatable, such as Windows.
|
||||
.It Fl -dont-define-prefix
|
||||
Disables the
|
||||
.Sq define-prefix
|
||||
feature.
|
||||
.It Fl -prefix-variable Ns = Ns Ar VARIABLE
|
||||
Sets the
|
||||
.Sq prefix
|
||||
variable used by the
|
||||
.Sq define-prefix
|
||||
feature.
|
||||
.It Fl -print-errors
|
||||
Print some messages about fatal errors to standard error output
|
||||
that would otherwise be omitted.
|
||||
This option is implied by many other options, but not by all.
|
||||
It can be overridden with
|
||||
.Fl -silence-errors .
|
||||
.It Fl -print-provides
|
||||
For each specified
|
||||
.Ar module ,
|
||||
print one line to standard output containing the
|
||||
.Ic Name
|
||||
property, an equal sign
|
||||
.Pq Sq = ,
|
||||
and the
|
||||
.Ic Version
|
||||
property.
|
||||
If the
|
||||
.Ar module
|
||||
contains one or more
|
||||
.Ic Provides
|
||||
properties, print additional lines in dependency list format, one name
|
||||
per line, each name optionally followed by an operator and a version.
|
||||
This option implies
|
||||
.Fl -maximum-traverse-depth Ns =1
|
||||
and overrides and disables all
|
||||
.Fl -cflags
|
||||
and
|
||||
.Fl -libs
|
||||
flags.
|
||||
.It Fl -print-requires , Fl -print-requires-private
|
||||
For each specified
|
||||
.Ar module ,
|
||||
print the
|
||||
.Ic Requires
|
||||
or
|
||||
.Ic Requires.private
|
||||
properties, respectively, in dependency list format to standard output.
|
||||
Both of these options imply
|
||||
.Fl -maximum-traverse-depth Ns =1
|
||||
and override and disable all
|
||||
.Fl -cflags
|
||||
and
|
||||
.Fl -libs
|
||||
flags.
|
||||
.It Fl -print-variables
|
||||
For the first
|
||||
.Ar module
|
||||
given on the command line, print the names of all seen variables
|
||||
to standard output, one per line.
|
||||
Any subsequent arguments are silently ignored.
|
||||
This option implies
|
||||
.Fl -print-errors
|
||||
and
|
||||
.Fl -maximum-traverse-depth Ns =1
|
||||
and overrides and disables all
|
||||
.Fl -cflags
|
||||
and
|
||||
.Fl -libs
|
||||
flags.
|
||||
.It Fl -pure
|
||||
Treats the computed dependency graph as if it were pure.
|
||||
This is mainly intended for use with the
|
||||
.Fl -static
|
||||
flag and has no effect if
|
||||
.Fl -shared
|
||||
is also specified.
|
||||
.It Fl -relocate Ns = Ns Ar path
|
||||
.It Fl -relocate Ns = Ns Ar PATH
|
||||
Relocates a path using the pkgconf_path_relocate API.
|
||||
This is mainly used by the testsuite to provide a guaranteed interface
|
||||
to the system's path relocation backend.
|
||||
.It Fl -shared
|
||||
Compute a simple dependency graph that is only suitable for shared linking.
|
||||
This option overrides
|
||||
.Fl -static .
|
||||
.It Fl -short-errors
|
||||
When printing error messages about modules that are not found
|
||||
or conflict with each other, avoid printing additional, verbose
|
||||
instructions explaining potential methods for solving the problem.
|
||||
.It Fl -silence-errors
|
||||
Do not print any error, warning, or debugging messages at all.
|
||||
Overrides all of
|
||||
.Fl -debug ,
|
||||
.Fl -errors-to-stdout ,
|
||||
and
|
||||
.Fl -print-errors .
|
||||
This option is overridden and disabled if the
|
||||
.Ev PKG_CONFIG_DEBUG_SPEW
|
||||
environment variable is set.
|
||||
.It Fl -simulate
|
||||
Simulates resolving a dependency graph based on the requested modules on the
|
||||
command line.
|
||||
Dumps a series of trees denoting pkgconf's resolver state.
|
||||
This option is only available if the preprocessor macro
|
||||
.Dv PKGCONF_LITE
|
||||
was not defined during compilation.
|
||||
.It Fl -solution
|
||||
Print the names of the modules requested with
|
||||
.Ar module
|
||||
arguments and their dependencies to standard output.
|
||||
This option is only available if the preprocessor macro
|
||||
.Dv PKGCONF_LITE
|
||||
was not defined during compilation.
|
||||
.It Fl -static
|
||||
Compute a deeper dependency graph and use compiler/linker flags intended for
|
||||
static linking.
|
||||
This option is overridden by
|
||||
.Fl -shared .
|
||||
.It Fl -dont-relocate-paths
|
||||
Disables the path relocation feature.
|
||||
.El
|
||||
.Sh MODULE-SPECIFIC OPTIONS
|
||||
.Bl -tag -width indent
|
||||
.It Fl -atleast-version Ns = Ns Ar VERSION
|
||||
Exit with error if a module's version is less than the specified version.
|
||||
.It Fl -exact-version Ns = Ns Ar VERSION
|
||||
Exit with error if a module's version is not exactly the specified version.
|
||||
.It Fl -max-version Ns = Ns Ar VERSION
|
||||
Exit with error if a module's version is greater than the specified version.
|
||||
.It Fl -exists
|
||||
Exit with a non-zero result if the dependency resolver was unable to find all of
|
||||
the requested modules.
|
||||
.It Fl -uninstalled
|
||||
Exit with a non-zero result if the dependency resolver uses an
|
||||
.Sq uninstalled
|
||||
module as part of its solution.
|
||||
.It Fl -validate Ar package ...
|
||||
Validate specific
|
||||
.It Fl -no-uninstalled
|
||||
Forbids the dependency resolver from considering 'uninstalled' modules as part
|
||||
of a solution.
|
||||
.El
|
||||
.Sh QUERY-SPECIFIC OPTIONS
|
||||
.Bl -tag -width indent
|
||||
.It Fl -cflags , Fl -cflags-only-I , Fl -cflags-only-other
|
||||
Display either all CFLAGS, only
|
||||
.Fl I
|
||||
CFLAGS or only CFLAGS that are not
|
||||
.Fl I .
|
||||
.It Fl -libs , Fl -libs-only-L , Fl -libs-only-l , Fl -libs-only-other
|
||||
Display either all linker flags, only
|
||||
.Fl L
|
||||
linker flags, only
|
||||
.Fl l
|
||||
linker flags or only linker flags that are not
|
||||
.Fl L
|
||||
or
|
||||
.Fl l .
|
||||
.It Fl -keep-system-cflags , Fl -keep-system-libs
|
||||
Keep CFLAGS or linker flag fragments that would be filtered due to being
|
||||
included by default in the compiler.
|
||||
.It Fl -define-variable Ns = Ns Ar VARNAME Ns = Ns Ar VALUE
|
||||
Define
|
||||
.Va VARNAME
|
||||
as
|
||||
.Va VALUE .
|
||||
Variables are used in query output, and some modules' results may change based
|
||||
on the presence of a variable definition.
|
||||
.It Fl -print-variables
|
||||
Print all seen variables for a module to the output channel.
|
||||
.It Fl -print-provides
|
||||
Print all relevant
|
||||
.Sq Provides
|
||||
entries for a module to the output channel.
|
||||
.It Fl -variable Ns = Ns Ar VARNAME
|
||||
Print the value of
|
||||
.Va VARNAME .
|
||||
.It Fl -print-requires , Fl -print-requires-private
|
||||
Print the modules included in either the
|
||||
.Va Requires
|
||||
field or the
|
||||
.Va Requires.private
|
||||
field.
|
||||
.It Fl -digraph
|
||||
Dump the dependency resolver's solution as a graphviz
|
||||
.Sq dot
|
||||
file.
|
||||
This can be used with graphviz to visualize module interdependencies.
|
||||
.It Fl -path
|
||||
Display the filenames of the
|
||||
.Sq .pc
|
||||
files for correctness.
|
||||
This option implies
|
||||
.Fl -print-errors
|
||||
and
|
||||
.Fl -errors-to-stdout .
|
||||
.It Fl -variable Ns = Ns Ar varname
|
||||
For the first
|
||||
.Ar module
|
||||
given on the command line, print the value of the variable with the name
|
||||
.Ar varname
|
||||
to standard output.
|
||||
Any subsequent arguments are silently ignored.
|
||||
This option implies
|
||||
.Fl -maximum-traverse-depth Ns =1
|
||||
and overrides and disables all
|
||||
.Fl -cflags
|
||||
and
|
||||
.Fl -libs
|
||||
flags.
|
||||
.It Fl -verbose
|
||||
This option only has an effect if
|
||||
.Fl -modversion
|
||||
is also specified.
|
||||
It prints the name of the respective
|
||||
.Ar module
|
||||
and a colon before each version number.
|
||||
.It Fl -version
|
||||
Print the version number of the
|
||||
.Nm
|
||||
program to standard output and exit.
|
||||
Most other options and all command line arguments are ignored.
|
||||
.It Fl -with-path Ns = Ns Ar path
|
||||
Prepend the directory
|
||||
.Ar path
|
||||
to the module search path,
|
||||
giving it priority over all other directories including those from
|
||||
.Ev PKG_CONFIG_PATH
|
||||
and
|
||||
.Ev PKG_CONFIG_LIBDIR .
|
||||
files used by the dependency resolver for a given dependency set.
|
||||
.It Fl -env Ns = Ns Ar VARNAME
|
||||
Print the requested values as variable declarations in a similar format as the
|
||||
.Xr env 1
|
||||
command.
|
||||
.It Fl -fragment-filter Ns = Ns Ar TYPES
|
||||
Filter the fragment lists for the specified types.
|
||||
.It Fl -modversion
|
||||
Print the version of the queried module.
|
||||
.El
|
||||
.Sh ENVIRONMENT
|
||||
.Bl -tag -width indent
|
||||
.It Ev CPATH
|
||||
First supplementary colon-separated list of include paths filtered out
|
||||
in the same way as
|
||||
.Ev PKG_CONFIG_SYSTEM_INCLUDE_PATH .
|
||||
.It Ev CPLUS_INCLUDE_PATH
|
||||
Third supplementary colon-separated list of include paths filtered out
|
||||
in the same way as
|
||||
.Ev PKG_CONFIG_SYSTEM_INCLUDE_PATH .
|
||||
.It Ev C_INCLUDE_PATH
|
||||
Second supplementary colon-separated list of include paths filtered out
|
||||
in the same way as
|
||||
.Ev PKG_CONFIG_SYSTEM_INCLUDE_PATH .
|
||||
.It Ev DESTDIR
|
||||
If set to the same value as
|
||||
.Ev PKG_CONFIG_SYSROOT_DIR ,
|
||||
behave in the same way as if
|
||||
.Ev PKG_CONFIG_FDO_SYSROOT_RULES
|
||||
is set.
|
||||
If
|
||||
.Ev PKG_CONFIG_SYSROOT_DIR
|
||||
is not set or set to a different value,
|
||||
.Ev DESTDIR
|
||||
is ignored.
|
||||
.It Ev LIBRARY_PATH
|
||||
Supplementary colon-separated list of library paths filtered out
|
||||
in the same way as
|
||||
.Ev PKG_CONFIG_SYSTEM_LIBRARY_PATH .
|
||||
.It Ev OBJC_INCLUDE_PATH
|
||||
Fourth supplementary colon-separated list of include paths filtered out
|
||||
in the same way as
|
||||
.Ev PKG_CONFIG_SYSTEM_INCLUDE_PATH .
|
||||
.It Ev PKG_CONFIG_ALLOW_SYSTEM_CFLAGS
|
||||
If set, this variable has the same effect as the
|
||||
.Fl -keep-system-cflags
|
||||
option.
|
||||
.It Ev PKG_CONFIG_ALLOW_SYSTEM_LIBS
|
||||
If set, this variable has the same effect as the
|
||||
.Fl -keep-system-libs
|
||||
option.
|
||||
.It Ev PKG_CONFIG_DEBUG_SPEW
|
||||
If set, override and disable the
|
||||
.Fl -silence-errors
|
||||
option.
|
||||
.It Ev PKG_CONFIG_DISABLE_UNINSTALLED
|
||||
If set, enables the same behaviour as the
|
||||
.Fl -no-uninstalled
|
||||
flag.
|
||||
.It Ev PKG_CONFIG_DONT_DEFINE_PREFIX
|
||||
If set, this variable has the same effect as the
|
||||
.Fl -dont-define-prefix
|
||||
option.
|
||||
.It Ev PKG_CONFIG_DONT_RELOCATE_PATHS
|
||||
If set, disables the path relocation feature.
|
||||
.It Ev PKG_CONFIG_FDO_SYSROOT_RULES
|
||||
If set, follow the sysroot prefixing rules that freedesktop.org pkg-config uses.
|
||||
.It Ev PKG_CONFIG_IGNORE_CONFLICTS
|
||||
If set, ignore
|
||||
.Ic Conflicts
|
||||
rules in modules.
|
||||
Has the same effect as the
|
||||
.Fl -ignore-conflicts
|
||||
option.
|
||||
.It Ev PKG_CONFIG_LIBDIR
|
||||
A colon-separated list of low-priority directories where
|
||||
.Xr pc 5
|
||||
.It Va PKG_CONFIG_PATH
|
||||
List of secondary directories where
|
||||
.Sq .pc
|
||||
files are looked up.
|
||||
The module search path is constructed by appending this list to
|
||||
.Ev PKG_CONFIG_PATH ,
|
||||
which enjoys higher priority.
|
||||
If
|
||||
.Ev PKG_CONFIG_LIBDIR
|
||||
is not defined, the default list compiled into the
|
||||
.Nm
|
||||
program from the
|
||||
.Dv PKG_DEFAULT_PATH
|
||||
preprocessor macro is appended instead.
|
||||
If
|
||||
.Ev PKG_CONFIG_LIBDIR
|
||||
is defined but empty, nothing is appended.
|
||||
.It Ev PKG_CONFIG_LOG
|
||||
If set, log information about selected modules
|
||||
to the file with the name stored in this variable.
|
||||
For more details, see the
|
||||
.Fl -log-file
|
||||
command line option, which overrides this variable.
|
||||
.It Ev PKG_CONFIG_MAXIMUM_TRAVERSE_DEPTH
|
||||
Impose a limit on the allowed depth in the dependency graph.
|
||||
This variable overrides the
|
||||
.Fl -maximum-traverse-depth
|
||||
option, but is overridden by the other options mentioned there.
|
||||
.It Ev PKG_CONFIG_MSVC_SYNTAX
|
||||
If set, use MSVC syntax for
|
||||
.Fl -cflags ,
|
||||
.Fl -env ,
|
||||
and
|
||||
.Fl -libs
|
||||
output.
|
||||
This variable has the same effect as the
|
||||
.Fl -msvc-syntax
|
||||
option.
|
||||
If the preprocessor macro
|
||||
.Dv PKGCONF_LITE
|
||||
was defined during compilation, this variable is ignored.
|
||||
.It Ev PKG_CONFIG_PATH
|
||||
A colon-separated list of high-priority directories where
|
||||
.Xr pc 5
|
||||
.It Va PKG_CONFIG_LIBDIR
|
||||
List of primary directories where
|
||||
.Sq .pc
|
||||
files are looked up.
|
||||
The module search path is constructed
|
||||
by prepending the directory specified with
|
||||
.Fl -with-path ,
|
||||
if any, and unless
|
||||
.Fl -env-only
|
||||
is specified, by appending either
|
||||
.Ev PKG_CONFIG_LIBDIR
|
||||
or the compiled-in default directories with lower priority.
|
||||
.It Ev PKG_CONFIG_PRELOADED_FILES
|
||||
Colon-separated list of
|
||||
.Xr pc 5
|
||||
files which are loaded before any other pkg-config files.
|
||||
These packages are given highest priority over any other
|
||||
.Xr pc 5
|
||||
files that would otherwise provide a given package.
|
||||
.It Ev PKG_CONFIG_PURE_DEPGRAPH
|
||||
.It Va PKG_CONFIG_SYSROOT_DIR
|
||||
.Sq sysroot
|
||||
directory, will be prepended to every path defined in
|
||||
.Va PKG_CONFIG_PATH .
|
||||
Useful for cross compilation.
|
||||
.It Va PKG_CONFIG_TOP_BUILD_DIR
|
||||
Provides an alternative setting for the
|
||||
.Sq pc_top_builddir
|
||||
global variable.
|
||||
.It Va PKG_CONFIG_PURE_DEPGRAPH
|
||||
If set, enables the same behaviour as the
|
||||
.Fl -pure
|
||||
flag.
|
||||
.It Ev PKG_CONFIG_RELOCATE_PATHS
|
||||
If set, this variable has the same effect as the
|
||||
.Fl -define-prefix
|
||||
option.
|
||||
.It Ev PKG_CONFIG_SYSROOT_DIR
|
||||
If set, this variable defines a
|
||||
.Sq sysroot
|
||||
directory, which will be prepended to every path variable
|
||||
beginning with the prefix variable in a given
|
||||
.Xr pc 5
|
||||
file.
|
||||
Useful for cross compilation.
|
||||
The value of this environment variable is also copied into the global variable
|
||||
.Va pc_sysrootdir .
|
||||
.It Ev PKG_CONFIG_SYSTEM_INCLUDE_PATH
|
||||
Colon-separated list of include paths that are filtered out
|
||||
and not printed by the
|
||||
.Fl -cflags
|
||||
and
|
||||
.Fl -cflags-only-I
|
||||
options because they are considered system include paths.
|
||||
If not defined, the default list compiled into the
|
||||
.Nm
|
||||
program from the
|
||||
.Dv SYSTEM_INCLUDEDIR
|
||||
preprocessor macro is used instead.
|
||||
This variable is a pkgconf-specific extension.
|
||||
Any directories listed in the environment variables
|
||||
.Ev CPATH ,
|
||||
.Ev C_INCLUDE_PATH ,
|
||||
.Ev CPLUS_INCLUDE_PATH ,
|
||||
and
|
||||
.Ev OBJC_INCLUDE_PATH
|
||||
are also filtered out.
|
||||
.It Ev PKG_CONFIG_SYSTEM_LIBRARY_PATH
|
||||
Colon-separated list of library paths that are filtered out
|
||||
and not printed by the
|
||||
.Fl -libs
|
||||
and
|
||||
.Fl -libs-only-L
|
||||
options because they are considered system library paths.
|
||||
If not defined, the default list compiled into the
|
||||
.Nm
|
||||
program from the
|
||||
.Dv SYSTEM_LIBDIR
|
||||
preprocessor macro is used instead.
|
||||
This variable is a pkgconf-specific extension.
|
||||
.It Ev PKG_CONFIG_TOP_BUILD_DIR
|
||||
The value of the
|
||||
.Va pc_top_builddir
|
||||
global variable.
|
||||
If this environment variable is not defined, the string
|
||||
.Qq $(top_builddir)
|
||||
is used as the value of
|
||||
.Va pc_top_builddir .
|
||||
.It Va PKG_CONFIG_SYSTEM_INCLUDE_PATH
|
||||
List of paths that are considered system include paths by the toolchain.
|
||||
This is a pkgconf-specific extension.
|
||||
.It Va PKG_CONFIG_SYSTEM_LIBRARY_PATH
|
||||
List of paths that are considered system library paths by the toolchain.
|
||||
This is a pkgconf-specific extension.
|
||||
.It Va PKG_CONFIG_DISABLE_UNINSTALLED
|
||||
If set, enables the same behaviour as the
|
||||
.Fl -no-uninstalled
|
||||
flag.
|
||||
.It Va PKG_CONFIG_LOG
|
||||
.Sq logfile
|
||||
which is used for dumping audit information concerning installed module versions.
|
||||
.It Va PKG_CONFIG_DEBUG_SPEW
|
||||
If set, enables additional debug logging.
|
||||
The format of the debug log messages is implementation-specific.
|
||||
.It Va PKG_CONFIG_DONT_RELOCATE_PATHS
|
||||
If set, disables the path relocation feature.
|
||||
.It Va PKG_CONFIG_MSVC_SYNTAX
|
||||
If set, uses MSVC syntax for fragments.
|
||||
.It Va PKG_CONFIG_FDO_SYSROOT_RULES
|
||||
If set, follow the sysroot prefixing rules that freedesktop.org pkg-config uses.
|
||||
.It Va DESTDIR
|
||||
If set to PKG_CONFIG_SYSROOT_DIR, assume that PKG_CONFIG_FDO_SYSROOT_RULES is set.
|
||||
.El
|
||||
.Sh EXIT STATUS
|
||||
.Ex -std
|
||||
.Sh EXAMPLES
|
||||
Displaying the CFLAGS of a package:
|
||||
.Dl $ pkgconf --cflags foo
|
||||
|
||||
110
meson.build
110
meson.build
@ -1,17 +1,15 @@
|
||||
project('pkgconf', 'c',
|
||||
version : '2.5.1',
|
||||
version : '2.1.0',
|
||||
license : 'ISC',
|
||||
meson_version : '>=0.49',
|
||||
default_options : ['c_std=c99'],
|
||||
meson_version: '>=0.52',
|
||||
)
|
||||
|
||||
cc = meson.get_compiler('c')
|
||||
|
||||
add_project_arguments(
|
||||
'-D_BSD_SOURCE',
|
||||
'-D_DARWIN_C_SOURCE',
|
||||
'-D_DEFAULT_SOURCE',
|
||||
'-D_POSIX_C_SOURCE=200809L',
|
||||
cc.get_supported_arguments(
|
||||
'-Wimplicit-function-declaration',
|
||||
'-Wmisleading-indentation',
|
||||
@ -29,14 +27,11 @@ check_functions = [
|
||||
['strncasecmp', 'strings.h'],
|
||||
['strcasecmp', 'strings.h'],
|
||||
['reallocarray', 'stdlib.h'],
|
||||
['pledge', 'unistd.h'],
|
||||
['unveil', 'unistd.h'],
|
||||
['readlinkat', 'unistd.h'],
|
||||
]
|
||||
|
||||
foreach f : check_functions
|
||||
name = f[0].to_upper().underscorify()
|
||||
if cc.has_function(f[0], prefix : '#define _BSD_SOURCE\n#define _DARWIN_C_SOURCE\n#define _DEFAULT_SOURCE\n#define _POSIX_C_SOURCE 200809L\n#include <@0@>'.format(f[1])) and cc.has_header_symbol(f[1], f[0], prefix : '#define _BSD_SOURCE\n#define _DARWIN_C_SOURCE\n#define _DEFAULT_SOURCE\n#define _POSIX_C_SOURCE 200809L')
|
||||
if cc.has_function(f[0], prefix : '#define _BSD_SOURCE\n#include <@0@>'.format(f[1])) and cc.has_header_symbol(f[1], f[0], prefix : '#define _BSD_SOURCE')
|
||||
cdata.set('HAVE_@0@'.format(name), 1)
|
||||
cdata.set('HAVE_DECL_@0@'.format(name), 1)
|
||||
else
|
||||
@ -87,14 +82,12 @@ endif
|
||||
libpkgconf = library('pkgconf',
|
||||
'libpkgconf/argvsplit.c',
|
||||
'libpkgconf/audit.c',
|
||||
'libpkgconf/buffer.c',
|
||||
'libpkgconf/bsdstubs.c',
|
||||
'libpkgconf/cache.c',
|
||||
'libpkgconf/client.c',
|
||||
'libpkgconf/dependency.c',
|
||||
'libpkgconf/fileio.c',
|
||||
'libpkgconf/fragment.c',
|
||||
'libpkgconf/output.c',
|
||||
'libpkgconf/parser.c',
|
||||
'libpkgconf/path.c',
|
||||
'libpkgconf/personality.c',
|
||||
@ -103,8 +96,8 @@ libpkgconf = library('pkgconf',
|
||||
'libpkgconf/tuple.c',
|
||||
c_args: ['-DLIBPKGCONF_EXPORT', build_static],
|
||||
install : true,
|
||||
version : '7.0.0',
|
||||
soversion : '7',
|
||||
version : '4.0.0',
|
||||
soversion : '4',
|
||||
)
|
||||
|
||||
# For other projects using libpkgconfig as a subproject
|
||||
@ -129,72 +122,22 @@ pkg.generate(libpkgconf,
|
||||
extra_cflags : build_static
|
||||
)
|
||||
|
||||
cli_include = include_directories('cli')
|
||||
|
||||
pkgconf_exe = executable('pkgconf',
|
||||
'cli/main.c',
|
||||
'cli/core.c',
|
||||
'cli/getopt_long.c',
|
||||
'cli/renderer-msvc.c',
|
||||
link_with : libpkgconf,
|
||||
c_args : build_static,
|
||||
include_directories : cli_include,
|
||||
c_args: build_static,
|
||||
install : true)
|
||||
|
||||
bomtool_exe = executable('bomtool',
|
||||
'cli/bomtool/main.c',
|
||||
'cli/getopt_long.c',
|
||||
link_with : libpkgconf,
|
||||
c_args : build_static,
|
||||
include_directories : cli_include,
|
||||
install : true)
|
||||
|
||||
spdxtool_exe = executable('spdxtool',
|
||||
'cli/spdxtool/main.c',
|
||||
'cli/spdxtool/core.c',
|
||||
'cli/spdxtool/software.c',
|
||||
'cli/spdxtool/serialize.c',
|
||||
'cli/spdxtool/simplelicensing.c',
|
||||
'cli/spdxtool/util.c',
|
||||
'cli/getopt_long.c',
|
||||
link_with : libpkgconf,
|
||||
c_args : build_static,
|
||||
include_directories : include_directories('cli', 'cli/spdxtool'),
|
||||
install : true)
|
||||
|
||||
test_runner_exe = executable('test-runner',
|
||||
'cli/core.c',
|
||||
'cli/getopt_long.c',
|
||||
'cli/renderer-msvc.c',
|
||||
'tests/test-runner.c',
|
||||
link_with : libpkgconf,
|
||||
c_args : build_static,
|
||||
include_directories : cli_include,
|
||||
install : true)
|
||||
|
||||
fixtures_dir = '@0@/tests'.format(meson.current_source_dir())
|
||||
test_suites = [
|
||||
'basic',
|
||||
'ordering',
|
||||
'parser',
|
||||
'solver',
|
||||
'sbom',
|
||||
'sysroot',
|
||||
'tuple',
|
||||
]
|
||||
|
||||
foreach t : test_suites
|
||||
test(t, test_runner_exe, args : ['--test-fixtures', fixtures_dir, '@0@/t/@1@'.format(meson.current_source_dir(), t)])
|
||||
endforeach
|
||||
|
||||
with_tests = get_option('tests')
|
||||
kyua_exe = find_program('kyua', required : with_tests, disabler : true, native : true)
|
||||
atf_sh_exe = find_program('atf-sh', required : with_tests, disabler : true, native : true)
|
||||
kyua_exe = find_program('kyua', required : with_tests, disabler : true)
|
||||
atf_sh_exe = find_program('atf-sh', required : with_tests, disabler : true)
|
||||
kyuafile = configure_file(input : 'Kyuafile.in', output : 'Kyuafile', configuration : cdata)
|
||||
test('kyua', kyua_exe, args : ['--config=none', 'test', '--kyuafile', kyuafile, '--build-root', meson.current_build_dir()])
|
||||
subdir('tests')
|
||||
|
||||
install_man('man/bomtool.1')
|
||||
install_man('man/pkgconf.1')
|
||||
install_man('man/pkg.m4.7')
|
||||
install_man('man/pc.5')
|
||||
@ -202,40 +145,3 @@ install_man('man/pkgconf-personality.5')
|
||||
install_data('pkg.m4', install_dir: 'share/aclocal')
|
||||
install_data('AUTHORS', install_dir: 'share/doc/pkgconf')
|
||||
install_data('README.md', install_dir: 'share/doc/pkgconf')
|
||||
|
||||
if host_machine.system() == 'windows'
|
||||
conf_data = configuration_data()
|
||||
conf_data.set('VERSION', meson.project_version())
|
||||
conf_data.set('EXE', pkgconf_exe.full_path())
|
||||
conf_data.set('DLL', libpkgconf.full_path())
|
||||
if host_machine.cpu() != 'x86_64'
|
||||
wixl_arch = 'x86'
|
||||
else
|
||||
wixl_arch = 'x64'
|
||||
endif
|
||||
conf_data.set('WIXL_ARCH', wixl_arch)
|
||||
|
||||
python = find_program('python3')
|
||||
wixl = find_program('wixl', required: false, version: '>= 0.105')
|
||||
msi_filename = 'pkgconf-@0@-@1@.msi'.format(wixl_arch, meson.project_version())
|
||||
|
||||
wxsfile = configure_file(input: 'pkgconf.wxs.in', output: 'pkgconf.wxs', configuration: conf_data)
|
||||
|
||||
if wixl.found()
|
||||
licensefile = custom_target(
|
||||
'License.rtf',
|
||||
input: 'COPYING',
|
||||
output: 'License.rtf',
|
||||
command: [python, files('txt2rtf.py'), '@INPUT@', '@OUTPUT@'],
|
||||
)
|
||||
|
||||
msi = custom_target(
|
||||
msi_filename,
|
||||
input: [wxsfile, licensefile, pkgconf_exe],
|
||||
output: msi_filename,
|
||||
command: [wixl, '--arch', wixl_arch, '--ext', 'ui', '-o', msi_filename, wxsfile],
|
||||
)
|
||||
|
||||
alias_target('msi', msi)
|
||||
endif
|
||||
endif
|
||||
|
||||
12
pkg.m4
12
pkg.m4
@ -1,5 +1,5 @@
|
||||
# pkg.m4 - Macros to locate and use pkg-config. -*- Autoconf -*-
|
||||
# serial 16 (pkgconf)
|
||||
# serial 12 (pkg-config-0.29.2)
|
||||
|
||||
dnl Copyright © 2004 Scott James Remnant <scott@netsplit.com>.
|
||||
dnl Copyright © 2012-2015 Dan Nicholson <dbn.lists@gmail.com>
|
||||
@ -15,7 +15,9 @@ dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
dnl General Public License for more details.
|
||||
dnl
|
||||
dnl You should have received a copy of the GNU General Public License
|
||||
dnl along with this program; if not, see <https://www.gnu.org/licenses/>.
|
||||
dnl along with this program; if not, write to the Free Software
|
||||
dnl Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
dnl 02111-1307, USA.
|
||||
dnl
|
||||
dnl As a special exception to the GNU General Public License, if you
|
||||
dnl distribute this file as part of a program that contains a
|
||||
@ -173,13 +175,13 @@ _PKG_TEXT])[]dnl
|
||||
elif test $pkg_failed = untried; then
|
||||
AC_MSG_RESULT([no])
|
||||
m4_default([$4], [AC_MSG_FAILURE(
|
||||
[A pkg-config implementation could not be found or is too old. Make sure it
|
||||
[The pkg-config script could not be found or is too old. Make sure it
|
||||
is in your PATH or set the PKG_CONFIG environment variable to the full
|
||||
path to pkg-config.
|
||||
|
||||
_PKG_TEXT
|
||||
|
||||
To get a pkg-config implementation, see <http://github.com/pkgconf/pkgconf>.])[]dnl
|
||||
To get pkg-config, see <http://pkg-config.freedesktop.org/>.])[]dnl
|
||||
])
|
||||
else
|
||||
$1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS
|
||||
@ -300,7 +302,7 @@ AC_ARG_WITH(with_arg,
|
||||
[AS_TR_SH([with_]with_arg)=def_arg])
|
||||
|
||||
AS_CASE([$AS_TR_SH([with_]with_arg)],
|
||||
[yes],[PKG_CHECK_MODULES([$1],[$2],[$3],[$4])],
|
||||
[yes],[PKG_CHECK_MODULES([$1],[$2],$3,$4)],
|
||||
[auto],[PKG_CHECK_MODULES([$1],[$2],
|
||||
[m4_n([def_action_if_found]) $3],
|
||||
[m4_n([def_action_if_not_found]) $4])])
|
||||
|
||||
@ -1,64 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
|
||||
|
||||
<?define Arch = "@WIXL_ARCH@"?>
|
||||
<?if $(var.Arch) = "x64"?>
|
||||
<?define GLIB_ARCH = "win64"?>
|
||||
<?define ArchString = "64-bit"?>
|
||||
<?define ArchProgramFilesFolder = "ProgramFiles64Folder"?>
|
||||
<?define Win64 = "yes"?>
|
||||
<?else?>
|
||||
<?define GLIB_ARCH = "win32"?>
|
||||
<?define ArchString = "32-bit"?>
|
||||
<?define ArchProgramFilesFolder = "ProgramFilesFolder"?>
|
||||
<?define Win64 = "no"?>
|
||||
<?endif?>
|
||||
|
||||
|
||||
<Product Id="*"
|
||||
Name="pkgconf @VERSION@ ($(var.ArchString))"
|
||||
Language="1033"
|
||||
Version="@VERSION@"
|
||||
Manufacturer="pkgconf"
|
||||
UpgradeCode="4faedad2-3f9d-45cc-89a7-3732ad2db0f7">
|
||||
|
||||
<Package InstallerVersion="200"
|
||||
Compressed="yes"
|
||||
InstallScope="perMachine" />
|
||||
|
||||
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
|
||||
<MediaTemplate EmbedCab="yes" />
|
||||
|
||||
<Feature Id="ProductFeature" Title="pkgconf" Level="1">
|
||||
<ComponentGroupRef Id="ProductComponents" />
|
||||
</Feature>
|
||||
|
||||
<Directory Id="TARGETDIR" Name="SourceDir">
|
||||
<Directory Id="$(var.ArchProgramFilesFolder)">
|
||||
<Directory Id="INSTALLFOLDER" Name="pkgconf @VERSION@" />
|
||||
</Directory>
|
||||
</Directory>
|
||||
|
||||
<ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
|
||||
<Component Id="PkgconfExe" Guid="*" Win64="$(var.Win64)">
|
||||
<File Id="PkgconfExeFile"
|
||||
Source="@EXE@"
|
||||
KeyPath="yes" />
|
||||
<File Id="PkgconfigExeFile"
|
||||
Name="pkg-config.exe"
|
||||
Source="@EXE@"/>
|
||||
<File Id="PkgconfDllFile"
|
||||
Source="@DLL@"/>
|
||||
<Environment Id="PATH"
|
||||
Name="PATH"
|
||||
Value="[INSTALLFOLDER]"
|
||||
Permanent="no"
|
||||
Part="last"
|
||||
Action="set"
|
||||
System="yes" />
|
||||
</Component>
|
||||
</ComponentGroup>
|
||||
|
||||
<UIRef Id="WixUI_Minimal" />
|
||||
</Product>
|
||||
</Wix>
|
||||
@ -1,3 +0,0 @@
|
||||
Query: %TEST_FIXTURES_DIR%/lib1/foo.pc
|
||||
WantedFlags: libs
|
||||
ExpectedStdout: -L/test/lib -lfoo
|
||||
@ -1,3 +0,0 @@
|
||||
Query: pkgconf
|
||||
WantedFlags: exists
|
||||
ExpectedExitCode: 0
|
||||
@ -1,5 +0,0 @@
|
||||
PackageSearchPath: lib1
|
||||
Query: pkg-config
|
||||
WantVariable: pc_path
|
||||
ExpectedExitCode: 0
|
||||
ExpectedStdout: %TEST_FIXTURES_DIR%/lib1
|
||||
@ -1,3 +0,0 @@
|
||||
Query: pkgconf
|
||||
WantedFlags: exists
|
||||
ExpectedExitCode: 0
|
||||
@ -1,5 +0,0 @@
|
||||
PackageSearchPath: lib1
|
||||
Query: pkgconf
|
||||
WantVariable: pc_path
|
||||
ExpectedExitCode: 0
|
||||
ExpectedStdout: %TEST_FIXTURES_DIR%/lib1
|
||||
@ -1,5 +0,0 @@
|
||||
Environment: PKG_CONFIG_PATH=%TEST_FIXTURES_DIR%/lib1/child-prefix/pkgconfig
|
||||
Environment: PKG_CONFIG_RELOCATE_PATHS=1
|
||||
WantedFlags: cflags libs
|
||||
Query: child-prefix-1
|
||||
ExpectedStdout: -I%TEST_FIXTURES_DIR%/lib1/include/child-prefix-1 -L%TEST_FIXTURES_DIR%/lib1/lib64 -lchild-prefix-1
|
||||
@ -1,4 +0,0 @@
|
||||
PackageSearchPath: lib1/child-prefix/pkgconfig
|
||||
WantedFlags: define-prefix cflags libs
|
||||
Query: child-prefix-1
|
||||
ExpectedStdout: -I%TEST_FIXTURES_DIR%/lib1/include/child-prefix-1 -L%TEST_FIXTURES_DIR%/lib1/lib64 -lchild-prefix-1
|
||||
@ -1,4 +0,0 @@
|
||||
WantVariable: prefix
|
||||
WantedFlags: define-prefix
|
||||
Query: %TEST_FIXTURES_DIR%/lib-relocatable/lib/pkgconfig/foo.pc
|
||||
ExpectedStdout: %TEST_FIXTURES_DIR%/lib-relocatable
|
||||
@ -1,4 +0,0 @@
|
||||
Environment: PKG_CONFIG_PATH=%TEST_FIXTURES_DIR%/lib2
|
||||
Query: %TEST_FIXTURES_DIR%/lib3/bar.pc
|
||||
WantedFlags: cflags
|
||||
ExpectedStdout: -fPIC -I/test/include/foo
|
||||
@ -1,5 +0,0 @@
|
||||
Environment: PKG_CONFIG_DUPLICATE_TUPLE_PREFIX=/bar
|
||||
PackageSearchPath: lib1
|
||||
WantVariable: prefix
|
||||
Query: duplicate-tuple
|
||||
ExpectedStdout: /bar
|
||||
@ -1,8 +0,0 @@
|
||||
PackageSearchPath: lib1
|
||||
Query: foo
|
||||
WantedFlags: cflags exists-cflags
|
||||
ExpectedExitCode: 0
|
||||
ExpectedStdout: FOO_CFLAGS='-DHAVE_FOO'
|
||||
MatchStdout: partial
|
||||
WantEnvPrefix: FOO
|
||||
FragmentFilter: D
|
||||
@ -1,6 +0,0 @@
|
||||
PackageSearchPath: lib1
|
||||
Query: foo
|
||||
WantedFlags: cflags exists-cflags
|
||||
ExpectedExitCode: 0
|
||||
ExpectedStdout: -DHAVE_FOO
|
||||
MatchStdout: partial
|
||||
@ -1,4 +0,0 @@
|
||||
PackageSearchPath: lib1
|
||||
Query: nonexistent
|
||||
WantedFlags: exists
|
||||
ExpectedExitCode: 1
|
||||
@ -1,3 +0,0 @@
|
||||
PackageSearchPath: lib1
|
||||
Query: tilde >= 1.0.0
|
||||
ExpectedExitCode: 1
|
||||
@ -1,4 +0,0 @@
|
||||
PackageSearchPath: lib1
|
||||
Query: foo > 1.2.3
|
||||
WantedFlags: exists
|
||||
ExpectedExitCode: 1
|
||||
@ -1,3 +0,0 @@
|
||||
PackageSearchPath: lib1
|
||||
Query: tilde <= 1.0.0
|
||||
ExpectedExitCode: 0
|
||||
@ -1,4 +0,0 @@
|
||||
PackageSearchPath: lib1
|
||||
Query: foo >=
|
||||
WantedFlags: exists
|
||||
ExpectedExitCode: 1
|
||||
@ -1,4 +0,0 @@
|
||||
PackageSearchPath: lib1
|
||||
Query: foo > 1.2
|
||||
WantedFlags: exists
|
||||
ExpectedExitCode: 0
|
||||
@ -1,3 +0,0 @@
|
||||
PackageSearchPath: lib1
|
||||
Query: tilde = 1.0.0~rc1
|
||||
ExpectedExitCode: 0
|
||||
@ -1,4 +0,0 @@
|
||||
PackageSearchPath: lib1
|
||||
Query: incomplete
|
||||
WantedFlags: cflags
|
||||
ExpectedStdout:
|
||||
@ -1,4 +0,0 @@
|
||||
PackageSearchPath: lib1
|
||||
Query: incomplete
|
||||
WantedFlags: libs
|
||||
ExpectedStdout:
|
||||
@ -1,4 +0,0 @@
|
||||
Environment: PKG_CONFIG_SYSTEM_LIBRARY_PATH=/test/local/lib
|
||||
PackageSearchPath: lib1
|
||||
WantedFlags: libs-only-ldpath keep-system-libs
|
||||
Query: cflags-libs-only
|
||||
@ -1,6 +0,0 @@
|
||||
Environment: PKG_CONFIG_SYSTEM_LIBRARY_PATH=/test/local/lib
|
||||
PackageSearchPath: lib1
|
||||
WantedFlags: libs-only-ldpath
|
||||
ExpectedStdout:
|
||||
MatchStdout: empty
|
||||
Query: cflags-libs-only
|
||||
@ -1,5 +0,0 @@
|
||||
PackageSearchPath: lib1
|
||||
Query: foo > 1.2,bar >= 1.3
|
||||
WantedFlags: libs cflags
|
||||
ExpectedExitCode: 0
|
||||
ExpectedStdout: -fPIC -I/test/include/foo -L/test/lib -lbar -lfoo
|
||||
@ -1,5 +0,0 @@
|
||||
PackageSearchPath: lib1
|
||||
Query: foo > 1.2 bar >= 1.3
|
||||
WantedFlags: libs cflags
|
||||
ExpectedExitCode: 0
|
||||
ExpectedStdout: -fPIC -I/test/include/foo -L/test/lib -lbar -lfoo
|
||||
@ -1,6 +0,0 @@
|
||||
PackageSearchPath: lib1
|
||||
Query: foo != 1.2.3
|
||||
WantedFlags: libs cflags
|
||||
ExpectedExitCode: 1
|
||||
MatchStderr: partial
|
||||
ExpectedStderr: Package 'foo' has version '1.2.3', required version is '!= 1.2.3'
|
||||
@ -1,5 +0,0 @@
|
||||
PackageSearchPath: lib1
|
||||
Query: foo != 1.3.0
|
||||
WantedFlags: libs cflags
|
||||
ExpectedExitCode: 0
|
||||
ExpectedStdout: -fPIC -I/test/include/foo -L/test/lib -lfoo
|
||||
@ -1,5 +0,0 @@
|
||||
PackageSearchPath: lib1
|
||||
Query: foo > 1.2
|
||||
WantedFlags: libs cflags
|
||||
ExpectedExitCode: 0
|
||||
ExpectedStdout: -fPIC -I/test/include/foo -L/test/lib -lfoo
|
||||
@ -1,5 +0,0 @@
|
||||
PackageSearchPath: lib1
|
||||
Query: foo
|
||||
WantedFlags: libs cflags
|
||||
ExpectedExitCode: 0
|
||||
ExpectedStdout: -fPIC -I/test/include/foo -L/test/lib -lfoo
|
||||
@ -1,6 +0,0 @@
|
||||
PackageSearchPath: lib1
|
||||
Query: foo
|
||||
WantedFlags: libs
|
||||
ExpectedExitCode: 0
|
||||
ExpectedStdout: FOO_LIBS='-L/test/lib -lfoo'
|
||||
WantEnvPrefix: FOO
|
||||
@ -1,4 +0,0 @@
|
||||
PackageSearchPath: lib1
|
||||
Query: cflags-libs-only
|
||||
WantedFlags: libs-only-ldpath libs-only-libname
|
||||
ExpectedStdout: -L/test/local/lib -lfoo
|
||||
@ -1,5 +0,0 @@
|
||||
PackageSearchPath: lib1
|
||||
Query: foo
|
||||
WantedFlags: libs
|
||||
ExpectedExitCode: 0
|
||||
ExpectedStdout: -L/test/lib -lfoo
|
||||
@ -1,3 +0,0 @@
|
||||
PackageSearchPath: lib1
|
||||
Query: , foo
|
||||
ExpectedExitCode: 0
|
||||
@ -1,3 +0,0 @@
|
||||
WantedFlags: modversion
|
||||
Query: %TEST_FIXTURES_DIR%/lib1/bar.pc
|
||||
ExpectedStdout: 1.3
|
||||
@ -1,4 +0,0 @@
|
||||
PackageSearchPath: lib1
|
||||
WantedFlags: modversion
|
||||
Query: bar
|
||||
ExpectedStdout: 1.3
|
||||
@ -1,4 +0,0 @@
|
||||
PackageSearchPath: lib1
|
||||
WantedFlags: modversion
|
||||
Query: omg
|
||||
ExpectedStdout: 1.2.3
|
||||
@ -1,7 +0,0 @@
|
||||
PackageSearchPath: lib1
|
||||
Query: foo, foobar
|
||||
WantedFlags: modversion
|
||||
VerbosityLevel: 1
|
||||
ExpectedStdout: foo: 1.2.3
|
||||
ExpectedStdout: foobar: 3.2.1
|
||||
MatchStdout: partial
|
||||
@ -1,3 +0,0 @@
|
||||
Query:
|
||||
ExpectedExitCode: 1
|
||||
ExpectedStderr: Please specify at least one package name on the command line.
|
||||
@ -1,5 +0,0 @@
|
||||
PackageSearchPath: lib1
|
||||
Query: nocflag
|
||||
WantedFlags: cflags
|
||||
ExpectedStdout:
|
||||
ExpectedExitCode: 0
|
||||
@ -1,5 +0,0 @@
|
||||
PackageSearchPath: lib1
|
||||
Query: nolib
|
||||
WantedFlags: libs
|
||||
ExpectedStdout:
|
||||
ExpectedExitCode: 0
|
||||
@ -1,4 +0,0 @@
|
||||
Environment: PKG_CONFIG_PATH=%TEST_FIXTURES_DIR%/lib1%DIR_SEP%%TEST_FIXTURES_DIR%/lib2
|
||||
WantedFlags: libs
|
||||
Query: bar
|
||||
ExpectedStdout: -L/test/lib -lbar -lfoo
|
||||
@ -1,12 +0,0 @@
|
||||
PackageSearchPath: lib1
|
||||
Query: foo
|
||||
WantedFlags: print-variables cflags libs
|
||||
WantEnvPrefix: FOO
|
||||
ExpectedStdout: FOO_CFLAGS='-fPIC -I/test/include/foo'
|
||||
ExpectedStdout: FOO_LIBS='-L/test/lib -lfoo'
|
||||
ExpectedStdout: FOO_INCLUDEDIR='/test/include'
|
||||
ExpectedStdout: FOO_LIBDIR='/test/lib'
|
||||
ExpectedStdout: FOO_EXEC_PREFIX='/test'
|
||||
ExpectedStdout: FOO_PREFIX='/test'
|
||||
ExpectedStdout: FOO_PCFILEDIR='%TEST_FIXTURES_DIR%/lib1'
|
||||
MatchStdout: partial
|
||||
@ -1,5 +0,0 @@
|
||||
Environment: PKG_CONFIG_MAXIMUM_TRAVERSE_DEPTH=1
|
||||
PackageSearchPath: lib3
|
||||
WantedFlags: print-requires
|
||||
Query: bar
|
||||
ExpectedStdout: foo
|
||||
@ -1,4 +0,0 @@
|
||||
PackageSearchPath: lib1
|
||||
WantedFlags: libs
|
||||
Query: static-archive-libs
|
||||
ExpectedStdout: /libfoo.a -pthread
|
||||
@ -1,4 +0,0 @@
|
||||
PackageSearchPath: lib1
|
||||
Query: foo
|
||||
WantedFlags: uninstalled
|
||||
ExpectedExitCode: 1
|
||||
@ -1,4 +0,0 @@
|
||||
PackageSearchPath: lib1
|
||||
Query: omg
|
||||
WantedFlags: uninstalled
|
||||
ExpectedExitCode: 0
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user