aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBilly O'Neal <bion@microsoft.com>2021-02-04 10:15:44 -0800
committerGitHub <noreply@github.com>2021-02-04 10:15:44 -0800
commitaa60b7efa56a83ead743718941d8b320ef4a05af (patch)
treedb9f9ebd6fa37598b2f5f2ad564eb858cdeddcb0
parentf226416d2eafc495dd03572cb61542fb1670ffdc (diff)
downloadvcpkg-aa60b7efa56a83ead743718941d8b320ef4a05af.tar.gz
vcpkg-aa60b7efa56a83ead743718941d8b320ef4a05af.zip
[vcpkg] Download vcpkg.exe rather than building it in bootstrap on Windows. (#15474)
This reduces bootstrap cost for Windows customers, resolving the issue initially submitted as #12502 . The `toolsrc` tree was extracted to https://github.com/microsoft/vcpkg-tool. `bootstrap.sh` was changed to download the right source tarball, extract, and build it. This was chosen over the previous attempt, a submodule, over concerns of accidentally destroying people's local modifications.
-rw-r--r--.gitignore9
-rw-r--r--docs/about/privacy.md2
-rw-r--r--docs/tool-maintainers/benchmarking.md195
-rw-r--r--docs/tool-maintainers/layout.md74
-rw-r--r--docs/tool-maintainers/testing.md152
-rw-r--r--scripts/Generate-SpdxLicenseList.ps163
-rw-r--r--scripts/azure-pipelines/Create-PRDiff.ps1 (renamed from scripts/azure-pipelines/Create-FormatDiff.ps1)0
-rw-r--r--scripts/azure-pipelines/Format-CxxCode.ps150
-rw-r--r--scripts/azure-pipelines/azure-pipelines.yml14
-rw-r--r--scripts/azure-pipelines/end-to-end-tests-dir/backcompat-helpers.ps124
-rw-r--r--scripts/azure-pipelines/end-to-end-tests-dir/binarycaching.ps186
-rw-r--r--scripts/azure-pipelines/end-to-end-tests-dir/build-missing.ps118
-rw-r--r--scripts/azure-pipelines/end-to-end-tests-dir/cli.ps111
-rw-r--r--scripts/azure-pipelines/end-to-end-tests-dir/create.ps110
-rw-r--r--scripts/azure-pipelines/end-to-end-tests-dir/disable-metrics.ps167
-rw-r--r--scripts/azure-pipelines/end-to-end-tests-dir/env-passthrough.ps121
-rw-r--r--scripts/azure-pipelines/end-to-end-tests-dir/integrate-install.ps128
-rw-r--r--scripts/azure-pipelines/end-to-end-tests-dir/registries.ps1192
-rw-r--r--scripts/azure-pipelines/end-to-end-tests-dir/spaces.ps111
-rw-r--r--scripts/azure-pipelines/end-to-end-tests-dir/vcpkg-minimum-required.ps122
-rw-r--r--scripts/azure-pipelines/end-to-end-tests-dir/versions.ps198
-rw-r--r--scripts/azure-pipelines/end-to-end-tests-prelude.ps180
-rw-r--r--scripts/azure-pipelines/end-to-end-tests.ps155
-rw-r--r--scripts/azure-pipelines/linux/azure-pipelines.yml13
-rw-r--r--scripts/azure-pipelines/osx/azure-pipelines.yml11
-rw-r--r--scripts/azure-pipelines/signing.yml125
-rw-r--r--scripts/azure-pipelines/windows/azure-pipelines.yml29
-rw-r--r--scripts/azure-pipelines/windows/packages.config4
-rw-r--r--scripts/azure-pipelines/windows/signing.signproj39
-rw-r--r--scripts/bootstrap.ps1401
-rw-r--r--scripts/bootstrap.sh24
-rw-r--r--scripts/cleanEnvironmentHelper.ps152
-rw-r--r--scripts/e2e_ports/overlays/vcpkg-requires-current-date/portfile.cmake2
-rw-r--r--scripts/e2e_ports/overlays/vcpkg-requires-current-date/vcpkg.json6
-rw-r--r--scripts/e2e_ports/overlays/vcpkg-requires-future-date/portfile.cmake2
-rw-r--r--scripts/e2e_ports/overlays/vcpkg-requires-future-date/vcpkg.json6
-rw-r--r--scripts/e2e_ports/overlays/vcpkg-requires-old-date/portfile.cmake2
-rw-r--r--scripts/e2e_ports/overlays/vcpkg-requires-old-date/vcpkg.json6
-rw-r--r--scripts/e2e_ports/overlays/vcpkg-uses-test-cmake/portfile.cmake3
-rw-r--r--scripts/e2e_ports/overlays/vcpkg-uses-test-cmake/vcpkg.json6
-rw-r--r--scripts/e2e_ports/overlays/vcpkg-uses-vcpkg-common-functions/portfile.cmake3
-rw-r--r--scripts/e2e_ports/overlays/vcpkg-uses-vcpkg-common-functions/vcpkg.json6
-rw-r--r--scripts/e2e_ports/vcpkg-internal-e2e-test-port/portfile.cmake1
-rw-r--r--scripts/e2e_ports/vcpkg-internal-e2e-test-port/vcpkg.json4
-rw-r--r--scripts/e2e_ports/versions/baseline.json5
-rw-r--r--scripts/e2e_ports/versions/v-/vcpkg-internal-e2e-test-port.json8
-rw-r--r--scripts/testing/env-passthrough/passthrough.cmake6
-rw-r--r--scripts/testing/integrate-install/NoProps.vcxproj145
-rw-r--r--scripts/testing/integrate-install/Project1.vcxproj146
-rw-r--r--scripts/testing/integrate-install/Source.cpp6
-rw-r--r--scripts/testing/integrate-install/VcpkgTriplet.vcxproj151
-rw-r--r--scripts/testing/integrate-install/VcpkgTriplet2.vcxproj149
-rw-r--r--scripts/testing/integrate-install/VcpkgUseStatic.vcxproj151
-rw-r--r--scripts/testing/integrate-install/VcpkgUseStatic2.vcxproj149
-rw-r--r--scripts/tls12-download.exebin0 -> 18312 bytes
-rw-r--r--toolsrc/.clang-format54
-rw-r--r--toolsrc/CMakeLists.txt222
-rw-r--r--toolsrc/cmake/utilities.cmake250
-rw-r--r--toolsrc/include/catch2/catch.hpp16865
-rw-r--r--toolsrc/include/pch.h55
-rw-r--r--toolsrc/include/vcpkg-test/mockcmakevarprovider.h42
-rw-r--r--toolsrc/include/vcpkg-test/util.h132
-rw-r--r--toolsrc/include/vcpkg/archives.h10
-rw-r--r--toolsrc/include/vcpkg/base/basic_checks.h41
-rw-r--r--toolsrc/include/vcpkg/base/cache.h21
-rw-r--r--toolsrc/include/vcpkg/base/checks.h60
-rw-r--r--toolsrc/include/vcpkg/base/chrono.h75
-rw-r--r--toolsrc/include/vcpkg/base/cofffilereader.h25
-rw-r--r--toolsrc/include/vcpkg/base/cstringview.h60
-rw-r--r--toolsrc/include/vcpkg/base/delayed_init.h29
-rw-r--r--toolsrc/include/vcpkg/base/downloads.h41
-rw-r--r--toolsrc/include/vcpkg/base/enums.h11
-rw-r--r--toolsrc/include/vcpkg/base/expected.h245
-rw-r--r--toolsrc/include/vcpkg/base/files.h315
-rw-r--r--toolsrc/include/vcpkg/base/fwd/json.h10
-rw-r--r--toolsrc/include/vcpkg/base/fwd/lockguarded.h10
-rw-r--r--toolsrc/include/vcpkg/base/fwd/optional.h7
-rw-r--r--toolsrc/include/vcpkg/base/fwd/span.h10
-rw-r--r--toolsrc/include/vcpkg/base/fwd/stringview.h6
-rw-r--r--toolsrc/include/vcpkg/base/graphs.h113
-rw-r--r--toolsrc/include/vcpkg/base/hash.h52
-rw-r--r--toolsrc/include/vcpkg/base/ignore_errors.h10
-rw-r--r--toolsrc/include/vcpkg/base/json.h302
-rw-r--r--toolsrc/include/vcpkg/base/jsonreader.h367
-rw-r--r--toolsrc/include/vcpkg/base/lazy.h26
-rw-r--r--toolsrc/include/vcpkg/base/lineinfo.h13
-rw-r--r--toolsrc/include/vcpkg/base/lockguarded.h35
-rw-r--r--toolsrc/include/vcpkg/base/machinetype.h37
-rw-r--r--toolsrc/include/vcpkg/base/optional.h382
-rw-r--r--toolsrc/include/vcpkg/base/parse.h129
-rw-r--r--toolsrc/include/vcpkg/base/pragmas.h35
-rw-r--r--toolsrc/include/vcpkg/base/sortedvector.h52
-rw-r--r--toolsrc/include/vcpkg/base/span.h55
-rw-r--r--toolsrc/include/vcpkg/base/stringliteral.h18
-rw-r--r--toolsrc/include/vcpkg/base/strings.h306
-rw-r--r--toolsrc/include/vcpkg/base/stringview.h55
-rw-r--r--toolsrc/include/vcpkg/base/system.debug.h45
-rw-r--r--toolsrc/include/vcpkg/base/system.h50
-rw-r--r--toolsrc/include/vcpkg/base/system.print.h67
-rw-r--r--toolsrc/include/vcpkg/base/system.process.h144
-rw-r--r--toolsrc/include/vcpkg/base/system_headers.h40
-rw-r--r--toolsrc/include/vcpkg/base/uint128.h24
-rw-r--r--toolsrc/include/vcpkg/base/unicode.h148
-rw-r--r--toolsrc/include/vcpkg/base/util.h248
-rw-r--r--toolsrc/include/vcpkg/base/view.h3
-rw-r--r--toolsrc/include/vcpkg/base/xmlserializer.h31
-rw-r--r--toolsrc/include/vcpkg/base/zstringview.h52
-rw-r--r--toolsrc/include/vcpkg/binarycaching.h62
-rw-r--r--toolsrc/include/vcpkg/binarycaching.private.h51
-rw-r--r--toolsrc/include/vcpkg/binaryparagraph.h55
-rw-r--r--toolsrc/include/vcpkg/build.h389
-rw-r--r--toolsrc/include/vcpkg/buildenvironment.h15
-rw-r--r--toolsrc/include/vcpkg/cmakevars.h38
-rw-r--r--toolsrc/include/vcpkg/commands.add-version.h13
-rw-r--r--toolsrc/include/vcpkg/commands.autocomplete.h13
-rw-r--r--toolsrc/include/vcpkg/commands.buildexternal.h15
-rw-r--r--toolsrc/include/vcpkg/commands.cache.h13
-rw-r--r--toolsrc/include/vcpkg/commands.ci.h16
-rw-r--r--toolsrc/include/vcpkg/commands.ciclean.h13
-rw-r--r--toolsrc/include/vcpkg/commands.civerifyversions.h13
-rw-r--r--toolsrc/include/vcpkg/commands.contact.h15
-rw-r--r--toolsrc/include/vcpkg/commands.create.h15
-rw-r--r--toolsrc/include/vcpkg/commands.dependinfo.h16
-rw-r--r--toolsrc/include/vcpkg/commands.edit.h14
-rw-r--r--toolsrc/include/vcpkg/commands.env.h16
-rw-r--r--toolsrc/include/vcpkg/commands.fetch.h13
-rw-r--r--toolsrc/include/vcpkg/commands.format-manifest.h14
-rw-r--r--toolsrc/include/vcpkg/commands.h32
-rw-r--r--toolsrc/include/vcpkg/commands.hash.h13
-rw-r--r--toolsrc/include/vcpkg/commands.info.h13
-rw-r--r--toolsrc/include/vcpkg/commands.integrate.h17
-rw-r--r--toolsrc/include/vcpkg/commands.interface.h37
-rw-r--r--toolsrc/include/vcpkg/commands.list.h14
-rw-r--r--toolsrc/include/vcpkg/commands.owns.h15
-rw-r--r--toolsrc/include/vcpkg/commands.porthistory.h13
-rw-r--r--toolsrc/include/vcpkg/commands.portsdiff.h13
-rw-r--r--toolsrc/include/vcpkg/commands.search.h15
-rw-r--r--toolsrc/include/vcpkg/commands.setinstalled.h26
-rw-r--r--toolsrc/include/vcpkg/commands.upgrade.h16
-rw-r--r--toolsrc/include/vcpkg/commands.upload-metrics.h12
-rw-r--r--toolsrc/include/vcpkg/commands.version.h15
-rw-r--r--toolsrc/include/vcpkg/commands.xvsinstances.h14
-rw-r--r--toolsrc/include/vcpkg/configuration.h25
-rw-r--r--toolsrc/include/vcpkg/dependencies.h188
-rw-r--r--toolsrc/include/vcpkg/export.chocolatey.h20
-rw-r--r--toolsrc/include/vcpkg/export.h19
-rw-r--r--toolsrc/include/vcpkg/export.ifw.h25
-rw-r--r--toolsrc/include/vcpkg/export.prefab.h79
-rw-r--r--toolsrc/include/vcpkg/fwd/build.h7
-rw-r--r--toolsrc/include/vcpkg/fwd/cmakevars.h6
-rw-r--r--toolsrc/include/vcpkg/fwd/configuration.h6
-rw-r--r--toolsrc/include/vcpkg/fwd/dependencies.h7
-rw-r--r--toolsrc/include/vcpkg/fwd/packagespec.h6
-rw-r--r--toolsrc/include/vcpkg/fwd/portfileprovider.h10
-rw-r--r--toolsrc/include/vcpkg/fwd/registries.h9
-rw-r--r--toolsrc/include/vcpkg/fwd/vcpkgcmdarguments.h14
-rw-r--r--toolsrc/include/vcpkg/fwd/vcpkgpaths.h8
-rw-r--r--toolsrc/include/vcpkg/globalstate.h21
-rw-r--r--toolsrc/include/vcpkg/help.h19
-rw-r--r--toolsrc/include/vcpkg/input.h15
-rw-r--r--toolsrc/include/vcpkg/install.h116
-rw-r--r--toolsrc/include/vcpkg/metrics.h33
-rw-r--r--toolsrc/include/vcpkg/packagespec.h226
-rw-r--r--toolsrc/include/vcpkg/paragraphparser.h68
-rw-r--r--toolsrc/include/vcpkg/paragraphs.h60
-rw-r--r--toolsrc/include/vcpkg/platform-expression.h82
-rw-r--r--toolsrc/include/vcpkg/portfileprovider.h70
-rw-r--r--toolsrc/include/vcpkg/postbuildlint.buildtype.h65
-rw-r--r--toolsrc/include/vcpkg/postbuildlint.h20
-rw-r--r--toolsrc/include/vcpkg/registries.h111
-rw-r--r--toolsrc/include/vcpkg/remove.h34
-rw-r--r--toolsrc/include/vcpkg/sourceparagraph.h156
-rw-r--r--toolsrc/include/vcpkg/statusparagraph.h68
-rw-r--r--toolsrc/include/vcpkg/statusparagraphs.h82
-rw-r--r--toolsrc/include/vcpkg/textrowcol.h17
-rw-r--r--toolsrc/include/vcpkg/tools.h37
-rw-r--r--toolsrc/include/vcpkg/triplet.h50
-rw-r--r--toolsrc/include/vcpkg/update.h35
-rw-r--r--toolsrc/include/vcpkg/userconfig.h23
-rw-r--r--toolsrc/include/vcpkg/vcpkgcmdarguments.h236
-rw-r--r--toolsrc/include/vcpkg/vcpkglib.h26
-rw-r--r--toolsrc/include/vcpkg/vcpkgpaths.h178
-rw-r--r--toolsrc/include/vcpkg/versiondeserializers.h41
-rw-r--r--toolsrc/include/vcpkg/versions.h87
-rw-r--r--toolsrc/include/vcpkg/versiont.h44
-rw-r--r--toolsrc/include/vcpkg/visualstudio.h14
-rw-r--r--toolsrc/src/pch.cpp2
-rw-r--r--toolsrc/src/tls12-download.c311
-rw-r--r--toolsrc/src/vcpkg-fuzz/main.cpp194
-rw-r--r--toolsrc/src/vcpkg-test/arguments.cpp135
-rw-r--r--toolsrc/src/vcpkg-test/binarycaching.cpp290
-rw-r--r--toolsrc/src/vcpkg-test/binaryconfigparser.cpp336
-rw-r--r--toolsrc/src/vcpkg-test/catch.cpp12
-rw-r--r--toolsrc/src/vcpkg-test/chrono.cpp34
-rw-r--r--toolsrc/src/vcpkg-test/commands.cpp83
-rw-r--r--toolsrc/src/vcpkg-test/dependencies.cpp1713
-rw-r--r--toolsrc/src/vcpkg-test/downloads.cpp59
-rw-r--r--toolsrc/src/vcpkg-test/files.cpp406
-rw-r--r--toolsrc/src/vcpkg-test/hash.cpp276
-rw-r--r--toolsrc/src/vcpkg-test/json.cpp241
-rw-r--r--toolsrc/src/vcpkg-test/large-json-document.json.inc516
-rw-r--r--toolsrc/src/vcpkg-test/manifests.cpp733
-rw-r--r--toolsrc/src/vcpkg-test/mockcmakevarsprovider.cpp28
-rw-r--r--toolsrc/src/vcpkg-test/optional.cpp121
-rw-r--r--toolsrc/src/vcpkg-test/paragraph.cpp516
-rw-r--r--toolsrc/src/vcpkg-test/plan.cpp1297
-rw-r--r--toolsrc/src/vcpkg-test/platform-expression.cpp80
-rw-r--r--toolsrc/src/vcpkg-test/registries.cpp132
-rw-r--r--toolsrc/src/vcpkg-test/specifier.cpp130
-rw-r--r--toolsrc/src/vcpkg-test/statusparagraphs.cpp116
-rw-r--r--toolsrc/src/vcpkg-test/strings.cpp114
-rw-r--r--toolsrc/src/vcpkg-test/stringview.cpp19
-rw-r--r--toolsrc/src/vcpkg-test/system.cpp149
-rw-r--r--toolsrc/src/vcpkg-test/uint128.cpp68
-rw-r--r--toolsrc/src/vcpkg-test/update.cpp105
-rw-r--r--toolsrc/src/vcpkg-test/util.cpp230
-rw-r--r--toolsrc/src/vcpkg-test/versionplan.cpp152
-rw-r--r--toolsrc/src/vcpkg.cpp313
-rw-r--r--toolsrc/src/vcpkg/archives.cpp130
-rw-r--r--toolsrc/src/vcpkg/base/checks.cpp120
-rw-r--r--toolsrc/src/vcpkg/base/chrono.cpp180
-rw-r--r--toolsrc/src/vcpkg/base/cofffilereader.cpp311
-rw-r--r--toolsrc/src/vcpkg/base/downloads.cpp467
-rw-r--r--toolsrc/src/vcpkg/base/enums.cpp12
-rw-r--r--toolsrc/src/vcpkg/base/files.cpp1595
-rw-r--r--toolsrc/src/vcpkg/base/hash.cpp703
-rw-r--r--toolsrc/src/vcpkg/base/json.cpp1411
-rw-r--r--toolsrc/src/vcpkg/base/machinetype.cpp39
-rw-r--r--toolsrc/src/vcpkg/base/parse.cpp110
-rw-r--r--toolsrc/src/vcpkg/base/strings.cpp381
-rw-r--r--toolsrc/src/vcpkg/base/stringview.cpp45
-rw-r--r--toolsrc/src/vcpkg/base/system.cpp343
-rw-r--r--toolsrc/src/vcpkg/base/system.print.cpp30
-rw-r--r--toolsrc/src/vcpkg/base/system.process.cpp793
-rw-r--r--toolsrc/src/vcpkg/base/uint128.cpp66
-rw-r--r--toolsrc/src/vcpkg/base/unicode.cpp282
-rw-r--r--toolsrc/src/vcpkg/base/xmlserializer.cpp113
-rw-r--r--toolsrc/src/vcpkg/binarycaching.cpp1477
-rw-r--r--toolsrc/src/vcpkg/binaryparagraph.cpp312
-rw-r--r--toolsrc/src/vcpkg/build.cpp1491
-rw-r--r--toolsrc/src/vcpkg/buildenvironment.cpp20
-rw-r--r--toolsrc/src/vcpkg/cmakevars.cpp323
-rw-r--r--toolsrc/src/vcpkg/commands.add-version.cpp416
-rw-r--r--toolsrc/src/vcpkg/commands.autocomplete.cpp185
-rw-r--r--toolsrc/src/vcpkg/commands.buildexternal.cpp54
-rw-r--r--toolsrc/src/vcpkg/commands.cache.cpp79
-rw-r--r--toolsrc/src/vcpkg/commands.ci.cpp606
-rw-r--r--toolsrc/src/vcpkg/commands.ciclean.cpp46
-rw-r--r--toolsrc/src/vcpkg/commands.civerifyversions.cpp418
-rw-r--r--toolsrc/src/vcpkg/commands.contact.cpp66
-rw-r--r--toolsrc/src/vcpkg/commands.cpp134
-rw-r--r--toolsrc/src/vcpkg/commands.create.cpp70
-rw-r--r--toolsrc/src/vcpkg/commands.dependinfo.cpp339
-rw-r--r--toolsrc/src/vcpkg/commands.edit.cpp278
-rw-r--r--toolsrc/src/vcpkg/commands.env.cpp122
-rw-r--r--toolsrc/src/vcpkg/commands.fetch.cpp30
-rw-r--r--toolsrc/src/vcpkg/commands.format-manifest.cpp291
-rw-r--r--toolsrc/src/vcpkg/commands.hash.cpp41
-rw-r--r--toolsrc/src/vcpkg/commands.info.cpp147
-rw-r--r--toolsrc/src/vcpkg/commands.integrate.cpp607
-rw-r--r--toolsrc/src/vcpkg/commands.list.cpp147
-rw-r--r--toolsrc/src/vcpkg/commands.owns.cpp47
-rw-r--r--toolsrc/src/vcpkg/commands.porthistory.cpp240
-rw-r--r--toolsrc/src/vcpkg/commands.portsdiff.cpp200
-rw-r--r--toolsrc/src/vcpkg/commands.search.cpp184
-rw-r--r--toolsrc/src/vcpkg/commands.setinstalled.cpp176
-rw-r--r--toolsrc/src/vcpkg/commands.upgrade.cpp210
-rw-r--r--toolsrc/src/vcpkg/commands.upload-metrics.cpp29
-rw-r--r--toolsrc/src/vcpkg/commands.version.cpp60
-rw-r--r--toolsrc/src/vcpkg/commands.xvsinstances.cpp41
-rw-r--r--toolsrc/src/vcpkg/configuration.cpp84
-rw-r--r--toolsrc/src/vcpkg/dependencies.cpp1896
-rw-r--r--toolsrc/src/vcpkg/export.chocolatey.cpp233
-rw-r--r--toolsrc/src/vcpkg/export.cpp707
-rw-r--r--toolsrc/src/vcpkg/export.ifw.cpp517
-rw-r--r--toolsrc/src/vcpkg/export.prefab.cpp719
-rw-r--r--toolsrc/src/vcpkg/globalstate.cpp13
-rw-r--r--toolsrc/src/vcpkg/help.cpp205
-rw-r--r--toolsrc/src/vcpkg/input.cpp56
-rw-r--r--toolsrc/src/vcpkg/install.cpp1105
-rw-r--r--toolsrc/src/vcpkg/metrics.cpp501
-rw-r--r--toolsrc/src/vcpkg/packagespec.cpp291
-rw-r--r--toolsrc/src/vcpkg/paragraphs.cpp531
-rw-r--r--toolsrc/src/vcpkg/platform-expression.cpp577
-rw-r--r--toolsrc/src/vcpkg/portfileprovider.cpp390
-rw-r--r--toolsrc/src/vcpkg/postbuildlint.buildtype.cpp71
-rw-r--r--toolsrc/src/vcpkg/postbuildlint.cpp981
-rw-r--r--toolsrc/src/vcpkg/registries.cpp1204
-rw-r--r--toolsrc/src/vcpkg/remove.cpp337
-rw-r--r--toolsrc/src/vcpkg/sourceparagraph.cpp1389
-rw-r--r--toolsrc/src/vcpkg/spdx-exceptions.inc45
-rw-r--r--toolsrc/src/vcpkg/spdx-licenses.inc426
-rw-r--r--toolsrc/src/vcpkg/statusparagraph.cpp121
-rw-r--r--toolsrc/src/vcpkg/statusparagraphs.cpp186
-rw-r--r--toolsrc/src/vcpkg/tools.cpp615
-rw-r--r--toolsrc/src/vcpkg/triplet.cpp110
-rw-r--r--toolsrc/src/vcpkg/update.cpp103
-rw-r--r--toolsrc/src/vcpkg/userconfig.cpp77
-rw-r--r--toolsrc/src/vcpkg/vcpkgcmdarguments.cpp960
-rw-r--r--toolsrc/src/vcpkg/vcpkglib.cpp239
-rw-r--r--toolsrc/src/vcpkg/vcpkgpaths.cpp1086
-rw-r--r--toolsrc/src/vcpkg/versiondeserializers.cpp202
-rw-r--r--toolsrc/src/vcpkg/versions.cpp247
-rw-r--r--toolsrc/src/vcpkg/versiont.cpp48
-rw-r--r--toolsrc/src/vcpkg/visualstudio.cpp381
-rw-r--r--toolsrc/vcpkg.natvis35
-rw-r--r--toolsrc/windows-bootstrap/vcpkg.vcxproj374
307 files changed, 46 insertions, 69859 deletions
diff --git a/.gitignore b/.gitignore
index 6b77e62ba..15b8c8b6d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -11,8 +11,6 @@
*.userosscache
*.sln.docstates
-toolsrc/out*
-toolsrc/CMakeSettings.json
# fuzzing
sync_dir*
@@ -30,8 +28,6 @@ bld/
[Bb]in/
[Oo]bj/
[Ll]og/
-# VS Code build
-toolsrc/build
# Ignore the executable
/vcpkg
/vcpkg.exe
@@ -290,11 +286,6 @@ __pycache__/
/installed*/
/packages/
/scripts/buildsystems/tmp/
-/toolsrc/build.rel/
-/toolsrc/windows-bootstrap/msbuild.x86.debug/
-/toolsrc/windows-bootstrap/msbuild.x86.release/
-/toolsrc/windows-bootstrap/msbuild.x64.debug/
-/toolsrc/windows-bootstrap/msbuild.x64.release/
#ignore custom triplets
/triplets/*
#add vcpkg-designed triplets back in
diff --git a/docs/about/privacy.md b/docs/about/privacy.md
index 15ef69d76..5efecb679 100644
--- a/docs/about/privacy.md
+++ b/docs/about/privacy.md
@@ -41,7 +41,7 @@ We collect various telemetry events such as the command line used, the time of i
You can see the telemetry events any command by appending `--printmetrics` after the vcpkg command line.
-In the source code (included in `toolsrc\`), you can search for calls to the functions `track_property()`, `track_feature()`, `track_metric()`, and `track_buildtime()`
+In the source code (included at https://github.com/microsoft/vcpkg-tool/ ), you can search for calls to the functions `track_property()`, `track_feature()`, `track_metric()`, and `track_buildtime()`
to see every specific data point we collect.
## Avoid inadvertent disclosure information
diff --git a/docs/tool-maintainers/benchmarking.md b/docs/tool-maintainers/benchmarking.md
deleted file mode 100644
index e0295be50..000000000
--- a/docs/tool-maintainers/benchmarking.md
+++ /dev/null
@@ -1,195 +0,0 @@
-# Benchmarking
-
-Benchmarking new code against old code is extremely important whenever making
-large changes to how something works. If you are attempting to make something
-faster, and you end up slowing it down, you'll never know if you don't
-benchmark! We have benchmarks in the `toolsrc/src/vcpkg-test` directory, just
-like the tests -- they're treated as a special kind of test.
-
-## Running Benchmarks
-
-Unlike normal tests, benchmarks are hidden behind a special define -- `CATCH_CONFIG_ENABLE_BENCHMARKING` -- so that you never try to run benchmarks
-unless you specifically want to. This is because benchmarks actually take quite
-a long time! However, if you want to run benchmarks (and I recommend running
-only specific benchmarks at a time), you can do so by passing the
-`VCPKG_ENABLE_BENCHMARKING` option at cmake configure time.
-
-```sh
-$ cmake -B toolsrc/out -S toolsrc -G Ninja \
- -DCMAKE_BUILD_TYPE=Release \
- -DVCPKG_BUILD_BENCHMARKING=On
-
--- The C compiler identification is MSVC 19.22.27905.0
--- The CXX compiler identification is MSVC 19.22.27905.0
--- Check for working C compiler: C:/Program Files (x86)/Microsoft Visual Studio/2019/Enterprise/VC/Tools/MSVC/14.22.27905/bin/Hostx64/x64/cl.exe
--- Check for working C compiler: C:/Program Files (x86)/Microsoft Visual Studio/2019/Enterprise/VC/Tools/MSVC/14.22.27905/bin/Hostx64/x64/cl.exe -- works
--- Detecting C compiler ABI info
--- Detecting C compiler ABI info - done
--- Detecting C compile features
--- Detecting C compile features - done
--- Check for working CXX compiler: C:/Program Files (x86)/Microsoft Visual Studio/2019/Enterprise/VC/Tools/MSVC/14.22.27905/bin/Hostx64/x64/cl.exe
--- Check for working CXX compiler: C:/Program Files (x86)/Microsoft Visual Studio/2019/Enterprise/VC/Tools/MSVC/14.22.27905/bin/Hostx64/x64/cl.exe -- works
--- Detecting CXX compiler ABI info
--- Detecting CXX compiler ABI info - done
--- Detecting CXX compile features
--- Detecting CXX compile features - done
--- Looking for pthread.h
--- Looking for pthread.h - not found
--- Found Threads: TRUE
--- Configuring done
--- Generating done
--- Build files have been written to: C:/Users/t-nimaz/src/vcpkg/toolsrc/out
-
-$ cmake --build toolsrc/out
-
-[0/2] Re-checking globbed directories...
-[80/80] Linking CXX executable vcpkg-test.exe
-```
-
-You can then run benchmarks easily with the following command (which run the
-files benchmarks):
-
-```sh
-$ ./toolsrc/out/vcpkg-test [!benchmark][file]
-```
-
-You can switch out `[file]` for a different set -- `[hash]`, for example.
-
-## Writing Benchmarks
-
-First, before anything else, I recommend reading the
-[benchmarking documentation] at Catch2's repository.
-
-Now, after that, let's say that you wanted to benchmark, say, our ASCII
-case-insensitive string compare against your new implementation. We place
-benchmarks for code in the same file as their tests, so open
-`vcpkg-test/strings.cpp`, and add the following at the bottom:
-
-```cpp
-#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
-TEST_CASE ("case insensitive ascii equals: benchmark", "[strings][!benchmark]")
-{
- BENCHMARK("qwertyuiop") {
- return vcpkg::Strings::case_insensitive_ascii_equals("qwertyuiop", "QWERTYUIOP");
- };
-}
-#endif
-```
-
-Remember the `;` at the end of the benchmark -- it's not required for
-`TEST_CASE`s, but is for `BENCHMARK`s.
-
-Now, let's rebuild and run:
-
-```sh
-$ cmake --build toolsrc/out
-[0/2] Re-checking globbed directories...
-[2/2] Linking CXX executable vcpkg-test.exe
-$ ./toolsrc/out/vcpkg-test [strings][!benchmark]
-Filters: [strings][!benchmark]
-
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-vcpkg-test.exe is a Catch v2.9.1 host application.
-Run with -? for options
-
--------------------------------------------------------------------------------
-case insensitive ascii equals: benchmark
--------------------------------------------------------------------------------
-C:\Users\t-nimaz\src\vcpkg\toolsrc\src\vcpkg-test\strings.cpp(36)
-...............................................................................
-
-benchmark name samples iterations estimated
- mean low mean high mean
- std dev low std dev high std dev
--------------------------------------------------------------------------------
-qwertyuiop 100 2088 3.9672 ms
- 25 ns 24 ns 26 ns
- 6 ns 5 ns 8 ns
-
-
-===============================================================================
-test cases: 1 | 1 passed
-assertions: - none -
-```
-
-You've now written your first benchmark!
-
-But wait. This seems kind of silly. Benchmarking the comparison of literal
-strings is great and all, but could we make it a little more realistic?
-
-This is where `BENCHMARK_ADVANCED` comes in. `BENCHMARK_ADVANCED` allows one to
-write a benchmark that has a little setup to it without screwing up the numbers.
-Let's try it now:
-
-```cpp
-TEST_CASE ("case insensitive ascii equals: benchmark", "[strings][!benchmark]")
-{
- BENCHMARK_ADVANCED("equal strings")(Catch::Benchmark::Chronometer meter)
- {
- std::vector<std::string> strings;
- strings.resize(meter.runs());
- std::mt19937_64 urbg;
- std::uniform_int_distribution<std::uint64_t> data_generator;
-
- std::generate(strings.begin(), strings.end(), [&] {
- std::string result;
- for (std::size_t i = 0; i < 1000; ++i)
- {
- result += vcpkg::Strings::b32_encode(data_generator(urbg));
- }
-
- return result;
- });
-
- meter.measure(
- [&](int run) { return vcpkg::Strings::case_insensitive_ascii_equals(strings[run], strings[run]); });
- };
-}
-```
-
-Then, run it again!
-
-```sh
-$ cmake --build toolsrc/out
-[0/2] Re-checking globbed directories...
-[2/2] Linking CXX executable vcpkg-test.exe
-$ toolsrc/out/vcpkg-test [strings][!benchmark]
-Filters: [strings][!benchmark]
-
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-vcpkg-test.exe is a Catch v2.9.1 host application.
-Run with -? for options
-
--------------------------------------------------------------------------------
-case insensitive ascii equals: benchmark
--------------------------------------------------------------------------------
-C:\Users\t-nimaz\src\vcpkg\toolsrc\src\vcpkg-test\strings.cpp(36)
-...............................................................................
-
-benchmark name samples iterations estimated
- mean low mean high mean
- std dev low std dev high std dev
--------------------------------------------------------------------------------
-equal strings 100 2 5.4806 ms
- 22.098 us 21.569 us 23.295 us
- 3.842 us 2.115 us 7.41 us
-
-
-===============================================================================
-test cases: 1 | 1 passed
-assertions: - none -
-```
-
-And now you have a working benchmark to test the speed of the existing code, and
-of new code!
-
-If you're writing a lot of benchmarks that follow the same sort of pattern, with
-some differences in constants, look into `vcpkg-test/files.cpp`'s benchmarks --
-there are a lot of things one can do to make writing new benchmarks really easy.
-
-If you wish to add a benchmark for a piece of code that has not yet been tested,
-please read the [testing documentation], and please write some unit tests.
-The speed of your code isn't very important if it doesn't work at all!
-
-[benchmarking documentation]: https://github.com/catchorg/Catch2/blob/master/docs/benchmarks.md#top
-[testing documentation]: ./testing.md#adding-new-test-files
diff --git a/docs/tool-maintainers/layout.md b/docs/tool-maintainers/layout.md
deleted file mode 100644
index ca9fa5c6a..000000000
--- a/docs/tool-maintainers/layout.md
+++ /dev/null
@@ -1,74 +0,0 @@
-# Layout of the vcpkg source tree
-
-All vcpkg sources and build systems are in `toolsrc`. If you'd like to
-contribute to the vcpkg tool itself, most of your time will be spent in here.
-
-## Build Files
-
-These are the files used to build and configure the project. In order to build
-with CMake, the only files you should be interested in are `CMakeLists.txt`, and
-`.clang-format`; in order to build with msbuild or the Visual Studio IDE, you
-will be interested in `dirs.proj` or `vcpkg.sln`. However, if you add or remove
-files, you will need to edit the MSBuild project files in the `vcpkg*`
-directories no matter what system you use.
-
-### Top Level
-
-We have six files in this directory -- one `.clang-format` file, one
-`CMakeLists.txt` file, three Visual Studio files, and `VERSION.txt`.
-
- - `.clang-format`: This is where we store the formatting settings of the
- project. If you want to format the project, you can use the `format` target
- with the CMake build system.
- - `CMakeLists.txt`: This is where the CMake build system definition lives. If
- you want to modify how one builds the project, or add a target, you can do
- it here.
- - `VERSION.txt`: This is a file which tells `vcpkg` to tell the user to
- rebuild. If this version is different from the version when the user built
- the binary (for example, after a `git pull` or a `vcpkg update`), then
- `vcpkg` will print a message to re-bootstrap. This is updated whenever major
- changes are made to the `vcpkg` tool.
- - The Visual Studio files:
- - `vcpkg.natvis`: NATVIS files allow one to visualize objects of user
- defined type in the debugger -- this one contains the definitions for
- `vcpkg`'s types.
- - `dirs.proj`: This is how one builds with `msbuild` without calling into
- the IDE.
- - `vcpkg.sln`: The solution file is how one opens the project in the VS IDE.
-
-## Source Files
-
-If you're modifying the project, it's likely that these are the directories that
-you're going to deal with.
-
-### `include`
-
-There's one file in here -- `pch.h`. This contains most of the C++ standard
-library, and acts as a [precompiled header]. You can read more at the link.
-
-There are three directories:
-
- - `catch2` -- This contains the single-header library [catch2]. We use this
- library for both [testing] and [benchmarking].
- - `vcpkg` -- This contains the header files for the `vcpkg` project. All of
- the interfaces for building, installing, and generally "port stuff" live
- here.
- - `vcpkg/base` -- This contains the interfaces for the
- "vcpkg standard library" -- file handling, hashing, strings,
- `Span<T>`, printing, etc.
- - `vcpkg-test` -- This contains the interfaces for any common utilities
- required by the tests.
-
-### `src`
-
-The source files live here. `pch.cpp` is the source file for the
-[precompiled header]; `vcpkg.cpp` is where the `vcpkg` binary lives.
-
-The interesting files live in the `vcpkg` and `vcpkg-test` directories. In
-`vcpkg`, you have the implementation for the interfaces that live in
-`include/vcpkg`; and in `vcpkg-test`, you have the tests and benchmarks.
-
-[precompiled header]: https://en.wikipedia.org/wiki/Precompiled_header
-[catch2]: https://github.com/catchorg/Catch2
-[testing]: ./testing.md
-[benchmarking]: ./benchmarking.md
diff --git a/docs/tool-maintainers/testing.md b/docs/tool-maintainers/testing.md
deleted file mode 100644
index a9e866d9e..000000000
--- a/docs/tool-maintainers/testing.md
+++ /dev/null
@@ -1,152 +0,0 @@
-# Testing
-
-Testing vcpkg is important whenever one makes changes to the tool itself, and
-writing new tests and keeping them up to date is also very important. If one's
-code is subtly broken, we'd rather find it out right away than a few weeks down
-the line when someone complains!
-
-## Running Tests
-
-Before anything else, we should know whether you can actually run the tests!
-All you should need is a way to build vcpkg -- anything will do! All you have to
-do is follow the guide 😄
-
-With `$VCPKG_DIRECTORY` being the directory where you have cloned vcpkg, create
-a build directory in `$VCPKG_DIRECTORY/toolsrc` (commonly named `out`), and
-`cd` into it. Make sure to clean it out if it already exists!
-
-```sh
-$ cmake .. -DCMAKE_BUILD_TYPE=Debug -G Ninja
-$ cmake --build .
-$ ./vcpkg-test # ./vcpkg-test [$SPECIFIC_TEST] for a specific set of tests
-$ # i.e., ./vcpkg-test [arguments]
-```
-
-If you make any modifications to `vcpkg`, you'll have to do the
-`cmake --build .` step again.
-
-## Writing Tests
-
-In your journey to write new tests, and to modify existing tests, reading the
-[Catch2 documentation] will be very helpful! Come back after reading those 😀
-
-You'll want to place your tests in one of the existing files, or, if it doesn't
-belong in any of those, in a [new file](#adding-new-test-files).
-
-The layout of these tests is as follows:
-
-```cpp
-// ... includes
-
-TEST_CASE("Name of test", "[filename without the .cpp]") {
- // setup and the like
- REQUIRE(some boolean expression);
-}
-
-// etc.
-```
-
-You want to give these test cases good, descriptive, unique names, like
-`SourceParagraph construct minimum` -- it doesn't need to be extremely clear
-english, and shorthand is good, but make sure it's clear what the test is from
-the name. For the latter parameter, known as "tags", you should at least put the
-name of the file which the test case is in -- e.g., in `arguments.cpp`, you'd
-tag all of the test cases with `[arguments]`.
-
-If you wish to add helper functions, make sure to place them in an anonymous
-namespace -- this will ensure that they don't trample over anybody else's
-space. Additionally, there are a few helper functions that live in
-`<vcpkg-test/util.h>` and `src/vcpkg-test/util.cpp` -- make sure to look into
-them so that you're not rewriting functionality.
-
-That should be all you need to know to start writing your own tests!
-Remember to check out the [Catch2 documentation]
-if you'd like to get more advanced with your tests,
-and good luck on your testing journey!
-
-## Adding New Test Files
-
-Adding new test files should be easy and straightforward. All it requires is
-creating a new source file in `toolsrc/src/vcpkg-test`.
-
-### Example
-
-Let's try writing a new test file called `example` (very creative, I know).
-
-First, we should create a file, `example.cpp`, in `toolsrc/src/vcpkg-test`:
-
-```cpp
-// vcpkg-test/example.cpp
-#include <catch2/catch.hpp>
-```
-
-This is the minimum file needed for tests; let's rebuild!
-
-```sh
-$ cmake --build .
-[80/80] Linking CXX executable vcpkg.exe
-```
-
-Okay, now let's make sure this worked; add a test case to `example.cpp`:
-
-```cpp
-TEST_CASE("Example 1 - fail", "[example]") {
- REQUIRE(false);
-}
-```
-
-Now build the tests again, and run them:
-
-```sh
-$ cmake --build .
-[2/2] Linking CXX executable vcpkg-test.exe
-$ ./vcpkg-test
-
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-vcpkg-test.exe is a Catch v2.9.1 host application.
-Run with -? for options
-
--------------------------------------------------------------------------------
-Example 1 - fail
--------------------------------------------------------------------------------
-$VCPKG_DIRECTORY/toolsrc/src/vcpkg-test/example.cpp(3)
-...............................................................................
-
-$VCPKG_DIRECTORY/toolsrc/src/vcpkg-test/example.cpp(14): FAILED:
- REQUIRE( false )
-
-===============================================================================
-test cases: 102 | 101 passed | 1 failed
-assertions: 3611 | 3610 passed | 1 failed
-```
-
-Hopefully, that worked! It should compile correctly, and have one failing test.
-Now let's try a more complex test, after deleting the old one;
-
-```cpp
-// add #include <vcpkg/base/strings.h> to the top of the file
-namespace Strings = vcpkg::Strings;
-
-TEST_CASE("Example 2 - success", "[example]") {
- std::string hello = "Hello";
- REQUIRE(Strings::case_insensitive_ascii_equals(hello, "hELLo"));
- REQUIRE_FALSE(Strings::case_insensitive_ascii_starts_with(hello, "E"));
-}
-```
-
-Now compile and build the tests, and this time let's only run our example tests:
-
-```sh
-$ cmake --build .
-[2/2] Linking CXX executable vcpkg-test.exe
-$ ./vcpkg-test [example]
-Filters: [example]
-===============================================================================
-All tests passed (2 assertions in 1 test case)
-```
-
-Hopefully you have one test running and succeeding! If you have that, you have
-succeeded at adding a new file to vcpkg's tests. Congratulations! Have fun on
-the rest of your journey 🐱‍👤😁
-
-[Catch2 documentation]: https://github.com/catchorg/Catch2/blob/master/docs/tutorial.md#top
diff --git a/scripts/Generate-SpdxLicenseList.ps1 b/scripts/Generate-SpdxLicenseList.ps1
deleted file mode 100644
index 8af5fd4de..000000000
--- a/scripts/Generate-SpdxLicenseList.ps1
+++ /dev/null
@@ -1,63 +0,0 @@
-<#
-#>
-[CmdletBinding(PositionalBinding=$False)]
-Param(
- [Parameter(Mandatory=$True)]
- [string]$Commit,
-
- [Parameter()]
- [string]$GithubRepository = "spdx/license-list-data",
-
- [Parameter()]
- [string]$LicensesOutFile = "$PSScriptRoot/../toolsrc/src/vcpkg/spdx-licenses.inc",
-
- [Parameter()]
- [string]$ExceptionsOutFile = "$PSScriptRoot/../toolsrc/src/vcpkg/spdx-exceptions.inc"
-)
-
-function Transform-JsonFile {
- [CmdletBinding()]
- Param(
- [string]$Uri,
- [string]$OutFile,
- [string]$OuterName,
- [string]$Id
- )
-
- $req = Invoke-WebRequest -Uri $Uri
-
- if ($req.StatusCode -ne 200)
- {
- Write-Error "Failed to GET $Uri"
- throw
- }
-
- $json = $req.Content | ConvertFrom-Json -Depth 10
- Write-Verbose "Writing output to $OutFile"
-
- $fileContent = @(
- "// Data downloaded from $Uri",
- "// Generated by scripts/Generate-SpdxLicenseList.ps1",
- "{")
- $json.$OuterName | ForEach-Object {
- $fileContent += " `"$($_.$Id)`","
- }
- $fileContent += "}"
-
- $fileContent -join "`n" | Out-File -FilePath $OutFile -Encoding 'utf8'
-}
-
-$baseUrl = "https://raw.githubusercontent.com/$GithubRepository/$Commit/json"
-Write-Verbose "Getting json files from $baseUrl"
-
-Transform-JsonFile `
- -Uri "$baseUrl/licenses.json" `
- -OutFile $LicensesOutFile `
- -OuterName 'licenses' `
- -Id 'licenseId'
-
-Transform-JsonFile `
- -Uri "$baseUrl/exceptions.json" `
- -OutFile $ExceptionsOutFile `
- -OuterName 'exceptions' `
- -Id 'licenseExceptionId'
diff --git a/scripts/azure-pipelines/Create-FormatDiff.ps1 b/scripts/azure-pipelines/Create-PRDiff.ps1
index 599118089..599118089 100644
--- a/scripts/azure-pipelines/Create-FormatDiff.ps1
+++ b/scripts/azure-pipelines/Create-PRDiff.ps1
diff --git a/scripts/azure-pipelines/Format-CxxCode.ps1 b/scripts/azure-pipelines/Format-CxxCode.ps1
deleted file mode 100644
index 2653562a7..000000000
--- a/scripts/azure-pipelines/Format-CxxCode.ps1
+++ /dev/null
@@ -1,50 +0,0 @@
-[CmdletBinding()]
-Param(
- [Parameter(Mandatory=$True)]
- [string]$Root
-)
-
-$Root = Resolve-Path -LiteralPath $Root
-
-$clangFormat = Get-Command 'clang-format' -ErrorAction 'SilentlyContinue'
-if ($null -ne $clangFormat)
-{
- $clangFormat = $clangFormat.Source
-}
-
-if ($IsWindows)
-{
- if ([String]::IsNullOrEmpty($clangFormat) -or -not (Test-Path $clangFormat))
- {
- $clangFormat = 'C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Tools\Llvm\x64\bin\clang-format.exe'
- }
- if (-not (Test-Path $clangFormat))
- {
- $clangFormat = 'C:\Program Files\LLVM\bin\clang-format.exe'
- }
-}
-
-if ([String]::IsNullOrEmpty($clangFormat) -or -not (Test-Path $clangFormat))
-{
- Write-Error 'clang-format not found; is it installed?'
- throw
-}
-
-$toolsrc = Get-Item "$Root/toolsrc"
-Push-Location $toolsrc
-
-try
-{
- $files = Get-ChildItem -Recurse -LiteralPath "$toolsrc/src" -Filter '*.cpp'
- $files += Get-ChildItem -Recurse -LiteralPath "$toolsrc/src" -Filter '*.c'
- $files += Get-ChildItem -Recurse -LiteralPath "$toolsrc/include/vcpkg" -Filter '*.h'
- $files += Get-ChildItem -Recurse -LiteralPath "$toolsrc/include/vcpkg-test" -Filter '*.h'
- $files += Get-Item "$toolsrc/include/pch.h"
- $fileNames = $files.FullName
-
- & $clangFormat -style=file -i @fileNames
-}
-finally
-{
- Pop-Location
-}
diff --git a/scripts/azure-pipelines/azure-pipelines.yml b/scripts/azure-pipelines/azure-pipelines.yml
index 7fce6a5c1..27db6a93d 100644
--- a/scripts/azure-pipelines/azure-pipelines.yml
+++ b/scripts/azure-pipelines/azure-pipelines.yml
@@ -21,30 +21,24 @@ stages:
value: $(Build.ArtifactStagingDirectory)\format.diff
steps:
- task: Powershell@2
- displayName: 'Format C++'
- inputs:
- filePath: 'scripts/azure-pipelines/Format-CxxCode.ps1'
- arguments: '-Root .'
- pwsh: true
- - task: Powershell@2
displayName: 'Generate Documentation'
inputs:
filePath: 'docs/regenerate.ps1'
arguments: '-VcpkgRoot . -WarningAction Stop'
pwsh: true
- script: .\bootstrap-vcpkg.bat
- displayName: 'Build vcpkg'
- - script: '.\vcpkg format-manifest --all'
+ displayName: 'Bootstrap vcpkg'
+ - script: '.\vcpkg.exe format-manifest --all'
displayName: 'Format Manifests'
- task: Powershell@2
displayName: 'Create Diff'
inputs:
- filePath: scripts/azure-pipelines/Create-FormatDiff.ps1
+ filePath: scripts/azure-pipelines/Create-PRDiff.ps1
arguments: '-DiffFile $(DiffFile)'
pwsh: true
- task: PublishBuildArtifacts@1
condition: failed()
- displayName: 'Publish C++ Diff'
+ displayName: 'Publish Format and Documentation Diff'
inputs:
PathtoPublish: '$(DiffFile)'
ArtifactName: 'format.diff'
diff --git a/scripts/azure-pipelines/end-to-end-tests-dir/backcompat-helpers.ps1 b/scripts/azure-pipelines/end-to-end-tests-dir/backcompat-helpers.ps1
deleted file mode 100644
index 704b52752..000000000
--- a/scripts/azure-pipelines/end-to-end-tests-dir/backcompat-helpers.ps1
+++ /dev/null
@@ -1,24 +0,0 @@
-. $PSScriptRoot/../end-to-end-tests-prelude.ps1
-
-# Test that prohibiting backcompat features actually prohibits
-$backcompatFeaturePorts = @('vcpkg-uses-test-cmake', 'vcpkg-uses-vcpkg-common-functions')
-foreach ($backcompatFeaturePort in $backcompatFeaturePorts) {
- $succeedArgs = $commonArgs + @('install',$backcompatFeaturePort,'--no-binarycaching')
- $failArgs = $succeedArgs + @('--x-prohibit-backcompat-features')
- $CurrentTest = "Should fail: ./vcpkg $($failArgs -join ' ')"
- Run-Vcpkg @failArgs
- if ($LastExitCode -ne 0) {
- Write-Host "... failed (this is good!)."
- } else {
- throw $CurrentTest
- }
-
- # Install failed when prohibiting backcompat features, so it should succeed if we allow them
- $CurrentTest = "Should succeeed: ./vcpkg $($succeedArgs -join ' ')"
- Run-Vcpkg @succeedArgs
- if ($LastExitCode -ne 0) {
- throw $CurrentTest
- } else {
- Write-Host "... succeeded."
- }
-}
diff --git a/scripts/azure-pipelines/end-to-end-tests-dir/binarycaching.ps1 b/scripts/azure-pipelines/end-to-end-tests-dir/binarycaching.ps1
deleted file mode 100644
index e4ee6e698..000000000
--- a/scripts/azure-pipelines/end-to-end-tests-dir/binarycaching.ps1
+++ /dev/null
@@ -1,86 +0,0 @@
-if ($IsLinux) {
- # The tests below need a mono installation not currently available on the Linux agents.
- return
-}
-
-. $PSScriptRoot/../end-to-end-tests-prelude.ps1
-
-# Test simple installation
-Run-Vcpkg -TestArgs ($commonArgs + @("install", "rapidjson", "--binarycaching", "--x-binarysource=clear;files,$ArchiveRoot,write;nuget,$NuGetRoot,readwrite"))
-Throw-IfFailed
-Require-FileExists "$installRoot/$Triplet/include/rapidjson/rapidjson.h"
-
-# Test simple removal
-Run-Vcpkg -TestArgs ($commonArgs + @("remove", "rapidjson"))
-Throw-IfFailed
-Require-FileNotExists "$installRoot/$Triplet/include/rapidjson/rapidjson.h"
-
-# Test restoring from files archive
-Remove-Item -Recurse -Force $installRoot
-Remove-Item -Recurse -Force $buildtreesRoot
-Run-Vcpkg -TestArgs ($commonArgs + @("install","rapidjson","--binarycaching","--x-binarysource=clear;files,$ArchiveRoot,read"))
-Throw-IfFailed
-Require-FileExists "$installRoot/$Triplet/include/rapidjson/rapidjson.h"
-Require-FileNotExists "$buildtreesRoot/rapidjson/src"
-Require-FileExists "$buildtreesRoot/detect_compiler"
-
-# Test --no-binarycaching
-Remove-Item -Recurse -Force $installRoot
-Remove-Item -Recurse -Force $buildtreesRoot
-Run-Vcpkg -TestArgs ($commonArgs + @("install","rapidjson","--no-binarycaching","--x-binarysource=clear;files,$ArchiveRoot,read"))
-Throw-IfFailed
-Require-FileExists "$installRoot/$Triplet/include/rapidjson/rapidjson.h"
-Require-FileExists "$buildtreesRoot/rapidjson/src"
-Require-FileExists "$buildtreesRoot/detect_compiler"
-
-# Test --editable
-Remove-Item -Recurse -Force $installRoot
-Remove-Item -Recurse -Force $buildtreesRoot
-Run-Vcpkg -TestArgs ($commonArgs + @("install","rapidjson","--editable","--x-binarysource=clear;files,$ArchiveRoot,read"))
-Throw-IfFailed
-Require-FileExists "$installRoot/$Triplet/include/rapidjson/rapidjson.h"
-Require-FileExists "$buildtreesRoot/rapidjson/src"
-Require-FileNotExists "$buildtreesRoot/detect_compiler"
-
-# Test restoring from nuget
-Remove-Item -Recurse -Force $installRoot
-Remove-Item -Recurse -Force $buildtreesRoot
-Run-Vcpkg -TestArgs ($commonArgs + @("install", "rapidjson", "--binarycaching", "--x-binarysource=clear;nuget,$NuGetRoot"))
-Throw-IfFailed
-Require-FileExists "$installRoot/$Triplet/include/rapidjson/rapidjson.h"
-Require-FileNotExists "$buildtreesRoot/rapidjson/src"
-
-# Test four-phase flow
-Remove-Item -Recurse -Force $installRoot -ErrorAction SilentlyContinue
-Run-Vcpkg -TestArgs ($commonArgs + @("install", "rapidjson", "--dry-run", "--x-write-nuget-packages-config=$TestingRoot/packages.config"))
-Throw-IfFailed
-Require-FileNotExists "$installRoot/$Triplet/include/rapidjson/rapidjson.h"
-Require-FileNotExists "$buildtreesRoot/rapidjson/src"
-Require-FileExists "$TestingRoot/packages.config"
-if ($IsLinux -or $IsMacOS) {
- mono $(./vcpkg fetch nuget) restore $TestingRoot/packages.config -OutputDirectory "$NuGetRoot2" -Source "$NuGetRoot"
-} else {
- & $(./vcpkg fetch nuget) restore $TestingRoot/packages.config -OutputDirectory "$NuGetRoot2" -Source "$NuGetRoot"
-}
-Throw-IfFailed
-Remove-Item -Recurse -Force $NuGetRoot -ErrorAction SilentlyContinue
-mkdir $NuGetRoot
-Run-Vcpkg -TestArgs ($commonArgs + @("install", "rapidjson", "tinyxml", "--binarycaching", "--x-binarysource=clear;nuget,$NuGetRoot2;nuget,$NuGetRoot,write"))
-Throw-IfFailed
-Require-FileExists "$installRoot/$Triplet/include/rapidjson/rapidjson.h"
-Require-FileExists "$installRoot/$Triplet/include/tinyxml.h"
-Require-FileNotExists "$buildtreesRoot/rapidjson/src"
-Require-FileExists "$buildtreesRoot/tinyxml/src"
-if ((Get-ChildItem $NuGetRoot -Filter '*.nupkg' | Measure-Object).Count -ne 1) {
- throw "In '$CurrentTest': did not create exactly 1 NuGet package"
-}
-
-# Test export
-$CurrentTest = 'Exporting'
-Require-FileNotExists "$TestingRoot/vcpkg-export-output"
-Require-FileNotExists "$TestingRoot/vcpkg-export.1.0.0.nupkg"
-Require-FileNotExists "$TestingRoot/vcpkg-export-output.zip"
-Run-Vcpkg -TestArgs ($commonArgs + @("export", "rapidjson", "tinyxml", "--nuget", "--nuget-id=vcpkg-export", "--nuget-version=1.0.0", "--output=vcpkg-export-output", "--raw", "--zip", "--output-dir=$TestingRoot"))
-Require-FileExists "$TestingRoot/vcpkg-export-output"
-Require-FileExists "$TestingRoot/vcpkg-export.1.0.0.nupkg"
-Require-FileExists "$TestingRoot/vcpkg-export-output.zip"
diff --git a/scripts/azure-pipelines/end-to-end-tests-dir/build-missing.ps1 b/scripts/azure-pipelines/end-to-end-tests-dir/build-missing.ps1
deleted file mode 100644
index 5f318e6af..000000000
--- a/scripts/azure-pipelines/end-to-end-tests-dir/build-missing.ps1
+++ /dev/null
@@ -1,18 +0,0 @@
-. $PSScriptRoot/../end-to-end-tests-prelude.ps1
-
-$CurrentTest = "Build Missing tests"
-
-Run-Vcpkg -TestArgs ($commonArgs + @("install", "rapidjson", "--only-binarycaching","--x-binarysource=clear;files,$ArchiveRoot,read"))
-Throw-IfNotFailed
-Require-FileNotExists "$installRoot/$Triplet/include/rapidjson/rapidjson.h"
-
-# Create the rapidjson archive
-Remove-Item -Recurse -Force $installRoot
-Run-Vcpkg -TestArgs ($commonArgs + @("install", "rapidjson","--x-binarysource=clear;files,$ArchiveRoot,write"))
-Throw-IfFailed
-Require-FileExists "$installRoot/$Triplet/include/rapidjson/rapidjson.h"
-
-Remove-Item -Recurse -Force $installRoot
-Run-Vcpkg -TestArgs ($commonArgs + @("install", "rapidjson", "--only-binarycaching","--x-binarysource=clear;files,$ArchiveRoot,read"))
-Throw-IfFailed
-Require-FileExists "$installRoot/$Triplet/include/rapidjson/rapidjson.h"
diff --git a/scripts/azure-pipelines/end-to-end-tests-dir/cli.ps1 b/scripts/azure-pipelines/end-to-end-tests-dir/cli.ps1
deleted file mode 100644
index 47f624fa8..000000000
--- a/scripts/azure-pipelines/end-to-end-tests-dir/cli.ps1
+++ /dev/null
@@ -1,11 +0,0 @@
-. $PSScriptRoot/../end-to-end-tests-prelude.ps1
-
-# Test bad command lines
-Run-Vcpkg -TestArgs ($commonArgs + @("install", "zlib", "--vcpkg-rootttttt", "C:\"))
-Throw-IfNotFailed
-
-Run-Vcpkg -TestArgs ($commonArgs + @("install", "zlib", "--vcpkg-rootttttt=C:\"))
-Throw-IfNotFailed
-
-Run-Vcpkg -TestArgs ($commonArgs + @("install", "zlib", "--fast")) # NB: --fast is not a switch
-Throw-IfNotFailed
diff --git a/scripts/azure-pipelines/end-to-end-tests-dir/create.ps1 b/scripts/azure-pipelines/end-to-end-tests-dir/create.ps1
deleted file mode 100644
index 9d59da539..000000000
--- a/scripts/azure-pipelines/end-to-end-tests-dir/create.ps1
+++ /dev/null
@@ -1,10 +0,0 @@
-. $PSScriptRoot/../end-to-end-tests-prelude.ps1
-
-# Test vcpkg create
-$Script:CurrentTest = "create zlib"
-Write-Host $Script:CurrentTest
-./vcpkg --x-builtin-ports-root=$TestingRoot/ports create zlib https://github.com/madler/zlib/archive/v1.2.11.tar.gz zlib-1.2.11.tar.gz
-Throw-IfFailed
-
-Require-FileExists "$TestingRoot/ports/zlib/portfile.cmake"
-Require-FileExists "$TestingRoot/ports/zlib/vcpkg.json"
diff --git a/scripts/azure-pipelines/end-to-end-tests-dir/disable-metrics.ps1 b/scripts/azure-pipelines/end-to-end-tests-dir/disable-metrics.ps1
deleted file mode 100644
index 5ad7616b4..000000000
--- a/scripts/azure-pipelines/end-to-end-tests-dir/disable-metrics.ps1
+++ /dev/null
@@ -1,67 +0,0 @@
-. $PSScriptRoot/../end-to-end-tests-prelude.ps1
-
-# Test that metrics are on by default
-$metricsTagName = 'vcpkg.disable-metrics'
-$metricsAreDisabledMessage = 'Warning: passed --sendmetrics, but metrics are disabled.'
-
-function Test-Metrics-Enabled() {
- Param(
- [Parameter(ValueFromRemainingArguments)]
- [string[]]$TestArgs
- )
-
- $actualArgs = @('version', '--sendmetrics')
- if ($TestArgs.Length -ne 0) {
- $actualArgs += $TestArgs
- }
-
- $vcpkgOutput = Run-Vcpkg $actualArgs
- if ($vcpkgOutput -contains $metricsAreDisabledMessage) {
- Write-Host 'Metrics are disabled'
- return $false
- }
-
- Write-Host 'Metrics are enabled'
- return $true
-}
-
-# By default, metrics are enabled.
-Require-FileNotExists $metricsTagName
-if (-Not (Test-Metrics-Enabled)) {
- throw "Metrics were not on by default."
-}
-
-if (Test-Metrics-Enabled '--disable-metrics') {
- throw "Metrics were not disabled by switch."
-}
-
-$env:VCPKG_DISABLE_METRICS = 'ON'
-try {
- if (Test-Metrics-Enabled) {
- throw "Environment variable did not disable metrics."
- }
-
- # Also test that you get no message without --sendmetrics
- $vcpkgOutput = Run-Vcpkg list
- if ($vcpkgOutput -contains $metricsAreDisabledMessage) {
- throw "Disabled metrics emit message even without --sendmetrics"
- }
-
- if (-Not (Test-Metrics-Enabled '--no-disable-metrics')) {
- throw "Environment variable to disable metrics could not be overridden by switch."
- }
-} finally {
- Remove-Item env:VCPKG_DISABLE_METRICS
-}
-
-# If the disable-metrics tag file exists, metrics are disabled even if attempted to be enabled on
-# the command line.
-Set-Content -Path $metricsTagName -Value ""
-try {
- if (Test-Metrics-Enabled '--disable-metrics') {
- throw "Metrics were not force-disabled by the disable-metrics tag file."
- }
-}
-finally {
- Remove-Item $metricsTagName
-}
diff --git a/scripts/azure-pipelines/end-to-end-tests-dir/env-passthrough.ps1 b/scripts/azure-pipelines/end-to-end-tests-dir/env-passthrough.ps1
deleted file mode 100644
index 6de1335d7..000000000
--- a/scripts/azure-pipelines/end-to-end-tests-dir/env-passthrough.ps1
+++ /dev/null
@@ -1,21 +0,0 @@
-if (-not $IsLinux -and -not $IsMacOS) {
- . $PSScriptRoot/../end-to-end-tests-prelude.ps1
-
- $env:_VCPKG_TEST_TRACKED = "a"
- $env:_VCPKG_TEST_UNTRACKED = "b"
-
- $x = ./vcpkg "--overlay-triplets=$PSScriptRoot/../../testing/env-passthrough" env "echo %_VCPKG_TEST_TRACKED% %_VCPKG_TEST_TRACKED2% %_VCPKG_TEST_UNTRACKED% %_VCPKG_TEST_UNTRACKED2%"
- if ($x -ne "%_VCPKG_TEST_TRACKED% %_VCPKG_TEST_TRACKED2% %_VCPKG_TEST_UNTRACKED% %_VCPKG_TEST_UNTRACKED2%")
- {
- throw "env should have cleaned the environment ($x)"
- }
-
- $y = ./vcpkg "--overlay-triplets=$PSScriptRoot/../../testing/env-passthrough" env --triplet passthrough "echo %_VCPKG_TEST_TRACKED% %_VCPKG_TEST_TRACKED2% %_VCPKG_TEST_UNTRACKED% %_VCPKG_TEST_UNTRACKED2%"
- if ($y -ne "a %_VCPKG_TEST_TRACKED2% b %_VCPKG_TEST_UNTRACKED2%")
- {
- throw "env should have kept the environment ($y)"
- }
-
- rm env:_VCPKG_TEST_TRACKED
- rm env:_VCPKG_TEST_UNTRACKED
-} \ No newline at end of file
diff --git a/scripts/azure-pipelines/end-to-end-tests-dir/integrate-install.ps1 b/scripts/azure-pipelines/end-to-end-tests-dir/integrate-install.ps1
deleted file mode 100644
index 38362ba8c..000000000
--- a/scripts/azure-pipelines/end-to-end-tests-dir/integrate-install.ps1
+++ /dev/null
@@ -1,28 +0,0 @@
-if (-not $IsLinux -and -not $IsMacOS) {
- . $PSScriptRoot/../end-to-end-tests-prelude.ps1
-
- # Test msbuild props and targets
- $Script:CurrentTest = "zlib:x86-windows-static msbuild scripts\testing\integrate-install\..."
- Write-Host $Script:CurrentTest
- ./vcpkg $commonArgs install zlib:x86-windows-static --x-binarysource=clear
- Throw-IfFailed
- foreach ($project in @("VcpkgTriplet", "VcpkgTriplet2", "VcpkgUseStatic", "VcpkgUseStatic2")) {
- $Script:CurrentTest = "msbuild scripts\testing\integrate-install\$project.vcxproj"
- ./vcpkg $commonArgs env "msbuild scripts\testing\integrate-install\$project.vcxproj /p:VcpkgRoot=$TestingRoot /p:IntDir=$TestingRoot\int\ /p:OutDir=$TestingRoot\out\ "
- Throw-IfFailed
- Remove-Item -Recurse -Force $TestingRoot\int
- Remove-Item -Recurse -Force $TestingRoot\out
- }
- $Script:CurrentTest = "zlib:x86-windows msbuild scripts\testing\integrate-install\..."
- Write-Host $Script:CurrentTest
- ./vcpkg $commonArgs install zlib:x86-windows --x-binarysource=clear
- Throw-IfFailed
- foreach ($project in @("Project1", "NoProps")) {
- $Script:CurrentTest = "msbuild scripts\testing\integrate-install\$project.vcxproj"
- Write-Host $Script:CurrentTest
- ./vcpkg $commonArgs env "msbuild scripts\testing\integrate-install\$project.vcxproj /p:VcpkgRoot=$TestingRoot /p:IntDir=$TestingRoot\int\ /p:OutDir=$TestingRoot\out\ "
- Throw-IfFailed
- Remove-Item -Recurse -Force $TestingRoot\int
- Remove-Item -Recurse -Force $TestingRoot\out
- }
-}
diff --git a/scripts/azure-pipelines/end-to-end-tests-dir/registries.ps1 b/scripts/azure-pipelines/end-to-end-tests-dir/registries.ps1
deleted file mode 100644
index bdeeb0a15..000000000
--- a/scripts/azure-pipelines/end-to-end-tests-dir/registries.ps1
+++ /dev/null
@@ -1,192 +0,0 @@
-. "$PSScriptRoot/../end-to-end-tests-prelude.ps1"
-
-
-$builtinRegistryArgs = $commonArgs + @("--x-builtin-registry-versions-dir=$PSScriptRoot/../../e2e_ports/versions")
-
-Run-Vcpkg install @builtinRegistryArgs 'vcpkg-internal-e2e-test-port'
-Throw-IfNotFailed
-
-# We should not look into the versions directory unless we have a baseline,
-# even if we pass the registries feature flag
-Run-Vcpkg install @builtinRegistryArgs --feature-flags=registries 'vcpkg-internal-e2e-test-port'
-Throw-IfNotFailed
-
-Run-Vcpkg install @builtinRegistryArgs --feature-flags=registries 'zlib'
-Throw-IfFailed
-
-Write-Trace "Test git and filesystem registries"
-Refresh-TestRoot
-$filesystemRegistry = "$TestingRoot/filesystem-registry"
-$gitRegistryUpstream = "$TestingRoot/git-registry-upstream"
-
-# build a filesystem registry
-Write-Trace "build a filesystem registry"
-New-Item -Path $filesystemRegistry -ItemType Directory
-$filesystemRegistry = (Get-Item $filesystemRegistry).FullName
-
-Copy-Item -Recurse `
- -LiteralPath "$PSScriptRoot/../../e2e_ports/vcpkg-internal-e2e-test-port" `
- -Destination "$filesystemRegistry"
-New-Item `
- -Path "$filesystemRegistry/versions" `
- -ItemType Directory
-Copy-Item `
- -LiteralPath "$PSScriptRoot/../../e2e_ports/versions/baseline.json" `
- -Destination "$filesystemRegistry/versions/baseline.json"
-New-Item `
- -Path "$filesystemRegistry/versions/v-" `
- -ItemType Directory
-
-$vcpkgInternalE2eTestPortJson = @{
- "versions" = @(
- @{
- "version-string" = "1.0.0";
- "path" = "$/vcpkg-internal-e2e-test-port"
- }
- )
-}
-New-Item `
- -Path "$filesystemRegistry/versions/v-/vcpkg-internal-e2e-test-port.json" `
- -ItemType File `
- -Value (ConvertTo-Json -Depth 5 -InputObject $vcpkgInternalE2eTestPortJson)
-
-
-# build a git registry
-Write-Trace "build a git registry"
-New-Item -Path $gitRegistryUpstream -ItemType Directory
-$gitRegistryUpstream = (Get-Item $gitRegistryUpstream).FullName
-
-Push-Location $gitRegistryUpstream
-try
-{
- $gitConfigOptions = @(
- '-c', 'user.name=Nobody',
- '-c', 'user.email=nobody@example.com',
- '-c', 'core.autocrlf=false'
- )
-
- $CurrentTest = 'git init .'
- git @gitConfigOptions init .
- Throw-IfFailed
- Copy-Item -Recurse -LiteralPath "$PSScriptRoot/../../e2e_ports/vcpkg-internal-e2e-test-port" -Destination .
- New-Item -Path './vcpkg-internal-e2e-test-port/foobar' -Value 'this is just to get a distinct git tree'
-
- $CurrentTest = 'git add -A'
- git @gitConfigOptions add -A
- Throw-IfFailed
- $CurrentTest = 'git commit'
- git @gitConfigOptions commit -m 'initial commit'
- Throw-IfFailed
-
- $vcpkgInternalE2eTestPortGitTree = git rev-parse 'HEAD:vcpkg-internal-e2e-test-port'
- $vcpkgInternalE2eTestPortVersionsJson = @{
- "versions" = @(
- @{
- "version-string" = "1.0.0";
- "git-tree" = $vcpkgInternalE2eTestPortGitTree
- }
- )
- }
- $vcpkgBaseline = @{
- "default" = @{
- "vcpkg-internal-e2e-test-port" = @{
- "baseline" = "1.0.0"
- }
- }
- }
-
- New-Item -Path './versions' -ItemType Directory
- New-Item -Path './versions/v-' -ItemType Directory
-
- New-Item -Path './versions/baseline.json' -Value (ConvertTo-Json -Depth 5 -InputObject $vcpkgBaseline)
- New-Item -Path './versions/v-/vcpkg-internal-e2e-test-port.json' -Value (ConvertTo-Json -Depth 5 -InputObject $vcpkgInternalE2eTestPortVersionsJson)
-
- $CurrentTest = 'git add -A'
- git @gitConfigOptions add -A
- Throw-IfFailed
- $CurrentTest = 'git commit'
- git @gitConfigOptions commit --amend --no-edit
- Throw-IfFailed
-}
-finally
-{
- Pop-Location
-}
-
-# actually test the registries
-Write-Trace "actually test the registries"
-$vcpkgJson = @{
- "name" = "manifest-test";
- "version-string" = "1.0.0";
- "dependencies" = @(
- "vcpkg-internal-e2e-test-port"
- )
-}
-
-# test the filesystem registry
-Write-Trace "test the filesystem registry"
-$manifestDir = "$TestingRoot/filesystem-registry-test-manifest-dir"
-
-New-Item -Path $manifestDir -ItemType Directory
-$manifestDir = (Get-Item $manifestDir).FullName
-
-Push-Location $manifestDir
-try
-{
- New-Item -Path 'vcpkg.json' -ItemType File `
- -Value (ConvertTo-Json -Depth 5 -InputObject $vcpkgJson)
-
- $vcpkgConfigurationJson = @{
- "default-registry" = $null;
- "registries" = @(
- @{
- "kind" = "filesystem";
- "path" = $filesystemRegistry;
- "packages" = @( "vcpkg-internal-e2e-test-port" )
- }
- )
- }
- New-Item -Path 'vcpkg-configuration.json' -ItemType File `
- -Value (ConvertTo-Json -Depth 5 -InputObject $vcpkgConfigurationJson)
-
- Run-Vcpkg install @builtinRegistryArgs '--feature-flags=registries,manifests'
- Throw-IfFailed
-}
-finally
-{
- Pop-Location
-}
-
-# test the git registry
-Write-Trace "test the git registry"
-$manifestDir = "$TestingRoot/git-registry-test-manifest-dir"
-
-New-Item -Path $manifestDir -ItemType Directory
-$manifestDir = (Get-Item $manifestDir).FullName
-
-Push-Location $manifestDir
-try
-{
- New-Item -Path 'vcpkg.json' -ItemType File `
- -Value (ConvertTo-Json -Depth 5 -InputObject $vcpkgJson)
-
- $vcpkgConfigurationJson = @{
- "default-registry" = $null;
- "registries" = @(
- @{
- "kind" = "git";
- "repository" = $gitRegistryUpstream;
- "packages" = @( "vcpkg-internal-e2e-test-port" )
- }
- )
- }
- New-Item -Path 'vcpkg-configuration.json' -ItemType File `
- -Value (ConvertTo-Json -Depth 5 -InputObject $vcpkgConfigurationJson)
-
- Run-Vcpkg install @builtinRegistryArgs '--feature-flags=registries,manifests'
- Throw-IfFailed
-}
-finally
-{
- Pop-Location
-}
diff --git a/scripts/azure-pipelines/end-to-end-tests-dir/spaces.ps1 b/scripts/azure-pipelines/end-to-end-tests-dir/spaces.ps1
deleted file mode 100644
index b7aaf6462..000000000
--- a/scripts/azure-pipelines/end-to-end-tests-dir/spaces.ps1
+++ /dev/null
@@ -1,11 +0,0 @@
-. $PSScriptRoot/../end-to-end-tests-prelude.ps1
-
-##### Test spaces in the path
-$Script:CurrentTest = "zlib with spaces in path"
-Write-Host $Script:CurrentTest
-./vcpkg install zlib "--triplet" $Triplet `
- "--no-binarycaching" `
- "--x-buildtrees-root=$TestingRoot/build Trees" `
- "--x-install-root=$TestingRoot/instalL ed" `
- "--x-packages-root=$TestingRoot/packaG es"
-Throw-IfFailed
diff --git a/scripts/azure-pipelines/end-to-end-tests-dir/vcpkg-minimum-required.ps1 b/scripts/azure-pipelines/end-to-end-tests-dir/vcpkg-minimum-required.ps1
deleted file mode 100644
index 8f512ae7a..000000000
--- a/scripts/azure-pipelines/end-to-end-tests-dir/vcpkg-minimum-required.ps1
+++ /dev/null
@@ -1,22 +0,0 @@
-. $PSScriptRoot/../end-to-end-tests-prelude.ps1
-
-$successCases = @('vcpkg-requires-current-date', 'vcpkg-requires-old-date')
-foreach ($successCase in $successCases) {
- $CurrentTest = "Should succeeed: ./vcpkg install $successCase"
- Write-Host $CurrentTest
- Run-Vcpkg install $successCase @commonArgs
- if ($LastExitCode -ne 0) {
- throw $CurrentTest
- } else {
- Write-Host "... succeeded."
- }
-}
-
-$CurrentTest = "Should fail: ./vcpkg install vcpkg-requires-future-date"
-Write-Host $CurrentTest
-Run-Vcpkg install vcpkg-requires-future-date @commonArgs
-if ($LastExitCode -ne 0) {
- Write-Host "... failed (this is good!)."
-} else {
- throw $CurrentTest
-}
diff --git a/scripts/azure-pipelines/end-to-end-tests-dir/versions.ps1 b/scripts/azure-pipelines/end-to-end-tests-dir/versions.ps1
deleted file mode 100644
index 7f927759f..000000000
--- a/scripts/azure-pipelines/end-to-end-tests-dir/versions.ps1
+++ /dev/null
@@ -1,98 +0,0 @@
-. $PSScriptRoot/../end-to-end-tests-prelude.ps1
-
-# Test verify versions
-mkdir $VersionFilesRoot
-Copy-Item -Recurse "scripts/testing/version-files/versions_incomplete" $VersionFilesRoot
-$portsRedirectArgsOK = @(
- "--feature-flags=versions",
- "--x-builtin-ports-root=scripts/testing/version-files/ports",
- "--x-builtin-registry-versions-dir=scripts/testing/version-files/versions"
-)
-$portsRedirectArgsIncomplete = @(
- "--feature-flags=versions",
- "--x-builtin-ports-root=scripts/testing/version-files/ports_incomplete",
- "--x-builtin-registry-versions-dir=$VersionFilesRoot/versions_incomplete"
-)
-$CurrentTest = "x-verify-ci-versions (All files OK)"
-Write-Host $CurrentTest
-./vcpkg $portsRedirectArgsOK x-ci-verify-versions --verbose
-Throw-IfFailed
-
-$CurrentTest = "x-verify-ci-versions (Incomplete)"
-./vcpkg $portsRedirectArgsIncomplete x-ci-verify-versions --verbose
-Throw-IfNotFailed
-
-$CurrentTest = "x-add-version cat"
-# Do not fail if there's nothing to update
-./vcpkg $portsRedirectArgsIncomplete x-add-version cat
-Throw-IfFailed
-
-$CurrentTest = "x-add-version dog"
-# Local version is not in baseline and versions file
-./vcpkg $portsRedirectArgsIncomplete x-add-version dog
-Throw-IfFailed
-
-$CurrentTest = "x-add-version duck"
-# Missing versions file
-./vcpkg $portsRedirectArgsIncomplete x-add-version duck
-Throw-IfFailed
-
-$CurrentTest = "x-add-version ferret"
-# Missing versions file and missing baseline entry
-./vcpkg $portsRedirectArgsIncomplete x-add-version ferret
-Throw-IfFailed
-
-$CurrentTest = "x-add-version fish (must fail)"
-# Discrepancy between local SHA and SHA in fish.json. Requires --overwrite-version.
-$out = ./vcpkg $portsRedirectArgsIncomplete x-add-version fish
-Throw-IfNotFailed
-$CurrentTest = "x-add-version fish --overwrite-version"
-./vcpkg $portsRedirectArgsIncomplete x-add-version fish --overwrite-version
-Throw-IfFailed
-
-$CurrentTest = "x-add-version mouse"
-# Missing baseline entry
-./vcpkg $portsRedirectArgsIncomplete x-add-version mouse
-Throw-IfFailed
-# Validate changes
-./vcpkg $portsRedirectArgsIncomplete x-ci-verify-versions --verbose
-Throw-IfFailed
-
-$CurrentTest = "default baseline"
-$out = ./vcpkg $commonArgs "--feature-flags=versions" install --x-manifest-root=scripts/testing/version-files/default-baseline-1 2>&1 | Out-String
-Throw-IfNotFailed
-if ($out -notmatch ".*Error: while checking out baseline.*")
-{
- $out
- throw "Expected to fail due to missing baseline"
-}
-
-git fetch https://github.com/vicroms/test-registries
-foreach ($opt_registries in @("",",registries"))
-{
- Write-Trace "testing baselines: $opt_registries"
- Refresh-TestRoot
- $CurrentTest = "without default baseline 2 -- enabling versions should not change behavior"
- Remove-Item -Recurse $buildtreesRoot/versioning -ErrorAction SilentlyContinue
- ./vcpkg $commonArgs "--feature-flags=versions$opt_registries" install `
- "--dry-run" `
- "--x-manifest-root=scripts/testing/version-files/without-default-baseline-2" `
- "--x-builtin-registry-versions-dir=scripts/testing/version-files/default-baseline-2/versions"
- Throw-IfFailed
- Require-FileNotExists $buildtreesRoot/versioning
-
- $CurrentTest = "default baseline 2"
- ./vcpkg $commonArgs "--feature-flags=versions$opt_registries" install `
- "--dry-run" `
- "--x-manifest-root=scripts/testing/version-files/default-baseline-2" `
- "--x-builtin-registry-versions-dir=scripts/testing/version-files/default-baseline-2/versions"
- Throw-IfFailed
- Require-FileExists $buildtreesRoot/versioning
-
- $CurrentTest = "using version features fails without flag"
- ./vcpkg $commonArgs "--feature-flags=-versions$opt_registries" install `
- "--dry-run" `
- "--x-manifest-root=scripts/testing/version-files/default-baseline-2" `
- "--x-builtin-registry-versions-dir=scripts/testing/version-files/default-baseline-2/versions"
- Throw-IfNotFailed
-}
diff --git a/scripts/azure-pipelines/end-to-end-tests-prelude.ps1 b/scripts/azure-pipelines/end-to-end-tests-prelude.ps1
deleted file mode 100644
index 29718bf76..000000000
--- a/scripts/azure-pipelines/end-to-end-tests-prelude.ps1
+++ /dev/null
@@ -1,80 +0,0 @@
-$TestingRoot = Join-Path $WorkingRoot 'testing'
-$buildtreesRoot = Join-Path $TestingRoot 'buildtrees'
-$installRoot = Join-Path $TestingRoot 'installed'
-$packagesRoot = Join-Path $TestingRoot 'packages'
-$NuGetRoot = Join-Path $TestingRoot 'nuget'
-$NuGetRoot2 = Join-Path $TestingRoot 'nuget2'
-$ArchiveRoot = Join-Path $TestingRoot 'archives'
-$VersionFilesRoot = Join-Path $TestingRoot 'version-test'
-$commonArgs = @(
- "--triplet",
- $Triplet,
- "--x-buildtrees-root=$buildtreesRoot",
- "--x-install-root=$installRoot",
- "--x-packages-root=$packagesRoot",
- "--overlay-ports=$PSScriptRoot/../e2e_ports/overlays"
-)
-$Script:CurrentTest = 'unassigned'
-
-if ($IsWindows)
-{
- $VcpkgExe = Get-Item './vcpkg.exe'
-}
-else
-{
- $VcpkgExe = Get-Item './vcpkg'
-}
-
-function Refresh-TestRoot {
- Remove-Item -Recurse -Force $TestingRoot -ErrorAction SilentlyContinue
- mkdir $TestingRoot | Out-Null
- mkdir $NuGetRoot | Out-Null
-}
-
-function Require-FileExists {
- [CmdletBinding()]
- Param(
- [string]$File
- )
- if (-Not (Test-Path $File)) {
- throw "'$Script:CurrentTest' failed to create file '$File'"
- }
-}
-
-function Require-FileNotExists {
- [CmdletBinding()]
- Param(
- [string]$File
- )
- if (Test-Path $File) {
- throw "'$Script:CurrentTest' should not have created file '$File'"
- }
-}
-
-function Throw-IfFailed {
- if ($LASTEXITCODE -ne 0) {
- throw "'$Script:CurrentTest' had a step with a nonzero exit code"
- }
-}
-
-function Throw-IfNotFailed {
- if ($LASTEXITCODE -eq 0) {
- throw "'$Script:CurrentTest' had a step with an unexpectedly zero exit code"
- }
-}
-
-function Write-Trace ([string]$text) {
- Write-Host (@($MyInvocation.ScriptName, ":", $MyInvocation.ScriptLineNumber, ": ", $text) -join "")
-}
-
-function Run-Vcpkg {
- Param(
- [Parameter(ValueFromRemainingArguments)]
- [string[]]$TestArgs
- )
- $Script:CurrentTest = "vcpkg $($testArgs -join ' ')"
- Write-Host $Script:CurrentTest
- & $VcpkgExe @testArgs
-}
-
-Refresh-TestRoot
diff --git a/scripts/azure-pipelines/end-to-end-tests.ps1 b/scripts/azure-pipelines/end-to-end-tests.ps1
deleted file mode 100644
index 8858b362e..000000000
--- a/scripts/azure-pipelines/end-to-end-tests.ps1
+++ /dev/null
@@ -1,55 +0,0 @@
-# Copyright (c) Microsoft Corporation.
-# SPDX-License-Identifier: MIT
-#
-<#
-.SYNOPSIS
-End-to-End tests for the vcpkg executable.
-
-.DESCRIPTION
-These tests cover the command line interface and broad functions of vcpkg, including `install`, `remove` and certain
-binary caching scenarios. They use the vcpkg executable in the current directory.
-
-.PARAMETER Triplet
-The triplet to use for testing purposes.
-
-.PARAMETER WorkingRoot
-The location used as scratch space for testing.
-
-#>
-
-[CmdletBinding()]
-Param(
- [Parameter(Mandatory = $true)]
- [ValidateNotNullOrEmpty()]
- [string]$Triplet,
- [Parameter(Mandatory = $true)]
- [ValidateNotNullOrEmpty()]
- [string]$WorkingRoot,
- [Parameter(Mandatory = $false)]
- [ValidateNotNullOrEmpty()]
- [string]$Filter
-)
-
-$ErrorActionPreference = "Stop"
-
-if (-Not (Test-Path $WorkingRoot)) {
- New-Item -Path $WorkingRoot -ItemType Directory
-}
-
-$WorkingRoot = (Get-Item $WorkingRoot).FullName
-
-$AllTests = Get-ChildItem $PSScriptRoot/end-to-end-tests-dir/*.ps1
-if ($Filter -ne $Null) {
- $AllTests = $AllTests | ? { $_.Name -match $Filter }
-}
-$n = 1
-$m = $AllTests.Count
-
-$AllTests | % {
- Write-Host "[end-to-end-tests.ps1] [$n/$m] Running suite $_"
- & $_
- $n += 1
-}
-
-Write-Host "[end-to-end-tests.ps1] All tests passed."
-$LASTEXITCODE = 0
diff --git a/scripts/azure-pipelines/linux/azure-pipelines.yml b/scripts/azure-pipelines/linux/azure-pipelines.yml
index b20908f97..df5cceda6 100644
--- a/scripts/azure-pipelines/linux/azure-pipelines.yml
+++ b/scripts/azure-pipelines/linux/azure-pipelines.yml
@@ -30,20 +30,9 @@ jobs:
exit 0
displayName: 'Create ${{ variables.VCPKG_DOWNLOADS }}'
- task: Bash@3
- displayName: 'Build vcpkg'
+ displayName: 'Bootstrap vcpkg'
inputs:
filePath: bootstrap-vcpkg.sh
- arguments: '-buildTests'
- - bash: toolsrc/build.rel/vcpkg-test
- displayName: 'Run vcpkg tests'
- env:
- VCPKG_DEBUG: 1
- - task: PowerShell@2
- displayName: 'Run vcpkg end-to-end tests'
- inputs:
- filePath: 'scripts/azure-pipelines/end-to-end-tests.ps1'
- arguments: '-Triplet x64-linux -WorkingRoot ${{ variables.WORKING_ROOT }}'
- pwsh: true
- task: PowerShell@2
displayName: '*** Test Modified Ports and Prepare Test Logs ***'
inputs:
diff --git a/scripts/azure-pipelines/osx/azure-pipelines.yml b/scripts/azure-pipelines/osx/azure-pipelines.yml
index 50bba080f..52e974c93 100644
--- a/scripts/azure-pipelines/osx/azure-pipelines.yml
+++ b/scripts/azure-pipelines/osx/azure-pipelines.yml
@@ -30,17 +30,6 @@ jobs:
displayName: 'Build vcpkg'
inputs:
filePath: bootstrap-vcpkg.sh
- arguments: '-buildTests'
- - bash: toolsrc/build.rel/vcpkg-test
- displayName: 'Run vcpkg tests'
- env:
- VCPKG_DEBUG: 1
- - task: PowerShell@2
- displayName: 'Run vcpkg end-to-end tests'
- inputs:
- filePath: 'scripts/azure-pipelines/end-to-end-tests.ps1'
- arguments: '-Triplet x64-osx -WorkingRoot ${{ variables.WORKING_ROOT }}'
- pwsh: true
- task: PowerShell@2
displayName: '*** Test Modified Ports and Prepare Test Logs ***'
inputs:
diff --git a/scripts/azure-pipelines/signing.yml b/scripts/azure-pipelines/signing.yml
deleted file mode 100644
index b7a3137d9..000000000
--- a/scripts/azure-pipelines/signing.yml
+++ /dev/null
@@ -1,125 +0,0 @@
-# This script is used internally to produce signed vcpkg builds.
-# It uses machines / tasks that are not exposed here on GitHub, as
-# the hardware on which we allow signing is restricted.
-
-trigger: none
-
-variables:
- TeamName: vcpkg
-jobs:
- - job: windows
- displayName: "Windows"
- dependsOn:
- pool:
- name: 'VSEng-MicroBuildVS2019'
- demands:
- - CMAKE
- steps:
- - task: PoliCheck@1
- inputs:
- inputType: 'Basic'
- targetType: 'F'
- targetArgument: '$(Build.SourcesDirectory)'
- result: 'PoliCheck.xml'
- - task: CmdLine@2
- displayName: "Build vcpkg with CMake"
- inputs:
- failOnStderr: true
- script: |
- call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\Tools\VsDevCmd.bat" -arch=x86 -host_arch=x86
- cmake.exe -G Ninja -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTING=OFF -DVCPKG_DEVELOPMENT_WARNINGS=ON -DVCPKG_WARNINGS_AS_ERRORS=ON -DVCPKG_BUILD_FUZZING=OFF -B "$(Build.StagingDirectory)" -S toolsrc
- ninja.exe -C "$(Build.StagingDirectory)"
- - task: MicroBuildSigningPlugin@2
- inputs:
- signType: 'real'
- feedSource: 'https://devdiv.pkgs.visualstudio.com/DefaultCollection/_packaging/MicroBuildToolset/nuget/v3/index.json'
- - task: NuGetToolInstaller@1
- inputs:
- versionSpec: 5.7
- - task: NuGetCommand@2
- displayName: 'NuGet Restore MicroBuild Signing Extension'
- inputs:
- command: 'restore'
- restoreSolution: 'scripts/azure-pipelines/windows/signing.signproj'
- feedsToUse: 'config'
- restoreDirectory: '$(Build.SourcesDirectory)\scripts\azure-pipelines\packages'
- - task: MSBuild@1
- displayName: 'Sign vcpkg.exe'
- inputs:
- solution: 'scripts\azure-pipelines\windows\signing.signproj'
- msbuildArguments: '/p:OutDir=$(Build.ArtifactStagingDirectory)\ /p:IntermediateOutputPath=$(Build.StagingDirectory)\'
- - task: BinSkim@3
- inputs:
- InputType: 'CommandLine'
- arguments: 'analyze "$(Build.StagingDirectory)\vcpkg.exe"'
- - task: BinSkim@3
- inputs:
- InputType: 'CommandLine'
- arguments: 'analyze "$(Build.StagingDirectory)\tls12-download.exe"'
- - task: PublishBuildArtifacts@1
- displayName: 'Publish vcpkg.exe'
- inputs:
- PathtoPublish: '$(Build.ArtifactStagingDirectory)\vcpkg.exe'
- ArtifactName: 'Windows'
- publishLocation: 'Container'
- - task: PublishBuildArtifacts@1
- displayName: 'Publish vcpkg.pdb'
- inputs:
- PathtoPublish: '$(Build.ArtifactStagingDirectory)\vcpkg.pdb'
- ArtifactName: 'Windows'
- publishLocation: 'Container'
- - task: PublishBuildArtifacts@1
- displayName: 'Publish tls12-download.exe'
- inputs:
- PathtoPublish: '$(Build.ArtifactStagingDirectory)\tls12-download.exe'
- ArtifactName: 'Windows'
- publishLocation: 'Container'
- - task: PublishBuildArtifacts@1
- displayName: 'Publish tls12-download.pdb'
- inputs:
- PathtoPublish: '$(Build.ArtifactStagingDirectory)\tls12-download.pdb'
- ArtifactName: 'Windows'
- publishLocation: 'Container'
- - task: MicroBuildCleanup@1
- condition: succeededOrFailed()
- displayName: MicroBuild Cleanup
- - job: macos_build
- displayName: 'MacOS Build'
- pool:
- vmImage: macOS-10.15
- steps:
- - task: CmdLine@2
- displayName: "Build vcpkg with CMake"
- inputs:
- failOnStderr: true
- script: |
- cmake -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTING=OFF -DVCPKG_DEVELOPMENT_WARNINGS=ON -DVCPKG_WARNINGS_AS_ERRORS=ON -DVCPKG_BUILD_FUZZING=OFF -B "$(Build.StagingDirectory)" -S toolsrc
- make -j 8 -C "$(Build.StagingDirectory)"
- zip "$(Build.StagingDirectory)/vcpkg.zip" "$(Build.StagingDirectory)/vcpkg"
- - task: PublishBuildArtifacts@1
- displayName: "Publish Unsigned MacOS Binary"
- inputs:
- PathtoPublish: '$(Build.StagingDirectory)/vcpkg.zip'
- ArtifactName: 'staging'
- publishLocation: 'Container'
- - job: macos_sign
- displayName: 'MacOS Sign'
- dependsOn: macos_build
- pool:
- name: VSEng-MicroBuildVS2019
- steps:
- - checkout: none
- - task: DownloadBuildArtifacts@0
- displayName: 'Download Unsigned Binary'
- inputs:
- artifactName: staging
- - task: ms-vseng.MicroBuildTasks.7973a23b-33e3-4b00-a7d9-c06d90f8297f.MicroBuildSignMacFiles@1
- displayName: 'Sign Mac Files'
- inputs:
- SigningTarget: '$(Build.ArtifactStagingDirectory)\staging\vcpkg.zip'
- SigningCert: 8003
- - task: PublishBuildArtifacts@1
- displayName: 'Publish Signed Binary'
- inputs:
- PathtoPublish: '$(Build.ArtifactStagingDirectory)\staging\vcpkg.zip'
- ArtifactName: 'MacOS'
diff --git a/scripts/azure-pipelines/windows/azure-pipelines.yml b/scripts/azure-pipelines/windows/azure-pipelines.yml
index 4c46e86a7..c2d74b8bc 100644
--- a/scripts/azure-pipelines/windows/azure-pipelines.yml
+++ b/scripts/azure-pipelines/windows/azure-pipelines.yml
@@ -24,34 +24,7 @@ jobs:
pwsh: true
# Note: D: is the Azure machines' temporary disk.
- script: .\bootstrap-vcpkg.bat
- displayName: 'Build vcpkg'
- - task: PowerShell@2
- displayName: 'Run vcpkg end-to-end tests'
- condition: eq('${{ parameters.triplet }}', 'x86-windows')
- inputs:
- filePath: 'scripts/azure-pipelines/end-to-end-tests.ps1'
- arguments: '-Triplet ${{ parameters.triplet }} -WorkingRoot ${{ variables.WORKING_ROOT }}'
- pwsh: true
- - task: CmdLine@2
- displayName: "Build vcpkg with CMake, with older VS, and Run Tests"
- condition: eq('${{ parameters.triplet }}', 'x86-windows')
- inputs:
- script: |
- :: TRANSITION, get these tools on the VMs next time we roll them
- .\vcpkg.exe fetch cmake
- .\vcpkg.exe fetch ninja
- set PATH=${{ variables.VCPKG_DOWNLOADS }}\tools\cmake-3.19.2-windows\cmake-3.19.2-win32-x86\bin;${{ variables.VCPKG_DOWNLOADS }}\tools\ninja-1.10.1-windows;%PATH%
- call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\Tools\VsDevCmd.bat" -arch=x86 -host_arch=x86
- rmdir /s /q build.x86.debug > nul 2> nul
- cmake.exe -G Ninja -DCMAKE_BUILD_TYPE=Debug -DBUILD_TESTING=ON -DVCPKG_DEVELOPMENT_WARNINGS=ON -DVCPKG_WARNINGS_AS_ERRORS=ON -DVCPKG_BUILD_FUZZING=ON -B build.x86.debug -S toolsrc
- ninja.exe -C build.x86.debug
- set VCPKG_DEBUG=1
- build.x86.debug\vcpkg-test.exe
- cmake -G "Visual Studio 16 2019" -A Win32 -T v140 -DBUILD_TESTING=OFF -DVCPKG_DEVELOPMENT_WARNINGS=OFF -DVCPKG_WARNINGS_AS_ERRORS=ON -DVCPKG_BUILD_FUZZING=OFF -B build.x86.vs2015 -S toolsrc
- cmake --build build.x86.vs2015
- cmake -G "Visual Studio 16 2019" -A Win32 -T v141 -DBUILD_TESTING=OFF -DVCPKG_DEVELOPMENT_WARNINGS=OFF -DVCPKG_WARNINGS_AS_ERRORS=ON -DVCPKG_BUILD_FUZZING=OFF -B build.x86.vs2017 -S toolsrc
- cmake --build build.x86.vs2017
- failOnStderr: true
+ displayName: 'Bootstrap vcpkg'
- task: PowerShell@2
displayName: '*** Test Modified Ports and Prepare Test Logs ***'
inputs:
diff --git a/scripts/azure-pipelines/windows/packages.config b/scripts/azure-pipelines/windows/packages.config
deleted file mode 100644
index d48977f79..000000000
--- a/scripts/azure-pipelines/windows/packages.config
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<packages>
- <package id="Microsoft.VisualStudioEng.MicroBuild.Core" version="0.4.1" targetFramework="native" developmentDependency="true" />
-</packages> \ No newline at end of file
diff --git a/scripts/azure-pipelines/windows/signing.signproj b/scripts/azure-pipelines/windows/signing.signproj
deleted file mode 100644
index 9382e0a0e..000000000
--- a/scripts/azure-pipelines/windows/signing.signproj
+++ /dev/null
@@ -1,39 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-
- <Import Project="$(MSBuildThisFileDirectory)..\packages\Microsoft.VisualStudioEng.MicroBuild.Core.0.4.1\build\Microsoft.VisualStudioEng.MicroBuild.Core.props" Condition="Exists('..\packages\Microsoft.VisualStudioEng.MicroBuild.Core.0.4.1\build\Microsoft.VisualStudioEng.MicroBuild.Core.props')" />
-
- <ItemGroup>
- <PackageReference Include="Microsoft.VisualStudioEng.MicroBuild.Core" Version="0.4.1">
- <PrivateAssets>all</PrivateAssets>
- <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
- </PackageReference>
- </ItemGroup>
-
- <ItemGroup>
- <FilesToSign Include="$(IntermediateOutputPath)\vcpkg.exe">
- <Authenticode>Microsoft400</Authenticode>
- </FilesToSign>
- <FilesToSign Include="$(IntermediateOutputPath)\tls12-download.exe">
- <Authenticode>Microsoft400</Authenticode>
- </FilesToSign>
- </ItemGroup>
-
- <ImportGroup Label="ExtensionTargets">
- <Import Project="$(MSBuildThisFileDirectory)..\packages\Microsoft.VisualStudioEng.MicroBuild.Core.0.4.1\build\Microsoft.VisualStudioEng.MicroBuild.Core.targets" Condition="Exists('..\packages\Microsoft.VisualStudioEng.MicroBuild.Core.0.4.1\build\Microsoft.VisualStudioEng.MicroBuild.Core.targets')" />
- </ImportGroup>
- <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="Build">
- <PropertyGroup>
- <ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
- </PropertyGroup>
- <Error Condition="!Exists('$(MSBuildThisFileDirectory)..\packages\Microsoft.VisualStudioEng.MicroBuild.Core.0.4.1\build\Microsoft.VisualStudioEng.MicroBuild.Core.props')" Text="$([System.String]::Format('$(ErrorText)', '$(MSBuildThisFileDirectory)..\packages\Microsoft.VisualStudioEng.MicroBuild.Core.0.4.1\build\Microsoft.VisualStudioEng.MicroBuild.Core.props'))" />
- <Error Condition="!Exists('$(MSBuildThisFileDirectory)..\packages\Microsoft.VisualStudioEng.MicroBuild.Core.0.4.1\build\Microsoft.VisualStudioEng.MicroBuild.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(MSBuildThisFileDirectory)..\packages\Microsoft.VisualStudioEng.MicroBuild.Core.0.4.1\build\Microsoft.VisualStudioEng.MicroBuild.Core.targets'))" />
- </Target>
-
- <!-- Define an empty build target as we don't really build anything -->
- <Target Name="Build" />
-
- <!-- Target AfterBuild is required to trigger signing -->
- <Target Name="AfterBuild" AfterTargets="Build" />
-
-</Project>
diff --git a/scripts/bootstrap.ps1 b/scripts/bootstrap.ps1
index b4c6295c0..e4153aad4 100644
--- a/scripts/bootstrap.ps1
+++ b/scripts/bootstrap.ps1
@@ -1,10 +1,10 @@
[CmdletBinding()]
param(
$badParam,
- [Parameter(Mandatory=$False)][switch]$disableMetrics = $false,
[Parameter(Mandatory=$False)][switch]$win64 = $false,
[Parameter(Mandatory=$False)][string]$withVSPath = "",
- [Parameter(Mandatory=$False)][string]$withWinSDK = ""
+ [Parameter(Mandatory=$False)][string]$withWinSDK = "",
+ [Parameter(Mandatory=$False)][switch]$disableMetrics = $false
)
Set-StrictMode -Version Latest
# Powershell2-compatible way of forcing named-parameters
@@ -12,407 +12,48 @@ if ($badParam)
{
if ($disableMetrics -and $badParam -eq "1")
{
- Write-Warning "'disableMetrics 1' is deprecated, please change to 'disableMetrics' (without '1')"
+ Write-Warning "'disableMetrics 1' is deprecated, please change to 'disableMetrics' (without '1')."
}
else
{
- throw "Only named parameters are allowed"
+ throw "Only named parameters are allowed."
}
}
-$scriptsDir = split-path -parent $script:MyInvocation.MyCommand.Definition
-$withVSPath = $withVSPath -replace "\\$" # Remove potential trailing backslash
-
-function vcpkgHasProperty([Parameter(Mandatory=$true)][AllowNull()]$object, [Parameter(Mandatory=$true)]$propertyName)
+if ($win64)
{
- if ($null -eq $object)
- {
- return $false
- }
-
- return [bool]($object.psobject.Properties | Where-Object { $_.Name -eq "$propertyName"})
+ Write-Warning "-win64 no longer has any effect; ignored."
}
-function getProgramFiles32bit()
+if (-Not [string]::IsNullOrWhiteSpace($withVSPath))
{
- $out = ${env:PROGRAMFILES(X86)}
- if ($null -eq $out)
- {
- $out = ${env:PROGRAMFILES}
- }
-
- if ($null -eq $out)
- {
- throw "Could not find [Program Files 32-bit]"
- }
+ Write-Warning "-withVSPath no longer has any effect; ignored."
+}
- return $out
+if (-Not [string]::IsNullOrWhiteSpace($withWinSDK))
+{
+ Write-Warning "-withWinSDK no longer has any effect; ignored."
}
+$scriptsDir = split-path -parent $script:MyInvocation.MyCommand.Definition
$vcpkgRootDir = $scriptsDir
while (!($vcpkgRootDir -eq "") -and !(Test-Path "$vcpkgRootDir\.vcpkg-root"))
{
Write-Verbose "Examining $vcpkgRootDir for .vcpkg-root"
$vcpkgRootDir = Split-path $vcpkgRootDir -Parent
}
-Write-Verbose "Examining $vcpkgRootDir for .vcpkg-root - Found"
-
-$vcpkgBootstrapPath = "$vcpkgRootDir\toolsrc\windows-bootstrap"
-
-if (-not (Test-Path $vcpkgBootstrapPath))
-{
- Write-Error "Unable to determine vcpkg build directory. '$vcpkgBootstrapPath' does not exist."
- throw
-}
-
-function getVisualStudioInstances()
-{
- $programFiles = getProgramFiles32bit
- $results = New-Object System.Collections.ArrayList
- $vswhereExe = "$programFiles\Microsoft Visual Studio\Installer\vswhere.exe"
- if (Test-Path $vswhereExe)
- {
- $output = & $vswhereExe -prerelease -legacy -products * -format xml
- [xml]$asXml = $output
-
- foreach ($instance in $asXml.instances.instance)
- {
- $installationPath = $instance.InstallationPath -replace "\\$" # Remove potential trailing backslash
- $installationVersion = $instance.InstallationVersion
-
- $isPrerelease = -7
- if (vcpkgHasProperty -object $instance -propertyName "isPrerelease")
- {
- $isPrerelease = $instance.isPrerelease
- }
-
- if ($isPrerelease -eq 0)
- {
- $releaseType = "PreferenceWeight3::StableRelease"
- }
- elseif ($isPrerelease -eq 1)
- {
- $releaseType = "PreferenceWeight2::PreRelease"
- }
- else
- {
- $releaseType = "PreferenceWeight1::Legacy"
- }
-
- # Placed like that for easy sorting according to preference
- $results.Add("${releaseType}::${installationVersion}::${installationPath}") > $null
- }
- }
- else
- {
- Write-Verbose "Could not locate vswhere at $vswhereExe"
- }
-
- if ("$env:vs140comntools" -ne "")
- {
- $installationPath = Split-Path -Parent $(Split-Path -Parent "$env:vs140comntools")
- $clExe = "$installationPath\VC\bin\cl.exe"
- $vcvarsallbat = "$installationPath\VC\vcvarsall.bat"
-
- if ((Test-Path $clExe) -And (Test-Path $vcvarsallbat))
- {
- $results.Add("PreferenceWeight1::Legacy::14.0::$installationPath") > $null
- }
- }
-
- $installationPath = "$programFiles\Microsoft Visual Studio 14.0"
- $clExe = "$installationPath\VC\bin\cl.exe"
- $vcvarsallbat = "$installationPath\VC\vcvarsall.bat"
-
- if ((Test-Path $clExe) -And (Test-Path $vcvarsallbat))
- {
- $results.Add("PreferenceWeight1::Legacy::14.0::$installationPath") > $null
- }
-
- $results.Sort()
- $results.Reverse()
-
- return $results
-}
-
-function findAnyMSBuildWithCppPlatformToolset([string]$withVSPath)
-{
- $VisualStudioInstances = getVisualStudioInstances
- if ($null -eq $VisualStudioInstances)
- {
- throw "Could not find Visual Studio. VS2015, VS2017, or VS2019 (with C++) needs to be installed."
- }
-
- Write-Verbose "VS Candidates:`n`r$([system.String]::Join([Environment]::NewLine, $VisualStudioInstances))"
- foreach ($instanceCandidate in $VisualStudioInstances)
- {
- Write-Verbose "Inspecting: $instanceCandidate"
- $split = $instanceCandidate -split "::"
- # $preferenceWeight = $split[0]
- # $releaseType = $split[1]
- $version = $split[2]
- $path = $split[3]
-
- if ($withVSPath -ne "" -and $withVSPath -ne $path)
- {
- Write-Verbose "Skipping: $instanceCandidate"
- continue
- }
-
- $majorVersion = $version.Substring(0,2);
- if ($majorVersion -eq "16")
- {
- $VCFolder= "$path\VC\Tools\MSVC\"
- if (Test-Path $VCFolder)
- {
- Write-Verbose "Picking: $instanceCandidate"
- return "$path\MSBuild\Current\Bin\MSBuild.exe", "v142"
- }
- }
-
- if ($majorVersion -eq "15")
- {
- $VCFolder= "$path\VC\Tools\MSVC\"
- if (Test-Path $VCFolder)
- {
- Write-Verbose "Picking: $instanceCandidate"
- return "$path\MSBuild\15.0\Bin\MSBuild.exe", "v141"
- }
- }
-
- if ($majorVersion -eq "14")
- {
- $clExe= "$path\VC\bin\cl.exe"
- if (Test-Path $clExe)
- {
- Write-Verbose "Picking: $instanceCandidate"
- $programFilesPath = getProgramFiles32bit
- return "$programFilesPath\MSBuild\14.0\Bin\MSBuild.exe", "v140"
- }
- }
- }
-
- throw "Could not find MSBuild version with C++ support. VS2015, VS2017, or VS2019 (with C++) needs to be installed."
-}
-function getWindowsSDK( [Parameter(Mandatory=$False)][switch]$DisableWin10SDK = $False,
- [Parameter(Mandatory=$False)][switch]$DisableWin81SDK = $False,
- [Parameter(Mandatory=$False)][string]$withWinSDK)
-{
- if ($DisableWin10SDK -and $DisableWin81SDK)
- {
- throw "Both Win10SDK and Win81SDK were disabled."
- }
-
- Write-Verbose "Finding WinSDK"
-
- $validInstances = New-Object System.Collections.ArrayList
- # Windows 10 SDK
- function CheckWindows10SDK($path)
- {
- if ($null -eq $path)
- {
- return
- }
-
- $folder = (Join-Path $path "Include")
- if (!(Test-Path $folder))
- {
- Write-Verbose "$folder - Not Found"
- return
- }
-
- Write-Verbose "$folder - Found"
- $win10sdkVersions = @(Get-ChildItem $folder | Where-Object {$_.Name -match "^10"} | Sort-Object)
- [array]::Reverse($win10sdkVersions) # Newest SDK first
-
- foreach ($win10sdk in $win10sdkVersions)
- {
- $win10sdkV = $win10sdk.Name
- $windowsheader = "$folder\$win10sdkV\um\windows.h"
- if (!(Test-Path $windowsheader))
- {
- Write-Verbose "$windowsheader - Not Found"
- continue
- }
- Write-Verbose "$windowsheader - Found"
-
- $ddkheader = "$folder\$win10sdkV\shared\sdkddkver.h"
- if (!(Test-Path $ddkheader))
- {
- Write-Verbose "$ddkheader - Not Found"
- continue
- }
-
- Write-Verbose "$ddkheader - Found"
- $win10sdkVersionString = $win10sdkV.ToString()
- Write-Verbose "Found $win10sdkVersionString"
- $validInstances.Add($win10sdkVersionString) > $null
- }
- }
-
- Write-Verbose "`n"
- Write-Verbose "Looking for Windows 10 SDK"
- $regkey10 = Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows Kits\Installed Roots\' -Name 'KitsRoot10' -ErrorAction SilentlyContinue
- $regkey10Wow6432 = Get-ItemProperty -Path 'HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows Kits\Installed Roots\' -Name 'KitsRoot10' -ErrorAction SilentlyContinue
- if (vcpkgHasProperty -object $regkey10 "KitsRoot10") { CheckWindows10SDK($regkey10.KitsRoot10) }
- if (vcpkgHasProperty -object $regkey10Wow6432 "KitsRoot10") { CheckWindows10SDK($regkey10Wow6432.KitsRoot10) }
- CheckWindows10SDK("$env:ProgramFiles\Windows Kits\10")
- CheckWindows10SDK("${env:ProgramFiles(x86)}\Windows Kits\10")
-
- # Windows 8.1 SDK
- function CheckWindows81SDK($path)
- {
- if ($null -eq $path)
- {
- return
- }
-
- $folder = "$path\Include"
- if (!(Test-Path $folder))
- {
- Write-Verbose "$folder - Not Found"
- return
- }
-
- Write-Verbose "$folder - Found"
- $win81sdkVersionString = "8.1"
- Write-Verbose "Found $win81sdkVersionString"
- $validInstances.Add($win81sdkVersionString) > $null
- }
-
- Write-Verbose "`n"
- Write-Verbose "Looking for Windows 8.1 SDK"
- $regkey81 = Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows Kits\Installed Roots\' -Name 'KitsRoot81' -ErrorAction SilentlyContinue
- $regkey81Wow6432 = Get-ItemProperty -Path 'HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows Kits\Installed Roots\' -Name 'KitsRoot81' -ErrorAction SilentlyContinue
- if (vcpkgHasProperty -object $regkey81 "KitsRoot81") { CheckWindows81SDK($regkey81.KitsRoot81) }
- if (vcpkgHasProperty -object $regkey81Wow6432 "KitsRoot81") { CheckWindows81SDK($regkey81Wow6432.KitsRoot81) }
- CheckWindows81SDK("$env:ProgramFiles\Windows Kits\8.1")
- CheckWindows81SDK("${env:ProgramFiles(x86)}\Windows Kits\8.1")
-
- Write-Verbose "`n`n`n"
- Write-Verbose "The following Windows SDKs were found:"
- foreach ($instance in $validInstances)
- {
- Write-Verbose $instance
- }
-
- # Selecting
- if ($withWinSDK -ne "")
- {
- foreach ($instance in $validInstances)
- {
- if ($instance -eq $withWinSDK)
- {
- return $instance
- }
- }
-
- throw "Could not find the requested Windows SDK version: $withWinSDK"
- }
-
- foreach ($instance in $validInstances)
- {
- if (!$DisableWin10SDK -and $instance -match "10.")
- {
- return $instance
- }
-
- if (!$DisableWin81SDK -and $instance -match "8.1")
- {
- return $instance
- }
- }
-
- throw "Could not detect a Windows SDK / TargetPlatformVersion"
-}
-
-$msbuildExeWithPlatformToolset = findAnyMSBuildWithCppPlatformToolset $withVSPath
-$msbuildExe = $msbuildExeWithPlatformToolset[0]
-$platformToolset = $msbuildExeWithPlatformToolset[1]
-$windowsSDK = getWindowsSDK -withWinSDK $withWinSDK
-
-$disableMetricsValue = "0"
-if ($disableMetrics)
-{
- $disableMetricsValue = "1"
-}
-
-$platform = "x86"
-$vcpkgReleaseDir = "$vcpkgBootstrapPath\msbuild.x86.release"
-if($PSVersionTable.PSVersion.Major -le 2)
-{
- $architecture=(Get-WmiObject win32_operatingsystem | Select-Object osarchitecture).osarchitecture
-}
-else
-{
- $architecture=(Get-CimInstance win32_operatingsystem | Select-Object osarchitecture).osarchitecture
-}
-if ($win64)
-{
- if (-not $architecture -like "*64*")
- {
- throw "Cannot build 64-bit on non-64-bit system"
- }
-
- $platform = "x64"
- $vcpkgReleaseDir = "$vcpkgBootstrapPath\msbuild.x64.release"
-}
-
-if ($architecture -like "*64*")
-{
- $PreferredToolArchitecture = "x64"
-}
-else
-{
- $PreferredToolArchitecture = "x86"
-}
-
-$arguments = (
-"`"/p:VCPKG_VERSION=unknownhash`"",
-"`"/p:VCPKG_BASE_VERSION=2021-01-13`"", # Note: This duplicate date version will be short lived. See https://github.com/microsoft/vcpkg/pull/15474
-"/p:Configuration=Release",
-"/p:Platform=$platform",
-"/p:PlatformToolset=$platformToolset",
-"/p:TargetPlatformVersion=$windowsSDK",
-"/p:PreferredToolArchitecture=$PreferredToolArchitecture",
-"/verbosity:minimal",
-"/m",
-"/nologo",
-"`"$vcpkgBootstrapPath\vcpkg.vcxproj`"") -join " "
-
-function vcpkgInvokeCommandClean()
-{
- param ( [Parameter(Mandatory=$true)][string]$executable,
- [string]$arguments = "")
-
- Write-Verbose "Clean-Executing: ${executable} ${arguments}"
- $scriptsDir = split-path -parent $script:MyInvocation.MyCommand.Definition
- $cleanEnvScript = "$scriptsDir\cleanEnvironmentHelper.ps1"
- $tripleQuotes = "`"`"`""
- $argumentsWithEscapedQuotes = $arguments -replace "`"", $tripleQuotes
- $command = ". $tripleQuotes$cleanEnvScript$tripleQuotes; & $tripleQuotes$executable$tripleQuotes $argumentsWithEscapedQuotes"
- $arg = "-NoProfile", "-ExecutionPolicy Bypass", "-command $command"
-
- $process = Start-Process -FilePath powershell.exe -ArgumentList $arg -PassThru -NoNewWindow
- Wait-Process -InputObject $process
- $ec = $process.ExitCode
- Write-Verbose "Execution terminated with exit code $ec."
- return $ec
-}
+Write-Verbose "Examining $vcpkgRootDir for .vcpkg-root - Found"
-# vcpkgInvokeCommandClean cmd "/c echo %PATH%"
-Write-Host "`nBuilding vcpkg.exe ...`n"
-$ec = vcpkgInvokeCommandClean $msbuildExe $arguments
+& "$scriptsDir/tls12-download.exe" github.com "/microsoft/vcpkg-tool/releases/download/2021-01-13-768d8f95c9e752603d2c5901c7a7c7fbdb08af35/vcpkg.exe" "$vcpkgRootDir/vcpkg.exe"
+Write-Host ""
-if ($ec -ne 0)
+if ($LASTEXITCODE -ne 0)
{
- Write-Error "Building vcpkg.exe failed. Please ensure you have installed Visual Studio with the Desktop C++ workload and the Windows SDK for Desktop C++."
+ Write-Error "Downloading vcpkg.exe failed. Please check your internet connection, or consider downloading a recent vcpkg.exe from https://github.com/microsoft/vcpkg-tool with a browser."
throw
}
-Write-Host "`nBuilding vcpkg.exe... done.`n"
-
if ($disableMetrics)
{
Set-Content -Value "" -Path "$vcpkgRootDir\vcpkg.disable-metrics" -Force
@@ -433,9 +74,3 @@ or by setting the VCPKG_DISABLE_METRICS environment variable.
Read more about vcpkg telemetry at docs/about/privacy.md
"@
}
-
-Write-Verbose "Placing vcpkg.exe in the correct location"
-
-Copy-Item "$vcpkgReleaseDir\vcpkg.exe" "$vcpkgRootDir\vcpkg.exe"
-
-Remove-Item "$vcpkgReleaseDir" -Force -Recurse -ErrorAction SilentlyContinue
diff --git a/scripts/bootstrap.sh b/scripts/bootstrap.sh
index b7d889f9e..2188b8af7 100644
--- a/scripts/bootstrap.sh
+++ b/scripts/bootstrap.sh
@@ -276,11 +276,29 @@ else
fi
# Do the build
-buildDir="$vcpkgRootDir/toolsrc/build.rel"
-rm -rf "$buildDir"
+vcpkgToolReleaseTag="2021-01-13-768d8f95c9e752603d2c5901c7a7c7fbdb08af35"
+vcpkgToolReleaseSha="99c9949637f83bf361ee23557edc889e2865c2105c45306c39c40855a3e1440e2f6fb5ec59e95176fca61eff33929462d23c7b49feb1975f24adb8ca443a98a6"
+vcpkgToolReleaseTarball="$vcpkgToolReleaseTag.tar.gz"
+vcpkgToolUrl="https://github.com/microsoft/vcpkg-tool/archive/$vcpkgToolReleaseTarball"
+baseBuildDir="$vcpkgRootDir/buildtrees/_vcpkg"
+buildDir="$baseBuildDir/build"
+tarballPath="$downloadsDir/$vcpkgToolReleaseTarball"
+srcBaseDir="$baseBuildDir/src"
+srcDir="$srcBaseDir/vcpkg-tool-$vcpkgToolReleaseTag"
+
+if [ -e "$tarballPath" ]; then
+ vcpkgCheckEqualFileHash "$vcpkgToolUrl" "$tarballPath" "$vcpkgToolReleaseSha"
+else
+ echo "Downloading vcpkg tool sources"
+ vcpkgDownloadFile "$vcpkgToolUrl" "$tarballPath" "$vcpkgToolReleaseSha"
+fi
+
+echo "Building vcpkg-tool..."
+rm -rf "$baseBuildDir"
mkdir -p "$buildDir"
+vcpkgExtractArchive "$tarballPath" "$srcBaseDir"
-(cd "$buildDir" && CXX="$CXX" "$cmakeExe" .. -DCMAKE_BUILD_TYPE=Release -G "Ninja" "-DCMAKE_MAKE_PROGRAM=$ninjaExe" "-DBUILD_TESTING=$vcpkgBuildTests" "-DVCPKG_DEVELOPMENT_WARNINGS=OFF" "-DVCPKG_ALLOW_APPLE_CLANG=$vcpkgAllowAppleClang") || exit 1
+(cd "$buildDir" && CXX="$CXX" "$cmakeExe" "$srcDir" -DCMAKE_BUILD_TYPE=Release -G "Ninja" "-DCMAKE_MAKE_PROGRAM=$ninjaExe" "-DBUILD_TESTING=$vcpkgBuildTests" "-DVCPKG_DEVELOPMENT_WARNINGS=OFF" "-DVCPKG_ALLOW_APPLE_CLANG=$vcpkgAllowAppleClang") || exit 1
(cd "$buildDir" && "$cmakeExe" --build .) || exit 1
rm -rf "$vcpkgRootDir/vcpkg"
diff --git a/scripts/cleanEnvironmentHelper.ps1 b/scripts/cleanEnvironmentHelper.ps1
deleted file mode 100644
index fa5fe869d..000000000
--- a/scripts/cleanEnvironmentHelper.ps1
+++ /dev/null
@@ -1,52 +0,0 @@
-# Capture environment variables for the System and User. Also add some special/built-in variables.
-# These will be used to synthesize a clean environment
-$specialEnvironmentMap = @{ "SystemDrive"=$env:SystemDrive; "SystemRoot"=$env:SystemRoot; "UserProfile"=$env:UserProfile; "TMP"=$env:TMP } # These are built-in and not set in the registry
-$machineEnvironmentMap = [Environment]::GetEnvironmentVariables('Machine') # HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment
-$userEnvironmentMap = [Environment]::GetEnvironmentVariables('User') # HKEY_CURRENT_USER\Environment
-
-# Identify the keySet of environment variable names
-$nameSet = ($specialEnvironmentMap.Keys + $machineEnvironmentMap.Keys + $userEnvironmentMap.Keys) | Sort-Object | Select-Object -Unique
-
-# Any environment variable in the $nameSet should be restored to its original value
-foreach ($name in $nameSet)
-{
- if ($specialEnvironmentMap.ContainsKey($name))
- {
- [Environment]::SetEnvironmentVariable($name, $specialEnvironmentMap[$name], 'Process')
- continue;
- }
-
- # PATH needs to be concatenated as it has values in both machine and user environment. Any other values should be set.
- if ($name -eq 'path')
- {
- $pathValuePartial = @()
- # Machine values before user values
- $pathValuePartial += $machineEnvironmentMap[$name] -split ';'
- $pathValuePartial += $userEnvironmentMap[$name] -split ';'
- $pathValue = $pathValuePartial -join ';'
- [Environment]::SetEnvironmentVariable($name, $pathValue, 'Process')
- continue;
- }
-
- if ($userEnvironmentMap.ContainsKey($name))
- {
- [Environment]::SetEnvironmentVariable($name, $userEnvironmentMap[$name], 'Process')
- continue;
- }
-
- if ($machineEnvironmentMap.ContainsKey($name))
- {
- [Environment]::SetEnvironmentVariable($name, $machineEnvironmentMap[$name], 'Process')
- continue;
- }
-
- throw "Unreachable: Unknown variable $name"
-}
-
-# Any environment variable NOT in the $nameSet should be removed
-$processEnvironmentMap = [Environment]::GetEnvironmentVariables('Process')
-$variablesForRemoval = $processEnvironmentMap.Keys | Where-Object {$nameSet -notcontains $_}
-foreach ($name in $variablesForRemoval)
-{
- [Environment]::SetEnvironmentVariable($name, $null, 'Process')
-}
diff --git a/scripts/e2e_ports/overlays/vcpkg-requires-current-date/portfile.cmake b/scripts/e2e_ports/overlays/vcpkg-requires-current-date/portfile.cmake
deleted file mode 100644
index 68dc779a8..000000000
--- a/scripts/e2e_ports/overlays/vcpkg-requires-current-date/portfile.cmake
+++ /dev/null
@@ -1,2 +0,0 @@
-vcpkg_minimum_required(VERSION ${VCPKG_BASE_VERSION})
-set(VCPKG_POLICY_EMPTY_PACKAGE enabled)
diff --git a/scripts/e2e_ports/overlays/vcpkg-requires-current-date/vcpkg.json b/scripts/e2e_ports/overlays/vcpkg-requires-current-date/vcpkg.json
deleted file mode 100644
index 48debf1e7..000000000
--- a/scripts/e2e_ports/overlays/vcpkg-requires-current-date/vcpkg.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- "name": "vcpkg-requires-current-date",
- "version-string": "1.0.0",
- "description": "A test port that verifies that vcpkg_minimum_required is inclusive by using the current base version value.",
- "homepage": ""
-}
diff --git a/scripts/e2e_ports/overlays/vcpkg-requires-future-date/portfile.cmake b/scripts/e2e_ports/overlays/vcpkg-requires-future-date/portfile.cmake
deleted file mode 100644
index b68e53e95..000000000
--- a/scripts/e2e_ports/overlays/vcpkg-requires-future-date/portfile.cmake
+++ /dev/null
@@ -1,2 +0,0 @@
-vcpkg_minimum_required(VERSION 2999-12-31)
-set(VCPKG_POLICY_EMPTY_PACKAGE enabled)
diff --git a/scripts/e2e_ports/overlays/vcpkg-requires-future-date/vcpkg.json b/scripts/e2e_ports/overlays/vcpkg-requires-future-date/vcpkg.json
deleted file mode 100644
index f60901998..000000000
--- a/scripts/e2e_ports/overlays/vcpkg-requires-future-date/vcpkg.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- "name": "vcpkg-requires-future-date",
- "version-string": "1.0.0",
- "description": "A test port that requires a vcpkg version from an impossibly far future.",
- "homepage": ""
-}
diff --git a/scripts/e2e_ports/overlays/vcpkg-requires-old-date/portfile.cmake b/scripts/e2e_ports/overlays/vcpkg-requires-old-date/portfile.cmake
deleted file mode 100644
index 5a4fbf421..000000000
--- a/scripts/e2e_ports/overlays/vcpkg-requires-old-date/portfile.cmake
+++ /dev/null
@@ -1,2 +0,0 @@
-vcpkg_minimum_required(VERSION 2020-01-12)
-set(VCPKG_POLICY_EMPTY_PACKAGE enabled)
diff --git a/scripts/e2e_ports/overlays/vcpkg-requires-old-date/vcpkg.json b/scripts/e2e_ports/overlays/vcpkg-requires-old-date/vcpkg.json
deleted file mode 100644
index 31e6fb62f..000000000
--- a/scripts/e2e_ports/overlays/vcpkg-requires-old-date/vcpkg.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- "name": "vcpkg-requires-old-date",
- "version-string": "1.0.0",
- "description": "A test port that requires a vcpkg version from before vcpkg_minimum_required's introduction.",
- "homepage": ""
-}
diff --git a/scripts/e2e_ports/overlays/vcpkg-uses-test-cmake/portfile.cmake b/scripts/e2e_ports/overlays/vcpkg-uses-test-cmake/portfile.cmake
deleted file mode 100644
index 571ae3b7a..000000000
--- a/scripts/e2e_ports/overlays/vcpkg-uses-test-cmake/portfile.cmake
+++ /dev/null
@@ -1,3 +0,0 @@
-set(VCPKG_POLICY_EMPTY_PACKAGE enabled)
-
-vcpkg_test_cmake(args args args)
diff --git a/scripts/e2e_ports/overlays/vcpkg-uses-test-cmake/vcpkg.json b/scripts/e2e_ports/overlays/vcpkg-uses-test-cmake/vcpkg.json
deleted file mode 100644
index 9f34e058d..000000000
--- a/scripts/e2e_ports/overlays/vcpkg-uses-test-cmake/vcpkg.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- "name": "vcpkg-uses-test-cmake",
- "version-string": "1.0.0",
- "description": "A test port that uses the deprecated function vcpkg_test_cmake.",
- "homepage": ""
-}
diff --git a/scripts/e2e_ports/overlays/vcpkg-uses-vcpkg-common-functions/portfile.cmake b/scripts/e2e_ports/overlays/vcpkg-uses-vcpkg-common-functions/portfile.cmake
deleted file mode 100644
index 9207d30b1..000000000
--- a/scripts/e2e_ports/overlays/vcpkg-uses-vcpkg-common-functions/portfile.cmake
+++ /dev/null
@@ -1,3 +0,0 @@
-set(VCPKG_POLICY_EMPTY_PACKAGE enabled)
-
-include(vcpkg_common_functions)
diff --git a/scripts/e2e_ports/overlays/vcpkg-uses-vcpkg-common-functions/vcpkg.json b/scripts/e2e_ports/overlays/vcpkg-uses-vcpkg-common-functions/vcpkg.json
deleted file mode 100644
index 7c16ffe82..000000000
--- a/scripts/e2e_ports/overlays/vcpkg-uses-vcpkg-common-functions/vcpkg.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- "name": "vcpkg-uses-vcpkg-common-functions",
- "version-string": "1.0.0",
- "description": "A test port that uses the deprecated file vcpkg_common_functions.",
- "homepage": ""
-}
diff --git a/scripts/e2e_ports/vcpkg-internal-e2e-test-port/portfile.cmake b/scripts/e2e_ports/vcpkg-internal-e2e-test-port/portfile.cmake
deleted file mode 100644
index 065116c27..000000000
--- a/scripts/e2e_ports/vcpkg-internal-e2e-test-port/portfile.cmake
+++ /dev/null
@@ -1 +0,0 @@
-set(VCPKG_POLICY_EMPTY_PACKAGE enabled)
diff --git a/scripts/e2e_ports/vcpkg-internal-e2e-test-port/vcpkg.json b/scripts/e2e_ports/vcpkg-internal-e2e-test-port/vcpkg.json
deleted file mode 100644
index a25da6d23..000000000
--- a/scripts/e2e_ports/vcpkg-internal-e2e-test-port/vcpkg.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{
- "name": "vcpkg-internal-e2e-test-port",
- "version-string": "1.0.0"
-}
diff --git a/scripts/e2e_ports/versions/baseline.json b/scripts/e2e_ports/versions/baseline.json
deleted file mode 100644
index 2413f8afc..000000000
--- a/scripts/e2e_ports/versions/baseline.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "default": {
- "vcpkg-internal-e2e-test-port": { "baseline": "1.0.0" }
- }
-}
diff --git a/scripts/e2e_ports/versions/v-/vcpkg-internal-e2e-test-port.json b/scripts/e2e_ports/versions/v-/vcpkg-internal-e2e-test-port.json
deleted file mode 100644
index ce7698ebb..000000000
--- a/scripts/e2e_ports/versions/v-/vcpkg-internal-e2e-test-port.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
- "versions": [
- {
- "version-string": "1.0.0",
- "git-tree": "1dc3e42a3c0cafe2884d379af4399273238b986e"
- }
- ]
-}
diff --git a/scripts/testing/env-passthrough/passthrough.cmake b/scripts/testing/env-passthrough/passthrough.cmake
deleted file mode 100644
index 071b8381e..000000000
--- a/scripts/testing/env-passthrough/passthrough.cmake
+++ /dev/null
@@ -1,6 +0,0 @@
-set(VCPKG_TARGET_ARCHITECTURE x64)
-set(VCPKG_CRT_LINKAGE dynamic)
-set(VCPKG_LIBRARY_LINKAGE dynamic)
-
-set(VCPKG_ENV_PASSTHROUGH _VCPKG_TEST_TRACKED _VCPKG_TEST_TRACKED2)
-set(VCPKG_ENV_PASSTHROUGH_UNTRACKED _VCPKG_TEST_UNTRACKED _VCPKG_TEST_UNTRACKED2)
diff --git a/scripts/testing/integrate-install/NoProps.vcxproj b/scripts/testing/integrate-install/NoProps.vcxproj
deleted file mode 100644
index 5b75d0961..000000000
--- a/scripts/testing/integrate-install/NoProps.vcxproj
+++ /dev/null
@@ -1,145 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <ItemGroup Label="ProjectConfigurations">
- <ProjectConfiguration Include="Debug|Win32">
- <Configuration>Debug</Configuration>
- <Platform>Win32</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Release|Win32">
- <Configuration>Release</Configuration>
- <Platform>Win32</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Debug|x64">
- <Configuration>Debug</Configuration>
- <Platform>x64</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Release|x64">
- <Configuration>Release</Configuration>
- <Platform>x64</Platform>
- </ProjectConfiguration>
- </ItemGroup>
- <PropertyGroup Label="Globals">
- <VCProjectVersion>16.0</VCProjectVersion>
- <ProjectGuid>{5AFB7AF5-D8FC-4A86-B0D2-3BBD039ED03A}</ProjectGuid>
- <RootNamespace>Project1</RootNamespace>
- <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
- </PropertyGroup>
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
- <ConfigurationType>Application</ConfigurationType>
- <UseDebugLibraries>true</UseDebugLibraries>
- <PlatformToolset>v142</PlatformToolset>
- <CharacterSet>Unicode</CharacterSet>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
- <ConfigurationType>Application</ConfigurationType>
- <UseDebugLibraries>false</UseDebugLibraries>
- <PlatformToolset>v142</PlatformToolset>
- <WholeProgramOptimization>true</WholeProgramOptimization>
- <CharacterSet>Unicode</CharacterSet>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
- <ConfigurationType>Application</ConfigurationType>
- <UseDebugLibraries>true</UseDebugLibraries>
- <PlatformToolset>v142</PlatformToolset>
- <CharacterSet>Unicode</CharacterSet>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
- <ConfigurationType>Application</ConfigurationType>
- <UseDebugLibraries>false</UseDebugLibraries>
- <PlatformToolset>v142</PlatformToolset>
- <WholeProgramOptimization>true</WholeProgramOptimization>
- <CharacterSet>Unicode</CharacterSet>
- </PropertyGroup>
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
- <ImportGroup Label="ExtensionSettings">
- </ImportGroup>
- <ImportGroup Label="Shared">
- </ImportGroup>
- <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
- </ImportGroup>
- <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
- </ImportGroup>
- <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
- </ImportGroup>
- <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
- </ImportGroup>
- <PropertyGroup Label="UserMacros" />
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <LinkIncremental>true</LinkIncremental>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
- <LinkIncremental>true</LinkIncremental>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <LinkIncremental>false</LinkIncremental>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
- <LinkIncremental>false</LinkIncremental>
- </PropertyGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <ClCompile>
- <WarningLevel>Level3</WarningLevel>
- <SDLCheck>true</SDLCheck>
- <PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <ConformanceMode>true</ConformanceMode>
- </ClCompile>
- <Link>
- <SubSystem>Console</SubSystem>
- <GenerateDebugInformation>true</GenerateDebugInformation>
- </Link>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
- <ClCompile>
- <WarningLevel>Level3</WarningLevel>
- <SDLCheck>true</SDLCheck>
- <PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <ConformanceMode>true</ConformanceMode>
- </ClCompile>
- <Link>
- <SubSystem>Console</SubSystem>
- <GenerateDebugInformation>true</GenerateDebugInformation>
- </Link>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <ClCompile>
- <WarningLevel>Level3</WarningLevel>
- <FunctionLevelLinking>true</FunctionLevelLinking>
- <IntrinsicFunctions>true</IntrinsicFunctions>
- <SDLCheck>true</SDLCheck>
- <PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <ConformanceMode>true</ConformanceMode>
- </ClCompile>
- <Link>
- <SubSystem>Console</SubSystem>
- <EnableCOMDATFolding>true</EnableCOMDATFolding>
- <OptimizeReferences>true</OptimizeReferences>
- <GenerateDebugInformation>true</GenerateDebugInformation>
- </Link>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
- <ClCompile>
- <WarningLevel>Level3</WarningLevel>
- <FunctionLevelLinking>true</FunctionLevelLinking>
- <IntrinsicFunctions>true</IntrinsicFunctions>
- <SDLCheck>true</SDLCheck>
- <PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <ConformanceMode>true</ConformanceMode>
- </ClCompile>
- <Link>
- <SubSystem>Console</SubSystem>
- <EnableCOMDATFolding>true</EnableCOMDATFolding>
- <OptimizeReferences>true</OptimizeReferences>
- <GenerateDebugInformation>true</GenerateDebugInformation>
- </Link>
- </ItemDefinitionGroup>
- <ItemGroup>
- <ClCompile Include="Source.cpp" />
- </ItemGroup>
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
- <Import Project="..\..\buildsystems\msbuild\vcpkg.targets" />
-</Project> \ No newline at end of file
diff --git a/scripts/testing/integrate-install/Project1.vcxproj b/scripts/testing/integrate-install/Project1.vcxproj
deleted file mode 100644
index a8896fe29..000000000
--- a/scripts/testing/integrate-install/Project1.vcxproj
+++ /dev/null
@@ -1,146 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <ItemGroup Label="ProjectConfigurations">
- <ProjectConfiguration Include="Debug|Win32">
- <Configuration>Debug</Configuration>
- <Platform>Win32</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Release|Win32">
- <Configuration>Release</Configuration>
- <Platform>Win32</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Debug|x64">
- <Configuration>Debug</Configuration>
- <Platform>x64</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Release|x64">
- <Configuration>Release</Configuration>
- <Platform>x64</Platform>
- </ProjectConfiguration>
- </ItemGroup>
- <PropertyGroup Label="Globals">
- <VCProjectVersion>16.0</VCProjectVersion>
- <ProjectGuid>{5AFB7AF5-D8FC-4A86-B0D2-3BBD039ED03A}</ProjectGuid>
- <RootNamespace>Project1</RootNamespace>
- <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
- </PropertyGroup>
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
- <ConfigurationType>Application</ConfigurationType>
- <UseDebugLibraries>true</UseDebugLibraries>
- <PlatformToolset>v142</PlatformToolset>
- <CharacterSet>Unicode</CharacterSet>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
- <ConfigurationType>Application</ConfigurationType>
- <UseDebugLibraries>false</UseDebugLibraries>
- <PlatformToolset>v142</PlatformToolset>
- <WholeProgramOptimization>true</WholeProgramOptimization>
- <CharacterSet>Unicode</CharacterSet>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
- <ConfigurationType>Application</ConfigurationType>
- <UseDebugLibraries>true</UseDebugLibraries>
- <PlatformToolset>v142</PlatformToolset>
- <CharacterSet>Unicode</CharacterSet>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
- <ConfigurationType>Application</ConfigurationType>
- <UseDebugLibraries>false</UseDebugLibraries>
- <PlatformToolset>v142</PlatformToolset>
- <WholeProgramOptimization>true</WholeProgramOptimization>
- <CharacterSet>Unicode</CharacterSet>
- </PropertyGroup>
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
- <Import Project="..\..\buildsystems\msbuild\vcpkg.props" />
- <ImportGroup Label="ExtensionSettings">
- </ImportGroup>
- <ImportGroup Label="Shared">
- </ImportGroup>
- <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
- </ImportGroup>
- <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
- </ImportGroup>
- <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
- </ImportGroup>
- <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
- </ImportGroup>
- <PropertyGroup Label="UserMacros" />
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <LinkIncremental>true</LinkIncremental>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
- <LinkIncremental>true</LinkIncremental>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <LinkIncremental>false</LinkIncremental>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
- <LinkIncremental>false</LinkIncremental>
- </PropertyGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <ClCompile>
- <WarningLevel>Level3</WarningLevel>
- <SDLCheck>true</SDLCheck>
- <PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <ConformanceMode>true</ConformanceMode>
- </ClCompile>
- <Link>
- <SubSystem>Console</SubSystem>
- <GenerateDebugInformation>true</GenerateDebugInformation>
- </Link>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
- <ClCompile>
- <WarningLevel>Level3</WarningLevel>
- <SDLCheck>true</SDLCheck>
- <PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <ConformanceMode>true</ConformanceMode>
- </ClCompile>
- <Link>
- <SubSystem>Console</SubSystem>
- <GenerateDebugInformation>true</GenerateDebugInformation>
- </Link>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <ClCompile>
- <WarningLevel>Level3</WarningLevel>
- <FunctionLevelLinking>true</FunctionLevelLinking>
- <IntrinsicFunctions>true</IntrinsicFunctions>
- <SDLCheck>true</SDLCheck>
- <PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <ConformanceMode>true</ConformanceMode>
- </ClCompile>
- <Link>
- <SubSystem>Console</SubSystem>
- <EnableCOMDATFolding>true</EnableCOMDATFolding>
- <OptimizeReferences>true</OptimizeReferences>
- <GenerateDebugInformation>true</GenerateDebugInformation>
- </Link>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
- <ClCompile>
- <WarningLevel>Level3</WarningLevel>
- <FunctionLevelLinking>true</FunctionLevelLinking>
- <IntrinsicFunctions>true</IntrinsicFunctions>
- <SDLCheck>true</SDLCheck>
- <PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <ConformanceMode>true</ConformanceMode>
- </ClCompile>
- <Link>
- <SubSystem>Console</SubSystem>
- <EnableCOMDATFolding>true</EnableCOMDATFolding>
- <OptimizeReferences>true</OptimizeReferences>
- <GenerateDebugInformation>true</GenerateDebugInformation>
- </Link>
- </ItemDefinitionGroup>
- <ItemGroup>
- <ClCompile Include="Source.cpp" />
- </ItemGroup>
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
- <Import Project="..\..\buildsystems\msbuild\vcpkg.targets" />
-</Project> \ No newline at end of file
diff --git a/scripts/testing/integrate-install/Source.cpp b/scripts/testing/integrate-install/Source.cpp
deleted file mode 100644
index 24a84e4d7..000000000
--- a/scripts/testing/integrate-install/Source.cpp
+++ /dev/null
@@ -1,6 +0,0 @@
-#include <zlib.h>
-
-int main() {
- zlibVersion();
- return 0;
-} \ No newline at end of file
diff --git a/scripts/testing/integrate-install/VcpkgTriplet.vcxproj b/scripts/testing/integrate-install/VcpkgTriplet.vcxproj
deleted file mode 100644
index 883fc8ec1..000000000
--- a/scripts/testing/integrate-install/VcpkgTriplet.vcxproj
+++ /dev/null
@@ -1,151 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <ItemGroup Label="ProjectConfigurations">
- <ProjectConfiguration Include="Debug|Win32">
- <Configuration>Debug</Configuration>
- <Platform>Win32</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Release|Win32">
- <Configuration>Release</Configuration>
- <Platform>Win32</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Debug|x64">
- <Configuration>Debug</Configuration>
- <Platform>x64</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Release|x64">
- <Configuration>Release</Configuration>
- <Platform>x64</Platform>
- </ProjectConfiguration>
- </ItemGroup>
- <PropertyGroup Label="Globals">
- <VCProjectVersion>16.0</VCProjectVersion>
- <ProjectGuid>{5AFB7AF5-D8FC-4A86-B0D2-3BBD039ED03A}</ProjectGuid>
- <RootNamespace>VcpkgUseStatic</RootNamespace>
- <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
- </PropertyGroup>
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
- <ConfigurationType>Application</ConfigurationType>
- <UseDebugLibraries>true</UseDebugLibraries>
- <PlatformToolset>v142</PlatformToolset>
- <CharacterSet>Unicode</CharacterSet>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
- <ConfigurationType>Application</ConfigurationType>
- <UseDebugLibraries>false</UseDebugLibraries>
- <PlatformToolset>v142</PlatformToolset>
- <WholeProgramOptimization>true</WholeProgramOptimization>
- <CharacterSet>Unicode</CharacterSet>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
- <ConfigurationType>Application</ConfigurationType>
- <UseDebugLibraries>true</UseDebugLibraries>
- <PlatformToolset>v142</PlatformToolset>
- <CharacterSet>Unicode</CharacterSet>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
- <ConfigurationType>Application</ConfigurationType>
- <UseDebugLibraries>false</UseDebugLibraries>
- <PlatformToolset>v142</PlatformToolset>
- <WholeProgramOptimization>true</WholeProgramOptimization>
- <CharacterSet>Unicode</CharacterSet>
- </PropertyGroup>
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
- <Import Project="..\..\buildsystems\msbuild\vcpkg.props" />
- <ImportGroup Label="ExtensionSettings">
- </ImportGroup>
- <ImportGroup Label="Shared">
- </ImportGroup>
- <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
- </ImportGroup>
- <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
- </ImportGroup>
- <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
- </ImportGroup>
- <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
- </ImportGroup>
- <PropertyGroup Label="UserMacros" />
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <LinkIncremental>true</LinkIncremental>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
- <LinkIncremental>true</LinkIncremental>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <LinkIncremental>false</LinkIncremental>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
- <LinkIncremental>false</LinkIncremental>
- </PropertyGroup>
- <PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <VcpkgTriplet>x86-windows-static</VcpkgTriplet>
- </PropertyGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <ClCompile>
- <WarningLevel>Level3</WarningLevel>
- <SDLCheck>true</SDLCheck>
- <PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <ConformanceMode>true</ConformanceMode>
- <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
- </ClCompile>
- <Link>
- <SubSystem>Console</SubSystem>
- <GenerateDebugInformation>true</GenerateDebugInformation>
- </Link>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
- <ClCompile>
- <WarningLevel>Level3</WarningLevel>
- <SDLCheck>true</SDLCheck>
- <PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <ConformanceMode>true</ConformanceMode>
- </ClCompile>
- <Link>
- <SubSystem>Console</SubSystem>
- <GenerateDebugInformation>true</GenerateDebugInformation>
- </Link>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <ClCompile>
- <WarningLevel>Level3</WarningLevel>
- <FunctionLevelLinking>true</FunctionLevelLinking>
- <IntrinsicFunctions>true</IntrinsicFunctions>
- <SDLCheck>true</SDLCheck>
- <PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <ConformanceMode>true</ConformanceMode>
- <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
- </ClCompile>
- <Link>
- <SubSystem>Console</SubSystem>
- <EnableCOMDATFolding>true</EnableCOMDATFolding>
- <OptimizeReferences>true</OptimizeReferences>
- <GenerateDebugInformation>true</GenerateDebugInformation>
- </Link>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
- <ClCompile>
- <WarningLevel>Level3</WarningLevel>
- <FunctionLevelLinking>true</FunctionLevelLinking>
- <IntrinsicFunctions>true</IntrinsicFunctions>
- <SDLCheck>true</SDLCheck>
- <PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <ConformanceMode>true</ConformanceMode>
- </ClCompile>
- <Link>
- <SubSystem>Console</SubSystem>
- <EnableCOMDATFolding>true</EnableCOMDATFolding>
- <OptimizeReferences>true</OptimizeReferences>
- <GenerateDebugInformation>true</GenerateDebugInformation>
- </Link>
- </ItemDefinitionGroup>
- <ItemGroup>
- <ClCompile Include="Source.cpp" />
- </ItemGroup>
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
- <Import Project="..\..\buildsystems\msbuild\vcpkg.targets" />
-</Project> \ No newline at end of file
diff --git a/scripts/testing/integrate-install/VcpkgTriplet2.vcxproj b/scripts/testing/integrate-install/VcpkgTriplet2.vcxproj
deleted file mode 100644
index d3352e195..000000000
--- a/scripts/testing/integrate-install/VcpkgTriplet2.vcxproj
+++ /dev/null
@@ -1,149 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <ItemGroup Label="ProjectConfigurations">
- <ProjectConfiguration Include="Debug|Win32">
- <Configuration>Debug</Configuration>
- <Platform>Win32</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Release|Win32">
- <Configuration>Release</Configuration>
- <Platform>Win32</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Debug|x64">
- <Configuration>Debug</Configuration>
- <Platform>x64</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Release|x64">
- <Configuration>Release</Configuration>
- <Platform>x64</Platform>
- </ProjectConfiguration>
- </ItemGroup>
- <PropertyGroup Label="Globals">
- <VCProjectVersion>16.0</VCProjectVersion>
- <ProjectGuid>{5AFB7AF5-D8FC-4A86-B0D2-3BBD039ED03A}</ProjectGuid>
- <RootNamespace>VcpkgUseStatic</RootNamespace>
- <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
- <VcpkgTriplet>x86-windows-static</VcpkgTriplet>
- </PropertyGroup>
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
- <ConfigurationType>Application</ConfigurationType>
- <UseDebugLibraries>true</UseDebugLibraries>
- <PlatformToolset>v142</PlatformToolset>
- <CharacterSet>Unicode</CharacterSet>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
- <ConfigurationType>Application</ConfigurationType>
- <UseDebugLibraries>false</UseDebugLibraries>
- <PlatformToolset>v142</PlatformToolset>
- <WholeProgramOptimization>true</WholeProgramOptimization>
- <CharacterSet>Unicode</CharacterSet>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
- <ConfigurationType>Application</ConfigurationType>
- <UseDebugLibraries>true</UseDebugLibraries>
- <PlatformToolset>v142</PlatformToolset>
- <CharacterSet>Unicode</CharacterSet>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
- <ConfigurationType>Application</ConfigurationType>
- <UseDebugLibraries>false</UseDebugLibraries>
- <PlatformToolset>v142</PlatformToolset>
- <WholeProgramOptimization>true</WholeProgramOptimization>
- <CharacterSet>Unicode</CharacterSet>
- </PropertyGroup>
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
- <Import Project="..\..\buildsystems\msbuild\vcpkg.props" />
- <ImportGroup Label="ExtensionSettings">
- </ImportGroup>
- <ImportGroup Label="Shared">
- </ImportGroup>
- <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
- </ImportGroup>
- <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
- </ImportGroup>
- <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
- </ImportGroup>
- <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
- </ImportGroup>
- <PropertyGroup Label="UserMacros" />
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <LinkIncremental>true</LinkIncremental>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
- <LinkIncremental>true</LinkIncremental>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <LinkIncremental>false</LinkIncremental>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
- <LinkIncremental>false</LinkIncremental>
- </PropertyGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <ClCompile>
- <WarningLevel>Level3</WarningLevel>
- <SDLCheck>true</SDLCheck>
- <PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <ConformanceMode>true</ConformanceMode>
- <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
- </ClCompile>
- <Link>
- <SubSystem>Console</SubSystem>
- <GenerateDebugInformation>true</GenerateDebugInformation>
- </Link>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
- <ClCompile>
- <WarningLevel>Level3</WarningLevel>
- <SDLCheck>true</SDLCheck>
- <PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <ConformanceMode>true</ConformanceMode>
- </ClCompile>
- <Link>
- <SubSystem>Console</SubSystem>
- <GenerateDebugInformation>true</GenerateDebugInformation>
- </Link>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <ClCompile>
- <WarningLevel>Level3</WarningLevel>
- <FunctionLevelLinking>true</FunctionLevelLinking>
- <IntrinsicFunctions>true</IntrinsicFunctions>
- <SDLCheck>true</SDLCheck>
- <PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <ConformanceMode>true</ConformanceMode>
- <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
- </ClCompile>
- <Link>
- <SubSystem>Console</SubSystem>
- <EnableCOMDATFolding>true</EnableCOMDATFolding>
- <OptimizeReferences>true</OptimizeReferences>
- <GenerateDebugInformation>true</GenerateDebugInformation>
- </Link>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
- <ClCompile>
- <WarningLevel>Level3</WarningLevel>
- <FunctionLevelLinking>true</FunctionLevelLinking>
- <IntrinsicFunctions>true</IntrinsicFunctions>
- <SDLCheck>true</SDLCheck>
- <PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <ConformanceMode>true</ConformanceMode>
- </ClCompile>
- <Link>
- <SubSystem>Console</SubSystem>
- <EnableCOMDATFolding>true</EnableCOMDATFolding>
- <OptimizeReferences>true</OptimizeReferences>
- <GenerateDebugInformation>true</GenerateDebugInformation>
- </Link>
- </ItemDefinitionGroup>
- <ItemGroup>
- <ClCompile Include="Source.cpp" />
- </ItemGroup>
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
- <Import Project="..\..\buildsystems\msbuild\vcpkg.targets" />
-</Project> \ No newline at end of file
diff --git a/scripts/testing/integrate-install/VcpkgUseStatic.vcxproj b/scripts/testing/integrate-install/VcpkgUseStatic.vcxproj
deleted file mode 100644
index 28c4fc715..000000000
--- a/scripts/testing/integrate-install/VcpkgUseStatic.vcxproj
+++ /dev/null
@@ -1,151 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <ItemGroup Label="ProjectConfigurations">
- <ProjectConfiguration Include="Debug|Win32">
- <Configuration>Debug</Configuration>
- <Platform>Win32</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Release|Win32">
- <Configuration>Release</Configuration>
- <Platform>Win32</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Debug|x64">
- <Configuration>Debug</Configuration>
- <Platform>x64</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Release|x64">
- <Configuration>Release</Configuration>
- <Platform>x64</Platform>
- </ProjectConfiguration>
- </ItemGroup>
- <PropertyGroup Label="Globals">
- <VCProjectVersion>16.0</VCProjectVersion>
- <ProjectGuid>{5AFB7AF5-D8FC-4A86-B0D2-3BBD039ED03A}</ProjectGuid>
- <RootNamespace>VcpkgUseStatic</RootNamespace>
- <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
- </PropertyGroup>
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
- <ConfigurationType>Application</ConfigurationType>
- <UseDebugLibraries>true</UseDebugLibraries>
- <PlatformToolset>v142</PlatformToolset>
- <CharacterSet>Unicode</CharacterSet>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
- <ConfigurationType>Application</ConfigurationType>
- <UseDebugLibraries>false</UseDebugLibraries>
- <PlatformToolset>v142</PlatformToolset>
- <WholeProgramOptimization>true</WholeProgramOptimization>
- <CharacterSet>Unicode</CharacterSet>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
- <ConfigurationType>Application</ConfigurationType>
- <UseDebugLibraries>true</UseDebugLibraries>
- <PlatformToolset>v142</PlatformToolset>
- <CharacterSet>Unicode</CharacterSet>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
- <ConfigurationType>Application</ConfigurationType>
- <UseDebugLibraries>false</UseDebugLibraries>
- <PlatformToolset>v142</PlatformToolset>
- <WholeProgramOptimization>true</WholeProgramOptimization>
- <CharacterSet>Unicode</CharacterSet>
- </PropertyGroup>
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
- <Import Project="..\..\buildsystems\msbuild\vcpkg.props" />
- <ImportGroup Label="ExtensionSettings">
- </ImportGroup>
- <ImportGroup Label="Shared">
- </ImportGroup>
- <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
- </ImportGroup>
- <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
- </ImportGroup>
- <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
- </ImportGroup>
- <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
- </ImportGroup>
- <PropertyGroup Label="UserMacros" />
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <LinkIncremental>true</LinkIncremental>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
- <LinkIncremental>true</LinkIncremental>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <LinkIncremental>false</LinkIncremental>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
- <LinkIncremental>false</LinkIncremental>
- </PropertyGroup>
- <PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <VcpkgUseStatic>true</VcpkgUseStatic>
- </PropertyGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <ClCompile>
- <WarningLevel>Level3</WarningLevel>
- <SDLCheck>true</SDLCheck>
- <PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <ConformanceMode>true</ConformanceMode>
- <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
- </ClCompile>
- <Link>
- <SubSystem>Console</SubSystem>
- <GenerateDebugInformation>true</GenerateDebugInformation>
- </Link>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
- <ClCompile>
- <WarningLevel>Level3</WarningLevel>
- <SDLCheck>true</SDLCheck>
- <PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <ConformanceMode>true</ConformanceMode>
- </ClCompile>
- <Link>
- <SubSystem>Console</SubSystem>
- <GenerateDebugInformation>true</GenerateDebugInformation>
- </Link>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <ClCompile>
- <WarningLevel>Level3</WarningLevel>
- <FunctionLevelLinking>true</FunctionLevelLinking>
- <IntrinsicFunctions>true</IntrinsicFunctions>
- <SDLCheck>true</SDLCheck>
- <PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <ConformanceMode>true</ConformanceMode>
- <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
- </ClCompile>
- <Link>
- <SubSystem>Console</SubSystem>
- <EnableCOMDATFolding>true</EnableCOMDATFolding>
- <OptimizeReferences>true</OptimizeReferences>
- <GenerateDebugInformation>true</GenerateDebugInformation>
- </Link>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
- <ClCompile>
- <WarningLevel>Level3</WarningLevel>
- <FunctionLevelLinking>true</FunctionLevelLinking>
- <IntrinsicFunctions>true</IntrinsicFunctions>
- <SDLCheck>true</SDLCheck>
- <PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <ConformanceMode>true</ConformanceMode>
- </ClCompile>
- <Link>
- <SubSystem>Console</SubSystem>
- <EnableCOMDATFolding>true</EnableCOMDATFolding>
- <OptimizeReferences>true</OptimizeReferences>
- <GenerateDebugInformation>true</GenerateDebugInformation>
- </Link>
- </ItemDefinitionGroup>
- <ItemGroup>
- <ClCompile Include="Source.cpp" />
- </ItemGroup>
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
- <Import Project="..\..\buildsystems\msbuild\vcpkg.targets" />
-</Project> \ No newline at end of file
diff --git a/scripts/testing/integrate-install/VcpkgUseStatic2.vcxproj b/scripts/testing/integrate-install/VcpkgUseStatic2.vcxproj
deleted file mode 100644
index 98beaee4b..000000000
--- a/scripts/testing/integrate-install/VcpkgUseStatic2.vcxproj
+++ /dev/null
@@ -1,149 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <ItemGroup Label="ProjectConfigurations">
- <ProjectConfiguration Include="Debug|Win32">
- <Configuration>Debug</Configuration>
- <Platform>Win32</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Release|Win32">
- <Configuration>Release</Configuration>
- <Platform>Win32</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Debug|x64">
- <Configuration>Debug</Configuration>
- <Platform>x64</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Release|x64">
- <Configuration>Release</Configuration>
- <Platform>x64</Platform>
- </ProjectConfiguration>
- </ItemGroup>
- <PropertyGroup Label="Globals">
- <VCProjectVersion>16.0</VCProjectVersion>
- <ProjectGuid>{5AFB7AF5-D8FC-4A86-B0D2-3BBD039ED03A}</ProjectGuid>
- <RootNamespace>VcpkgUseStatic</RootNamespace>
- <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
- <VcpkgUseStatic>true</VcpkgUseStatic>
- </PropertyGroup>
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
- <ConfigurationType>Application</ConfigurationType>
- <UseDebugLibraries>true</UseDebugLibraries>
- <PlatformToolset>v142</PlatformToolset>
- <CharacterSet>Unicode</CharacterSet>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
- <ConfigurationType>Application</ConfigurationType>
- <UseDebugLibraries>false</UseDebugLibraries>
- <PlatformToolset>v142</PlatformToolset>
- <WholeProgramOptimization>true</WholeProgramOptimization>
- <CharacterSet>Unicode</CharacterSet>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
- <ConfigurationType>Application</ConfigurationType>
- <UseDebugLibraries>true</UseDebugLibraries>
- <PlatformToolset>v142</PlatformToolset>
- <CharacterSet>Unicode</CharacterSet>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
- <ConfigurationType>Application</ConfigurationType>
- <UseDebugLibraries>false</UseDebugLibraries>
- <PlatformToolset>v142</PlatformToolset>
- <WholeProgramOptimization>true</WholeProgramOptimization>
- <CharacterSet>Unicode</CharacterSet>
- </PropertyGroup>
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
- <Import Project="..\..\buildsystems\msbuild\vcpkg.props" />
- <ImportGroup Label="ExtensionSettings">
- </ImportGroup>
- <ImportGroup Label="Shared">
- </ImportGroup>
- <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
- </ImportGroup>
- <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
- </ImportGroup>
- <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
- </ImportGroup>
- <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
- </ImportGroup>
- <PropertyGroup Label="UserMacros" />
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <LinkIncremental>true</LinkIncremental>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
- <LinkIncremental>true</LinkIncremental>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <LinkIncremental>false</LinkIncremental>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
- <LinkIncremental>false</LinkIncremental>
- </PropertyGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <ClCompile>
- <WarningLevel>Level3</WarningLevel>
- <SDLCheck>true</SDLCheck>
- <PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <ConformanceMode>true</ConformanceMode>
- <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
- </ClCompile>
- <Link>
- <SubSystem>Console</SubSystem>
- <GenerateDebugInformation>true</GenerateDebugInformation>
- </Link>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
- <ClCompile>
- <WarningLevel>Level3</WarningLevel>
- <SDLCheck>true</SDLCheck>
- <PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <ConformanceMode>true</ConformanceMode>
- </ClCompile>
- <Link>
- <SubSystem>Console</SubSystem>
- <GenerateDebugInformation>true</GenerateDebugInformation>
- </Link>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <ClCompile>
- <WarningLevel>Level3</WarningLevel>
- <FunctionLevelLinking>true</FunctionLevelLinking>
- <IntrinsicFunctions>true</IntrinsicFunctions>
- <SDLCheck>true</SDLCheck>
- <PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <ConformanceMode>true</ConformanceMode>
- <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
- </ClCompile>
- <Link>
- <SubSystem>Console</SubSystem>
- <EnableCOMDATFolding>true</EnableCOMDATFolding>
- <OptimizeReferences>true</OptimizeReferences>
- <GenerateDebugInformation>true</GenerateDebugInformation>
- </Link>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
- <ClCompile>
- <WarningLevel>Level3</WarningLevel>
- <FunctionLevelLinking>true</FunctionLevelLinking>
- <IntrinsicFunctions>true</IntrinsicFunctions>
- <SDLCheck>true</SDLCheck>
- <PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <ConformanceMode>true</ConformanceMode>
- </ClCompile>
- <Link>
- <SubSystem>Console</SubSystem>
- <EnableCOMDATFolding>true</EnableCOMDATFolding>
- <OptimizeReferences>true</OptimizeReferences>
- <GenerateDebugInformation>true</GenerateDebugInformation>
- </Link>
- </ItemDefinitionGroup>
- <ItemGroup>
- <ClCompile Include="Source.cpp" />
- </ItemGroup>
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
- <Import Project="..\..\buildsystems\msbuild\vcpkg.targets" />
-</Project> \ No newline at end of file
diff --git a/scripts/tls12-download.exe b/scripts/tls12-download.exe
new file mode 100644
index 000000000..3eff1dd4e
--- /dev/null
+++ b/scripts/tls12-download.exe
Binary files differ
diff --git a/toolsrc/.clang-format b/toolsrc/.clang-format
deleted file mode 100644
index 374a4233e..000000000
--- a/toolsrc/.clang-format
+++ /dev/null
@@ -1,54 +0,0 @@
-BasedOnStyle: WebKit
-Language: Cpp
-Standard: Cpp11
-
-UseTab: Never
-IndentWidth: 4
-ColumnLimit: 120
-PointerAlignment: Left
-
-BreakBeforeBraces: Allman
-
-AllowShortBlocksOnASingleLine: false
-AllowShortCaseLabelsOnASingleLine: true
-AllowShortFunctionsOnASingleLine: All
-AllowShortIfStatementsOnASingleLine: true
-AllowShortLoopsOnASingleLine: false
-AlwaysBreakTemplateDeclarations: true
-AlignAfterOpenBracket: true
-AlignOperands: true
-AlignTrailingComments: true
-BinPackArguments: false
-BinPackParameters: false
-BreakBeforeBinaryOperators: None
-BreakConstructorInitializersBeforeComma: true
-ConstructorInitializerAllOnOneLineOrOnePerLine: true
-Cpp11BracedListStyle: true
-IndentCaseLabels: true
-KeepEmptyLinesAtTheStartOfBlocks: false
-NamespaceIndentation: All
-ForEachMacros: [TEST_CASE, SECTION]
-PenaltyReturnTypeOnItsOwnLine: 1000
-SpaceAfterTemplateKeyword: false
-SpaceBeforeCpp11BracedList: false
-DeriveLineEnding: false
-UseCRLF: false
-
-IncludeBlocks: Regroup
-IncludeCategories:
- - Regex: '^(<vcpkg/base/system_headers\.h>|"pch\.h")$'
- Priority: -1
- - Regex: '^<catch2/catch\.hpp>$'
- Priority: 1
- - Regex: '^<vcpkg/base/fwd/.*\.h>$'
- Priority: 2
- - Regex: '^<vcpkg/fwd/.*\.h>$'
- Priority: 3
- - Regex: '^<vcpkg/base/.*\.h>$'
- Priority: 4
- - Regex: '^<vcpkg/.*\.h>$'
- Priority: 5
- - Regex: '^<[a-z0-9_]*\.h>$'
- Priority: 6
- - Regex: '^<[a-z0-9_]*>$' # C++ standard library
- Priority: 7
diff --git a/toolsrc/CMakeLists.txt b/toolsrc/CMakeLists.txt
deleted file mode 100644
index 24ab12818..000000000
--- a/toolsrc/CMakeLists.txt
+++ /dev/null
@@ -1,222 +0,0 @@
-if(WIN32)
-# 3.16 for MSVC_RUNTIME_LIBRARY
-cmake_minimum_required(VERSION 3.16)
-else()
-cmake_minimum_required(VERSION 3.14)
-endif()
-
-project(vcpkg C CXX)
-include(cmake/utilities.cmake)
-
-# ===============
-# === Options ===
-# ===============
-
-include(CMakeDependentOption)
-
-option(BUILD_TESTING "Option for enabling testing" ON)
-option(VCPKG_ALLOW_APPLE_CLANG "Option for allowing apple clang, even versions that we don't know will work" OFF)
-option(VCPKG_DEVELOPMENT_WARNINGS "Option for turning on all warnings" ON)
-option(VCPKG_WARNINGS_AS_ERRORS "Set warnings to be errors" ${VCPKG_DEVELOPMENT_WARNINGS})
-option(VCPKG_BUILD_FUZZING "Option for enabling vcpkg-fuzz support" OFF)
-option(VCPKG_EMBED_GIT_SHA "Option for to fill in the Git SHA version; off by default to avoid privacy concerns out of official builds" OFF)
-
-CMAKE_DEPENDENT_OPTION(VCPKG_BUILD_BENCHMARKING "Option for enabling benchmarking" OFF
- "BUILD_TESTING" OFF)
-
-if(WERROR)
- message(DEPRECATION "-DWERROR is no longer a supported flag. It doesn't do anything.")
-endif()
-if(DEFINE_DISABLE_METRICS OR VCPKG_DISABLE_METRICS)
- message(DEPRECATION "DEFINE_DISABLE_METRICS / VCPKG_DISABLE_METRICS are now handled by creating a "
- "file vcpkg.disable_metrics next to the binary.")
-endif()
-
-# =============
-# === Files ===
-# =============
-
-file(GLOB VCPKGLIB_SOURCES CONFIGURE_DEPENDS src/vcpkg/*.cpp)
-file(GLOB VCPKGLIB_BASE_SOURCES CONFIGURE_DEPENDS src/vcpkg/base/*.cpp)
-file(GLOB VCPKGLIB_INCLUDES CONFIGURE_DEPENDS include/vcpkg/*.h include/vcpkg/fwd/*.h)
-file(GLOB VCPKGLIB_BASE_INCLUDES CONFIGURE_DEPENDS include/vcpkg/base/*.h include/vcpkg/base/fwd/*.h)
-
-set(VCPKG_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/vcpkg.cpp)
-
-file(GLOB VCPKG_TEST_SOURCES CONFIGURE_DEPENDS src/vcpkg-test/*.cpp)
-file(GLOB VCPKG_TEST_INCLUDES CONFIGURE_DEPENDS include/vcpkg-test/*.h)
-
-file(GLOB VCPKG_FUZZ_SOURCES CONFIGURE_DEPENDS src/vcpkg-fuzz/*.cpp)
-
-# ========================
-# === System detection ===
-# ========================
-
-vcpkg_detect_compiler()
-vcpkg_detect_standard_library()
-vcpkg_detect_std_filesystem()
-
-if (VCPKG_EMBED_GIT_SHA)
- find_package(Git REQUIRED)
- execute_process(
- COMMAND "${GIT_EXECUTABLE}" status --porcelain=v1
- WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
- OUTPUT_VARIABLE VCPKG_GIT_STATUS
- OUTPUT_STRIP_TRAILING_WHITESPACE
- )
-
- if (VCPKG_GIT_STATUS STREQUAL "")
- execute_process(
- COMMAND "${GIT_EXECUTABLE}" rev-parse HEAD
- WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
- OUTPUT_VARIABLE VCPKG_VERSION
- OUTPUT_STRIP_TRAILING_WHITESPACE
- )
- else()
- message(WARNING "Skipping embedding SHA due to local changes.")
- endif()
-endif()
-
-if (NOT DEFINED VCPKG_VERSION OR VCPKG_VERSION STREQUAL "")
- set(VCPKG_VERSION "unknownhash")
-endif()
-
-set(VCPKG_BASE_VERSION "2021-01-13")
-
-set(CMAKE_CXX_EXTENSIONS OFF)
-set(CMAKE_CXX_STANDARD_REQUIRED ON)
-set(CMAKE_CXX_STANDARD 17)
-if(MSVC)
- string(REGEX REPLACE "[-/]W[0-4]" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
- if (CMAKE_BUILD_TYPE STREQUAL "Release")
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /Zi /guard:cf")
- set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /DEBUG /debugtype:cv,fixup /guard:cf")
- endif()
-endif()
-
-if(APPLE)
- SET(CMAKE_C_ARCHIVE_CREATE "<CMAKE_AR> Scr <TARGET> <LINK_FLAGS> <OBJECTS>")
- SET(CMAKE_CXX_ARCHIVE_CREATE "<CMAKE_AR> Scr <TARGET> <LINK_FLAGS> <OBJECTS>")
- SET(CMAKE_C_ARCHIVE_FINISH "<CMAKE_RANLIB> -no_warning_for_no_symbols -c <TARGET>")
- SET(CMAKE_CXX_ARCHIVE_FINISH "<CMAKE_RANLIB> -no_warning_for_no_symbols -c <TARGET>")
-endif()
-
-# ===============
-# === Targets ===
-# ===============
-
-# === Target: vcpkglib ===
-
-add_library(vcpkglib
- ${VCPKGLIB_BASE_SOURCES}
- ${VCPKGLIB_SOURCES}
- ${VCPKGLIB_BASE_INCLUDES}
- ${VCPKGLIB_INCLUDES})
-target_include_directories(vcpkglib PUBLIC include)
-
-vcpkg_target_add_warning_options(vcpkglib)
-target_compile_definitions(vcpkglib PUBLIC
- VCPKG_USE_STD_FILESYSTEM=$<BOOL:${VCPKG_USE_STD_FILESYSTEM}>
- VCPKG_VERSION=${VCPKG_VERSION}
- VCPKG_BASE_VERSION=${VCPKG_BASE_VERSION}
- )
-
-set(THREADS_PREFER_PTHREAD_FLAG ON)
-find_package(Threads REQUIRED)
-target_link_libraries(vcpkglib PRIVATE Threads::Threads)
-
-if(VCPKG_CXXFS_LIBRARY)
- target_link_libraries(vcpkglib PRIVATE ${VCPKG_CXXFS_LIBRARY})
-endif()
-
-if(MSVC)
- get_target_property(_srcs vcpkglib SOURCES)
-
- if(NOT CMAKE_GENERATOR MATCHES "Visual Studio .*")
- set_property(SOURCE src/pch.cpp APPEND PROPERTY OBJECT_OUTPUTS "${CMAKE_CURRENT_BINARY_DIR}/pch.pch")
- set_property(SOURCE ${_srcs} APPEND PROPERTY OBJECT_DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/pch.pch")
- endif()
-
- set_source_files_properties(src/pch.cpp PROPERTIES COMPILE_FLAGS "/Ycpch.h")
- target_sources(vcpkglib PRIVATE src/pch.cpp)
- target_compile_options(vcpkglib PRIVATE /Yupch.h /FIpch.h /Zm200)
-else()
- target_compile_options(vcpkglib PRIVATE -include "${CMAKE_CURRENT_SOURCE_DIR}/include/pch.h")
-endif()
-
-if (MINGW)
- target_compile_definitions(vcpkglib
- PUBLIC
- UNICODE
- _WIN32_WINNT=0x0601
- WINHTTP_ACCESS_TYPE_AUTOMATIC_PROXY=4
- __fastfail=exit)
- target_link_libraries(vcpkglib PUBLIC winhttp bcrypt version ole32 uuid)
-endif()
-
-# === Target: vcpkg ===
-
-add_executable(vcpkg ${VCPKG_SOURCES})
-target_link_libraries(vcpkg PRIVATE vcpkglib)
-vcpkg_target_add_warning_options(vcpkg)
-
-# === Target: vcpkg-test ===
-
-if (BUILD_TESTING)
- enable_testing()
-
- add_executable(vcpkg-test
- ${VCPKG_TEST_SOURCES}
- ${VCPKG_TEST_INCLUDES})
- target_link_libraries(vcpkg-test PRIVATE vcpkglib)
- vcpkg_target_add_warning_options(vcpkg-test)
-
- add_test(NAME default COMMAND vcpkg-test --order rand --rng-seed time)
-
- if (VCPKG_BUILD_BENCHMARKING)
- target_compile_options(vcpkg-test PRIVATE -DCATCH_CONFIG_ENABLE_BENCHMARKING)
- endif()
-endif()
-
-# === Target: vcpkg-fuzz ===
-
-if(VCPKG_BUILD_FUZZING)
- add_executable(vcpkg-fuzz ${VCPKG_FUZZ_SOURCES})
- target_link_libraries(vcpkg-fuzz PRIVATE vcpkglib)
- vcpkg_target_add_warning_options(vcpkg-fuzz)
-endif()
-
-
-# === Target: tls12-download ===
-
-set(TLS12_DOWNLOAD_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/tls12-download.c)
-if(WIN32)
- add_executable(tls12-download ${TLS12_DOWNLOAD_SOURCES})
- set_property(TARGET tls12-download PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded")
- set_property(TARGET tls12-download APPEND PROPERTY LINK_OPTIONS "$<IF:$<CONFIG:Debug>,,/ENTRY:entry>")
- target_link_libraries(tls12-download winhttp)
-endif()
-
-
-# === Target: format ===
-
-find_program(CLANG_FORMAT clang-format)
-if(CLANG_FORMAT)
- # doing all of these formats in one line has a tendency to overflow the command line length
- add_custom_target(format
- COMMAND ${CLANG_FORMAT} -i -verbose ${CMAKE_CURRENT_SOURCE_DIR}/src/pch.cpp
- COMMAND ${CLANG_FORMAT} -i -verbose ${VCPKGLIB_BASE_SOURCES}
- COMMAND ${CLANG_FORMAT} -i -verbose ${VCPKGLIB_SOURCES}
- COMMAND ${CLANG_FORMAT} -i -verbose ${CMAKE_CURRENT_SOURCE_DIR}/include/pch.h
- COMMAND ${CLANG_FORMAT} -i -verbose ${VCPKGLIB_BASE_INCLUDES}
- COMMAND ${CLANG_FORMAT} -i -verbose ${VCPKGLIB_INCLUDES}
-
- COMMAND ${CLANG_FORMAT} -i -verbose ${VCPKG_SOURCES}
-
- COMMAND ${CLANG_FORMAT} -i -verbose ${VCPKG_TEST_SOURCES}
- COMMAND ${CLANG_FORMAT} -i -verbose ${VCPKG_TEST_INCLUDES}
-
- COMMAND ${CLANG_FORMAT} -i -verbose ${VCPKG_FUZZ_SOURCES}
- COMMAND ${CLANG_FORMAT} -i -verbose ${TLS12_DOWNLOAD_SOURCES}
- )
-endif()
diff --git a/toolsrc/cmake/utilities.cmake b/toolsrc/cmake/utilities.cmake
deleted file mode 100644
index 4b434a9c7..000000000
--- a/toolsrc/cmake/utilities.cmake
+++ /dev/null
@@ -1,250 +0,0 @@
-# Outputs to Cache: VCPKG_COMPILER
-function(vcpkg_detect_compiler)
- if(NOT DEFINED CACHE{VCPKG_COMPILER})
- message(STATUS "Detecting the C++ compiler in use")
- if(CMAKE_COMPILER_IS_GNUXX OR CMAKE_CXX_COMPILER_ID MATCHES "GNU")
- if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 6.0)
- message(FATAL_ERROR [[
-The g++ version picked up is too old; please install a newer compiler such as g++-7.
-On Ubuntu try the following:
- sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y
- sudo apt-get update -y
- sudo apt-get install g++-7 -y
-On CentOS try the following:
- sudo yum install centos-release-scl
- sudo yum install devtoolset-7
- scl enable devtoolset-7 bash
-]])
- endif()
-
- set(COMPILER "gcc")
- elseif(CMAKE_CXX_COMPILER_ID MATCHES "AppleClang")
- #[[
- Note: CMAKE_SYSTEM_VERSION uses darwin versions
- - Darwin 19.0.0 = macOS 10.15, iOS 13
- - Darwin 18.0.0 = macOS 10.14, iOS 12
- - Darwin 17.0.0 = macOS 10.13, iOS 11
- - Darwin 16.0.0 = macOS 10.12, iOS 10
- ]]
- if(CMAKE_SYSTEM_VERSION VERSION_LESS "19.0.0" AND NOT VCPKG_ALLOW_APPLE_CLANG)
- message(FATAL_ERROR [[
-Building the vcpkg tool requires support for the C++ Filesystem TS.
-macOS versions below 10.15 do not have support for it with Apple Clang.
-Please install gcc6 or newer from homebrew (brew install gcc).
-If you would like to try anyway, pass --allowAppleClang to bootstrap.sh.
-]])
- endif()
- set(COMPILER "clang")
- elseif(CMAKE_CXX_COMPILER_ID MATCHES "[Cc]lang")
- set(COMPILER "clang")
- elseif(MSVC)
- set(COMPILER "msvc")
- else()
- message(FATAL_ERROR "Unknown compiler: ${CMAKE_CXX_COMPILER_ID}")
- endif()
-
- set(VCPKG_COMPILER ${COMPILER}
- CACHE STRING
- "The compiler in use; one of gcc, clang, msvc")
- message(STATUS "Detecting the C++ compiler in use - ${VCPKG_COMPILER}")
- endif()
-endfunction()
-
-# Outputs to Cache: VCPKG_STANDARD_LIBRARY
-function(vcpkg_detect_standard_library)
- if(NOT DEFINED CACHE{VCPKG_STANDARD_LIBRARY})
- include(CheckCXXSourceCompiles)
-
- message(STATUS "Detecting the C++ standard library")
-
- # note: since <ciso646> is the smallest header, generally it's used to get the standard library version
- set(CMAKE_REQUIRED_QUIET ON)
- check_cxx_source_compiles([[
-#include <ciso646>
-#if !defined(__GLIBCXX__)
-#error "not libstdc++"
-#endif
-int main() {}
-]]
- _VCPKG_STANDARD_LIBRARY_LIBSTDCXX)
- check_cxx_source_compiles([[
-#include <ciso646>
-#if !defined(_LIBCPP_VERSION)
-#error "not libc++"
-#endif
-int main() {}
-]]
- _VCPKG_STANDARD_LIBRARY_LIBCXX)
- check_cxx_source_compiles([[
-#include <ciso646>
-#if !defined(_MSVC_STL_VERSION) && !(defined(_MSC_VER) && _MSC_VER <= 1900)
-#error "not MSVC stl"
-#endif
-int main() {}
-]]
- _VCPKG_STANDARD_LIBRARY_MSVC_STL)
- if(_VCPKG_STANDARD_LIBRARY_LIBSTDCXX)
- set(STANDARD_LIBRARY "libstdc++")
- elseif(_VCPKG_STANDARD_LIBRARY_LIBCXX)
- set(STANDARD_LIBRARY "libc++")
- elseif(_VCPKG_STANDARD_LIBRARY_MSVC_STL)
- set(STANDARD_LIBRARY "msvc-stl")
- else()
- message(FATAL_ERROR "Can't find which C++ runtime is in use")
- endif()
-
- set(VCPKG_STANDARD_LIBRARY ${STANDARD_LIBRARY}
- CACHE STRING
- "The C++ standard library in use; one of libstdc++, libc++, msvc-stl")
-
- message(STATUS "Detecting the C++ standard library - ${VCPKG_STANDARD_LIBRARY}")
- endif()
-endfunction()
-
-# Outputs to Cache: VCPKG_USE_STD_FILESYSTEM, VCPKG_CXXFS_LIBRARY
-function(vcpkg_detect_std_filesystem)
- vcpkg_detect_standard_library()
-
- if(NOT DEFINED CACHE{VCPKG_USE_STD_FILESYSTEM})
- include(CheckCXXSourceCompiles)
-
- message(STATUS "Detecting how to use the C++ filesystem library")
-
- set(CMAKE_REQUIRED_QUIET ON)
- if(VCPKG_STANDARD_LIBRARY STREQUAL "libstdc++")
- check_cxx_source_compiles([[
-#include <ciso646>
-#if defined(_GLIBCXX_RELEASE) && _GLIBCXX_RELEASE >= 9
-#error "libstdc++ after version 9 does not require -lstdc++fs"
-#endif
-int main() {}
-]]
- _VCPKG_REQUIRE_LINK_CXXFS)
-
- check_cxx_source_compiles([[
-#include <ciso646>
-#if !defined(_GLIBCXX_RELEASE) || _GLIBCXX_RELEASE < 8
-#error "libstdc++ before version 8 does not support <filesystem>"
-#endif
-int main() {}
-]]
- _VCPKG_USE_STD_FILESYSTEM)
-
- if(_VCPKG_REQUIRE_LINK_CXXFS)
- set(_VCPKG_CXXFS_LIBRARY "stdc++fs")
- endif()
- elseif(VCPKG_STANDARD_LIBRARY STREQUAL "libc++")
- if(CMAKE_CXX_COMPILER_ID MATCHES "AppleClang")
- # AppleClang never requires (or allows) -lc++fs, even with libc++ version 8.0.0
- set(_VCPKG_CXXFS_LIBRARY OFF)
- elseif(CMAKE_SYSTEM_NAME STREQUAL "OpenBSD")
- # As above, not required on this platform (tested at least on 6.8)
- set(_VCPKG_CXXFS_LIBRARY OFF)
- else()
- check_cxx_source_compiles([[
-#include <ciso646>
-#if _LIBCPP_VERSION >= 9000
-#error "libc++ after version 9 does not require -lc++fs"
-#endif
-int main() {}
-]]
- _VCPKG_REQUIRE_LINK_CXXFS)
-
- if(_VCPKG_REQUIRE_LINK_CXXFS)
- set(_VCPKG_CXXFS_LIBRARY "c++fs")
- endif()
- endif()
-
- # We don't support versions of libc++ < 7.0.0, and libc++ 7.0.0 has <filesystem>
- set(_VCPKG_USE_STD_FILESYSTEM ON)
- elseif(VCPKG_STANDARD_LIBRARY STREQUAL "msvc-stl")
- check_cxx_source_compiles(
- "#include <ciso646>
- #if !defined(_MSVC_STL_UPDATE) || _MSVC_STL_UPDATE < 201803
- #error \"MSVC STL before 15.7 does not support <filesystem>\"
- #endif
- int main() {}"
- _VCPKG_USE_STD_FILESYSTEM)
-
- set(_VCPKG_CXXFS_LIBRARY OFF)
- endif()
-
- set(VCPKG_USE_STD_FILESYSTEM ${_VCPKG_USE_STD_FILESYSTEM}
- CACHE BOOL
- "Whether to use <filesystem>, as opposed to <experimental/filesystem>"
- FORCE)
- set(VCPKG_CXXFS_LIBRARY ${_VCPKG_CXXFS_LIBRARY}
- CACHE STRING
- "Library to link (if any) in order to use <filesystem>"
- FORCE)
-
- if(VCPKG_USE_STD_FILESYSTEM)
- set(msg "<filesystem>")
- else()
- set(msg "<experimental/filesystem>")
- endif()
- if(VCPKG_CXXFS_LIBRARY)
- set(msg "${msg} with -l${VCPKG_CXXFS_LIBRARY}")
- endif()
-
- message(STATUS "Detecting how to use the C++ filesystem library - ${msg}")
- endif()
-endfunction()
-
-function(vcpkg_target_add_warning_options TARGET)
- if(MSVC)
- # either MSVC, or clang-cl
- target_compile_options(${TARGET} PRIVATE -FC)
-
- if (MSVC_VERSION GREATER 1900)
- # Visual Studio 2017 or later
- target_compile_options(${TARGET} PRIVATE -permissive- -utf-8)
- endif()
-
- if(VCPKG_DEVELOPMENT_WARNINGS)
- target_compile_options(${TARGET} PRIVATE -W4)
- if(VCPKG_COMPILER STREQUAL "clang")
- # -Wno-range-loop-analysis is due to an LLVM bug which will be fixed in a
- # future version of clang https://reviews.llvm.org/D73007
- target_compile_options(${TARGET} PRIVATE
- -Wmissing-prototypes
- -Wno-missing-field-initializers
- -Wno-range-loop-analysis
- )
- else()
- target_compile_options(${TARGET} PRIVATE -analyze)
- endif()
- else()
- target_compile_options(${TARGET} PRIVATE -W3)
- endif()
-
- if(VCPKG_WARNINGS_AS_ERRORS)
- target_compile_options(${TARGET} PRIVATE -WX)
- endif()
- else()
- if(VCPKG_DEVELOPMENT_WARNINGS)
- target_compile_options(${TARGET} PRIVATE
- -Wall -Wextra -Wpedantic
- -Wno-unknown-pragmas
- -Wno-missing-field-initializers
- -Wno-redundant-move
- )
-
- # GCC and clang have different names for the same warning
- if(VCPKG_COMPILER STREQUAL "gcc")
- target_compile_options(${TARGET} PRIVATE
- -Wmissing-declarations
- )
- elseif(VCPKG_COMPILER STREQUAL "clang")
- target_compile_options(${TARGET} PRIVATE
- -Wmissing-prototypes
- -Wno-range-loop-analysis
- )
- endif()
- endif()
-
- if(VCPKG_WARNINGS_AS_ERRORS)
- target_compile_options(${TARGET} PRIVATE -Werror)
- endif()
- endif()
-endfunction()
diff --git a/toolsrc/include/catch2/catch.hpp b/toolsrc/include/catch2/catch.hpp
deleted file mode 100644
index f471a2ec6..000000000
--- a/toolsrc/include/catch2/catch.hpp
+++ /dev/null
@@ -1,16865 +0,0 @@
-/*
- * Catch v2.9.1
- * Generated: 2019-06-17 11:59:24.363643
- * ----------------------------------------------------------
- * This file has been merged from multiple headers. Please don't edit it directly
- * Copyright (c) 2019 Two Blue Cubes Ltd. All rights reserved.
- *
- * Distributed under the Boost Software License, Version 1.0. (See accompanying
- * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
- */
-#ifndef TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
-#define TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
-// start catch.hpp
-
-
-#define CATCH_VERSION_MAJOR 2
-#define CATCH_VERSION_MINOR 9
-#define CATCH_VERSION_PATCH 1
-
-#ifdef __clang__
-# pragma clang system_header
-#elif defined __GNUC__
-# pragma GCC system_header
-#endif
-
-// start catch_suppress_warnings.h
-
-#ifdef __clang__
-# ifdef __ICC // icpc defines the __clang__ macro
-# pragma warning(push)
-# pragma warning(disable: 161 1682)
-# else // __ICC
-# pragma clang diagnostic push
-# pragma clang diagnostic ignored "-Wpadded"
-# pragma clang diagnostic ignored "-Wswitch-enum"
-# pragma clang diagnostic ignored "-Wcovered-switch-default"
-# endif
-#elif defined __GNUC__
- // Because REQUIREs trigger GCC's -Wparentheses, and because still
- // supported version of g++ have only buggy support for _Pragmas,
- // Wparentheses have to be suppressed globally.
-# pragma GCC diagnostic ignored "-Wparentheses" // See #674 for details
-
-# pragma GCC diagnostic push
-# pragma GCC diagnostic ignored "-Wunused-variable"
-# pragma GCC diagnostic ignored "-Wpadded"
-#endif
-// end catch_suppress_warnings.h
-#if defined(CATCH_CONFIG_MAIN) || defined(CATCH_CONFIG_RUNNER)
-# define CATCH_IMPL
-# define CATCH_CONFIG_ALL_PARTS
-#endif
-
-// In the impl file, we want to have access to all parts of the headers
-// Can also be used to sanely support PCHs
-#if defined(CATCH_CONFIG_ALL_PARTS)
-# define CATCH_CONFIG_EXTERNAL_INTERFACES
-# if defined(CATCH_CONFIG_DISABLE_MATCHERS)
-# undef CATCH_CONFIG_DISABLE_MATCHERS
-# endif
-# if !defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER)
-# define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
-# endif
-#endif
-
-#if !defined(CATCH_CONFIG_IMPL_ONLY)
-// start catch_platform.h
-
-#ifdef __APPLE__
-# include <TargetConditionals.h>
-# if TARGET_OS_OSX == 1
-# define CATCH_PLATFORM_MAC
-# elif TARGET_OS_IPHONE == 1
-# define CATCH_PLATFORM_IPHONE
-# endif
-
-#elif defined(linux) || defined(__linux) || defined(__linux__)
-# define CATCH_PLATFORM_LINUX
-
-#elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) || defined(__MINGW32__)
-# define CATCH_PLATFORM_WINDOWS
-#endif
-
-// end catch_platform.h
-
-#ifdef CATCH_IMPL
-# ifndef CLARA_CONFIG_MAIN
-# define CLARA_CONFIG_MAIN_NOT_DEFINED
-# define CLARA_CONFIG_MAIN
-# endif
-#endif
-
-// start catch_user_interfaces.h
-
-namespace Catch {
- unsigned int rngSeed();
-}
-
-// end catch_user_interfaces.h
-// start catch_tag_alias_autoregistrar.h
-
-// start catch_common.h
-
-// start catch_compiler_capabilities.h
-
-// Detect a number of compiler features - by compiler
-// The following features are defined:
-//
-// CATCH_CONFIG_COUNTER : is the __COUNTER__ macro supported?
-// CATCH_CONFIG_WINDOWS_SEH : is Windows SEH supported?
-// CATCH_CONFIG_POSIX_SIGNALS : are POSIX signals supported?
-// CATCH_CONFIG_DISABLE_EXCEPTIONS : Are exceptions enabled?
-// ****************
-// Note to maintainers: if new toggles are added please document them
-// in configuration.md, too
-// ****************
-
-// In general each macro has a _NO_<feature name> form
-// (e.g. CATCH_CONFIG_NO_POSIX_SIGNALS) which disables the feature.
-// Many features, at point of detection, define an _INTERNAL_ macro, so they
-// can be combined, en-mass, with the _NO_ forms later.
-
-#ifdef __cplusplus
-
-# if (__cplusplus >= 201402L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201402L)
-# define CATCH_CPP14_OR_GREATER
-# endif
-
-# if (__cplusplus >= 201703L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)
-# define CATCH_CPP17_OR_GREATER
-# endif
-
-#endif
-
-#if defined(CATCH_CPP17_OR_GREATER)
-# define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
-#endif
-
-#ifdef __clang__
-
-# define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
- _Pragma( "clang diagnostic push" ) \
- _Pragma( "clang diagnostic ignored \"-Wexit-time-destructors\"" ) \
- _Pragma( "clang diagnostic ignored \"-Wglobal-constructors\"")
-# define CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
- _Pragma( "clang diagnostic pop" )
-
-# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
- _Pragma( "clang diagnostic push" ) \
- _Pragma( "clang diagnostic ignored \"-Wparentheses\"" )
-# define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \
- _Pragma( "clang diagnostic pop" )
-
-# define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \
- _Pragma( "clang diagnostic push" ) \
- _Pragma( "clang diagnostic ignored \"-Wunused-variable\"" )
-# define CATCH_INTERNAL_UNSUPPRESS_UNUSED_WARNINGS \
- _Pragma( "clang diagnostic pop" )
-
-# define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
- _Pragma( "clang diagnostic push" ) \
- _Pragma( "clang diagnostic ignored \"-Wgnu-zero-variadic-macro-arguments\"" )
-# define CATCH_INTERNAL_UNSUPPRESS_ZERO_VARIADIC_WARNINGS \
- _Pragma( "clang diagnostic pop" )
-
-#endif // __clang__
-
-////////////////////////////////////////////////////////////////////////////////
-// Assume that non-Windows platforms support posix signals by default
-#if !defined(CATCH_PLATFORM_WINDOWS)
- #define CATCH_INTERNAL_CONFIG_POSIX_SIGNALS
-#endif
-
-////////////////////////////////////////////////////////////////////////////////
-// We know some environments not to support full POSIX signals
-#if defined(__CYGWIN__) || defined(__QNX__) || defined(__EMSCRIPTEN__) || defined(__DJGPP__)
- #define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS
-#endif
-
-#ifdef __OS400__
-# define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS
-# define CATCH_CONFIG_COLOUR_NONE
-#endif
-
-////////////////////////////////////////////////////////////////////////////////
-// Android somehow still does not support std::to_string
-#if defined(__ANDROID__)
-# define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING
-#endif
-
-////////////////////////////////////////////////////////////////////////////////
-// Not all Windows environments support SEH properly
-#if defined(__MINGW32__)
-# define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH
-#endif
-
-////////////////////////////////////////////////////////////////////////////////
-// PS4
-#if defined(__ORBIS__)
-# define CATCH_INTERNAL_CONFIG_NO_NEW_CAPTURE
-#endif
-
-////////////////////////////////////////////////////////////////////////////////
-// Cygwin
-#ifdef __CYGWIN__
-
-// Required for some versions of Cygwin to declare gettimeofday
-// see: http://stackoverflow.com/questions/36901803/gettimeofday-not-declared-in-this-scope-cygwin
-# define _BSD_SOURCE
-// some versions of cygwin (most) do not support std::to_string. Use the libstd check.
-// https://gcc.gnu.org/onlinedocs/gcc-4.8.2/libstdc++/api/a01053_source.html line 2812-2813
-# if !((__cplusplus >= 201103L) && defined(_GLIBCXX_USE_C99) \
- && !defined(_GLIBCXX_HAVE_BROKEN_VSWPRINTF))
-
-# define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING
-
-# endif
-#endif // __CYGWIN__
-
-////////////////////////////////////////////////////////////////////////////////
-// Visual C++
-#ifdef _MSC_VER
-
-# if _MSC_VER >= 1900 // Visual Studio 2015 or newer
-# define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
-# endif
-
-// Universal Windows platform does not support SEH
-// Or console colours (or console at all...)
-# if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP)
-# define CATCH_CONFIG_COLOUR_NONE
-# else
-# define CATCH_INTERNAL_CONFIG_WINDOWS_SEH
-# endif
-
-// MSVC traditional preprocessor needs some workaround for __VA_ARGS__
-// _MSVC_TRADITIONAL == 0 means new conformant preprocessor
-// _MSVC_TRADITIONAL == 1 means old traditional non-conformant preprocessor
-# if !defined(_MSVC_TRADITIONAL) || (defined(_MSVC_TRADITIONAL) && _MSVC_TRADITIONAL)
-# define CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
-# endif
-#endif // _MSC_VER
-
-#if defined(_REENTRANT) || defined(_MSC_VER)
-// Enable async processing, as -pthread is specified or no additional linking is required
-# define CATCH_INTERNAL_CONFIG_USE_ASYNC
-#endif // _MSC_VER
-
-////////////////////////////////////////////////////////////////////////////////
-// Check if we are compiled with -fno-exceptions or equivalent
-#if defined(__EXCEPTIONS) || defined(__cpp_exceptions) || defined(_CPPUNWIND)
-# define CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED
-#endif
-
-////////////////////////////////////////////////////////////////////////////////
-// DJGPP
-#ifdef __DJGPP__
-# define CATCH_INTERNAL_CONFIG_NO_WCHAR
-#endif // __DJGPP__
-
-////////////////////////////////////////////////////////////////////////////////
-// Embarcadero C++Build
-#if defined(__BORLANDC__)
- #define CATCH_INTERNAL_CONFIG_POLYFILL_ISNAN
-#endif
-
-////////////////////////////////////////////////////////////////////////////////
-
-// Use of __COUNTER__ is suppressed during code analysis in
-// CLion/AppCode 2017.2.x and former, because __COUNTER__ is not properly
-// handled by it.
-// Otherwise all supported compilers support COUNTER macro,
-// but user still might want to turn it off
-#if ( !defined(__JETBRAINS_IDE__) || __JETBRAINS_IDE__ >= 20170300L )
- #define CATCH_INTERNAL_CONFIG_COUNTER
-#endif
-
-////////////////////////////////////////////////////////////////////////////////
-// Check if string_view is available and usable
-// The check is split apart to work around v140 (VS2015) preprocessor issue...
-#if defined(__has_include)
-#if __has_include(<string_view>) && defined(CATCH_CPP17_OR_GREATER)
-# define CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW
-#endif
-#endif
-
-////////////////////////////////////////////////////////////////////////////////
-// Check if optional is available and usable
-#if defined(__has_include)
-# if __has_include(<optional>) && defined(CATCH_CPP17_OR_GREATER)
-# define CATCH_INTERNAL_CONFIG_CPP17_OPTIONAL
-# endif // __has_include(<optional>) && defined(CATCH_CPP17_OR_GREATER)
-#endif // __has_include
-
-////////////////////////////////////////////////////////////////////////////////
-// Check if variant is available and usable
-#if defined(__has_include)
-# if __has_include(<variant>) && defined(CATCH_CPP17_OR_GREATER)
-# if defined(__clang__) && (__clang_major__ < 8)
- // work around clang bug with libstdc++ https://bugs.llvm.org/show_bug.cgi?id=31852
- // fix should be in clang 8, workaround in libstdc++ 8.2
-# include <ciso646>
-# if defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9)
-# define CATCH_CONFIG_NO_CPP17_VARIANT
-# else
-# define CATCH_INTERNAL_CONFIG_CPP17_VARIANT
-# endif // defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9)
-# else
-# define CATCH_INTERNAL_CONFIG_CPP17_VARIANT
-# endif // defined(__clang__) && (__clang_major__ < 8)
-# endif // __has_include(<variant>) && defined(CATCH_CPP17_OR_GREATER)
-#endif // __has_include
-
-#if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER)
-# define CATCH_CONFIG_COUNTER
-#endif
-#if defined(CATCH_INTERNAL_CONFIG_WINDOWS_SEH) && !defined(CATCH_CONFIG_NO_WINDOWS_SEH) && !defined(CATCH_CONFIG_WINDOWS_SEH) && !defined(CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH)
-# define CATCH_CONFIG_WINDOWS_SEH
-#endif
-// This is set by default, because we assume that unix compilers are posix-signal-compatible by default.
-#if defined(CATCH_INTERNAL_CONFIG_POSIX_SIGNALS) && !defined(CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_POSIX_SIGNALS)
-# define CATCH_CONFIG_POSIX_SIGNALS
-#endif
-// This is set by default, because we assume that compilers with no wchar_t support are just rare exceptions.
-#if !defined(CATCH_INTERNAL_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_WCHAR)
-# define CATCH_CONFIG_WCHAR
-#endif
-
-#if !defined(CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_CPP11_TO_STRING)
-# define CATCH_CONFIG_CPP11_TO_STRING
-#endif
-
-#if defined(CATCH_INTERNAL_CONFIG_CPP17_OPTIONAL) && !defined(CATCH_CONFIG_NO_CPP17_OPTIONAL) && !defined(CATCH_CONFIG_CPP17_OPTIONAL)
-# define CATCH_CONFIG_CPP17_OPTIONAL
-#endif
-
-#if defined(CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS) && !defined(CATCH_CONFIG_NO_CPP17_UNCAUGHT_EXCEPTIONS) && !defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS)
-# define CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
-#endif
-
-#if defined(CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_NO_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_CPP17_STRING_VIEW)
-# define CATCH_CONFIG_CPP17_STRING_VIEW
-#endif
-
-#if defined(CATCH_INTERNAL_CONFIG_CPP17_VARIANT) && !defined(CATCH_CONFIG_NO_CPP17_VARIANT) && !defined(CATCH_CONFIG_CPP17_VARIANT)
-# define CATCH_CONFIG_CPP17_VARIANT
-#endif
-
-#if defined(CATCH_CONFIG_EXPERIMENTAL_REDIRECT)
-# define CATCH_INTERNAL_CONFIG_NEW_CAPTURE
-#endif
-
-#if defined(CATCH_INTERNAL_CONFIG_NEW_CAPTURE) && !defined(CATCH_INTERNAL_CONFIG_NO_NEW_CAPTURE) && !defined(CATCH_CONFIG_NO_NEW_CAPTURE) && !defined(CATCH_CONFIG_NEW_CAPTURE)
-# define CATCH_CONFIG_NEW_CAPTURE
-#endif
-
-#if !defined(CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED) && !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
-# define CATCH_CONFIG_DISABLE_EXCEPTIONS
-#endif
-
-#if defined(CATCH_INTERNAL_CONFIG_POLYFILL_ISNAN) && !defined(CATCH_CONFIG_NO_POLYFILL_ISNAN) && !defined(CATCH_CONFIG_POLYFILL_ISNAN)
-# define CATCH_CONFIG_POLYFILL_ISNAN
-#endif
-
-#if defined(CATCH_INTERNAL_CONFIG_USE_ASYNC) && !defined(CATCH_CONFIG_NO_USE_ASYNC) && !defined(CATCH_CONFIG_USE_ASYNC)
-# define CATCH_CONFIG_USE_ASYNC
-#endif
-
-#if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS)
-# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS
-# define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS
-#endif
-#if !defined(CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS)
-# define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS
-# define CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
-#endif
-#if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS)
-# define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS
-# define CATCH_INTERNAL_UNSUPPRESS_UNUSED_WARNINGS
-#endif
-#if !defined(CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS)
-# define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS
-# define CATCH_INTERNAL_UNSUPPRESS_ZERO_VARIADIC_WARNINGS
-#endif
-
-#if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
-#define CATCH_TRY if ((true))
-#define CATCH_CATCH_ALL if ((false))
-#define CATCH_CATCH_ANON(type) if ((false))
-#else
-#define CATCH_TRY try
-#define CATCH_CATCH_ALL catch (...)
-#define CATCH_CATCH_ANON(type) catch (type)
-#endif
-
-#if defined(CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR) && !defined(CATCH_CONFIG_NO_TRADITIONAL_MSVC_PREPROCESSOR) && !defined(CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR)
-#define CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
-#endif
-
-// end catch_compiler_capabilities.h
-#define INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) name##line
-#define INTERNAL_CATCH_UNIQUE_NAME_LINE( name, line ) INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line )
-#ifdef CATCH_CONFIG_COUNTER
-# define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __COUNTER__ )
-#else
-# define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __LINE__ )
-#endif
-
-#include <iosfwd>
-#include <string>
-#include <cstdint>
-
-// We need a dummy global operator<< so we can bring it into Catch namespace later
-struct Catch_global_namespace_dummy {};
-std::ostream& operator<<(std::ostream&, Catch_global_namespace_dummy);
-
-namespace Catch {
-
- struct CaseSensitive { enum Choice {
- Yes,
- No
- }; };
-
- class NonCopyable {
- NonCopyable( NonCopyable const& ) = delete;
- NonCopyable( NonCopyable && ) = delete;
- NonCopyable& operator = ( NonCopyable const& ) = delete;
- NonCopyable& operator = ( NonCopyable && ) = delete;
-
- protected:
- NonCopyable();
- virtual ~NonCopyable();
- };
-
- struct SourceLineInfo {
-
- SourceLineInfo() = delete;
- SourceLineInfo( char const* _file, std::size_t _line ) noexcept
- : file( _file ),
- line( _line )
- {}
-
- SourceLineInfo( SourceLineInfo const& other ) = default;
- SourceLineInfo& operator = ( SourceLineInfo const& ) = default;
- SourceLineInfo( SourceLineInfo&& ) noexcept = default;
- SourceLineInfo& operator = ( SourceLineInfo&& ) noexcept = default;
-
- bool empty() const noexcept;
- bool operator == ( SourceLineInfo const& other ) const noexcept;
- bool operator < ( SourceLineInfo const& other ) const noexcept;
-
- char const* file;
- std::size_t line;
- };
-
- std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info );
-
- // Bring in operator<< from global namespace into Catch namespace
- // This is necessary because the overload of operator<< above makes
- // lookup stop at namespace Catch
- using ::operator<<;
-
- // Use this in variadic streaming macros to allow
- // >> +StreamEndStop
- // as well as
- // >> stuff +StreamEndStop
- struct StreamEndStop {
- std::string operator+() const;
- };
- template<typename T>
- T const& operator + ( T const& value, StreamEndStop ) {
- return value;
- }
-}
-
-#define CATCH_INTERNAL_LINEINFO \
- ::Catch::SourceLineInfo( __FILE__, static_cast<std::size_t>( __LINE__ ) )
-
-// end catch_common.h
-namespace Catch {
-
- struct RegistrarForTagAliases {
- RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo );
- };
-
-} // end namespace Catch
-
-#define CATCH_REGISTER_TAG_ALIAS( alias, spec ) \
- CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
- namespace{ Catch::RegistrarForTagAliases INTERNAL_CATCH_UNIQUE_NAME( AutoRegisterTagAlias )( alias, spec, CATCH_INTERNAL_LINEINFO ); } \
- CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
-
-// end catch_tag_alias_autoregistrar.h
-// start catch_test_registry.h
-
-// start catch_interfaces_testcase.h
-
-#include <vector>
-
-namespace Catch {
-
- class TestSpec;
-
- struct ITestInvoker {
- virtual void invoke () const = 0;
- virtual ~ITestInvoker();
- };
-
- class TestCase;
- struct IConfig;
-
- struct ITestCaseRegistry {
- virtual ~ITestCaseRegistry();
- virtual std::vector<TestCase> const& getAllTests() const = 0;
- virtual std::vector<TestCase> const& getAllTestsSorted( IConfig const& config ) const = 0;
- };
-
- bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config );
- std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config );
- std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config );
-
-}
-
-// end catch_interfaces_testcase.h
-// start catch_stringref.h
-
-#include <cstddef>
-#include <string>
-#include <iosfwd>
-
-namespace Catch {
-
- /// A non-owning string class (similar to the forthcoming std::string_view)
- /// Note that, because a StringRef may be a substring of another string,
- /// it may not be null terminated. c_str() must return a null terminated
- /// string, however, and so the StringRef will internally take ownership
- /// (taking a copy), if necessary. In theory this ownership is not externally
- /// visible - but it does mean (substring) StringRefs should not be shared between
- /// threads.
- class StringRef {
- public:
- using size_type = std::size_t;
-
- private:
- friend struct StringRefTestAccess;
-
- char const* m_start;
- size_type m_size;
-
- char* m_data = nullptr;
-
- void takeOwnership();
-
- static constexpr char const* const s_empty = "";
-
- public: // construction/ assignment
- StringRef() noexcept
- : StringRef( s_empty, 0 )
- {}
-
- StringRef( StringRef const& other ) noexcept
- : m_start( other.m_start ),
- m_size( other.m_size )
- {}
-
- StringRef( StringRef&& other ) noexcept
- : m_start( other.m_start ),
- m_size( other.m_size ),
- m_data( other.m_data )
- {
- other.m_data = nullptr;
- }
-
- StringRef( char const* rawChars ) noexcept;
-
- StringRef( char const* rawChars, size_type size ) noexcept
- : m_start( rawChars ),
- m_size( size )
- {}
-
- StringRef( std::string const& stdString ) noexcept
- : m_start( stdString.c_str() ),
- m_size( stdString.size() )
- {}
-
- ~StringRef() noexcept {
- delete[] m_data;
- }
-
- auto operator = ( StringRef const &other ) noexcept -> StringRef& {
- delete[] m_data;
- m_data = nullptr;
- m_start = other.m_start;
- m_size = other.m_size;
- return *this;
- }
-
- operator std::string() const;
-
- void swap( StringRef& other ) noexcept;
-
- public: // operators
- auto operator == ( StringRef const& other ) const noexcept -> bool;
- auto operator != ( StringRef const& other ) const noexcept -> bool;
-
- auto operator[] ( size_type index ) const noexcept -> char;
-
- public: // named queries
- auto empty() const noexcept -> bool {
- return m_size == 0;
- }
- auto size() const noexcept -> size_type {
- return m_size;
- }
-
- auto numberOfCharacters() const noexcept -> size_type;
- auto c_str() const -> char const*;
-
- public: // substrings and searches
- auto substr( size_type start, size_type size ) const noexcept -> StringRef;
-
- // Returns the current start pointer.
- // Note that the pointer can change when if the StringRef is a substring
- auto currentData() const noexcept -> char const*;
-
- private: // ownership queries - may not be consistent between calls
- auto isOwned() const noexcept -> bool;
- auto isSubstring() const noexcept -> bool;
- };
-
- auto operator + ( StringRef const& lhs, StringRef const& rhs ) -> std::string;
- auto operator + ( StringRef const& lhs, char const* rhs ) -> std::string;
- auto operator + ( char const* lhs, StringRef const& rhs ) -> std::string;
-
- auto operator += ( std::string& lhs, StringRef const& sr ) -> std::string&;
- auto operator << ( std::ostream& os, StringRef const& sr ) -> std::ostream&;
-
- inline auto operator "" _sr( char const* rawChars, std::size_t size ) noexcept -> StringRef {
- return StringRef( rawChars, size );
- }
-
-} // namespace Catch
-
-inline auto operator "" _catch_sr( char const* rawChars, std::size_t size ) noexcept -> Catch::StringRef {
- return Catch::StringRef( rawChars, size );
-}
-
-// end catch_stringref.h
-// start catch_type_traits.hpp
-
-
-#include <type_traits>
-
-namespace Catch{
-
-#ifdef CATCH_CPP17_OR_GREATER
- template <typename...>
- inline constexpr auto is_unique = std::true_type{};
-
- template <typename T, typename... Rest>
- inline constexpr auto is_unique<T, Rest...> = std::bool_constant<
- (!std::is_same_v<T, Rest> && ...) && is_unique<Rest...>
- >{};
-#else
-
-template <typename...>
-struct is_unique : std::true_type{};
-
-template <typename T0, typename T1, typename... Rest>
-struct is_unique<T0, T1, Rest...> : std::integral_constant
-<bool,
- !std::is_same<T0, T1>::value
- && is_unique<T0, Rest...>::value
- && is_unique<T1, Rest...>::value
->{};
-
-#endif
-}
-
-// end catch_type_traits.hpp
-// start catch_preprocessor.hpp
-
-
-#define CATCH_RECURSION_LEVEL0(...) __VA_ARGS__
-#define CATCH_RECURSION_LEVEL1(...) CATCH_RECURSION_LEVEL0(CATCH_RECURSION_LEVEL0(CATCH_RECURSION_LEVEL0(__VA_ARGS__)))
-#define CATCH_RECURSION_LEVEL2(...) CATCH_RECURSION_LEVEL1(CATCH_RECURSION_LEVEL1(CATCH_RECURSION_LEVEL1(__VA_ARGS__)))
-#define CATCH_RECURSION_LEVEL3(...) CATCH_RECURSION_LEVEL2(CATCH_RECURSION_LEVEL2(CATCH_RECURSION_LEVEL2(__VA_ARGS__)))
-#define CATCH_RECURSION_LEVEL4(...) CATCH_RECURSION_LEVEL3(CATCH_RECURSION_LEVEL3(CATCH_RECURSION_LEVEL3(__VA_ARGS__)))
-#define CATCH_RECURSION_LEVEL5(...) CATCH_RECURSION_LEVEL4(CATCH_RECURSION_LEVEL4(CATCH_RECURSION_LEVEL4(__VA_ARGS__)))
-
-#ifdef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
-#define INTERNAL_CATCH_EXPAND_VARGS(...) __VA_ARGS__
-// MSVC needs more evaluations
-#define CATCH_RECURSION_LEVEL6(...) CATCH_RECURSION_LEVEL5(CATCH_RECURSION_LEVEL5(CATCH_RECURSION_LEVEL5(__VA_ARGS__)))
-#define CATCH_RECURSE(...) CATCH_RECURSION_LEVEL6(CATCH_RECURSION_LEVEL6(__VA_ARGS__))
-#else
-#define CATCH_RECURSE(...) CATCH_RECURSION_LEVEL5(__VA_ARGS__)
-#endif
-
-#define CATCH_REC_END(...)
-#define CATCH_REC_OUT
-
-#define CATCH_EMPTY()
-#define CATCH_DEFER(id) id CATCH_EMPTY()
-
-#define CATCH_REC_GET_END2() 0, CATCH_REC_END
-#define CATCH_REC_GET_END1(...) CATCH_REC_GET_END2
-#define CATCH_REC_GET_END(...) CATCH_REC_GET_END1
-#define CATCH_REC_NEXT0(test, next, ...) next CATCH_REC_OUT
-#define CATCH_REC_NEXT1(test, next) CATCH_DEFER ( CATCH_REC_NEXT0 ) ( test, next, 0)
-#define CATCH_REC_NEXT(test, next) CATCH_REC_NEXT1(CATCH_REC_GET_END test, next)
-
-#define CATCH_REC_LIST0(f, x, peek, ...) , f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1) ) ( f, peek, __VA_ARGS__ )
-#define CATCH_REC_LIST1(f, x, peek, ...) , f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST0) ) ( f, peek, __VA_ARGS__ )
-#define CATCH_REC_LIST2(f, x, peek, ...) f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1) ) ( f, peek, __VA_ARGS__ )
-
-#define CATCH_REC_LIST0_UD(f, userdata, x, peek, ...) , f(userdata, x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1_UD) ) ( f, userdata, peek, __VA_ARGS__ )
-#define CATCH_REC_LIST1_UD(f, userdata, x, peek, ...) , f(userdata, x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST0_UD) ) ( f, userdata, peek, __VA_ARGS__ )
-#define CATCH_REC_LIST2_UD(f, userdata, x, peek, ...) f(userdata, x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1_UD) ) ( f, userdata, peek, __VA_ARGS__ )
-
-// Applies the function macro `f` to each of the remaining parameters, inserts commas between the results,
-// and passes userdata as the first parameter to each invocation,
-// e.g. CATCH_REC_LIST_UD(f, x, a, b, c) evaluates to f(x, a), f(x, b), f(x, c)
-#define CATCH_REC_LIST_UD(f, userdata, ...) CATCH_RECURSE(CATCH_REC_LIST2_UD(f, userdata, __VA_ARGS__, ()()(), ()()(), ()()(), 0))
-
-#define CATCH_REC_LIST(f, ...) CATCH_RECURSE(CATCH_REC_LIST2(f, __VA_ARGS__, ()()(), ()()(), ()()(), 0))
-
-#define INTERNAL_CATCH_EXPAND1(param) INTERNAL_CATCH_EXPAND2(param)
-#define INTERNAL_CATCH_EXPAND2(...) INTERNAL_CATCH_NO## __VA_ARGS__
-#define INTERNAL_CATCH_DEF(...) INTERNAL_CATCH_DEF __VA_ARGS__
-#define INTERNAL_CATCH_NOINTERNAL_CATCH_DEF
-#define INTERNAL_CATCH_STRINGIZE(...) INTERNAL_CATCH_STRINGIZE2(__VA_ARGS__)
-#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
-#define INTERNAL_CATCH_STRINGIZE2(...) #__VA_ARGS__
-#define INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS(param) INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_REMOVE_PARENS(param))
-#else
-// MSVC is adding extra space and needs another indirection to expand INTERNAL_CATCH_NOINTERNAL_CATCH_DEF
-#define INTERNAL_CATCH_STRINGIZE2(...) INTERNAL_CATCH_STRINGIZE3(__VA_ARGS__)
-#define INTERNAL_CATCH_STRINGIZE3(...) #__VA_ARGS__
-#define INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS(param) (INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_REMOVE_PARENS(param)) + 1)
-#endif
-
-#define INTERNAL_CATCH_MAKE_NAMESPACE2(...) ns_##__VA_ARGS__
-#define INTERNAL_CATCH_MAKE_NAMESPACE(name) INTERNAL_CATCH_MAKE_NAMESPACE2(name)
-
-#define INTERNAL_CATCH_REMOVE_PARENS(...) INTERNAL_CATCH_EXPAND1(INTERNAL_CATCH_DEF __VA_ARGS__)
-
-#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
-#define INTERNAL_CATCH_MAKE_TYPE_LIST2(...) decltype(get_wrapper<INTERNAL_CATCH_REMOVE_PARENS_GEN(__VA_ARGS__)>())
-#define INTERNAL_CATCH_MAKE_TYPE_LIST(...) INTERNAL_CATCH_MAKE_TYPE_LIST2(INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__))
-#else
-#define INTERNAL_CATCH_MAKE_TYPE_LIST2(...) INTERNAL_CATCH_EXPAND_VARGS(decltype(get_wrapper<INTERNAL_CATCH_REMOVE_PARENS_GEN(__VA_ARGS__)>()))
-#define INTERNAL_CATCH_MAKE_TYPE_LIST(...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_MAKE_TYPE_LIST2(INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__)))
-#endif
-
-#define INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(...)\
- CATCH_REC_LIST(INTERNAL_CATCH_MAKE_TYPE_LIST,__VA_ARGS__)
-
-#define INTERNAL_CATCH_REMOVE_PARENS_1_ARG(_0) INTERNAL_CATCH_REMOVE_PARENS(_0)
-#define INTERNAL_CATCH_REMOVE_PARENS_2_ARG(_0, _1) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_1_ARG(_1)
-#define INTERNAL_CATCH_REMOVE_PARENS_3_ARG(_0, _1, _2) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_2_ARG(_1, _2)
-#define INTERNAL_CATCH_REMOVE_PARENS_4_ARG(_0, _1, _2, _3) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_3_ARG(_1, _2, _3)
-#define INTERNAL_CATCH_REMOVE_PARENS_5_ARG(_0, _1, _2, _3, _4) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_4_ARG(_1, _2, _3, _4)
-#define INTERNAL_CATCH_REMOVE_PARENS_6_ARG(_0, _1, _2, _3, _4, _5) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_5_ARG(_1, _2, _3, _4, _5)
-#define INTERNAL_CATCH_REMOVE_PARENS_7_ARG(_0, _1, _2, _3, _4, _5, _6) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_6_ARG(_1, _2, _4, _5, _6)
-#define INTERNAL_CATCH_REMOVE_PARENS_8_ARG(_0, _1, _2, _3, _4, _5, _6, _7) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_7_ARG(_1, _2, _3, _4, _5, _6, _7)
-#define INTERNAL_CATCH_REMOVE_PARENS_9_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_8_ARG(_1, _2, _3, _4, _5, _6, _7, _8)
-#define INTERNAL_CATCH_REMOVE_PARENS_10_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_9_ARG(_1, _2, _3, _4, _5, _6, _7, _8, _9)
-#define INTERNAL_CATCH_REMOVE_PARENS_11_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_10_ARG(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10)
-
-#define INTERNAL_CATCH_VA_NARGS_IMPL(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...) N
-
-#define INTERNAL_CATCH_TYPE_GEN\
- template<typename...> struct TypeList {};\
- template<typename...Ts>\
- constexpr auto get_wrapper() noexcept -> TypeList<Ts...> { return {}; }\
- \
- template<template<typename...> class L1, typename...E1, template<typename...> class L2, typename...E2> \
- constexpr auto append(L1<E1...>, L2<E2...>) noexcept -> L1<E1...,E2...> { return {}; }\
- template< template<typename...> class L1, typename...E1, template<typename...> class L2, typename...E2, typename...Rest>\
- constexpr auto append(L1<E1...>, L2<E2...>, Rest...) noexcept -> decltype(append(L1<E1...,E2...>{}, Rest{}...)) { return {}; }\
- template< template<typename...> class L1, typename...E1, typename...Rest>\
- constexpr auto append(L1<E1...>, TypeList<mpl_::na>, Rest...) noexcept -> L1<E1...> { return {}; }\
- \
- template< template<typename...> class Container, template<typename...> class List, typename...elems>\
- constexpr auto rewrap(List<elems...>) noexcept -> TypeList<Container<elems...>> { return {}; }\
- template< template<typename...> class Container, template<typename...> class List, class...Elems, typename...Elements>\
- constexpr auto rewrap(List<Elems...>,Elements...) noexcept -> decltype(append(TypeList<Container<Elems...>>{}, rewrap<Container>(Elements{}...))) { return {}; }\
- \
- template<template <typename...> class Final, template< typename...> class...Containers, typename...Types>\
- constexpr auto create(TypeList<Types...>) noexcept -> decltype(append(Final<>{}, rewrap<Containers>(Types{}...)...)) { return {}; }\
- template<template <typename...> class Final, template <typename...> class List, typename...Ts>\
- constexpr auto convert(List<Ts...>) noexcept -> decltype(append(Final<>{},TypeList<Ts>{}...)) { return {}; }
-
-#define INTERNAL_CATCH_NTTP_1(signature, ...)\
- template<INTERNAL_CATCH_REMOVE_PARENS(signature)> struct Nttp{};\
- template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
- constexpr auto get_wrapper() noexcept -> Nttp<__VA_ARGS__> { return {}; } \
- \
- template< template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class Container, template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class List, INTERNAL_CATCH_REMOVE_PARENS(signature)>\
- constexpr auto rewrap(List<__VA_ARGS__>) noexcept -> TypeList<Container<__VA_ARGS__>> { return {}; }\
- template< template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class Container, template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class List, INTERNAL_CATCH_REMOVE_PARENS(signature), typename...Elements>\
- constexpr auto rewrap(List<__VA_ARGS__>,Elements...elems) noexcept -> decltype(append(TypeList<Container<__VA_ARGS__>>{}, rewrap<Container>(elems...))) { return {}; }\
- template<template <typename...> class Final, template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class...Containers, typename...Types>\
- constexpr auto create(TypeList<Types...>) noexcept -> decltype(append(Final<>{}, rewrap<Containers>(Types{}...)...)) { return {}; }
-
-#define INTERNAL_CATCH_DECLARE_SIG_TEST0(TestName)
-#define INTERNAL_CATCH_DECLARE_SIG_TEST1(TestName, signature)\
- template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
- static void TestName()
-#define INTERNAL_CATCH_DECLARE_SIG_TEST_X(TestName, signature, ...)\
- template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
- static void TestName()
-
-#define INTERNAL_CATCH_DEFINE_SIG_TEST0(TestName)
-#define INTERNAL_CATCH_DEFINE_SIG_TEST1(TestName, signature)\
- template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
- static void TestName()
-#define INTERNAL_CATCH_DEFINE_SIG_TEST_X(TestName, signature,...)\
- template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
- static void TestName()
-
-#define INTERNAL_CATCH_NTTP_REGISTER0(TestFunc, signature)\
- template<typename Type>\
- void reg_test(TypeList<Type>, Catch::NameAndTags nameAndTags)\
- {\
- Catch::AutoReg( Catch::makeTestInvoker(&TestFunc<Type>), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), nameAndTags);\
- }
-
-#define INTERNAL_CATCH_NTTP_REGISTER(TestFunc, signature, ...)\
- template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
- void reg_test(Nttp<__VA_ARGS__>, Catch::NameAndTags nameAndTags)\
- {\
- Catch::AutoReg( Catch::makeTestInvoker(&TestFunc<__VA_ARGS__>), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), nameAndTags);\
- }
-
-#define INTERNAL_CATCH_NTTP_REGISTER_METHOD0(TestName, signature, ...)\
- template<typename Type>\
- void reg_test(TypeList<Type>, Catch::StringRef className, Catch::NameAndTags nameAndTags)\
- {\
- Catch::AutoReg( Catch::makeTestInvoker(&TestName<Type>::test), CATCH_INTERNAL_LINEINFO, className, nameAndTags);\
- }
-
-#define INTERNAL_CATCH_NTTP_REGISTER_METHOD(TestName, signature, ...)\
- template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
- void reg_test(Nttp<__VA_ARGS__>, Catch::StringRef className, Catch::NameAndTags nameAndTags)\
- {\
- Catch::AutoReg( Catch::makeTestInvoker(&TestName<__VA_ARGS__>::test), CATCH_INTERNAL_LINEINFO, className, nameAndTags);\
- }
-
-#define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD0(TestName, ClassName)
-#define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD1(TestName, ClassName, signature)\
- template<typename TestType> \
- struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName)<TestType> { \
- void test();\
- }
-
-#define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X(TestName, ClassName, signature, ...)\
- template<INTERNAL_CATCH_REMOVE_PARENS(signature)> \
- struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName)<__VA_ARGS__> { \
- void test();\
- }
-
-#define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD0(TestName)
-#define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD1(TestName, signature)\
- template<typename TestType> \
- void INTERNAL_CATCH_MAKE_NAMESPACE(TestName)::TestName<TestType>::test()
-#define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X(TestName, signature, ...)\
- template<INTERNAL_CATCH_REMOVE_PARENS(signature)> \
- void INTERNAL_CATCH_MAKE_NAMESPACE(TestName)::TestName<__VA_ARGS__>::test()
-
-#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
-#define INTERNAL_CATCH_NTTP_0
-#define INTERNAL_CATCH_NTTP_GEN(...) INTERNAL_CATCH_VA_NARGS_IMPL(__VA_ARGS__, INTERNAL_CATCH_NTTP_1(__VA_ARGS__), INTERNAL_CATCH_NTTP_1(__VA_ARGS__), INTERNAL_CATCH_NTTP_1(__VA_ARGS__), INTERNAL_CATCH_NTTP_1(__VA_ARGS__), INTERNAL_CATCH_NTTP_1(__VA_ARGS__), INTERNAL_CATCH_NTTP_1( __VA_ARGS__), INTERNAL_CATCH_NTTP_1( __VA_ARGS__), INTERNAL_CATCH_NTTP_1( __VA_ARGS__), INTERNAL_CATCH_NTTP_1( __VA_ARGS__),INTERNAL_CATCH_NTTP_1( __VA_ARGS__), INTERNAL_CATCH_NTTP_0)
-#define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD(TestName, ...) INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD1, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD0)(TestName, __VA_ARGS__)
-#define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD(TestName, ClassName, ...) INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD1, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD0)(TestName, ClassName, __VA_ARGS__)
-#define INTERNAL_CATCH_NTTP_REG_METHOD_GEN(TestName, ...) INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD0, INTERNAL_CATCH_NTTP_REGISTER_METHOD0)(TestName, __VA_ARGS__)
-#define INTERNAL_CATCH_NTTP_REG_GEN(TestFunc, ...) INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER0, INTERNAL_CATCH_NTTP_REGISTER0)(TestFunc, __VA_ARGS__)
-#define INTERNAL_CATCH_DEFINE_SIG_TEST(TestName, ...) INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X,INTERNAL_CATCH_DEFINE_SIG_TEST_X,INTERNAL_CATCH_DEFINE_SIG_TEST1, INTERNAL_CATCH_DEFINE_SIG_TEST0)(TestName, __VA_ARGS__)
-#define INTERNAL_CATCH_DECLARE_SIG_TEST(TestName, ...) INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_DECLARE_SIG_TEST_X,INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X,INTERNAL_CATCH_DECLARE_SIG_TEST_X,INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST1, INTERNAL_CATCH_DECLARE_SIG_TEST0)(TestName, __VA_ARGS__)
-#define INTERNAL_CATCH_REMOVE_PARENS_GEN(...) INTERNAL_CATCH_VA_NARGS_IMPL(__VA_ARGS__, INTERNAL_CATCH_REMOVE_PARENS_11_ARG,INTERNAL_CATCH_REMOVE_PARENS_10_ARG,INTERNAL_CATCH_REMOVE_PARENS_9_ARG,INTERNAL_CATCH_REMOVE_PARENS_8_ARG,INTERNAL_CATCH_REMOVE_PARENS_7_ARG,INTERNAL_CATCH_REMOVE_PARENS_6_ARG,INTERNAL_CATCH_REMOVE_PARENS_5_ARG,INTERNAL_CATCH_REMOVE_PARENS_4_ARG,INTERNAL_CATCH_REMOVE_PARENS_3_ARG,INTERNAL_CATCH_REMOVE_PARENS_2_ARG,INTERNAL_CATCH_REMOVE_PARENS_1_ARG)(__VA_ARGS__)
-#else
-#define INTERNAL_CATCH_NTTP_0(signature)
-#define INTERNAL_CATCH_NTTP_GEN(...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL(__VA_ARGS__, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1,INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_0)( __VA_ARGS__))
-#define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD(TestName, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD1, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD0)(TestName, __VA_ARGS__))
-#define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD(TestName, ClassName, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD1, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD0)(TestName, ClassName, __VA_ARGS__))
-#define INTERNAL_CATCH_NTTP_REG_METHOD_GEN(TestName, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD0, INTERNAL_CATCH_NTTP_REGISTER_METHOD0)(TestName, __VA_ARGS__))
-#define INTERNAL_CATCH_NTTP_REG_GEN(TestFunc, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER0, INTERNAL_CATCH_NTTP_REGISTER0)(TestFunc, __VA_ARGS__))
-#define INTERNAL_CATCH_DEFINE_SIG_TEST(TestName, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X,INTERNAL_CATCH_DEFINE_SIG_TEST_X,INTERNAL_CATCH_DEFINE_SIG_TEST1, INTERNAL_CATCH_DEFINE_SIG_TEST0)(TestName, __VA_ARGS__))
-#define INTERNAL_CATCH_DECLARE_SIG_TEST(TestName, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_DECLARE_SIG_TEST_X,INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X,INTERNAL_CATCH_DECLARE_SIG_TEST_X,INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST1, INTERNAL_CATCH_DECLARE_SIG_TEST0)(TestName, __VA_ARGS__))
-#define INTERNAL_CATCH_REMOVE_PARENS_GEN(...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL(__VA_ARGS__, INTERNAL_CATCH_REMOVE_PARENS_11_ARG,INTERNAL_CATCH_REMOVE_PARENS_10_ARG,INTERNAL_CATCH_REMOVE_PARENS_9_ARG,INTERNAL_CATCH_REMOVE_PARENS_8_ARG,INTERNAL_CATCH_REMOVE_PARENS_7_ARG,INTERNAL_CATCH_REMOVE_PARENS_6_ARG,INTERNAL_CATCH_REMOVE_PARENS_5_ARG,INTERNAL_CATCH_REMOVE_PARENS_4_ARG,INTERNAL_CATCH_REMOVE_PARENS_3_ARG,INTERNAL_CATCH_REMOVE_PARENS_2_ARG,INTERNAL_CATCH_REMOVE_PARENS_1_ARG)(__VA_ARGS__))
-#endif
-
-// end catch_preprocessor.hpp
-// start catch_meta.hpp
-
-
-#include <type_traits>
-
-namespace Catch {
-template<typename T>
-struct always_false : std::false_type {};
-
-template <typename> struct true_given : std::true_type {};
-struct is_callable_tester {
- template <typename Fun, typename... Args>
- true_given<decltype(std::declval<Fun>()(std::declval<Args>()...))> static test(int);
- template <typename...>
- std::false_type static test(...);
-};
-
-template <typename T>
-struct is_callable;
-
-template <typename Fun, typename... Args>
-struct is_callable<Fun(Args...)> : decltype(is_callable_tester::test<Fun, Args...>(0)) {};
-
-} // namespace Catch
-
-namespace mpl_{
- struct na;
-}
-
-// end catch_meta.hpp
-namespace Catch {
-
-template<typename C>
-class TestInvokerAsMethod : public ITestInvoker {
- void (C::*m_testAsMethod)();
-public:
- TestInvokerAsMethod( void (C::*testAsMethod)() ) noexcept : m_testAsMethod( testAsMethod ) {}
-
- void invoke() const override {
- C obj;
- (obj.*m_testAsMethod)();
- }
-};
-
-auto makeTestInvoker( void(*testAsFunction)() ) noexcept -> ITestInvoker*;
-
-template<typename C>
-auto makeTestInvoker( void (C::*testAsMethod)() ) noexcept -> ITestInvoker* {
- return new(std::nothrow) TestInvokerAsMethod<C>( testAsMethod );
-}
-
-struct NameAndTags {
- NameAndTags( StringRef const& name_ = StringRef(), StringRef const& tags_ = StringRef() ) noexcept;
- StringRef name;
- StringRef tags;
-};
-
-struct AutoReg : NonCopyable {
- AutoReg( ITestInvoker* invoker, SourceLineInfo const& lineInfo, StringRef const& classOrMethod, NameAndTags const& nameAndTags ) noexcept;
- ~AutoReg();
-};
-
-} // end namespace Catch
-
-#if defined(CATCH_CONFIG_DISABLE)
- #define INTERNAL_CATCH_TESTCASE_NO_REGISTRATION( TestName, ... ) \
- static void TestName()
- #define INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION( TestName, ClassName, ... ) \
- namespace{ \
- struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName) { \
- void test(); \
- }; \
- } \
- void TestName::test()
- #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( TestName, TestFunc, Name, Tags, Signature, ... ) \
- INTERNAL_CATCH_DEFINE_SIG_TEST(TestFunc, INTERNAL_CATCH_REMOVE_PARENS(Signature))
- #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( TestNameClass, TestName, ClassName, Name, Tags, Signature, ... ) \
- namespace{ \
- namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName) { \
- INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD(TestName, ClassName, INTERNAL_CATCH_REMOVE_PARENS(Signature));\
- } \
- } \
- INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD(TestName, INTERNAL_CATCH_REMOVE_PARENS(Signature))
-
- #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
- #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(Name, Tags, ...) \
- INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, typename TestType, __VA_ARGS__ )
- #else
- #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(Name, Tags, ...) \
- INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, typename TestType, __VA_ARGS__ ) )
- #endif
-
- #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
- #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(Name, Tags, Signature, ...) \
- INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, Signature, __VA_ARGS__ )
- #else
- #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(Name, Tags, Signature, ...) \
- INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, Signature, __VA_ARGS__ ) )
- #endif
-
- #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
- #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION( ClassName, Name, Tags,... ) \
- INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ )
- #else
- #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION( ClassName, Name, Tags,... ) \
- INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ ) )
- #endif
-
- #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
- #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION( ClassName, Name, Tags, Signature, ... ) \
- INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ )
- #else
- #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION( ClassName, Name, Tags, Signature, ... ) \
- INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ ) )
- #endif
-#endif
-
- ///////////////////////////////////////////////////////////////////////////////
- #define INTERNAL_CATCH_TESTCASE2( TestName, ... ) \
- static void TestName(); \
- CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
- namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &TestName ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \
- CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
- static void TestName()
- #define INTERNAL_CATCH_TESTCASE( ... ) \
- INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), __VA_ARGS__ )
-
- ///////////////////////////////////////////////////////////////////////////////
- #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \
- CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
- namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &QualifiedMethod ), CATCH_INTERNAL_LINEINFO, "&" #QualifiedMethod, Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \
- CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
-
- ///////////////////////////////////////////////////////////////////////////////
- #define INTERNAL_CATCH_TEST_CASE_METHOD2( TestName, ClassName, ... )\
- CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
- namespace{ \
- struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName) { \
- void test(); \
- }; \
- Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( Catch::makeTestInvoker( &TestName::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \
- } \
- CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
- void TestName::test()
- #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, ... ) \
- INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), ClassName, __VA_ARGS__ )
-
- ///////////////////////////////////////////////////////////////////////////////
- #define INTERNAL_CATCH_REGISTER_TESTCASE( Function, ... ) \
- CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
- Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( Function ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \
- CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
-
- ///////////////////////////////////////////////////////////////////////////////
- #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_2(TestName, TestFunc, Name, Tags, Signature, ... )\
- CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
- CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
- INTERNAL_CATCH_DECLARE_SIG_TEST(TestFunc, INTERNAL_CATCH_REMOVE_PARENS(Signature));\
- namespace {\
- namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName){\
- INTERNAL_CATCH_TYPE_GEN\
- INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature))\
- INTERNAL_CATCH_NTTP_REG_GEN(TestFunc,INTERNAL_CATCH_REMOVE_PARENS(Signature))\
- template<typename...Types> \
- struct TestName{\
- TestName(){\
- int index = 0; \
- constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, __VA_ARGS__)};\
- using expander = int[];\
- (void)expander{(reg_test(Types{}, Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index]), Tags } ), index++, 0)... };/* NOLINT */ \
- }\
- };\
- static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
- TestName<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(__VA_ARGS__)>();\
- return 0;\
- }();\
- }\
- }\
- CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
- CATCH_INTERNAL_UNSUPPRESS_ZERO_VARIADIC_WARNINGS \
- INTERNAL_CATCH_DEFINE_SIG_TEST(TestFunc,INTERNAL_CATCH_REMOVE_PARENS(Signature))
-
-#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
- #define INTERNAL_CATCH_TEMPLATE_TEST_CASE(Name, Tags, ...) \
- INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, typename TestType, __VA_ARGS__ )
-#else
- #define INTERNAL_CATCH_TEMPLATE_TEST_CASE(Name, Tags, ...) \
- INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, typename TestType, __VA_ARGS__ ) )
-#endif
-
-#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
- #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG(Name, Tags, Signature, ...) \
- INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, Signature, __VA_ARGS__ )
-#else
- #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG(Name, Tags, Signature, ...) \
- INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, Signature, __VA_ARGS__ ) )
-#endif
-
- #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(TestName, TestFuncName, Name, Tags, Signature, TmplTypes, TypesList) \
- CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
- CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
- template<typename TestType> static void TestFuncName(); \
- namespace {\
- namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName) { \
- INTERNAL_CATCH_TYPE_GEN \
- INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature)) \
- template<typename... Types> \
- struct TestName { \
- void reg_tests() { \
- int index = 0; \
- using expander = int[]; \
- constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TmplTypes))};\
- constexpr char const* types_list[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TypesList))};\
- constexpr auto num_types = sizeof(types_list) / sizeof(types_list[0]);\
- (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestFuncName<Types> ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index / num_types]) + "<" + std::string(types_list[index % num_types]) + ">", Tags } ), index++, 0)... };/* NOLINT */\
- } \
- }; \
- static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){ \
- using TestInit = decltype(create<TestName, INTERNAL_CATCH_REMOVE_PARENS(TmplTypes)>(TypeList<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(INTERNAL_CATCH_REMOVE_PARENS(TypesList))>{})); \
- TestInit t; \
- t.reg_tests(); \
- return 0; \
- }(); \
- } \
- } \
- CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
- CATCH_INTERNAL_UNSUPPRESS_ZERO_VARIADIC_WARNINGS \
- template<typename TestType> \
- static void TestFuncName()
-
-#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
- #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE(Name, Tags, ...)\
- INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, typename T,__VA_ARGS__)
-#else
- #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE(Name, Tags, ...)\
- INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, typename T, __VA_ARGS__ ) )
-#endif
-
-#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
- #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG(Name, Tags, Signature, ...)\
- INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, Signature, __VA_ARGS__)
-#else
- #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG(Name, Tags, Signature, ...)\
- INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, Signature, __VA_ARGS__ ) )
-#endif
-
- #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_2(TestName, TestFunc, Name, Tags, TmplList)\
- CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
- template<typename TestType> static void TestFunc(); \
- namespace {\
- namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName){\
- INTERNAL_CATCH_TYPE_GEN\
- template<typename... Types> \
- struct TestName { \
- void reg_tests() { \
- int index = 0; \
- using expander = int[]; \
- (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestFunc<Types> ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ Name " - " + std::string(INTERNAL_CATCH_STRINGIZE(TmplList)) + " - " + std::to_string(index), Tags } ), index++, 0)... };/* NOLINT */\
- } \
- };\
- static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){ \
- using TestInit = decltype(convert<TestName>(TmplList {})); \
- TestInit t; \
- t.reg_tests(); \
- return 0; \
- }(); \
- }}\
- CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
- template<typename TestType> \
- static void TestFunc()
-
- #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE(Name, Tags, TmplList) \
- INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, TmplList )
-
- #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( TestNameClass, TestName, ClassName, Name, Tags, Signature, ... ) \
- CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
- CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
- namespace {\
- namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName){ \
- INTERNAL_CATCH_TYPE_GEN\
- INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature))\
- INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD(TestName, ClassName, INTERNAL_CATCH_REMOVE_PARENS(Signature));\
- INTERNAL_CATCH_NTTP_REG_METHOD_GEN(TestName, INTERNAL_CATCH_REMOVE_PARENS(Signature))\
- template<typename...Types> \
- struct TestNameClass{\
- TestNameClass(){\
- int index = 0; \
- constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, __VA_ARGS__)};\
- using expander = int[];\
- (void)expander{(reg_test(Types{}, #ClassName, Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index]), Tags } ), index++, 0)... };/* NOLINT */ \
- }\
- };\
- static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
- TestNameClass<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(__VA_ARGS__)>();\
- return 0;\
- }();\
- }\
- }\
- CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS\
- CATCH_INTERNAL_UNSUPPRESS_ZERO_VARIADIC_WARNINGS\
- INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD(TestName, INTERNAL_CATCH_REMOVE_PARENS(Signature))
-
-#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
- #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( ClassName, Name, Tags,... ) \
- INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ )
-#else
- #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( ClassName, Name, Tags,... ) \
- INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ ) )
-#endif
-
-#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
- #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... ) \
- INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ )
-#else
- #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... ) \
- INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ ) )
-#endif
-
- #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2(TestNameClass, TestName, ClassName, Name, Tags, Signature, TmplTypes, TypesList)\
- CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
- CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
- template<typename TestType> \
- struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName <TestType>) { \
- void test();\
- };\
- namespace {\
- namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestNameClass) {\
- INTERNAL_CATCH_TYPE_GEN \
- INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature))\
- template<typename...Types>\
- struct TestNameClass{\
- void reg_tests(){\
- int index = 0;\
- using expander = int[];\
- constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TmplTypes))};\
- constexpr char const* types_list[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TypesList))};\
- constexpr auto num_types = sizeof(types_list) / sizeof(types_list[0]);\
- (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestName<Types>::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index / num_types]) + "<" + std::string(types_list[index % num_types]) + ">", Tags } ), index++, 0)... };/* NOLINT */ \
- }\
- };\
- static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
- using TestInit = decltype(create<TestNameClass, INTERNAL_CATCH_REMOVE_PARENS(TmplTypes)>(TypeList<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(INTERNAL_CATCH_REMOVE_PARENS(TypesList))>{}));\
- TestInit t;\
- t.reg_tests();\
- return 0;\
- }(); \
- }\
- }\
- CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
- CATCH_INTERNAL_UNSUPPRESS_ZERO_VARIADIC_WARNINGS \
- template<typename TestType> \
- void TestName<TestType>::test()
-
-#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
- #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( ClassName, Name, Tags, ... )\
- INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), ClassName, Name, Tags, typename T, __VA_ARGS__ )
-#else
- #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( ClassName, Name, Tags, ... )\
- INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), ClassName, Name, Tags, typename T,__VA_ARGS__ ) )
-#endif
-
-#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
- #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... )\
- INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), ClassName, Name, Tags, Signature, __VA_ARGS__ )
-#else
- #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... )\
- INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), ClassName, Name, Tags, Signature,__VA_ARGS__ ) )
-#endif
-
- #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD_2( TestNameClass, TestName, ClassName, Name, Tags, TmplList) \
- CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
- template<typename TestType> \
- struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName <TestType>) { \
- void test();\
- };\
- namespace {\
- namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName){ \
- INTERNAL_CATCH_TYPE_GEN\
- template<typename...Types>\
- struct TestNameClass{\
- void reg_tests(){\
- int index = 0;\
- using expander = int[];\
- (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestName<Types>::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ Name " - " + std::string(INTERNAL_CATCH_STRINGIZE(TmplList)) + " - " + std::to_string(index), Tags } ), index++, 0)... };/* NOLINT */ \
- }\
- };\
- static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
- using TestInit = decltype(convert<TestNameClass>(TmplList {}));\
- TestInit t;\
- t.reg_tests();\
- return 0;\
- }(); \
- }}\
- CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
- template<typename TestType> \
- void TestName<TestType>::test()
-
-#define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD(ClassName, Name, Tags, TmplList) \
- INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), ClassName, Name, Tags, TmplList )
-
-// end catch_test_registry.h
-// start catch_capture.hpp
-
-// start catch_assertionhandler.h
-
-// start catch_assertioninfo.h
-
-// start catch_result_type.h
-
-namespace Catch {
-
- // ResultWas::OfType enum
- struct ResultWas { enum OfType {
- Unknown = -1,
- Ok = 0,
- Info = 1,
- Warning = 2,
-
- FailureBit = 0x10,
-
- ExpressionFailed = FailureBit | 1,
- ExplicitFailure = FailureBit | 2,
-
- Exception = 0x100 | FailureBit,
-
- ThrewException = Exception | 1,
- DidntThrowException = Exception | 2,
-
- FatalErrorCondition = 0x200 | FailureBit
-
- }; };
-
- bool isOk( ResultWas::OfType resultType );
- bool isJustInfo( int flags );
-
- // ResultDisposition::Flags enum
- struct ResultDisposition { enum Flags {
- Normal = 0x01,
-
- ContinueOnFailure = 0x02, // Failures fail test, but execution continues
- FalseTest = 0x04, // Prefix expression with !
- SuppressFail = 0x08 // Failures are reported but do not fail the test
- }; };
-
- ResultDisposition::Flags operator | ( ResultDisposition::Flags lhs, ResultDisposition::Flags rhs );
-
- bool shouldContinueOnFailure( int flags );
- inline bool isFalseTest( int flags ) { return ( flags & ResultDisposition::FalseTest ) != 0; }
- bool shouldSuppressFailure( int flags );
-
-} // end namespace Catch
-
-// end catch_result_type.h
-namespace Catch {
-
- struct AssertionInfo
- {
- StringRef macroName;
- SourceLineInfo lineInfo;
- StringRef capturedExpression;
- ResultDisposition::Flags resultDisposition;
-
- // We want to delete this constructor but a compiler bug in 4.8 means
- // the struct is then treated as non-aggregate
- //AssertionInfo() = delete;
- };
-
-} // end namespace Catch
-
-// end catch_assertioninfo.h
-// start catch_decomposer.h
-
-// start catch_tostring.h
-
-#include <vector>
-#include <cstddef>
-#include <type_traits>
-#include <string>
-// start catch_stream.h
-
-#include <iosfwd>
-#include <cstddef>
-#include <ostream>
-
-namespace Catch {
-
- std::ostream& cout();
- std::ostream& cerr();
- std::ostream& clog();
-
- class StringRef;
-
- struct IStream {
- virtual ~IStream();
- virtual std::ostream& stream() const = 0;
- };
-
- auto makeStream( StringRef const &filename ) -> IStream const*;
-
- class ReusableStringStream {
- std::size_t m_index;
- std::ostream* m_oss;
- public:
- ReusableStringStream();
- ~ReusableStringStream();
-
- auto str() const -> std::string;
-
- template<typename T>
- auto operator << ( T const& value ) -> ReusableStringStream& {
- *m_oss << value;
- return *this;
- }
- auto get() -> std::ostream& { return *m_oss; }
- };
-}
-
-// end catch_stream.h
-// start catch_interfaces_enum_values_registry.h
-
-#include <vector>
-
-namespace Catch {
-
- namespace Detail {
- struct EnumInfo {
- StringRef m_name;
- std::vector<std::pair<int, std::string>> m_values;
-
- ~EnumInfo();
-
- StringRef lookup( int value ) const;
- };
- } // namespace Detail
-
- struct IMutableEnumValuesRegistry {
- virtual ~IMutableEnumValuesRegistry();
-
- virtual Detail::EnumInfo const& registerEnum( StringRef enumName, StringRef allEnums, std::vector<int> const& values ) = 0;
-
- template<typename E>
- Detail::EnumInfo const& registerEnum( StringRef enumName, StringRef allEnums, std::initializer_list<E> values ) {
- std::vector<int> intValues;
- intValues.reserve( values.size() );
- for( auto enumValue : values )
- intValues.push_back( static_cast<int>( enumValue ) );
- return registerEnum( enumName, allEnums, intValues );
- }
- };
-
-} // Catch
-
-// end catch_interfaces_enum_values_registry.h
-
-#ifdef CATCH_CONFIG_CPP17_STRING_VIEW
-#include <string_view>
-#endif
-
-#ifdef __OBJC__
-// start catch_objc_arc.hpp
-
-#import <Foundation/Foundation.h>
-
-#ifdef __has_feature
-#define CATCH_ARC_ENABLED __has_feature(objc_arc)
-#else
-#define CATCH_ARC_ENABLED 0
-#endif
-
-void arcSafeRelease( NSObject* obj );
-id performOptionalSelector( id obj, SEL sel );
-
-#if !CATCH_ARC_ENABLED
-inline void arcSafeRelease( NSObject* obj ) {
- [obj release];
-}
-inline id performOptionalSelector( id obj, SEL sel ) {
- if( [obj respondsToSelector: sel] )
- return [obj performSelector: sel];
- return nil;
-}
-#define CATCH_UNSAFE_UNRETAINED
-#define CATCH_ARC_STRONG
-#else
-inline void arcSafeRelease( NSObject* ){}
-inline id performOptionalSelector( id obj, SEL sel ) {
-#ifdef __clang__
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
-#endif
- if( [obj respondsToSelector: sel] )
- return [obj performSelector: sel];
-#ifdef __clang__
-#pragma clang diagnostic pop
-#endif
- return nil;
-}
-#define CATCH_UNSAFE_UNRETAINED __unsafe_unretained
-#define CATCH_ARC_STRONG __strong
-#endif
-
-// end catch_objc_arc.hpp
-#endif
-
-#ifdef _MSC_VER
-#pragma warning(push)
-#pragma warning(disable:4180) // We attempt to stream a function (address) by const&, which MSVC complains about but is harmless
-#endif
-
-namespace Catch {
- namespace Detail {
-
- extern const std::string unprintableString;
-
- std::string rawMemoryToString( const void *object, std::size_t size );
-
- template<typename T>
- std::string rawMemoryToString( const T& object ) {
- return rawMemoryToString( &object, sizeof(object) );
- }
-
- template<typename T>
- class IsStreamInsertable {
- template<typename SS, typename TT>
- static auto test(int)
- -> decltype(std::declval<SS&>() << std::declval<TT>(), std::true_type());
-
- template<typename, typename>
- static auto test(...)->std::false_type;
-
- public:
- static const bool value = decltype(test<std::ostream, const T&>(0))::value;
- };
-
- template<typename E>
- std::string convertUnknownEnumToString( E e );
-
- template<typename T>
- typename std::enable_if<
- !std::is_enum<T>::value && !std::is_base_of<std::exception, T>::value,
- std::string>::type convertUnstreamable( T const& ) {
- return Detail::unprintableString;
- }
- template<typename T>
- typename std::enable_if<
- !std::is_enum<T>::value && std::is_base_of<std::exception, T>::value,
- std::string>::type convertUnstreamable(T const& ex) {
- return ex.what();
- }
-
- template<typename T>
- typename std::enable_if<
- std::is_enum<T>::value
- , std::string>::type convertUnstreamable( T const& value ) {
- return convertUnknownEnumToString( value );
- }
-
-#if defined(_MANAGED)
- //! Convert a CLR string to a utf8 std::string
- template<typename T>
- std::string clrReferenceToString( T^ ref ) {
- if (ref == nullptr)
- return std::string("null");
- auto bytes = System::Text::Encoding::UTF8->GetBytes(ref->ToString());
- cli::pin_ptr<System::Byte> p = &bytes[0];
- return std::string(reinterpret_cast<char const *>(p), bytes->Length);
- }
-#endif
-
- } // namespace Detail
-
- // If we decide for C++14, change these to enable_if_ts
- template <typename T, typename = void>
- struct StringMaker {
- template <typename Fake = T>
- static
- typename std::enable_if<::Catch::Detail::IsStreamInsertable<Fake>::value, std::string>::type
- convert(const Fake& value) {
- ReusableStringStream rss;
- // NB: call using the function-like syntax to avoid ambiguity with
- // user-defined templated operator<< under clang.
- rss.operator<<(value);
- return rss.str();
- }
-
- template <typename Fake = T>
- static
- typename std::enable_if<!::Catch::Detail::IsStreamInsertable<Fake>::value, std::string>::type
- convert( const Fake& value ) {
-#if !defined(CATCH_CONFIG_FALLBACK_STRINGIFIER)
- return Detail::convertUnstreamable(value);
-#else
- return CATCH_CONFIG_FALLBACK_STRINGIFIER(value);
-#endif
- }
- };
-
- namespace Detail {
-
- // This function dispatches all stringification requests inside of Catch.
- // Should be preferably called fully qualified, like ::Catch::Detail::stringify
- template <typename T>
- std::string stringify(const T& e) {
- return ::Catch::StringMaker<typename std::remove_cv<typename std::remove_reference<T>::type>::type>::convert(e);
- }
-
- template<typename E>
- std::string convertUnknownEnumToString( E e ) {
- return ::Catch::Detail::stringify(static_cast<typename std::underlying_type<E>::type>(e));
- }
-
-#if defined(_MANAGED)
- template <typename T>
- std::string stringify( T^ e ) {
- return ::Catch::StringMaker<T^>::convert(e);
- }
-#endif
-
- } // namespace Detail
-
- // Some predefined specializations
-
- template<>
- struct StringMaker<std::string> {
- static std::string convert(const std::string& str);
- };
-
-#ifdef CATCH_CONFIG_CPP17_STRING_VIEW
- template<>
- struct StringMaker<std::string_view> {
- static std::string convert(std::string_view str);
- };
-#endif
-
- template<>
- struct StringMaker<char const *> {
- static std::string convert(char const * str);
- };
- template<>
- struct StringMaker<char *> {
- static std::string convert(char * str);
- };
-
-#ifdef CATCH_CONFIG_WCHAR
- template<>
- struct StringMaker<std::wstring> {
- static std::string convert(const std::wstring& wstr);
- };
-
-# ifdef CATCH_CONFIG_CPP17_STRING_VIEW
- template<>
- struct StringMaker<std::wstring_view> {
- static std::string convert(std::wstring_view str);
- };
-# endif
-
- template<>
- struct StringMaker<wchar_t const *> {
- static std::string convert(wchar_t const * str);
- };
- template<>
- struct StringMaker<wchar_t *> {
- static std::string convert(wchar_t * str);
- };
-#endif
-
- // TBD: Should we use `strnlen` to ensure that we don't go out of the buffer,
- // while keeping string semantics?
- template<int SZ>
- struct StringMaker<char[SZ]> {
- static std::string convert(char const* str) {
- return ::Catch::Detail::stringify(std::string{ str });
- }
- };
- template<int SZ>
- struct StringMaker<signed char[SZ]> {
- static std::string convert(signed char const* str) {
- return ::Catch::Detail::stringify(std::string{ reinterpret_cast<char const *>(str) });
- }
- };
- template<int SZ>
- struct StringMaker<unsigned char[SZ]> {
- static std::string convert(unsigned char const* str) {
- return ::Catch::Detail::stringify(std::string{ reinterpret_cast<char const *>(str) });
- }
- };
-
- template<>
- struct StringMaker<int> {
- static std::string convert(int value);
- };
- template<>
- struct StringMaker<long> {
- static std::string convert(long value);
- };
- template<>
- struct StringMaker<long long> {
- static std::string convert(long long value);
- };
- template<>
- struct StringMaker<unsigned int> {
- static std::string convert(unsigned int value);
- };
- template<>
- struct StringMaker<unsigned long> {
- static std::string convert(unsigned long value);
- };
- template<>
- struct StringMaker<unsigned long long> {
- static std::string convert(unsigned long long value);
- };
-
- template<>
- struct StringMaker<bool> {
- static std::string convert(bool b);
- };
-
- template<>
- struct StringMaker<char> {
- static std::string convert(char c);
- };
- template<>
- struct StringMaker<signed char> {
- static std::string convert(signed char c);
- };
- template<>
- struct StringMaker<unsigned char> {
- static std::string convert(unsigned char c);
- };
-
- template<>
- struct StringMaker<std::nullptr_t> {
- static std::string convert(std::nullptr_t);
- };
-
- template<>
- struct StringMaker<float> {
- static std::string convert(float value);
- static int precision;
- };
-
- template<>
- struct StringMaker<double> {
- static std::string convert(double value);
- static int precision;
- };
-
- template <typename T>
- struct StringMaker<T*> {
- template <typename U>
- static std::string convert(U* p) {
- if (p) {
- return ::Catch::Detail::rawMemoryToString(p);
- } else {
- return "nullptr";
- }
- }
- };
-
- template <typename R, typename C>
- struct StringMaker<R C::*> {
- static std::string convert(R C::* p) {
- if (p) {
- return ::Catch::Detail::rawMemoryToString(p);
- } else {
- return "nullptr";
- }
- }
- };
-
-#if defined(_MANAGED)
- template <typename T>
- struct StringMaker<T^> {
- static std::string convert( T^ ref ) {
- return ::Catch::Detail::clrReferenceToString(ref);
- }
- };
-#endif
-
- namespace Detail {
- template<typename InputIterator>
- std::string rangeToString(InputIterator first, InputIterator last) {
- ReusableStringStream rss;
- rss << "{ ";
- if (first != last) {
- rss << ::Catch::Detail::stringify(*first);
- for (++first; first != last; ++first)
- rss << ", " << ::Catch::Detail::stringify(*first);
- }
- rss << " }";
- return rss.str();
- }
- }
-
-#ifdef __OBJC__
- template<>
- struct StringMaker<NSString*> {
- static std::string convert(NSString * nsstring) {
- if (!nsstring)
- return "nil";
- return std::string("@") + [nsstring UTF8String];
- }
- };
- template<>
- struct StringMaker<NSObject*> {
- static std::string convert(NSObject* nsObject) {
- return ::Catch::Detail::stringify([nsObject description]);
- }
-
- };
- namespace Detail {
- inline std::string stringify( NSString* nsstring ) {
- return StringMaker<NSString*>::convert( nsstring );
- }
-
- } // namespace Detail
-#endif // __OBJC__
-
-} // namespace Catch
-
-//////////////////////////////////////////////////////
-// Separate std-lib types stringification, so it can be selectively enabled
-// This means that we do not bring in
-
-#if defined(CATCH_CONFIG_ENABLE_ALL_STRINGMAKERS)
-# define CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER
-# define CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER
-# define CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER
-# define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
-# define CATCH_CONFIG_ENABLE_OPTIONAL_STRINGMAKER
-#endif
-
-// Separate std::pair specialization
-#if defined(CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER)
-#include <utility>
-namespace Catch {
- template<typename T1, typename T2>
- struct StringMaker<std::pair<T1, T2> > {
- static std::string convert(const std::pair<T1, T2>& pair) {
- ReusableStringStream rss;
- rss << "{ "
- << ::Catch::Detail::stringify(pair.first)
- << ", "
- << ::Catch::Detail::stringify(pair.second)
- << " }";
- return rss.str();
- }
- };
-}
-#endif // CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER
-
-#if defined(CATCH_CONFIG_ENABLE_OPTIONAL_STRINGMAKER) && defined(CATCH_CONFIG_CPP17_OPTIONAL)
-#include <optional>
-namespace Catch {
- template<typename T>
- struct StringMaker<std::optional<T> > {
- static std::string convert(const std::optional<T>& optional) {
- ReusableStringStream rss;
- if (optional.has_value()) {
- rss << ::Catch::Detail::stringify(*optional);
- } else {
- rss << "{ }";
- }
- return rss.str();
- }
- };
-}
-#endif // CATCH_CONFIG_ENABLE_OPTIONAL_STRINGMAKER
-
-// Separate std::tuple specialization
-#if defined(CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER)
-#include <tuple>
-namespace Catch {
- namespace Detail {
- template<
- typename Tuple,
- std::size_t N = 0,
- bool = (N < std::tuple_size<Tuple>::value)
- >
- struct TupleElementPrinter {
- static void print(const Tuple& tuple, std::ostream& os) {
- os << (N ? ", " : " ")
- << ::Catch::Detail::stringify(std::get<N>(tuple));
- TupleElementPrinter<Tuple, N + 1>::print(tuple, os);
- }
- };
-
- template<
- typename Tuple,
- std::size_t N
- >
- struct TupleElementPrinter<Tuple, N, false> {
- static void print(const Tuple&, std::ostream&) {}
- };
-
- }
-
- template<typename ...Types>
- struct StringMaker<std::tuple<Types...>> {
- static std::string convert(const std::tuple<Types...>& tuple) {
- ReusableStringStream rss;
- rss << '{';
- Detail::TupleElementPrinter<std::tuple<Types...>>::print(tuple, rss.get());
- rss << " }";
- return rss.str();
- }
- };
-}
-#endif // CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER
-
-#if defined(CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER) && defined(CATCH_CONFIG_CPP17_VARIANT)
-#include <variant>
-namespace Catch {
- template<>
- struct StringMaker<std::monostate> {
- static std::string convert(const std::monostate&) {
- return "{ }";
- }
- };
-
- template<typename... Elements>
- struct StringMaker<std::variant<Elements...>> {
- static std::string convert(const std::variant<Elements...>& variant) {
- if (variant.valueless_by_exception()) {
- return "{valueless variant}";
- } else {
- return std::visit(
- [](const auto& value) {
- return ::Catch::Detail::stringify(value);
- },
- variant
- );
- }
- }
- };
-}
-#endif // CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER
-
-namespace Catch {
- struct not_this_one {}; // Tag type for detecting which begin/ end are being selected
-
- // Import begin/ end from std here so they are considered alongside the fallback (...) overloads in this namespace
- using std::begin;
- using std::end;
-
- not_this_one begin( ... );
- not_this_one end( ... );
-
- template <typename T>
- struct is_range {
- static const bool value =
- !std::is_same<decltype(begin(std::declval<T>())), not_this_one>::value &&
- !std::is_same<decltype(end(std::declval<T>())), not_this_one>::value;
- };
-
-#if defined(_MANAGED) // Managed types are never ranges
- template <typename T>
- struct is_range<T^> {
- static const bool value = false;
- };
-#endif
-
- template<typename Range>
- std::string rangeToString( Range const& range ) {
- return ::Catch::Detail::rangeToString( begin( range ), end( range ) );
- }
-
- // Handle vector<bool> specially
- template<typename Allocator>
- std::string rangeToString( std::vector<bool, Allocator> const& v ) {
- ReusableStringStream rss;
- rss << "{ ";
- bool first = true;
- for( bool b : v ) {
- if( first )
- first = false;
- else
- rss << ", ";
- rss << ::Catch::Detail::stringify( b );
- }
- rss << " }";
- return rss.str();
- }
-
- template<typename R>
- struct StringMaker<R, typename std::enable_if<is_range<R>::value && !::Catch::Detail::IsStreamInsertable<R>::value>::type> {
- static std::string convert( R const& range ) {
- return rangeToString( range );
- }
- };
-
- template <typename T, int SZ>
- struct StringMaker<T[SZ]> {
- static std::string convert(T const(&arr)[SZ]) {
- return rangeToString(arr);
- }
- };
-
-} // namespace Catch
-
-// Separate std::chrono::duration specialization
-#if defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER)
-#include <ctime>
-#include <ratio>
-#include <chrono>
-
-namespace Catch {
-
-template <class Ratio>
-struct ratio_string {
- static std::string symbol();
-};
-
-template <class Ratio>
-std::string ratio_string<Ratio>::symbol() {
- Catch::ReusableStringStream rss;
- rss << '[' << Ratio::num << '/'
- << Ratio::den << ']';
- return rss.str();
-}
-template <>
-struct ratio_string<std::atto> {
- static std::string symbol();
-};
-template <>
-struct ratio_string<std::femto> {
- static std::string symbol();
-};
-template <>
-struct ratio_string<std::pico> {
- static std::string symbol();
-};
-template <>
-struct ratio_string<std::nano> {
- static std::string symbol();
-};
-template <>
-struct ratio_string<std::micro> {
- static std::string symbol();
-};
-template <>
-struct ratio_string<std::milli> {
- static std::string symbol();
-};
-
- ////////////
- // std::chrono::duration specializations
- template<typename Value, typename Ratio>
- struct StringMaker<std::chrono::duration<Value, Ratio>> {
- static std::string convert(std::chrono::duration<Value, Ratio> const& duration) {
- ReusableStringStream rss;
- rss << duration.count() << ' ' << ratio_string<Ratio>::symbol() << 's';
- return rss.str();
- }
- };
- template<typename Value>
- struct StringMaker<std::chrono::duration<Value, std::ratio<1>>> {
- static std::string convert(std::chrono::duration<Value, std::ratio<1>> const& duration) {
- ReusableStringStream rss;
- rss << duration.count() << " s";
- return rss.str();
- }
- };
- template<typename Value>
- struct StringMaker<std::chrono::duration<Value, std::ratio<60>>> {
- static std::string convert(std::chrono::duration<Value, std::ratio<60>> const& duration) {
- ReusableStringStream rss;
- rss << duration.count() << " m";
- return rss.str();
- }
- };
- template<typename Value>
- struct StringMaker<std::chrono::duration<Value, std::ratio<3600>>> {
- static std::string convert(std::chrono::duration<Value, std::ratio<3600>> const& duration) {
- ReusableStringStream rss;
- rss << duration.count() << " h";
- return rss.str();
- }
- };
-
- ////////////
- // std::chrono::time_point specialization
- // Generic time_point cannot be specialized, only std::chrono::time_point<system_clock>
- template<typename Clock, typename Duration>
- struct StringMaker<std::chrono::time_point<Clock, Duration>> {
- static std::string convert(std::chrono::time_point<Clock, Duration> const& time_point) {
- return ::Catch::Detail::stringify(time_point.time_since_epoch()) + " since epoch";
- }
- };
- // std::chrono::time_point<system_clock> specialization
- template<typename Duration>
- struct StringMaker<std::chrono::time_point<std::chrono::system_clock, Duration>> {
- static std::string convert(std::chrono::time_point<std::chrono::system_clock, Duration> const& time_point) {
- auto converted = std::chrono::system_clock::to_time_t(time_point);
-
-#ifdef _MSC_VER
- std::tm timeInfo = {};
- gmtime_s(&timeInfo, &converted);
-#else
- std::tm* timeInfo = std::gmtime(&converted);
-#endif
-
- auto const timeStampSize = sizeof("2017-01-16T17:06:45Z");
- char timeStamp[timeStampSize];
- const char * const fmt = "%Y-%m-%dT%H:%M:%SZ";
-
-#ifdef _MSC_VER
- std::strftime(timeStamp, timeStampSize, fmt, &timeInfo);
-#else
- std::strftime(timeStamp, timeStampSize, fmt, timeInfo);
-#endif
- return std::string(timeStamp);
- }
- };
-}
-#endif // CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
-
-#define INTERNAL_CATCH_REGISTER_ENUM( enumName, ... ) \
-namespace Catch { \
- template<> struct StringMaker<enumName> { \
- static std::string convert( enumName value ) { \
- static const auto& enumInfo = ::Catch::getMutableRegistryHub().getMutableEnumValuesRegistry().registerEnum( #enumName, #__VA_ARGS__, { __VA_ARGS__ } ); \
- return enumInfo.lookup( static_cast<int>( value ) ); \
- } \
- }; \
-}
-
-#define CATCH_REGISTER_ENUM( enumName, ... ) INTERNAL_CATCH_REGISTER_ENUM( enumName, __VA_ARGS__ )
-
-#ifdef _MSC_VER
-#pragma warning(pop)
-#endif
-
-// end catch_tostring.h
-#include <iosfwd>
-
-#ifdef _MSC_VER
-#pragma warning(push)
-#pragma warning(disable:4389) // '==' : signed/unsigned mismatch
-#pragma warning(disable:4018) // more "signed/unsigned mismatch"
-#pragma warning(disable:4312) // Converting int to T* using reinterpret_cast (issue on x64 platform)
-#pragma warning(disable:4180) // qualifier applied to function type has no meaning
-#pragma warning(disable:4800) // Forcing result to true or false
-#endif
-
-namespace Catch {
-
- struct ITransientExpression {
- auto isBinaryExpression() const -> bool { return m_isBinaryExpression; }
- auto getResult() const -> bool { return m_result; }
- virtual void streamReconstructedExpression( std::ostream &os ) const = 0;
-
- ITransientExpression( bool isBinaryExpression, bool result )
- : m_isBinaryExpression( isBinaryExpression ),
- m_result( result )
- {}
-
- // We don't actually need a virtual destructor, but many static analysers
- // complain if it's not here :-(
- virtual ~ITransientExpression();
-
- bool m_isBinaryExpression;
- bool m_result;
-
- };
-
- void formatReconstructedExpression( std::ostream &os, std::string const& lhs, StringRef op, std::string const& rhs );
-
- template<typename LhsT, typename RhsT>
- class BinaryExpr : public ITransientExpression {
- LhsT m_lhs;
- StringRef m_op;
- RhsT m_rhs;
-
- void streamReconstructedExpression( std::ostream &os ) const override {
- formatReconstructedExpression
- ( os, Catch::Detail::stringify( m_lhs ), m_op, Catch::Detail::stringify( m_rhs ) );
- }
-
- public:
- BinaryExpr( bool comparisonResult, LhsT lhs, StringRef op, RhsT rhs )
- : ITransientExpression{ true, comparisonResult },
- m_lhs( lhs ),
- m_op( op ),
- m_rhs( rhs )
- {}
-
- template<typename T>
- auto operator && ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
- static_assert(always_false<T>::value,
- "chained comparisons are not supported inside assertions, "
- "wrap the expression inside parentheses, or decompose it");
- }
-
- template<typename T>
- auto operator || ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
- static_assert(always_false<T>::value,
- "chained comparisons are not supported inside assertions, "
- "wrap the expression inside parentheses, or decompose it");
- }
-
- template<typename T>
- auto operator == ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
- static_assert(always_false<T>::value,
- "chained comparisons are not supported inside assertions, "
- "wrap the expression inside parentheses, or decompose it");
- }
-
- template<typename T>
- auto operator != ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
- static_assert(always_false<T>::value,
- "chained comparisons are not supported inside assertions, "
- "wrap the expression inside parentheses, or decompose it");
- }
-
- template<typename T>
- auto operator > ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
- static_assert(always_false<T>::value,
- "chained comparisons are not supported inside assertions, "
- "wrap the expression inside parentheses, or decompose it");
- }
-
- template<typename T>
- auto operator < ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
- static_assert(always_false<T>::value,
- "chained comparisons are not supported inside assertions, "
- "wrap the expression inside parentheses, or decompose it");
- }
-
- template<typename T>
- auto operator >= ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
- static_assert(always_false<T>::value,
- "chained comparisons are not supported inside assertions, "
- "wrap the expression inside parentheses, or decompose it");
- }
-
- template<typename T>
- auto operator <= ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
- static_assert(always_false<T>::value,
- "chained comparisons are not supported inside assertions, "
- "wrap the expression inside parentheses, or decompose it");
- }
- };
-
- template<typename LhsT>
- class UnaryExpr : public ITransientExpression {
- LhsT m_lhs;
-
- void streamReconstructedExpression( std::ostream &os ) const override {
- os << Catch::Detail::stringify( m_lhs );
- }
-
- public:
- explicit UnaryExpr( LhsT lhs )
- : ITransientExpression{ false, static_cast<bool>(lhs) },
- m_lhs( lhs )
- {}
- };
-
- // Specialised comparison functions to handle equality comparisons between ints and pointers (NULL deduces as an int)
- template<typename LhsT, typename RhsT>
- auto compareEqual( LhsT const& lhs, RhsT const& rhs ) -> bool { return static_cast<bool>(lhs == rhs); }
- template<typename T>
- auto compareEqual( T* const& lhs, int rhs ) -> bool { return lhs == reinterpret_cast<void const*>( rhs ); }
- template<typename T>
- auto compareEqual( T* const& lhs, long rhs ) -> bool { return lhs == reinterpret_cast<void const*>( rhs ); }
- template<typename T>
- auto compareEqual( int lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) == rhs; }
- template<typename T>
- auto compareEqual( long lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) == rhs; }
-
- template<typename LhsT, typename RhsT>
- auto compareNotEqual( LhsT const& lhs, RhsT&& rhs ) -> bool { return static_cast<bool>(lhs != rhs); }
- template<typename T>
- auto compareNotEqual( T* const& lhs, int rhs ) -> bool { return lhs != reinterpret_cast<void const*>( rhs ); }
- template<typename T>
- auto compareNotEqual( T* const& lhs, long rhs ) -> bool { return lhs != reinterpret_cast<void const*>( rhs ); }
- template<typename T>
- auto compareNotEqual( int lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) != rhs; }
- template<typename T>
- auto compareNotEqual( long lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) != rhs; }
-
- template<typename LhsT>
- class ExprLhs {
- LhsT m_lhs;
- public:
- explicit ExprLhs( LhsT lhs ) : m_lhs( lhs ) {}
-
- template<typename RhsT>
- auto operator == ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
- return { compareEqual( m_lhs, rhs ), m_lhs, "==", rhs };
- }
- auto operator == ( bool rhs ) -> BinaryExpr<LhsT, bool> const {
- return { m_lhs == rhs, m_lhs, "==", rhs };
- }
-
- template<typename RhsT>
- auto operator != ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
- return { compareNotEqual( m_lhs, rhs ), m_lhs, "!=", rhs };
- }
- auto operator != ( bool rhs ) -> BinaryExpr<LhsT, bool> const {
- return { m_lhs != rhs, m_lhs, "!=", rhs };
- }
-
- template<typename RhsT>
- auto operator > ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
- return { static_cast<bool>(m_lhs > rhs), m_lhs, ">", rhs };
- }
- template<typename RhsT>
- auto operator < ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
- return { static_cast<bool>(m_lhs < rhs), m_lhs, "<", rhs };
- }
- template<typename RhsT>
- auto operator >= ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
- return { static_cast<bool>(m_lhs >= rhs), m_lhs, ">=", rhs };
- }
- template<typename RhsT>
- auto operator <= ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
- return { static_cast<bool>(m_lhs <= rhs), m_lhs, "<=", rhs };
- }
-
- template<typename RhsT>
- auto operator && ( RhsT const& ) -> BinaryExpr<LhsT, RhsT const&> const {
- static_assert(always_false<RhsT>::value,
- "operator&& is not supported inside assertions, "
- "wrap the expression inside parentheses, or decompose it");
- }
-
- template<typename RhsT>
- auto operator || ( RhsT const& ) -> BinaryExpr<LhsT, RhsT const&> const {
- static_assert(always_false<RhsT>::value,
- "operator|| is not supported inside assertions, "
- "wrap the expression inside parentheses, or decompose it");
- }
-
- auto makeUnaryExpr() const -> UnaryExpr<LhsT> {
- return UnaryExpr<LhsT>{ m_lhs };
- }
- };
-
- void handleExpression( ITransientExpression const& expr );
-
- template<typename T>
- void handleExpression( ExprLhs<T> const& expr ) {
- handleExpression( expr.makeUnaryExpr() );
- }
-
- struct Decomposer {
- template<typename T>
- auto operator <= ( T const& lhs ) -> ExprLhs<T const&> {
- return ExprLhs<T const&>{ lhs };
- }
-
- auto operator <=( bool value ) -> ExprLhs<bool> {
- return ExprLhs<bool>{ value };
- }
- };
-
-} // end namespace Catch
-
-#ifdef _MSC_VER
-#pragma warning(pop)
-#endif
-
-// end catch_decomposer.h
-// start catch_interfaces_capture.h
-
-#include <string>
-#include <chrono>
-
-namespace Catch {
-
- class AssertionResult;
- struct AssertionInfo;
- struct SectionInfo;
- struct SectionEndInfo;
- struct MessageInfo;
- struct MessageBuilder;
- struct Counts;
- struct AssertionReaction;
- struct SourceLineInfo;
-
- struct ITransientExpression;
- struct IGeneratorTracker;
-
-#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
- struct BenchmarkInfo;
- template <typename Duration = std::chrono::duration<double, std::nano>>
- struct BenchmarkStats;
-#endif // CATCH_CONFIG_ENABLE_BENCHMARKING
-
- struct IResultCapture {
-
- virtual ~IResultCapture();
-
- virtual bool sectionStarted( SectionInfo const& sectionInfo,
- Counts& assertions ) = 0;
- virtual void sectionEnded( SectionEndInfo const& endInfo ) = 0;
- virtual void sectionEndedEarly( SectionEndInfo const& endInfo ) = 0;
-
- virtual auto acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker& = 0;
-
-#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
- virtual void benchmarkPreparing( std::string const& name ) = 0;
- virtual void benchmarkStarting( BenchmarkInfo const& info ) = 0;
- virtual void benchmarkEnded( BenchmarkStats<> const& stats ) = 0;
- virtual void benchmarkFailed( std::string const& error ) = 0;
-#endif // CATCH_CONFIG_ENABLE_BENCHMARKING
-
- virtual void pushScopedMessage( MessageInfo const& message ) = 0;
- virtual void popScopedMessage( MessageInfo const& message ) = 0;
-
- virtual void emplaceUnscopedMessage( MessageBuilder const& builder ) = 0;
-
- virtual void handleFatalErrorCondition( StringRef message ) = 0;
-
- virtual void handleExpr
- ( AssertionInfo const& info,
- ITransientExpression const& expr,
- AssertionReaction& reaction ) = 0;
- virtual void handleMessage
- ( AssertionInfo const& info,
- ResultWas::OfType resultType,
- StringRef const& message,
- AssertionReaction& reaction ) = 0;
- virtual void handleUnexpectedExceptionNotThrown
- ( AssertionInfo const& info,
- AssertionReaction& reaction ) = 0;
- virtual void handleUnexpectedInflightException
- ( AssertionInfo const& info,
- std::string const& message,
- AssertionReaction& reaction ) = 0;
- virtual void handleIncomplete
- ( AssertionInfo const& info ) = 0;
- virtual void handleNonExpr
- ( AssertionInfo const &info,
- ResultWas::OfType resultType,
- AssertionReaction &reaction ) = 0;
-
- virtual bool lastAssertionPassed() = 0;
- virtual void assertionPassed() = 0;
-
- // Deprecated, do not use:
- virtual std::string getCurrentTestName() const = 0;
- virtual const AssertionResult* getLastResult() const = 0;
- virtual void exceptionEarlyReported() = 0;
- };
-
- IResultCapture& getResultCapture();
-}
-
-// end catch_interfaces_capture.h
-namespace Catch {
-
- struct TestFailureException{};
- struct AssertionResultData;
- struct IResultCapture;
- class RunContext;
-
- class LazyExpression {
- friend class AssertionHandler;
- friend struct AssertionStats;
- friend class RunContext;
-
- ITransientExpression const* m_transientExpression = nullptr;
- bool m_isNegated;
- public:
- LazyExpression( bool isNegated );
- LazyExpression( LazyExpression const& other );
- LazyExpression& operator = ( LazyExpression const& ) = delete;
-
- explicit operator bool() const;
-
- friend auto operator << ( std::ostream& os, LazyExpression const& lazyExpr ) -> std::ostream&;
- };
-
- struct AssertionReaction {
- bool shouldDebugBreak = false;
- bool shouldThrow = false;
- };
-
- class AssertionHandler {
- AssertionInfo m_assertionInfo;
- AssertionReaction m_reaction;
- bool m_completed = false;
- IResultCapture& m_resultCapture;
-
- public:
- AssertionHandler
- ( StringRef const& macroName,
- SourceLineInfo const& lineInfo,
- StringRef capturedExpression,
- ResultDisposition::Flags resultDisposition );
- ~AssertionHandler() {
- if ( !m_completed ) {
- m_resultCapture.handleIncomplete( m_assertionInfo );
- }
- }
-
- template<typename T>
- void handleExpr( ExprLhs<T> const& expr ) {
- handleExpr( expr.makeUnaryExpr() );
- }
- void handleExpr( ITransientExpression const& expr );
-
- void handleMessage(ResultWas::OfType resultType, StringRef const& message);
-
- void handleExceptionThrownAsExpected();
- void handleUnexpectedExceptionNotThrown();
- void handleExceptionNotThrownAsExpected();
- void handleThrowingCallSkipped();
- void handleUnexpectedInflightException();
-
- void complete();
- void setCompleted();
-
- // query
- auto allowThrows() const -> bool;
- };
-
- void handleExceptionMatchExpr( AssertionHandler& handler, std::string const& str, StringRef const& matcherString );
-
-} // namespace Catch
-
-// end catch_assertionhandler.h
-// start catch_message.h
-
-#include <string>
-#include <vector>
-
-namespace Catch {
-
- struct MessageInfo {
- MessageInfo( StringRef const& _macroName,
- SourceLineInfo const& _lineInfo,
- ResultWas::OfType _type );
-
- StringRef macroName;
- std::string message;
- SourceLineInfo lineInfo;
- ResultWas::OfType type;
- unsigned int sequence;
-
- bool operator == ( MessageInfo const& other ) const;
- bool operator < ( MessageInfo const& other ) const;
- private:
- static unsigned int globalCount;
- };
-
- struct MessageStream {
-
- template<typename T>
- MessageStream& operator << ( T const& value ) {
- m_stream << value;
- return *this;
- }
-
- ReusableStringStream m_stream;
- };
-
- struct MessageBuilder : MessageStream {
- MessageBuilder( StringRef const& macroName,
- SourceLineInfo const& lineInfo,
- ResultWas::OfType type );
-
- template<typename T>
- MessageBuilder& operator << ( T const& value ) {
- m_stream << value;
- return *this;
- }
-
- MessageInfo m_info;
- };
-
- class ScopedMessage {
- public:
- explicit ScopedMessage( MessageBuilder const& builder );
- ScopedMessage( ScopedMessage& duplicate ) = delete;
- ScopedMessage( ScopedMessage&& old );
- ~ScopedMessage();
-
- MessageInfo m_info;
- bool m_moved;
- };
-
- class Capturer {
- std::vector<MessageInfo> m_messages;
- IResultCapture& m_resultCapture = getResultCapture();
- size_t m_captured = 0;
- public:
- Capturer( StringRef macroName, SourceLineInfo const& lineInfo, ResultWas::OfType resultType, StringRef names );
- ~Capturer();
-
- void captureValue( size_t index, std::string const& value );
-
- template<typename T>
- void captureValues( size_t index, T const& value ) {
- captureValue( index, Catch::Detail::stringify( value ) );
- }
-
- template<typename T, typename... Ts>
- void captureValues( size_t index, T const& value, Ts const&... values ) {
- captureValue( index, Catch::Detail::stringify(value) );
- captureValues( index+1, values... );
- }
- };
-
-} // end namespace Catch
-
-// end catch_message.h
-#if !defined(CATCH_CONFIG_DISABLE)
-
-#if !defined(CATCH_CONFIG_DISABLE_STRINGIFICATION)
- #define CATCH_INTERNAL_STRINGIFY(...) #__VA_ARGS__
-#else
- #define CATCH_INTERNAL_STRINGIFY(...) "Disabled by CATCH_CONFIG_DISABLE_STRINGIFICATION"
-#endif
-
-#if defined(CATCH_CONFIG_FAST_COMPILE) || defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
-
-///////////////////////////////////////////////////////////////////////////////
-// Another way to speed-up compilation is to omit local try-catch for REQUIRE*
-// macros.
-#define INTERNAL_CATCH_TRY
-#define INTERNAL_CATCH_CATCH( capturer )
-
-#else // CATCH_CONFIG_FAST_COMPILE
-
-#define INTERNAL_CATCH_TRY try
-#define INTERNAL_CATCH_CATCH( handler ) catch(...) { handler.handleUnexpectedInflightException(); }
-
-#endif
-
-#define INTERNAL_CATCH_REACT( handler ) handler.complete();
-
-///////////////////////////////////////////////////////////////////////////////
-#define INTERNAL_CATCH_TEST( macroName, resultDisposition, ... ) \
- do { \
- Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition ); \
- INTERNAL_CATCH_TRY { \
- CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
- catchAssertionHandler.handleExpr( Catch::Decomposer() <= __VA_ARGS__ ); \
- CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \
- } INTERNAL_CATCH_CATCH( catchAssertionHandler ) \
- INTERNAL_CATCH_REACT( catchAssertionHandler ) \
- } while( (void)0, (false) && static_cast<bool>( !!(__VA_ARGS__) ) ) // the expression here is never evaluated at runtime but it forces the compiler to give it a look
- // The double negation silences MSVC's C4800 warning, the static_cast forces short-circuit evaluation if the type has overloaded &&.
-
-///////////////////////////////////////////////////////////////////////////////
-#define INTERNAL_CATCH_IF( macroName, resultDisposition, ... ) \
- INTERNAL_CATCH_TEST( macroName, resultDisposition, __VA_ARGS__ ); \
- if( Catch::getResultCapture().lastAssertionPassed() )
-
-///////////////////////////////////////////////////////////////////////////////
-#define INTERNAL_CATCH_ELSE( macroName, resultDisposition, ... ) \
- INTERNAL_CATCH_TEST( macroName, resultDisposition, __VA_ARGS__ ); \
- if( !Catch::getResultCapture().lastAssertionPassed() )
-
-///////////////////////////////////////////////////////////////////////////////
-#define INTERNAL_CATCH_NO_THROW( macroName, resultDisposition, ... ) \
- do { \
- Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition ); \
- try { \
- static_cast<void>(__VA_ARGS__); \
- catchAssertionHandler.handleExceptionNotThrownAsExpected(); \
- } \
- catch( ... ) { \
- catchAssertionHandler.handleUnexpectedInflightException(); \
- } \
- INTERNAL_CATCH_REACT( catchAssertionHandler ) \
- } while( false )
-
-///////////////////////////////////////////////////////////////////////////////
-#define INTERNAL_CATCH_THROWS( macroName, resultDisposition, ... ) \
- do { \
- Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition); \
- if( catchAssertionHandler.allowThrows() ) \
- try { \
- static_cast<void>(__VA_ARGS__); \
- catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
- } \
- catch( ... ) { \
- catchAssertionHandler.handleExceptionThrownAsExpected(); \
- } \
- else \
- catchAssertionHandler.handleThrowingCallSkipped(); \
- INTERNAL_CATCH_REACT( catchAssertionHandler ) \
- } while( false )
-
-///////////////////////////////////////////////////////////////////////////////
-#define INTERNAL_CATCH_THROWS_AS( macroName, exceptionType, resultDisposition, expr ) \
- do { \
- Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(expr) ", " CATCH_INTERNAL_STRINGIFY(exceptionType), resultDisposition ); \
- if( catchAssertionHandler.allowThrows() ) \
- try { \
- static_cast<void>(expr); \
- catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
- } \
- catch( exceptionType const& ) { \
- catchAssertionHandler.handleExceptionThrownAsExpected(); \
- } \
- catch( ... ) { \
- catchAssertionHandler.handleUnexpectedInflightException(); \
- } \
- else \
- catchAssertionHandler.handleThrowingCallSkipped(); \
- INTERNAL_CATCH_REACT( catchAssertionHandler ) \
- } while( false )
-
-///////////////////////////////////////////////////////////////////////////////
-#define INTERNAL_CATCH_MSG( macroName, messageType, resultDisposition, ... ) \
- do { \
- Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::StringRef(), resultDisposition ); \
- catchAssertionHandler.handleMessage( messageType, ( Catch::MessageStream() << __VA_ARGS__ + ::Catch::StreamEndStop() ).m_stream.str() ); \
- INTERNAL_CATCH_REACT( catchAssertionHandler ) \
- } while( false )
-
-///////////////////////////////////////////////////////////////////////////////
-#define INTERNAL_CATCH_CAPTURE( varName, macroName, ... ) \
- auto varName = Catch::Capturer( macroName, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info, #__VA_ARGS__ ); \
- varName.captureValues( 0, __VA_ARGS__ )
-
-///////////////////////////////////////////////////////////////////////////////
-#define INTERNAL_CATCH_INFO( macroName, log ) \
- Catch::ScopedMessage INTERNAL_CATCH_UNIQUE_NAME( scopedMessage )( Catch::MessageBuilder( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log );
-
-///////////////////////////////////////////////////////////////////////////////
-#define INTERNAL_CATCH_UNSCOPED_INFO( macroName, log ) \
- Catch::getResultCapture().emplaceUnscopedMessage( Catch::MessageBuilder( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log )
-
-///////////////////////////////////////////////////////////////////////////////
-// Although this is matcher-based, it can be used with just a string
-#define INTERNAL_CATCH_THROWS_STR_MATCHES( macroName, resultDisposition, matcher, ... ) \
- do { \
- Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
- if( catchAssertionHandler.allowThrows() ) \
- try { \
- static_cast<void>(__VA_ARGS__); \
- catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
- } \
- catch( ... ) { \
- Catch::handleExceptionMatchExpr( catchAssertionHandler, matcher, #matcher##_catch_sr ); \
- } \
- else \
- catchAssertionHandler.handleThrowingCallSkipped(); \
- INTERNAL_CATCH_REACT( catchAssertionHandler ) \
- } while( false )
-
-#endif // CATCH_CONFIG_DISABLE
-
-// end catch_capture.hpp
-// start catch_section.h
-
-// start catch_section_info.h
-
-// start catch_totals.h
-
-#include <cstddef>
-
-namespace Catch {
-
- struct Counts {
- Counts operator - ( Counts const& other ) const;
- Counts& operator += ( Counts const& other );
-
- std::size_t total() const;
- bool allPassed() const;
- bool allOk() const;
-
- std::size_t passed = 0;
- std::size_t failed = 0;
- std::size_t failedButOk = 0;
- };
-
- struct Totals {
-
- Totals operator - ( Totals const& other ) const;
- Totals& operator += ( Totals const& other );
-
- Totals delta( Totals const& prevTotals ) const;
-
- int error = 0;
- Counts assertions;
- Counts testCases;
- };
-}
-
-// end catch_totals.h
-#include <string>
-
-namespace Catch {
-
- struct SectionInfo {
- SectionInfo
- ( SourceLineInfo const& _lineInfo,
- std::string const& _name );
-
- // Deprecated
- SectionInfo
- ( SourceLineInfo const& _lineInfo,
- std::string const& _name,
- std::string const& ) : SectionInfo( _lineInfo, _name ) {}
-
- std::string name;
- std::string description; // !Deprecated: this will always be empty
- SourceLineInfo lineInfo;
- };
-
- struct SectionEndInfo {
- SectionInfo sectionInfo;
- Counts prevAssertions;
- double durationInSeconds;
- };
-
-} // end namespace Catch
-
-// end catch_section_info.h
-// start catch_timer.h
-
-#include <cstdint>
-
-namespace Catch {
-
- auto getCurrentNanosecondsSinceEpoch() -> uint64_t;
- auto getEstimatedClockResolution() -> uint64_t;
-
- class Timer {
- uint64_t m_nanoseconds = 0;
- public:
- void start();
- auto getElapsedNanoseconds() const -> uint64_t;
- auto getElapsedMicroseconds() const -> uint64_t;
- auto getElapsedMilliseconds() const -> unsigned int;
- auto getElapsedSeconds() const -> double;
- };
-
-} // namespace Catch
-
-// end catch_timer.h
-#include <string>
-
-namespace Catch {
-
- class Section : NonCopyable {
- public:
- Section( SectionInfo const& info );
- ~Section();
-
- // This indicates whether the section should be executed or not
- explicit operator bool() const;
-
- private:
- SectionInfo m_info;
-
- std::string m_name;
- Counts m_assertions;
- bool m_sectionIncluded;
- Timer m_timer;
- };
-
-} // end namespace Catch
-
-#define INTERNAL_CATCH_SECTION( ... ) \
- CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \
- if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, __VA_ARGS__ ) ) \
- CATCH_INTERNAL_UNSUPPRESS_UNUSED_WARNINGS
-
-#define INTERNAL_CATCH_DYNAMIC_SECTION( ... ) \
- CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \
- if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, (Catch::ReusableStringStream() << __VA_ARGS__).str() ) ) \
- CATCH_INTERNAL_UNSUPPRESS_UNUSED_WARNINGS
-
-// end catch_section.h
-// start catch_interfaces_exception.h
-
-// start catch_interfaces_registry_hub.h
-
-#include <string>
-#include <memory>
-
-namespace Catch {
-
- class TestCase;
- struct ITestCaseRegistry;
- struct IExceptionTranslatorRegistry;
- struct IExceptionTranslator;
- struct IReporterRegistry;
- struct IReporterFactory;
- struct ITagAliasRegistry;
- struct IMutableEnumValuesRegistry;
-
- class StartupExceptionRegistry;
-
- using IReporterFactoryPtr = std::shared_ptr<IReporterFactory>;
-
- struct IRegistryHub {
- virtual ~IRegistryHub();
-
- virtual IReporterRegistry const& getReporterRegistry() const = 0;
- virtual ITestCaseRegistry const& getTestCaseRegistry() const = 0;
- virtual ITagAliasRegistry const& getTagAliasRegistry() const = 0;
- virtual IExceptionTranslatorRegistry const& getExceptionTranslatorRegistry() const = 0;
-
- virtual StartupExceptionRegistry const& getStartupExceptionRegistry() const = 0;
- };
-
- struct IMutableRegistryHub {
- virtual ~IMutableRegistryHub();
- virtual void registerReporter( std::string const& name, IReporterFactoryPtr const& factory ) = 0;
- virtual void registerListener( IReporterFactoryPtr const& factory ) = 0;
- virtual void registerTest( TestCase const& testInfo ) = 0;
- virtual void registerTranslator( const IExceptionTranslator* translator ) = 0;
- virtual void registerTagAlias( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) = 0;
- virtual void registerStartupException() noexcept = 0;
- virtual IMutableEnumValuesRegistry& getMutableEnumValuesRegistry() = 0;
- };
-
- IRegistryHub const& getRegistryHub();
- IMutableRegistryHub& getMutableRegistryHub();
- void cleanUp();
- std::string translateActiveException();
-
-}
-
-// end catch_interfaces_registry_hub.h
-#if defined(CATCH_CONFIG_DISABLE)
- #define INTERNAL_CATCH_TRANSLATE_EXCEPTION_NO_REG( translatorName, signature) \
- static std::string translatorName( signature )
-#endif
-
-#include <exception>
-#include <string>
-#include <vector>
-
-namespace Catch {
- using exceptionTranslateFunction = std::string(*)();
-
- struct IExceptionTranslator;
- using ExceptionTranslators = std::vector<std::unique_ptr<IExceptionTranslator const>>;
-
- struct IExceptionTranslator {
- virtual ~IExceptionTranslator();
- virtual std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const = 0;
- };
-
- struct IExceptionTranslatorRegistry {
- virtual ~IExceptionTranslatorRegistry();
-
- virtual std::string translateActiveException() const = 0;
- };
-
- class ExceptionTranslatorRegistrar {
- template<typename T>
- class ExceptionTranslator : public IExceptionTranslator {
- public:
-
- ExceptionTranslator( std::string(*translateFunction)( T& ) )
- : m_translateFunction( translateFunction )
- {}
-
- std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const override {
- try {
- if( it == itEnd )
- std::rethrow_exception(std::current_exception());
- else
- return (*it)->translate( it+1, itEnd );
- }
- catch( T& ex ) {
- return m_translateFunction( ex );
- }
- }
-
- protected:
- std::string(*m_translateFunction)( T& );
- };
-
- public:
- template<typename T>
- ExceptionTranslatorRegistrar( std::string(*translateFunction)( T& ) ) {
- getMutableRegistryHub().registerTranslator
- ( new ExceptionTranslator<T>( translateFunction ) );
- }
- };
-}
-
-///////////////////////////////////////////////////////////////////////////////
-#define INTERNAL_CATCH_TRANSLATE_EXCEPTION2( translatorName, signature ) \
- static std::string translatorName( signature ); \
- CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
- namespace{ Catch::ExceptionTranslatorRegistrar INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionRegistrar )( &translatorName ); } \
- CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
- static std::string translatorName( signature )
-
-#define INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION2( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature )
-
-// end catch_interfaces_exception.h
-// start catch_approx.h
-
-#include <type_traits>
-
-namespace Catch {
-namespace Detail {
-
- class Approx {
- private:
- bool equalityComparisonImpl(double other) const;
- // Validates the new margin (margin >= 0)
- // out-of-line to avoid including stdexcept in the header
- void setMargin(double margin);
- // Validates the new epsilon (0 < epsilon < 1)
- // out-of-line to avoid including stdexcept in the header
- void setEpsilon(double epsilon);
-
- public:
- explicit Approx ( double value );
-
- static Approx custom();
-
- Approx operator-() const;
-
- template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
- Approx operator()( T const& value ) {
- Approx approx( static_cast<double>(value) );
- approx.m_epsilon = m_epsilon;
- approx.m_margin = m_margin;
- approx.m_scale = m_scale;
- return approx;
- }
-
- template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
- explicit Approx( T const& value ): Approx(static_cast<double>(value))
- {}
-
- template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
- friend bool operator == ( const T& lhs, Approx const& rhs ) {
- auto lhs_v = static_cast<double>(lhs);
- return rhs.equalityComparisonImpl(lhs_v);
- }
-
- template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
- friend bool operator == ( Approx const& lhs, const T& rhs ) {
- return operator==( rhs, lhs );
- }
-
- template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
- friend bool operator != ( T const& lhs, Approx const& rhs ) {
- return !operator==( lhs, rhs );
- }
-
- template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
- friend bool operator != ( Approx const& lhs, T const& rhs ) {
- return !operator==( rhs, lhs );
- }
-
- template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
- friend bool operator <= ( T const& lhs, Approx const& rhs ) {
- return static_cast<double>(lhs) < rhs.m_value || lhs == rhs;
- }
-
- template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
- friend bool operator <= ( Approx const& lhs, T const& rhs ) {
- return lhs.m_value < static_cast<double>(rhs) || lhs == rhs;
- }
-
- template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
- friend bool operator >= ( T const& lhs, Approx const& rhs ) {
- return static_cast<double>(lhs) > rhs.m_value || lhs == rhs;
- }
-
- template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
- friend bool operator >= ( Approx const& lhs, T const& rhs ) {
- return lhs.m_value > static_cast<double>(rhs) || lhs == rhs;
- }
-
- template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
- Approx& epsilon( T const& newEpsilon ) {
- double epsilonAsDouble = static_cast<double>(newEpsilon);
- setEpsilon(epsilonAsDouble);
- return *this;
- }
-
- template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
- Approx& margin( T const& newMargin ) {
- double marginAsDouble = static_cast<double>(newMargin);
- setMargin(marginAsDouble);
- return *this;
- }
-
- template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
- Approx& scale( T const& newScale ) {
- m_scale = static_cast<double>(newScale);
- return *this;
- }
-
- std::string toString() const;
-
- private:
- double m_epsilon;
- double m_margin;
- double m_scale;
- double m_value;
- };
-} // end namespace Detail
-
-namespace literals {
- Detail::Approx operator "" _a(long double val);
- Detail::Approx operator "" _a(unsigned long long val);
-} // end namespace literals
-
-template<>
-struct StringMaker<Catch::Detail::Approx> {
- static std::string convert(Catch::Detail::Approx const& value);
-};
-
-} // end namespace Catch
-
-// end catch_approx.h
-// start catch_string_manip.h
-
-#include <string>
-#include <iosfwd>
-#include <vector>
-
-namespace Catch {
-
- bool startsWith( std::string const& s, std::string const& prefix );
- bool startsWith( std::string const& s, char prefix );
- bool endsWith( std::string const& s, std::string const& suffix );
- bool endsWith( std::string const& s, char suffix );
- bool contains( std::string const& s, std::string const& infix );
- void toLowerInPlace( std::string& s );
- std::string toLower( std::string const& s );
- std::string trim( std::string const& str );
-
- // !!! Be aware, returns refs into original string - make sure original string outlives them
- std::vector<StringRef> splitStringRef( StringRef str, char delimiter );
- bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis );
-
- struct pluralise {
- pluralise( std::size_t count, std::string const& label );
-
- friend std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser );
-
- std::size_t m_count;
- std::string m_label;
- };
-}
-
-// end catch_string_manip.h
-#ifndef CATCH_CONFIG_DISABLE_MATCHERS
-// start catch_capture_matchers.h
-
-// start catch_matchers.h
-
-#include <string>
-#include <vector>
-
-namespace Catch {
-namespace Matchers {
- namespace Impl {
-
- template<typename ArgT> struct MatchAllOf;
- template<typename ArgT> struct MatchAnyOf;
- template<typename ArgT> struct MatchNotOf;
-
- class MatcherUntypedBase {
- public:
- MatcherUntypedBase() = default;
- MatcherUntypedBase ( MatcherUntypedBase const& ) = default;
- MatcherUntypedBase& operator = ( MatcherUntypedBase const& ) = delete;
- std::string toString() const;
-
- protected:
- virtual ~MatcherUntypedBase();
- virtual std::string describe() const = 0;
- mutable std::string m_cachedToString;
- };
-
-#ifdef __clang__
-# pragma clang diagnostic push
-# pragma clang diagnostic ignored "-Wnon-virtual-dtor"
-#endif
-
- template<typename ObjectT>
- struct MatcherMethod {
- virtual bool match( ObjectT const& arg ) const = 0;
- };
-
-#ifdef __clang__
-# pragma clang diagnostic pop
-#endif
-
- template<typename T>
- struct MatcherBase : MatcherUntypedBase, MatcherMethod<T> {
-
- MatchAllOf<T> operator && ( MatcherBase const& other ) const;
- MatchAnyOf<T> operator || ( MatcherBase const& other ) const;
- MatchNotOf<T> operator ! () const;
- };
-
- template<typename ArgT>
- struct MatchAllOf : MatcherBase<ArgT> {
- bool match( ArgT const& arg ) const override {
- for( auto matcher : m_matchers ) {
- if (!matcher->match(arg))
- return false;
- }
- return true;
- }
- std::string describe() const override {
- std::string description;
- description.reserve( 4 + m_matchers.size()*32 );
- description += "( ";
- bool first = true;
- for( auto matcher : m_matchers ) {
- if( first )
- first = false;
- else
- description += " and ";
- description += matcher->toString();
- }
- description += " )";
- return description;
- }
-
- MatchAllOf<ArgT>& operator && ( MatcherBase<ArgT> const& other ) {
- m_matchers.push_back( &other );
- return *this;
- }
-
- std::vector<MatcherBase<ArgT> const*> m_matchers;
- };
- template<typename ArgT>
- struct MatchAnyOf : MatcherBase<ArgT> {
-
- bool match( ArgT const& arg ) const override {
- for( auto matcher : m_matchers ) {
- if (matcher->match(arg))
- return true;
- }
- return false;
- }
- std::string describe() const override {
- std::string description;
- description.reserve( 4 + m_matchers.size()*32 );
- description += "( ";
- bool first = true;
- for( auto matcher : m_matchers ) {
- if( first )
- first = false;
- else
- description += " or ";
- description += matcher->toString();
- }
- description += " )";
- return description;
- }
-
- MatchAnyOf<ArgT>& operator || ( MatcherBase<ArgT> const& other ) {
- m_matchers.push_back( &other );
- return *this;
- }
-
- std::vector<MatcherBase<ArgT> const*> m_matchers;
- };
-
- template<typename ArgT>
- struct MatchNotOf : MatcherBase<ArgT> {
-
- MatchNotOf( MatcherBase<ArgT> const& underlyingMatcher ) : m_underlyingMatcher( underlyingMatcher ) {}
-
- bool match( ArgT const& arg ) const override {
- return !m_underlyingMatcher.match( arg );
- }
-
- std::string describe() const override {
- return "not " + m_underlyingMatcher.toString();
- }
- MatcherBase<ArgT> const& m_underlyingMatcher;
- };
-
- template<typename T>
- MatchAllOf<T> MatcherBase<T>::operator && ( MatcherBase const& other ) const {
- return MatchAllOf<T>() && *this && other;
- }
- template<typename T>
- MatchAnyOf<T> MatcherBase<T>::operator || ( MatcherBase const& other ) const {
- return MatchAnyOf<T>() || *this || other;
- }
- template<typename T>
- MatchNotOf<T> MatcherBase<T>::operator ! () const {
- return MatchNotOf<T>( *this );
- }
-
- } // namespace Impl
-
-} // namespace Matchers
-
-using namespace Matchers;
-using Matchers::Impl::MatcherBase;
-
-} // namespace Catch
-
-// end catch_matchers.h
-// start catch_matchers_floating.h
-
-#include <type_traits>
-#include <cmath>
-
-namespace Catch {
-namespace Matchers {
-
- namespace Floating {
-
- enum class FloatingPointKind : uint8_t;
-
- struct WithinAbsMatcher : MatcherBase<double> {
- WithinAbsMatcher(double target, double margin);
- bool match(double const& matchee) const override;
- std::string describe() const override;
- private:
- double m_target;
- double m_margin;
- };
-
- struct WithinUlpsMatcher : MatcherBase<double> {
- WithinUlpsMatcher(double target, int ulps, FloatingPointKind baseType);
- bool match(double const& matchee) const override;
- std::string describe() const override;
- private:
- double m_target;
- int m_ulps;
- FloatingPointKind m_type;
- };
-
- } // namespace Floating
-
- // The following functions create the actual matcher objects.
- // This allows the types to be inferred
- Floating::WithinUlpsMatcher WithinULP(double target, int maxUlpDiff);
- Floating::WithinUlpsMatcher WithinULP(float target, int maxUlpDiff);
- Floating::WithinAbsMatcher WithinAbs(double target, double margin);
-
-} // namespace Matchers
-} // namespace Catch
-
-// end catch_matchers_floating.h
-// start catch_matchers_generic.hpp
-
-#include <functional>
-#include <string>
-
-namespace Catch {
-namespace Matchers {
-namespace Generic {
-
-namespace Detail {
- std::string finalizeDescription(const std::string& desc);
-}
-
-template <typename T>
-class PredicateMatcher : public MatcherBase<T> {
- std::function<bool(T const&)> m_predicate;
- std::string m_description;
-public:
-
- PredicateMatcher(std::function<bool(T const&)> const& elem, std::string const& descr)
- :m_predicate(std::move(elem)),
- m_description(Detail::finalizeDescription(descr))
- {}
-
- bool match( T const& item ) const override {
- return m_predicate(item);
- }
-
- std::string describe() const override {
- return m_description;
- }
-};
-
-} // namespace Generic
-
- // The following functions create the actual matcher objects.
- // The user has to explicitly specify type to the function, because
- // inferring std::function<bool(T const&)> is hard (but possible) and
- // requires a lot of TMP.
- template<typename T>
- Generic::PredicateMatcher<T> Predicate(std::function<bool(T const&)> const& predicate, std::string const& description = "") {
- return Generic::PredicateMatcher<T>(predicate, description);
- }
-
-} // namespace Matchers
-} // namespace Catch
-
-// end catch_matchers_generic.hpp
-// start catch_matchers_string.h
-
-#include <string>
-
-namespace Catch {
-namespace Matchers {
-
- namespace StdString {
-
- struct CasedString
- {
- CasedString( std::string const& str, CaseSensitive::Choice caseSensitivity );
- std::string adjustString( std::string const& str ) const;
- std::string caseSensitivitySuffix() const;
-
- CaseSensitive::Choice m_caseSensitivity;
- std::string m_str;
- };
-
- struct StringMatcherBase : MatcherBase<std::string> {
- StringMatcherBase( std::string const& operation, CasedString const& comparator );
- std::string describe() const override;
-
- CasedString m_comparator;
- std::string m_operation;
- };
-
- struct EqualsMatcher : StringMatcherBase {
- EqualsMatcher( CasedString const& comparator );
- bool match( std::string const& source ) const override;
- };
- struct ContainsMatcher : StringMatcherBase {
- ContainsMatcher( CasedString const& comparator );
- bool match( std::string const& source ) const override;
- };
- struct StartsWithMatcher : StringMatcherBase {
- StartsWithMatcher( CasedString const& comparator );
- bool match( std::string const& source ) const override;
- };
- struct EndsWithMatcher : StringMatcherBase {
- EndsWithMatcher( CasedString const& comparator );
- bool match( std::string const& source ) const override;
- };
-
- struct RegexMatcher : MatcherBase<std::string> {
- RegexMatcher( std::string regex, CaseSensitive::Choice caseSensitivity );
- bool match( std::string const& matchee ) const override;
- std::string describe() const override;
-
- private:
- std::string m_regex;
- CaseSensitive::Choice m_caseSensitivity;
- };
-
- } // namespace StdString
-
- // The following functions create the actual matcher objects.
- // This allows the types to be inferred
-
- StdString::EqualsMatcher Equals( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
- StdString::ContainsMatcher Contains( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
- StdString::EndsWithMatcher EndsWith( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
- StdString::StartsWithMatcher StartsWith( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
- StdString::RegexMatcher Matches( std::string const& regex, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
-
-} // namespace Matchers
-} // namespace Catch
-
-// end catch_matchers_string.h
-// start catch_matchers_vector.h
-
-#include <algorithm>
-
-namespace Catch {
-namespace Matchers {
-
- namespace Vector {
- template<typename T>
- struct ContainsElementMatcher : MatcherBase<std::vector<T>> {
-
- ContainsElementMatcher(T const &comparator) : m_comparator( comparator) {}
-
- bool match(std::vector<T> const &v) const override {
- for (auto const& el : v) {
- if (el == m_comparator) {
- return true;
- }
- }
- return false;
- }
-
- std::string describe() const override {
- return "Contains: " + ::Catch::Detail::stringify( m_comparator );
- }
-
- T const& m_comparator;
- };
-
- template<typename T>
- struct ContainsMatcher : MatcherBase<std::vector<T>> {
-
- ContainsMatcher(std::vector<T> const &comparator) : m_comparator( comparator ) {}
-
- bool match(std::vector<T> const &v) const override {
- // !TBD: see note in EqualsMatcher
- if (m_comparator.size() > v.size())
- return false;
- for (auto const& comparator : m_comparator) {
- auto present = false;
- for (const auto& el : v) {
- if (el == comparator) {
- present = true;
- break;
- }
- }
- if (!present) {
- return false;
- }
- }
- return true;
- }
- std::string describe() const override {
- return "Contains: " + ::Catch::Detail::stringify( m_comparator );
- }
-
- std::vector<T> const& m_comparator;
- };
-
- template<typename T>
- struct EqualsMatcher : MatcherBase<std::vector<T>> {
-
- EqualsMatcher(std::vector<T> const &comparator) : m_comparator( comparator ) {}
-
- bool match(std::vector<T> const &v) const override {
- // !TBD: This currently works if all elements can be compared using !=
- // - a more general approach would be via a compare template that defaults
- // to using !=. but could be specialised for, e.g. std::vector<T> etc
- // - then just call that directly
- if (m_comparator.size() != v.size())
- return false;
- for (std::size_t i = 0; i < v.size(); ++i)
- if (m_comparator[i] != v[i])
- return false;
- return true;
- }
- std::string describe() const override {
- return "Equals: " + ::Catch::Detail::stringify( m_comparator );
- }
- std::vector<T> const& m_comparator;
- };
-
- template<typename T>
- struct ApproxMatcher : MatcherBase<std::vector<T>> {
-
- ApproxMatcher(std::vector<T> const& comparator) : m_comparator( comparator ) {}
-
- bool match(std::vector<T> const &v) const override {
- if (m_comparator.size() != v.size())
- return false;
- for (std::size_t i = 0; i < v.size(); ++i)
- if (m_comparator[i] != approx(v[i]))
- return false;
- return true;
- }
- std::string describe() const override {
- return "is approx: " + ::Catch::Detail::stringify( m_comparator );
- }
- template <typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
- ApproxMatcher& epsilon( T const& newEpsilon ) {
- approx.epsilon(newEpsilon);
- return *this;
- }
- template <typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
- ApproxMatcher& margin( T const& newMargin ) {
- approx.margin(newMargin);
- return *this;
- }
- template <typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
- ApproxMatcher& scale( T const& newScale ) {
- approx.scale(newScale);
- return *this;
- }
-
- std::vector<T> const& m_comparator;
- mutable Catch::Detail::Approx approx = Catch::Detail::Approx::custom();
- };
-
- template<typename T>
- struct UnorderedEqualsMatcher : MatcherBase<std::vector<T>> {
- UnorderedEqualsMatcher(std::vector<T> const& target) : m_target(target) {}
- bool match(std::vector<T> const& vec) const override {
- // Note: This is a reimplementation of std::is_permutation,
- // because I don't want to include <algorithm> inside the common path
- if (m_target.size() != vec.size()) {
- return false;
- }
- return std::is_permutation(m_target.begin(), m_target.end(), vec.begin());
- }
-
- std::string describe() const override {
- return "UnorderedEquals: " + ::Catch::Detail::stringify(m_target);
- }
- private:
- std::vector<T> const& m_target;
- };
-
- } // namespace Vector
-
- // The following functions create the actual matcher objects.
- // This allows the types to be inferred
-
- template<typename T>
- Vector::ContainsMatcher<T> Contains( std::vector<T> const& comparator ) {
- return Vector::ContainsMatcher<T>( comparator );
- }
-
- template<typename T>
- Vector::ContainsElementMatcher<T> VectorContains( T const& comparator ) {
- return Vector::ContainsElementMatcher<T>( comparator );
- }
-
- template<typename T>
- Vector::EqualsMatcher<T> Equals( std::vector<T> const& comparator ) {
- return Vector::EqualsMatcher<T>( comparator );
- }
-
- template<typename T>
- Vector::ApproxMatcher<T> Approx( std::vector<T> const& comparator ) {
- return Vector::ApproxMatcher<T>( comparator );
- }
-
- template<typename T>
- Vector::UnorderedEqualsMatcher<T> UnorderedEquals(std::vector<T> const& target) {
- return Vector::UnorderedEqualsMatcher<T>(target);
- }
-
-} // namespace Matchers
-} // namespace Catch
-
-// end catch_matchers_vector.h
-namespace Catch {
-
- template<typename ArgT, typename MatcherT>
- class MatchExpr : public ITransientExpression {
- ArgT const& m_arg;
- MatcherT m_matcher;
- StringRef m_matcherString;
- public:
- MatchExpr( ArgT const& arg, MatcherT const& matcher, StringRef const& matcherString )
- : ITransientExpression{ true, matcher.match( arg ) },
- m_arg( arg ),
- m_matcher( matcher ),
- m_matcherString( matcherString )
- {}
-
- void streamReconstructedExpression( std::ostream &os ) const override {
- auto matcherAsString = m_matcher.toString();
- os << Catch::Detail::stringify( m_arg ) << ' ';
- if( matcherAsString == Detail::unprintableString )
- os << m_matcherString;
- else
- os << matcherAsString;
- }
- };
-
- using StringMatcher = Matchers::Impl::MatcherBase<std::string>;
-
- void handleExceptionMatchExpr( AssertionHandler& handler, StringMatcher const& matcher, StringRef const& matcherString );
-
- template<typename ArgT, typename MatcherT>
- auto makeMatchExpr( ArgT const& arg, MatcherT const& matcher, StringRef const& matcherString ) -> MatchExpr<ArgT, MatcherT> {
- return MatchExpr<ArgT, MatcherT>( arg, matcher, matcherString );
- }
-
-} // namespace Catch
-
-///////////////////////////////////////////////////////////////////////////////
-#define INTERNAL_CHECK_THAT( macroName, matcher, resultDisposition, arg ) \
- do { \
- Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(arg) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
- INTERNAL_CATCH_TRY { \
- catchAssertionHandler.handleExpr( Catch::makeMatchExpr( arg, matcher, #matcher##_catch_sr ) ); \
- } INTERNAL_CATCH_CATCH( catchAssertionHandler ) \
- INTERNAL_CATCH_REACT( catchAssertionHandler ) \
- } while( false )
-
-///////////////////////////////////////////////////////////////////////////////
-#define INTERNAL_CATCH_THROWS_MATCHES( macroName, exceptionType, resultDisposition, matcher, ... ) \
- do { \
- Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__) ", " CATCH_INTERNAL_STRINGIFY(exceptionType) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
- if( catchAssertionHandler.allowThrows() ) \
- try { \
- static_cast<void>(__VA_ARGS__ ); \
- catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
- } \
- catch( exceptionType const& ex ) { \
- catchAssertionHandler.handleExpr( Catch::makeMatchExpr( ex, matcher, #matcher##_catch_sr ) ); \
- } \
- catch( ... ) { \
- catchAssertionHandler.handleUnexpectedInflightException(); \
- } \
- else \
- catchAssertionHandler.handleThrowingCallSkipped(); \
- INTERNAL_CATCH_REACT( catchAssertionHandler ) \
- } while( false )
-
-// end catch_capture_matchers.h
-#endif
-// start catch_generators.hpp
-
-// start catch_interfaces_generatortracker.h
-
-
-#include <memory>
-
-namespace Catch {
-
- namespace Generators {
- class GeneratorUntypedBase {
- public:
- GeneratorUntypedBase() = default;
- virtual ~GeneratorUntypedBase();
- // Attempts to move the generator to the next element
- //
- // Returns true iff the move succeeded (and a valid element
- // can be retrieved).
- virtual bool next() = 0;
- };
- using GeneratorBasePtr = std::unique_ptr<GeneratorUntypedBase>;
-
- } // namespace Generators
-
- struct IGeneratorTracker {
- virtual ~IGeneratorTracker();
- virtual auto hasGenerator() const -> bool = 0;
- virtual auto getGenerator() const -> Generators::GeneratorBasePtr const& = 0;
- virtual void setGenerator( Generators::GeneratorBasePtr&& generator ) = 0;
- };
-
-} // namespace Catch
-
-// end catch_interfaces_generatortracker.h
-// start catch_enforce.h
-
-#include <exception>
-
-namespace Catch {
-#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
- template <typename Ex>
- [[noreturn]]
- void throw_exception(Ex const& e) {
- throw e;
- }
-#else // ^^ Exceptions are enabled // Exceptions are disabled vv
- [[noreturn]]
- void throw_exception(std::exception const& e);
-#endif
-
- [[noreturn]]
- void throw_logic_error(std::string const& msg);
- [[noreturn]]
- void throw_domain_error(std::string const& msg);
- [[noreturn]]
- void throw_runtime_error(std::string const& msg);
-
-} // namespace Catch;
-
-#define CATCH_MAKE_MSG(...) \
- (Catch::ReusableStringStream() << __VA_ARGS__).str()
-
-#define CATCH_INTERNAL_ERROR(...) \
- Catch::throw_logic_error(CATCH_MAKE_MSG( CATCH_INTERNAL_LINEINFO << ": Internal Catch2 error: " << __VA_ARGS__));
-
-#define CATCH_ERROR(...) \
- Catch::throw_domain_error(CATCH_MAKE_MSG( __VA_ARGS__ ));
-
-#define CATCH_RUNTIME_ERROR(...) \
- Catch::throw_runtime_error(CATCH_MAKE_MSG( __VA_ARGS__ ));
-
-#define CATCH_ENFORCE( condition, ... ) \
- do{ if( !(condition) ) CATCH_ERROR( __VA_ARGS__ ); } while(false)
-
-// end catch_enforce.h
-#include <memory>
-#include <vector>
-#include <cassert>
-
-#include <utility>
-#include <exception>
-
-namespace Catch {
-
-class GeneratorException : public std::exception {
- const char* const m_msg = "";
-
-public:
- GeneratorException(const char* msg):
- m_msg(msg)
- {}
-
- const char* what() const noexcept override final;
-};
-
-namespace Generators {
-
- // !TBD move this into its own location?
- namespace pf{
- template<typename T, typename... Args>
- std::unique_ptr<T> make_unique( Args&&... args ) {
- return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
- }
- }
-
- template<typename T>
- struct IGenerator : GeneratorUntypedBase {
- virtual ~IGenerator() = default;
-
- // Returns the current element of the generator
- //
- // \Precondition The generator is either freshly constructed,
- // or the last call to `next()` returned true
- virtual T const& get() const = 0;
- using type = T;
- };
-
- template<typename T>
- class SingleValueGenerator final : public IGenerator<T> {
- T m_value;
- public:
- SingleValueGenerator(T const& value) : m_value( value ) {}
- SingleValueGenerator(T&& value) : m_value(std::move(value)) {}
-
- T const& get() const override {
- return m_value;
- }
- bool next() override {
- return false;
- }
- };
-
- template<typename T>
- class FixedValuesGenerator final : public IGenerator<T> {
- std::vector<T> m_values;
- size_t m_idx = 0;
- public:
- FixedValuesGenerator( std::initializer_list<T> values ) : m_values( values ) {}
-
- T const& get() const override {
- return m_values[m_idx];
- }
- bool next() override {
- ++m_idx;
- return m_idx < m_values.size();
- }
- };
-
- template <typename T>
- class GeneratorWrapper final {
- std::unique_ptr<IGenerator<T>> m_generator;
- public:
- GeneratorWrapper(std::unique_ptr<IGenerator<T>> generator):
- m_generator(std::move(generator))
- {}
- T const& get() const {
- return m_generator->get();
- }
- bool next() {
- return m_generator->next();
- }
- };
-
- template <typename T>
- GeneratorWrapper<T> value(T&& value) {
- return GeneratorWrapper<T>(pf::make_unique<SingleValueGenerator<T>>(std::forward<T>(value)));
- }
- template <typename T>
- GeneratorWrapper<T> values(std::initializer_list<T> values) {
- return GeneratorWrapper<T>(pf::make_unique<FixedValuesGenerator<T>>(values));
- }
-
- template<typename T>
- class Generators : public IGenerator<T> {
- std::vector<GeneratorWrapper<T>> m_generators;
- size_t m_current = 0;
-
- void populate(GeneratorWrapper<T>&& generator) {
- m_generators.emplace_back(std::move(generator));
- }
- void populate(T&& val) {
- m_generators.emplace_back(value(std::move(val)));
- }
- template<typename U>
- void populate(U&& val) {
- populate(T(std::move(val)));
- }
- template<typename U, typename... Gs>
- void populate(U&& valueOrGenerator, Gs... moreGenerators) {
- populate(std::forward<U>(valueOrGenerator));
- populate(std::forward<Gs>(moreGenerators)...);
- }
-
- public:
- template <typename... Gs>
- Generators(Gs... moreGenerators) {
- m_generators.reserve(sizeof...(Gs));
- populate(std::forward<Gs>(moreGenerators)...);
- }
-
- T const& get() const override {
- return m_generators[m_current].get();
- }
-
- bool next() override {
- if (m_current >= m_generators.size()) {
- return false;
- }
- const bool current_status = m_generators[m_current].next();
- if (!current_status) {
- ++m_current;
- }
- return m_current < m_generators.size();
- }
- };
-
- template<typename... Ts>
- GeneratorWrapper<std::tuple<Ts...>> table( std::initializer_list<std::tuple<typename std::decay<Ts>::type...>> tuples ) {
- return values<std::tuple<Ts...>>( tuples );
- }
-
- // Tag type to signal that a generator sequence should convert arguments to a specific type
- template <typename T>
- struct as {};
-
- template<typename T, typename... Gs>
- auto makeGenerators( GeneratorWrapper<T>&& generator, Gs... moreGenerators ) -> Generators<T> {
- return Generators<T>(std::move(generator), std::forward<Gs>(moreGenerators)...);
- }
- template<typename T>
- auto makeGenerators( GeneratorWrapper<T>&& generator ) -> Generators<T> {
- return Generators<T>(std::move(generator));
- }
- template<typename T, typename... Gs>
- auto makeGenerators( T&& val, Gs... moreGenerators ) -> Generators<T> {
- return makeGenerators( value( std::forward<T>( val ) ), std::forward<Gs>( moreGenerators )... );
- }
- template<typename T, typename U, typename... Gs>
- auto makeGenerators( as<T>, U&& val, Gs... moreGenerators ) -> Generators<T> {
- return makeGenerators( value( T( std::forward<U>( val ) ) ), std::forward<Gs>( moreGenerators )... );
- }
-
- auto acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker&;
-
- template<typename L>
- // Note: The type after -> is weird, because VS2015 cannot parse
- // the expression used in the typedef inside, when it is in
- // return type. Yeah.
- auto generate( SourceLineInfo const& lineInfo, L const& generatorExpression ) -> decltype(std::declval<decltype(generatorExpression())>().get()) {
- using UnderlyingType = typename decltype(generatorExpression())::type;
-
- IGeneratorTracker& tracker = acquireGeneratorTracker( lineInfo );
- if (!tracker.hasGenerator()) {
- tracker.setGenerator(pf::make_unique<Generators<UnderlyingType>>(generatorExpression()));
- }
-
- auto const& generator = static_cast<IGenerator<UnderlyingType> const&>( *tracker.getGenerator() );
- return generator.get();
- }
-
-} // namespace Generators
-} // namespace Catch
-
-#define GENERATE( ... ) \
- Catch::Generators::generate( CATCH_INTERNAL_LINEINFO, [ ]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } )
-#define GENERATE_COPY( ... ) \
- Catch::Generators::generate( CATCH_INTERNAL_LINEINFO, [=]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } )
-#define GENERATE_REF( ... ) \
- Catch::Generators::generate( CATCH_INTERNAL_LINEINFO, [&]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } )
-
-// end catch_generators.hpp
-// start catch_generators_generic.hpp
-
-namespace Catch {
-namespace Generators {
-
- template <typename T>
- class TakeGenerator : public IGenerator<T> {
- GeneratorWrapper<T> m_generator;
- size_t m_returned = 0;
- size_t m_target;
- public:
- TakeGenerator(size_t target, GeneratorWrapper<T>&& generator):
- m_generator(std::move(generator)),
- m_target(target)
- {
- assert(target != 0 && "Empty generators are not allowed");
- }
- T const& get() const override {
- return m_generator.get();
- }
- bool next() override {
- ++m_returned;
- if (m_returned >= m_target) {
- return false;
- }
-
- const auto success = m_generator.next();
- // If the underlying generator does not contain enough values
- // then we cut short as well
- if (!success) {
- m_returned = m_target;
- }
- return success;
- }
- };
-
- template <typename T>
- GeneratorWrapper<T> take(size_t target, GeneratorWrapper<T>&& generator) {
- return GeneratorWrapper<T>(pf::make_unique<TakeGenerator<T>>(target, std::move(generator)));
- }
-
- template <typename T, typename Predicate>
- class FilterGenerator : public IGenerator<T> {
- GeneratorWrapper<T> m_generator;
- Predicate m_predicate;
- public:
- template <typename P = Predicate>
- FilterGenerator(P&& pred, GeneratorWrapper<T>&& generator):
- m_generator(std::move(generator)),
- m_predicate(std::forward<P>(pred))
- {
- if (!m_predicate(m_generator.get())) {
- // It might happen that there are no values that pass the
- // filter. In that case we throw an exception.
- auto has_initial_value = next();
- if (!has_initial_value) {
- Catch::throw_exception(GeneratorException("No valid value found in filtered generator"));
- }
- }
- }
-
- T const& get() const override {
- return m_generator.get();
- }
-
- bool next() override {
- bool success = m_generator.next();
- if (!success) {
- return false;
- }
- while (!m_predicate(m_generator.get()) && (success = m_generator.next()) == true);
- return success;
- }
- };
-
- template <typename T, typename Predicate>
- GeneratorWrapper<T> filter(Predicate&& pred, GeneratorWrapper<T>&& generator) {
- return GeneratorWrapper<T>(std::unique_ptr<IGenerator<T>>(pf::make_unique<FilterGenerator<T, Predicate>>(std::forward<Predicate>(pred), std::move(generator))));
- }
-
- template <typename T>
- class RepeatGenerator : public IGenerator<T> {
- GeneratorWrapper<T> m_generator;
- mutable std::vector<T> m_returned;
- size_t m_target_repeats;
- size_t m_current_repeat = 0;
- size_t m_repeat_index = 0;
- public:
- RepeatGenerator(size_t repeats, GeneratorWrapper<T>&& generator):
- m_generator(std::move(generator)),
- m_target_repeats(repeats)
- {
- assert(m_target_repeats > 0 && "Repeat generator must repeat at least once");
- }
-
- T const& get() const override {
- if (m_current_repeat == 0) {
- m_returned.push_back(m_generator.get());
- return m_returned.back();
- }
- return m_returned[m_repeat_index];
- }
-
- bool next() override {
- // There are 2 basic cases:
- // 1) We are still reading the generator
- // 2) We are reading our own cache
-
- // In the first case, we need to poke the underlying generator.
- // If it happily moves, we are left in that state, otherwise it is time to start reading from our cache
- if (m_current_repeat == 0) {
- const auto success = m_generator.next();
- if (!success) {
- ++m_current_repeat;
- }
- return m_current_repeat < m_target_repeats;
- }
-
- // In the second case, we need to move indices forward and check that we haven't run up against the end
- ++m_repeat_index;
- if (m_repeat_index == m_returned.size()) {
- m_repeat_index = 0;
- ++m_current_repeat;
- }
- return m_current_repeat < m_target_repeats;
- }
- };
-
- template <typename T>
- GeneratorWrapper<T> repeat(size_t repeats, GeneratorWrapper<T>&& generator) {
- return GeneratorWrapper<T>(pf::make_unique<RepeatGenerator<T>>(repeats, std::move(generator)));
- }
-
- template <typename T, typename U, typename Func>
- class MapGenerator : public IGenerator<T> {
- // TBD: provide static assert for mapping function, for friendly error message
- GeneratorWrapper<U> m_generator;
- Func m_function;
- // To avoid returning dangling reference, we have to save the values
- T m_cache;
- public:
- template <typename F2 = Func>
- MapGenerator(F2&& function, GeneratorWrapper<U>&& generator) :
- m_generator(std::move(generator)),
- m_function(std::forward<F2>(function)),
- m_cache(m_function(m_generator.get()))
- {}
-
- T const& get() const override {
- return m_cache;
- }
- bool next() override {
- const auto success = m_generator.next();
- if (success) {
- m_cache = m_function(m_generator.get());
- }
- return success;
- }
- };
-
-#if defined(__cpp_lib_is_invocable) && __cpp_lib_is_invocable >= 201703
- // std::result_of is deprecated in C++17 and removed in C++20. Hence, it is
- // replaced with std::invoke_result here. Also *_t format is preferred over
- // typename *::type format.
- template <typename Func, typename U>
- using MapFunctionReturnType = std::remove_reference_t<std::remove_cv_t<std::invoke_result_t<Func, U>>>;
-#else
- template <typename Func, typename U>
- using MapFunctionReturnType = typename std::remove_reference<typename std::remove_cv<typename std::result_of<Func(U)>::type>::type>::type;
-#endif
-
- template <typename Func, typename U, typename T = MapFunctionReturnType<Func, U>>
- GeneratorWrapper<T> map(Func&& function, GeneratorWrapper<U>&& generator) {
- return GeneratorWrapper<T>(
- pf::make_unique<MapGenerator<T, U, Func>>(std::forward<Func>(function), std::move(generator))
- );
- }
-
- template <typename T, typename U, typename Func>
- GeneratorWrapper<T> map(Func&& function, GeneratorWrapper<U>&& generator) {
- return GeneratorWrapper<T>(
- pf::make_unique<MapGenerator<T, U, Func>>(std::forward<Func>(function), std::move(generator))
- );
- }
-
- template <typename T>
- class ChunkGenerator final : public IGenerator<std::vector<T>> {
- std::vector<T> m_chunk;
- size_t m_chunk_size;
- GeneratorWrapper<T> m_generator;
- bool m_used_up = false;
- public:
- ChunkGenerator(size_t size, GeneratorWrapper<T> generator) :
- m_chunk_size(size), m_generator(std::move(generator))
- {
- m_chunk.reserve(m_chunk_size);
- m_chunk.push_back(m_generator.get());
- for (size_t i = 1; i < m_chunk_size; ++i) {
- if (!m_generator.next()) {
- Catch::throw_exception(GeneratorException("Not enough values to initialize the first chunk"));
- }
- m_chunk.push_back(m_generator.get());
- }
- }
- std::vector<T> const& get() const override {
- return m_chunk;
- }
- bool next() override {
- m_chunk.clear();
- for (size_t idx = 0; idx < m_chunk_size; ++idx) {
- if (!m_generator.next()) {
- return false;
- }
- m_chunk.push_back(m_generator.get());
- }
- return true;
- }
- };
-
- template <typename T>
- GeneratorWrapper<std::vector<T>> chunk(size_t size, GeneratorWrapper<T>&& generator) {
- return GeneratorWrapper<std::vector<T>>(
- pf::make_unique<ChunkGenerator<T>>(size, std::move(generator))
- );
- }
-
-} // namespace Generators
-} // namespace Catch
-
-// end catch_generators_generic.hpp
-// start catch_generators_specific.hpp
-
-// start catch_context.h
-
-#include <memory>
-
-namespace Catch {
-
- struct IResultCapture;
- struct IRunner;
- struct IConfig;
- struct IMutableContext;
-
- using IConfigPtr = std::shared_ptr<IConfig const>;
-
- struct IContext
- {
- virtual ~IContext();
-
- virtual IResultCapture* getResultCapture() = 0;
- virtual IRunner* getRunner() = 0;
- virtual IConfigPtr const& getConfig() const = 0;
- };
-
- struct IMutableContext : IContext
- {
- virtual ~IMutableContext();
- virtual void setResultCapture( IResultCapture* resultCapture ) = 0;
- virtual void setRunner( IRunner* runner ) = 0;
- virtual void setConfig( IConfigPtr const& config ) = 0;
-
- private:
- static IMutableContext *currentContext;
- friend IMutableContext& getCurrentMutableContext();
- friend void cleanUpContext();
- static void createContext();
- };
-
- inline IMutableContext& getCurrentMutableContext()
- {
- if( !IMutableContext::currentContext )
- IMutableContext::createContext();
- return *IMutableContext::currentContext;
- }
-
- inline IContext& getCurrentContext()
- {
- return getCurrentMutableContext();
- }
-
- void cleanUpContext();
-}
-
-// end catch_context.h
-// start catch_interfaces_config.h
-
-// start catch_option.hpp
-
-namespace Catch {
-
- // An optional type
- template<typename T>
- class Option {
- public:
- Option() : nullableValue( nullptr ) {}
- Option( T const& _value )
- : nullableValue( new( storage ) T( _value ) )
- {}
- Option( Option const& _other )
- : nullableValue( _other ? new( storage ) T( *_other ) : nullptr )
- {}
-
- ~Option() {
- reset();
- }
-
- Option& operator= ( Option const& _other ) {
- if( &_other != this ) {
- reset();
- if( _other )
- nullableValue = new( storage ) T( *_other );
- }
- return *this;
- }
- Option& operator = ( T const& _value ) {
- reset();
- nullableValue = new( storage ) T( _value );
- return *this;
- }
-
- void reset() {
- if( nullableValue )
- nullableValue->~T();
- nullableValue = nullptr;
- }
-
- T& operator*() { return *nullableValue; }
- T const& operator*() const { return *nullableValue; }
- T* operator->() { return nullableValue; }
- const T* operator->() const { return nullableValue; }
-
- T valueOr( T const& defaultValue ) const {
- return nullableValue ? *nullableValue : defaultValue;
- }
-
- bool some() const { return nullableValue != nullptr; }
- bool none() const { return nullableValue == nullptr; }
-
- bool operator !() const { return nullableValue == nullptr; }
- explicit operator bool() const {
- return some();
- }
-
- private:
- T *nullableValue;
- alignas(alignof(T)) char storage[sizeof(T)];
- };
-
-} // end namespace Catch
-
-// end catch_option.hpp
-#include <iosfwd>
-#include <string>
-#include <vector>
-#include <memory>
-
-namespace Catch {
-
- enum class Verbosity {
- Quiet = 0,
- Normal,
- High
- };
-
- struct WarnAbout { enum What {
- Nothing = 0x00,
- NoAssertions = 0x01,
- NoTests = 0x02
- }; };
-
- struct ShowDurations { enum OrNot {
- DefaultForReporter,
- Always,
- Never
- }; };
- struct RunTests { enum InWhatOrder {
- InDeclarationOrder,
- InLexicographicalOrder,
- InRandomOrder
- }; };
- struct UseColour { enum YesOrNo {
- Auto,
- Yes,
- No
- }; };
- struct WaitForKeypress { enum When {
- Never,
- BeforeStart = 1,
- BeforeExit = 2,
- BeforeStartAndExit = BeforeStart | BeforeExit
- }; };
-
- class TestSpec;
-
- struct IConfig : NonCopyable {
-
- virtual ~IConfig();
-
- virtual bool allowThrows() const = 0;
- virtual std::ostream& stream() const = 0;
- virtual std::string name() const = 0;
- virtual bool includeSuccessfulResults() const = 0;
- virtual bool shouldDebugBreak() const = 0;
- virtual bool warnAboutMissingAssertions() const = 0;
- virtual bool warnAboutNoTests() const = 0;
- virtual int abortAfter() const = 0;
- virtual bool showInvisibles() const = 0;
- virtual ShowDurations::OrNot showDurations() const = 0;
- virtual TestSpec const& testSpec() const = 0;
- virtual bool hasTestFilters() const = 0;
- virtual std::vector<std::string> const& getTestsOrTags() const = 0;
- virtual RunTests::InWhatOrder runOrder() const = 0;
- virtual unsigned int rngSeed() const = 0;
- virtual UseColour::YesOrNo useColour() const = 0;
- virtual std::vector<std::string> const& getSectionsToRun() const = 0;
- virtual Verbosity verbosity() const = 0;
-
- virtual bool benchmarkNoAnalysis() const = 0;
- virtual int benchmarkSamples() const = 0;
- virtual double benchmarkConfidenceInterval() const = 0;
- virtual unsigned int benchmarkResamples() const = 0;
- };
-
- using IConfigPtr = std::shared_ptr<IConfig const>;
-}
-
-// end catch_interfaces_config.h
-#include <random>
-
-namespace Catch {
-namespace Generators {
-
-template <typename Float>
-class RandomFloatingGenerator final : public IGenerator<Float> {
- // FIXME: What is the right seed?
- std::minstd_rand m_rand;
- std::uniform_real_distribution<Float> m_dist;
- Float m_current_number;
-public:
-
- RandomFloatingGenerator(Float a, Float b):
- m_rand(getCurrentContext().getConfig()->rngSeed()),
- m_dist(a, b) {
- static_cast<void>(next());
- }
-
- Float const& get() const override {
- return m_current_number;
- }
- bool next() override {
- m_current_number = m_dist(m_rand);
- return true;
- }
-};
-
-template <typename Integer>
-class RandomIntegerGenerator final : public IGenerator<Integer> {
- std::minstd_rand m_rand;
- std::uniform_int_distribution<Integer> m_dist;
- Integer m_current_number;
-public:
-
- RandomIntegerGenerator(Integer a, Integer b):
- m_rand(getCurrentContext().getConfig()->rngSeed()),
- m_dist(a, b) {
- static_cast<void>(next());
- }
-
- Integer const& get() const override {
- return m_current_number;
- }
- bool next() override {
- m_current_number = m_dist(m_rand);
- return true;
- }
-};
-
-// TODO: Ideally this would be also constrained against the various char types,
-// but I don't expect users to run into that in practice.
-template <typename T>
-typename std::enable_if<std::is_integral<T>::value && !std::is_same<T, bool>::value,
-GeneratorWrapper<T>>::type
-random(T a, T b) {
- return GeneratorWrapper<T>(
- pf::make_unique<RandomIntegerGenerator<T>>(a, b)
- );
-}
-
-template <typename T>
-typename std::enable_if<std::is_floating_point<T>::value,
-GeneratorWrapper<T>>::type
-random(T a, T b) {
- return GeneratorWrapper<T>(
- pf::make_unique<RandomFloatingGenerator<T>>(a, b)
- );
-}
-
-template <typename T>
-class RangeGenerator final : public IGenerator<T> {
- T m_current;
- T m_end;
- T m_step;
- bool m_positive;
-
-public:
- RangeGenerator(T const& start, T const& end, T const& step):
- m_current(start),
- m_end(end),
- m_step(step),
- m_positive(m_step > T(0))
- {
- assert(m_current != m_end && "Range start and end cannot be equal");
- assert(m_step != T(0) && "Step size cannot be zero");
- assert(((m_positive && m_current <= m_end) || (!m_positive && m_current >= m_end)) && "Step moves away from end");
- }
-
- RangeGenerator(T const& start, T const& end):
- RangeGenerator(start, end, (start < end) ? T(1) : T(-1))
- {}
-
- T const& get() const override {
- return m_current;
- }
-
- bool next() override {
- m_current += m_step;
- return (m_positive) ? (m_current < m_end) : (m_current > m_end);
- }
-};
-
-template <typename T>
-GeneratorWrapper<T> range(T const& start, T const& end, T const& step) {
- static_assert(std::is_integral<T>::value && !std::is_same<T, bool>::value, "Type must be an integer");
- return GeneratorWrapper<T>(pf::make_unique<RangeGenerator<T>>(start, end, step));
-}
-
-template <typename T>
-GeneratorWrapper<T> range(T const& start, T const& end) {
- static_assert(std::is_integral<T>::value && !std::is_same<T, bool>::value, "Type must be an integer");
- return GeneratorWrapper<T>(pf::make_unique<RangeGenerator<T>>(start, end));
-}
-
-} // namespace Generators
-} // namespace Catch
-
-// end catch_generators_specific.hpp
-
-// These files are included here so the single_include script doesn't put them
-// in the conditionally compiled sections
-// start catch_test_case_info.h
-
-#include <string>
-#include <vector>
-#include <memory>
-
-#ifdef __clang__
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wpadded"
-#endif
-
-namespace Catch {
-
- struct ITestInvoker;
-
- struct TestCaseInfo {
- enum SpecialProperties{
- None = 0,
- IsHidden = 1 << 1,
- ShouldFail = 1 << 2,
- MayFail = 1 << 3,
- Throws = 1 << 4,
- NonPortable = 1 << 5,
- Benchmark = 1 << 6
- };
-
- TestCaseInfo( std::string const& _name,
- std::string const& _className,
- std::string const& _description,
- std::vector<std::string> const& _tags,
- SourceLineInfo const& _lineInfo );
-
- friend void setTags( TestCaseInfo& testCaseInfo, std::vector<std::string> tags );
-
- bool isHidden() const;
- bool throws() const;
- bool okToFail() const;
- bool expectedToFail() const;
-
- std::string tagsAsString() const;
-
- std::string name;
- std::string className;
- std::string description;
- std::vector<std::string> tags;
- std::vector<std::string> lcaseTags;
- SourceLineInfo lineInfo;
- SpecialProperties properties;
- };
-
- class TestCase : public TestCaseInfo {
- public:
-
- TestCase( ITestInvoker* testCase, TestCaseInfo&& info );
-
- TestCase withName( std::string const& _newName ) const;
-
- void invoke() const;
-
- TestCaseInfo const& getTestCaseInfo() const;
-
- bool operator == ( TestCase const& other ) const;
- bool operator < ( TestCase const& other ) const;
-
- private:
- std::shared_ptr<ITestInvoker> test;
- };
-
- TestCase makeTestCase( ITestInvoker* testCase,
- std::string const& className,
- NameAndTags const& nameAndTags,
- SourceLineInfo const& lineInfo );
-}
-
-#ifdef __clang__
-#pragma clang diagnostic pop
-#endif
-
-// end catch_test_case_info.h
-// start catch_interfaces_runner.h
-
-namespace Catch {
-
- struct IRunner {
- virtual ~IRunner();
- virtual bool aborting() const = 0;
- };
-}
-
-// end catch_interfaces_runner.h
-
-#ifdef __OBJC__
-// start catch_objc.hpp
-
-#import <objc/runtime.h>
-
-#include <string>
-
-// NB. Any general catch headers included here must be included
-// in catch.hpp first to make sure they are included by the single
-// header for non obj-usage
-
-///////////////////////////////////////////////////////////////////////////////
-// This protocol is really only here for (self) documenting purposes, since
-// all its methods are optional.
-@protocol OcFixture
-
-@optional
-
--(void) setUp;
--(void) tearDown;
-
-@end
-
-namespace Catch {
-
- class OcMethod : public ITestInvoker {
-
- public:
- OcMethod( Class cls, SEL sel ) : m_cls( cls ), m_sel( sel ) {}
-
- virtual void invoke() const {
- id obj = [[m_cls alloc] init];
-
- performOptionalSelector( obj, @selector(setUp) );
- performOptionalSelector( obj, m_sel );
- performOptionalSelector( obj, @selector(tearDown) );
-
- arcSafeRelease( obj );
- }
- private:
- virtual ~OcMethod() {}
-
- Class m_cls;
- SEL m_sel;
- };
-
- namespace Detail{
-
- inline std::string getAnnotation( Class cls,
- std::string const& annotationName,
- std::string const& testCaseName ) {
- NSString* selStr = [[NSString alloc] initWithFormat:@"Catch_%s_%s", annotationName.c_str(), testCaseName.c_str()];
- SEL sel = NSSelectorFromString( selStr );
- arcSafeRelease( selStr );
- id value = performOptionalSelector( cls, sel );
- if( value )
- return [(NSString*)value UTF8String];
- return "";
- }
- }
-
- inline std::size_t registerTestMethods() {
- std::size_t noTestMethods = 0;
- int noClasses = objc_getClassList( nullptr, 0 );
-
- Class* classes = (CATCH_UNSAFE_UNRETAINED Class *)malloc( sizeof(Class) * noClasses);
- objc_getClassList( classes, noClasses );
-
- for( int c = 0; c < noClasses; c++ ) {
- Class cls = classes[c];
- {
- u_int count;
- Method* methods = class_copyMethodList( cls, &count );
- for( u_int m = 0; m < count ; m++ ) {
- SEL selector = method_getName(methods[m]);
- std::string methodName = sel_getName(selector);
- if( startsWith( methodName, "Catch_TestCase_" ) ) {
- std::string testCaseName = methodName.substr( 15 );
- std::string name = Detail::getAnnotation( cls, "Name", testCaseName );
- std::string desc = Detail::getAnnotation( cls, "Description", testCaseName );
- const char* className = class_getName( cls );
-
- getMutableRegistryHub().registerTest( makeTestCase( new OcMethod( cls, selector ), className, NameAndTags( name.c_str(), desc.c_str() ), SourceLineInfo("",0) ) );
- noTestMethods++;
- }
- }
- free(methods);
- }
- }
- return noTestMethods;
- }
-
-#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
-
- namespace Matchers {
- namespace Impl {
- namespace NSStringMatchers {
-
- struct StringHolder : MatcherBase<NSString*>{
- StringHolder( NSString* substr ) : m_substr( [substr copy] ){}
- StringHolder( StringHolder const& other ) : m_substr( [other.m_substr copy] ){}
- StringHolder() {
- arcSafeRelease( m_substr );
- }
-
- bool match( NSString* const& str ) const override {
- return false;
- }
-
- NSString* CATCH_ARC_STRONG m_substr;
- };
-
- struct Equals : StringHolder {
- Equals( NSString* substr ) : StringHolder( substr ){}
-
- bool match( NSString* const& str ) const override {
- return (str != nil || m_substr == nil ) &&
- [str isEqualToString:m_substr];
- }
-
- std::string describe() const override {
- return "equals string: " + Catch::Detail::stringify( m_substr );
- }
- };
-
- struct Contains : StringHolder {
- Contains( NSString* substr ) : StringHolder( substr ){}
-
- bool match( NSString* const& str ) const override {
- return (str != nil || m_substr == nil ) &&
- [str rangeOfString:m_substr].location != NSNotFound;
- }
-
- std::string describe() const override {
- return "contains string: " + Catch::Detail::stringify( m_substr );
- }
- };
-
- struct StartsWith : StringHolder {
- StartsWith( NSString* substr ) : StringHolder( substr ){}
-
- bool match( NSString* const& str ) const override {
- return (str != nil || m_substr == nil ) &&
- [str rangeOfString:m_substr].location == 0;
- }
-
- std::string describe() const override {
- return "starts with: " + Catch::Detail::stringify( m_substr );
- }
- };
- struct EndsWith : StringHolder {
- EndsWith( NSString* substr ) : StringHolder( substr ){}
-
- bool match( NSString* const& str ) const override {
- return (str != nil || m_substr == nil ) &&
- [str rangeOfString:m_substr].location == [str length] - [m_substr length];
- }
-
- std::string describe() const override {
- return "ends with: " + Catch::Detail::stringify( m_substr );
- }
- };
-
- } // namespace NSStringMatchers
- } // namespace Impl
-
- inline Impl::NSStringMatchers::Equals
- Equals( NSString* substr ){ return Impl::NSStringMatchers::Equals( substr ); }
-
- inline Impl::NSStringMatchers::Contains
- Contains( NSString* substr ){ return Impl::NSStringMatchers::Contains( substr ); }
-
- inline Impl::NSStringMatchers::StartsWith
- StartsWith( NSString* substr ){ return Impl::NSStringMatchers::StartsWith( substr ); }
-
- inline Impl::NSStringMatchers::EndsWith
- EndsWith( NSString* substr ){ return Impl::NSStringMatchers::EndsWith( substr ); }
-
- } // namespace Matchers
-
- using namespace Matchers;
-
-#endif // CATCH_CONFIG_DISABLE_MATCHERS
-
-} // namespace Catch
-
-///////////////////////////////////////////////////////////////////////////////
-#define OC_MAKE_UNIQUE_NAME( root, uniqueSuffix ) root##uniqueSuffix
-#define OC_TEST_CASE2( name, desc, uniqueSuffix ) \
-+(NSString*) OC_MAKE_UNIQUE_NAME( Catch_Name_test_, uniqueSuffix ) \
-{ \
-return @ name; \
-} \
-+(NSString*) OC_MAKE_UNIQUE_NAME( Catch_Description_test_, uniqueSuffix ) \
-{ \
-return @ desc; \
-} \
--(void) OC_MAKE_UNIQUE_NAME( Catch_TestCase_test_, uniqueSuffix )
-
-#define OC_TEST_CASE( name, desc ) OC_TEST_CASE2( name, desc, __LINE__ )
-
-// end catch_objc.hpp
-#endif
-
-// Benchmarking needs the externally-facing parts of reporters to work
-#if defined(CATCH_CONFIG_EXTERNAL_INTERFACES) || defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
-// start catch_external_interfaces.h
-
-// start catch_reporter_bases.hpp
-
-// start catch_interfaces_reporter.h
-
-// start catch_config.hpp
-
-// start catch_test_spec_parser.h
-
-#ifdef __clang__
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wpadded"
-#endif
-
-// start catch_test_spec.h
-
-#ifdef __clang__
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wpadded"
-#endif
-
-// start catch_wildcard_pattern.h
-
-namespace Catch
-{
- class WildcardPattern {
- enum WildcardPosition {
- NoWildcard = 0,
- WildcardAtStart = 1,
- WildcardAtEnd = 2,
- WildcardAtBothEnds = WildcardAtStart | WildcardAtEnd
- };
-
- public:
-
- WildcardPattern( std::string const& pattern, CaseSensitive::Choice caseSensitivity );
- virtual ~WildcardPattern() = default;
- virtual bool matches( std::string const& str ) const;
-
- private:
- std::string adjustCase( std::string const& str ) const;
- CaseSensitive::Choice m_caseSensitivity;
- WildcardPosition m_wildcard = NoWildcard;
- std::string m_pattern;
- };
-}
-
-// end catch_wildcard_pattern.h
-#include <string>
-#include <vector>
-#include <memory>
-
-namespace Catch {
-
- class TestSpec {
- struct Pattern {
- virtual ~Pattern();
- virtual bool matches( TestCaseInfo const& testCase ) const = 0;
- };
- using PatternPtr = std::shared_ptr<Pattern>;
-
- class NamePattern : public Pattern {
- public:
- NamePattern( std::string const& name );
- virtual ~NamePattern();
- bool matches( TestCaseInfo const& testCase ) const override;
- private:
- WildcardPattern m_wildcardPattern;
- };
-
- class TagPattern : public Pattern {
- public:
- TagPattern( std::string const& tag );
- virtual ~TagPattern();
- bool matches( TestCaseInfo const& testCase ) const override;
- private:
- std::string m_tag;
- };
-
- class ExcludedPattern : public Pattern {
- public:
- ExcludedPattern( PatternPtr const& underlyingPattern );
- virtual ~ExcludedPattern();
- bool matches( TestCaseInfo const& testCase ) const override;
- private:
- PatternPtr m_underlyingPattern;
- };
-
- struct Filter {
- std::vector<PatternPtr> m_patterns;
-
- bool matches( TestCaseInfo const& testCase ) const;
- };
-
- public:
- bool hasFilters() const;
- bool matches( TestCaseInfo const& testCase ) const;
-
- private:
- std::vector<Filter> m_filters;
-
- friend class TestSpecParser;
- };
-}
-
-#ifdef __clang__
-#pragma clang diagnostic pop
-#endif
-
-// end catch_test_spec.h
-// start catch_interfaces_tag_alias_registry.h
-
-#include <string>
-
-namespace Catch {
-
- struct TagAlias;
-
- struct ITagAliasRegistry {
- virtual ~ITagAliasRegistry();
- // Nullptr if not present
- virtual TagAlias const* find( std::string const& alias ) const = 0;
- virtual std::string expandAliases( std::string const& unexpandedTestSpec ) const = 0;
-
- static ITagAliasRegistry const& get();
- };
-
-} // end namespace Catch
-
-// end catch_interfaces_tag_alias_registry.h
-namespace Catch {
-
- class TestSpecParser {
- enum Mode{ None, Name, QuotedName, Tag, EscapedName };
- Mode m_mode = None;
- bool m_exclusion = false;
- std::size_t m_start = std::string::npos, m_pos = 0;
- std::string m_arg;
- std::vector<std::size_t> m_escapeChars;
- TestSpec::Filter m_currentFilter;
- TestSpec m_testSpec;
- ITagAliasRegistry const* m_tagAliases = nullptr;
-
- public:
- TestSpecParser( ITagAliasRegistry const& tagAliases );
-
- TestSpecParser& parse( std::string const& arg );
- TestSpec testSpec();
-
- private:
- void visitChar( char c );
- void startNewMode( Mode mode, std::size_t start );
- void escape();
- std::string subString() const;
-
- template<typename T>
- void addPattern() {
- std::string token = subString();
- for( std::size_t i = 0; i < m_escapeChars.size(); ++i )
- token = token.substr( 0, m_escapeChars[i]-m_start-i ) + token.substr( m_escapeChars[i]-m_start-i+1 );
- m_escapeChars.clear();
- if( startsWith( token, "exclude:" ) ) {
- m_exclusion = true;
- token = token.substr( 8 );
- }
- if( !token.empty() ) {
- TestSpec::PatternPtr pattern = std::make_shared<T>( token );
- if( m_exclusion )
- pattern = std::make_shared<TestSpec::ExcludedPattern>( pattern );
- m_currentFilter.m_patterns.push_back( pattern );
- }
- m_exclusion = false;
- m_mode = None;
- }
-
- void addFilter();
- };
- TestSpec parseTestSpec( std::string const& arg );
-
-} // namespace Catch
-
-#ifdef __clang__
-#pragma clang diagnostic pop
-#endif
-
-// end catch_test_spec_parser.h
-// Libstdc++ doesn't like incomplete classes for unique_ptr
-
-#include <memory>
-#include <vector>
-#include <string>
-
-#ifndef CATCH_CONFIG_CONSOLE_WIDTH
-#define CATCH_CONFIG_CONSOLE_WIDTH 80
-#endif
-
-namespace Catch {
-
- struct IStream;
-
- struct ConfigData {
- bool listTests = false;
- bool listTags = false;
- bool listReporters = false;
- bool listTestNamesOnly = false;
-
- bool showSuccessfulTests = false;
- bool shouldDebugBreak = false;
- bool noThrow = false;
- bool showHelp = false;
- bool showInvisibles = false;
- bool filenamesAsTags = false;
- bool libIdentify = false;
-
- int abortAfter = -1;
- unsigned int rngSeed = 0;
-
- bool benchmarkNoAnalysis = false;
- unsigned int benchmarkSamples = 100;
- double benchmarkConfidenceInterval = 0.95;
- unsigned int benchmarkResamples = 100000;
-
- Verbosity verbosity = Verbosity::Normal;
- WarnAbout::What warnings = WarnAbout::Nothing;
- ShowDurations::OrNot showDurations = ShowDurations::DefaultForReporter;
- RunTests::InWhatOrder runOrder = RunTests::InDeclarationOrder;
- UseColour::YesOrNo useColour = UseColour::Auto;
- WaitForKeypress::When waitForKeypress = WaitForKeypress::Never;
-
- std::string outputFilename;
- std::string name;
- std::string processName;
-#ifndef CATCH_CONFIG_DEFAULT_REPORTER
-#define CATCH_CONFIG_DEFAULT_REPORTER "console"
-#endif
- std::string reporterName = CATCH_CONFIG_DEFAULT_REPORTER;
-#undef CATCH_CONFIG_DEFAULT_REPORTER
-
- std::vector<std::string> testsOrTags;
- std::vector<std::string> sectionsToRun;
- };
-
- class Config : public IConfig {
- public:
-
- Config() = default;
- Config( ConfigData const& data );
- virtual ~Config() = default;
-
- std::string const& getFilename() const;
-
- bool listTests() const;
- bool listTestNamesOnly() const;
- bool listTags() const;
- bool listReporters() const;
-
- std::string getProcessName() const;
- std::string const& getReporterName() const;
-
- std::vector<std::string> const& getTestsOrTags() const override;
- std::vector<std::string> const& getSectionsToRun() const override;
-
- TestSpec const& testSpec() const override;
- bool hasTestFilters() const override;
-
- bool showHelp() const;
-
- // IConfig interface
- bool allowThrows() const override;
- std::ostream& stream() const override;
- std::string name() const override;
- bool includeSuccessfulResults() const override;
- bool warnAboutMissingAssertions() const override;
- bool warnAboutNoTests() const override;
- ShowDurations::OrNot showDurations() const override;
- RunTests::InWhatOrder runOrder() const override;
- unsigned int rngSeed() const override;
- UseColour::YesOrNo useColour() const override;
- bool shouldDebugBreak() const override;
- int abortAfter() const override;
- bool showInvisibles() const override;
- Verbosity verbosity() const override;
- bool benchmarkNoAnalysis() const override;
- int benchmarkSamples() const override;
- double benchmarkConfidenceInterval() const override;
- unsigned int benchmarkResamples() const override;
-
- private:
-
- IStream const* openStream();
- ConfigData m_data;
-
- std::unique_ptr<IStream const> m_stream;
- TestSpec m_testSpec;
- bool m_hasTestFilters = false;
- };
-
-} // end namespace Catch
-
-// end catch_config.hpp
-// start catch_assertionresult.h
-
-#include <string>
-
-namespace Catch {
-
- struct AssertionResultData
- {
- AssertionResultData() = delete;
-
- AssertionResultData( ResultWas::OfType _resultType, LazyExpression const& _lazyExpression );
-
- std::string message;
- mutable std::string reconstructedExpression;
- LazyExpression lazyExpression;
- ResultWas::OfType resultType;
-
- std::string reconstructExpression() const;
- };
-
- class AssertionResult {
- public:
- AssertionResult() = delete;
- AssertionResult( AssertionInfo const& info, AssertionResultData const& data );
-
- bool isOk() const;
- bool succeeded() const;
- ResultWas::OfType getResultType() const;
- bool hasExpression() const;
- bool hasMessage() const;
- std::string getExpression() const;
- std::string getExpressionInMacro() const;
- bool hasExpandedExpression() const;
- std::string getExpandedExpression() const;
- std::string getMessage() const;
- SourceLineInfo getSourceInfo() const;
- StringRef getTestMacroName() const;
-
- //protected:
- AssertionInfo m_info;
- AssertionResultData m_resultData;
- };
-
-} // end namespace Catch
-
-// end catch_assertionresult.h
-#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
-// start catch_estimate.hpp
-
- // Statistics estimates
-
-
-namespace Catch {
- namespace Benchmark {
- template <typename Duration>
- struct Estimate {
- Duration point;
- Duration lower_bound;
- Duration upper_bound;
- double confidence_interval;
-
- template <typename Duration2>
- operator Estimate<Duration2>() const {
- return { point, lower_bound, upper_bound, confidence_interval };
- }
- };
- } // namespace Benchmark
-} // namespace Catch
-
-// end catch_estimate.hpp
-// start catch_outlier_classification.hpp
-
-// Outlier information
-
-namespace Catch {
- namespace Benchmark {
- struct OutlierClassification {
- int samples_seen = 0;
- int low_severe = 0; // more than 3 times IQR below Q1
- int low_mild = 0; // 1.5 to 3 times IQR below Q1
- int high_mild = 0; // 1.5 to 3 times IQR above Q3
- int high_severe = 0; // more than 3 times IQR above Q3
-
- int total() const {
- return low_severe + low_mild + high_mild + high_severe;
- }
- };
- } // namespace Benchmark
-} // namespace Catch
-
-// end catch_outlier_classification.hpp
-#endif // CATCH_CONFIG_ENABLE_BENCHMARKING
-
-#include <string>
-#include <iosfwd>
-#include <map>
-#include <set>
-#include <memory>
-#include <algorithm>
-
-namespace Catch {
-
- struct ReporterConfig {
- explicit ReporterConfig( IConfigPtr const& _fullConfig );
-
- ReporterConfig( IConfigPtr const& _fullConfig, std::ostream& _stream );
-
- std::ostream& stream() const;
- IConfigPtr fullConfig() const;
-
- private:
- std::ostream* m_stream;
- IConfigPtr m_fullConfig;
- };
-
- struct ReporterPreferences {
- bool shouldRedirectStdOut = false;
- bool shouldReportAllAssertions = false;
- };
-
- template<typename T>
- struct LazyStat : Option<T> {
- LazyStat& operator=( T const& _value ) {
- Option<T>::operator=( _value );
- used = false;
- return *this;
- }
- void reset() {
- Option<T>::reset();
- used = false;
- }
- bool used = false;
- };
-
- struct TestRunInfo {
- TestRunInfo( std::string const& _name );
- std::string name;
- };
- struct GroupInfo {
- GroupInfo( std::string const& _name,
- std::size_t _groupIndex,
- std::size_t _groupsCount );
-
- std::string name;
- std::size_t groupIndex;
- std::size_t groupsCounts;
- };
-
- struct AssertionStats {
- AssertionStats( AssertionResult const& _assertionResult,
- std::vector<MessageInfo> const& _infoMessages,
- Totals const& _totals );
-
- AssertionStats( AssertionStats const& ) = default;
- AssertionStats( AssertionStats && ) = default;
- AssertionStats& operator = ( AssertionStats const& ) = delete;
- AssertionStats& operator = ( AssertionStats && ) = delete;
- virtual ~AssertionStats();
-
- AssertionResult assertionResult;
- std::vector<MessageInfo> infoMessages;
- Totals totals;
- };
-
- struct SectionStats {
- SectionStats( SectionInfo const& _sectionInfo,
- Counts const& _assertions,
- double _durationInSeconds,
- bool _missingAssertions );
- SectionStats( SectionStats const& ) = default;
- SectionStats( SectionStats && ) = default;
- SectionStats& operator = ( SectionStats const& ) = default;
- SectionStats& operator = ( SectionStats && ) = default;
- virtual ~SectionStats();
-
- SectionInfo sectionInfo;
- Counts assertions;
- double durationInSeconds;
- bool missingAssertions;
- };
-
- struct TestCaseStats {
- TestCaseStats( TestCaseInfo const& _testInfo,
- Totals const& _totals,
- std::string const& _stdOut,
- std::string const& _stdErr,
- bool _aborting );
-
- TestCaseStats( TestCaseStats const& ) = default;
- TestCaseStats( TestCaseStats && ) = default;
- TestCaseStats& operator = ( TestCaseStats const& ) = default;
- TestCaseStats& operator = ( TestCaseStats && ) = default;
- virtual ~TestCaseStats();
-
- TestCaseInfo testInfo;
- Totals totals;
- std::string stdOut;
- std::string stdErr;
- bool aborting;
- };
-
- struct TestGroupStats {
- TestGroupStats( GroupInfo const& _groupInfo,
- Totals const& _totals,
- bool _aborting );
- TestGroupStats( GroupInfo const& _groupInfo );
-
- TestGroupStats( TestGroupStats const& ) = default;
- TestGroupStats( TestGroupStats && ) = default;
- TestGroupStats& operator = ( TestGroupStats const& ) = default;
- TestGroupStats& operator = ( TestGroupStats && ) = default;
- virtual ~TestGroupStats();
-
- GroupInfo groupInfo;
- Totals totals;
- bool aborting;
- };
-
- struct TestRunStats {
- TestRunStats( TestRunInfo const& _runInfo,
- Totals const& _totals,
- bool _aborting );
-
- TestRunStats( TestRunStats const& ) = default;
- TestRunStats( TestRunStats && ) = default;
- TestRunStats& operator = ( TestRunStats const& ) = default;
- TestRunStats& operator = ( TestRunStats && ) = default;
- virtual ~TestRunStats();
-
- TestRunInfo runInfo;
- Totals totals;
- bool aborting;
- };
-
-#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
- struct BenchmarkInfo {
- std::string name;
- double estimatedDuration;
- int iterations;
- int samples;
- unsigned int resamples;
- double clockResolution;
- double clockCost;
- };
-
- template <class Duration>
- struct BenchmarkStats {
- BenchmarkInfo info;
-
- std::vector<Duration> samples;
- Benchmark::Estimate<Duration> mean;
- Benchmark::Estimate<Duration> standardDeviation;
- Benchmark::OutlierClassification outliers;
- double outlierVariance;
-
- template <typename Duration2>
- operator BenchmarkStats<Duration2>() const {
- std::vector<Duration2> samples2;
- samples2.reserve(samples.size());
- std::transform(samples.begin(), samples.end(), std::back_inserter(samples2), [](Duration d) { return Duration2(d); });
- return {
- info,
- std::move(samples2),
- mean,
- standardDeviation,
- outliers,
- outlierVariance,
- };
- }
- };
-#endif // CATCH_CONFIG_ENABLE_BENCHMARKING
-
- struct IStreamingReporter {
- virtual ~IStreamingReporter() = default;
-
- // Implementing class must also provide the following static methods:
- // static std::string getDescription();
- // static std::set<Verbosity> getSupportedVerbosities()
-
- virtual ReporterPreferences getPreferences() const = 0;
-
- virtual void noMatchingTestCases( std::string const& spec ) = 0;
-
- virtual void testRunStarting( TestRunInfo const& testRunInfo ) = 0;
- virtual void testGroupStarting( GroupInfo const& groupInfo ) = 0;
-
- virtual void testCaseStarting( TestCaseInfo const& testInfo ) = 0;
- virtual void sectionStarting( SectionInfo const& sectionInfo ) = 0;
-
-#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
- virtual void benchmarkPreparing( std::string const& ) {}
- virtual void benchmarkStarting( BenchmarkInfo const& ) {}
- virtual void benchmarkEnded( BenchmarkStats<> const& ) {}
- virtual void benchmarkFailed( std::string const& ) {}
-#endif // CATCH_CONFIG_ENABLE_BENCHMARKING
-
- virtual void assertionStarting( AssertionInfo const& assertionInfo ) = 0;
-
- // The return value indicates if the messages buffer should be cleared:
- virtual bool assertionEnded( AssertionStats const& assertionStats ) = 0;
-
- virtual void sectionEnded( SectionStats const& sectionStats ) = 0;
- virtual void testCaseEnded( TestCaseStats const& testCaseStats ) = 0;
- virtual void testGroupEnded( TestGroupStats const& testGroupStats ) = 0;
- virtual void testRunEnded( TestRunStats const& testRunStats ) = 0;
-
- virtual void skipTest( TestCaseInfo const& testInfo ) = 0;
-
- // Default empty implementation provided
- virtual void fatalErrorEncountered( StringRef name );
-
- virtual bool isMulti() const;
- };
- using IStreamingReporterPtr = std::unique_ptr<IStreamingReporter>;
-
- struct IReporterFactory {
- virtual ~IReporterFactory();
- virtual IStreamingReporterPtr create( ReporterConfig const& config ) const = 0;
- virtual std::string getDescription() const = 0;
- };
- using IReporterFactoryPtr = std::shared_ptr<IReporterFactory>;
-
- struct IReporterRegistry {
- using FactoryMap = std::map<std::string, IReporterFactoryPtr>;
- using Listeners = std::vector<IReporterFactoryPtr>;
-
- virtual ~IReporterRegistry();
- virtual IStreamingReporterPtr create( std::string const& name, IConfigPtr const& config ) const = 0;
- virtual FactoryMap const& getFactories() const = 0;
- virtual Listeners const& getListeners() const = 0;
- };
-
-} // end namespace Catch
-
-// end catch_interfaces_reporter.h
-#include <algorithm>
-#include <cstring>
-#include <cfloat>
-#include <cstdio>
-#include <cassert>
-#include <memory>
-#include <ostream>
-
-namespace Catch {
- void prepareExpandedExpression(AssertionResult& result);
-
- // Returns double formatted as %.3f (format expected on output)
- std::string getFormattedDuration( double duration );
-
- std::string serializeFilters( std::vector<std::string> const& container );
-
- template<typename DerivedT>
- struct StreamingReporterBase : IStreamingReporter {
-
- StreamingReporterBase( ReporterConfig const& _config )
- : m_config( _config.fullConfig() ),
- stream( _config.stream() )
- {
- m_reporterPrefs.shouldRedirectStdOut = false;
- if( !DerivedT::getSupportedVerbosities().count( m_config->verbosity() ) )
- CATCH_ERROR( "Verbosity level not supported by this reporter" );
- }
-
- ReporterPreferences getPreferences() const override {
- return m_reporterPrefs;
- }
-
- static std::set<Verbosity> getSupportedVerbosities() {
- return { Verbosity::Normal };
- }
-
- ~StreamingReporterBase() override = default;
-
- void noMatchingTestCases(std::string const&) override {}
-
- void testRunStarting(TestRunInfo const& _testRunInfo) override {
- currentTestRunInfo = _testRunInfo;
- }
-
- void testGroupStarting(GroupInfo const& _groupInfo) override {
- currentGroupInfo = _groupInfo;
- }
-
- void testCaseStarting(TestCaseInfo const& _testInfo) override {
- currentTestCaseInfo = _testInfo;
- }
- void sectionStarting(SectionInfo const& _sectionInfo) override {
- m_sectionStack.push_back(_sectionInfo);
- }
-
- void sectionEnded(SectionStats const& /* _sectionStats */) override {
- m_sectionStack.pop_back();
- }
- void testCaseEnded(TestCaseStats const& /* _testCaseStats */) override {
- currentTestCaseInfo.reset();
- }
- void testGroupEnded(TestGroupStats const& /* _testGroupStats */) override {
- currentGroupInfo.reset();
- }
- void testRunEnded(TestRunStats const& /* _testRunStats */) override {
- currentTestCaseInfo.reset();
- currentGroupInfo.reset();
- currentTestRunInfo.reset();
- }
-
- void skipTest(TestCaseInfo const&) override {
- // Don't do anything with this by default.
- // It can optionally be overridden in the derived class.
- }
-
- IConfigPtr m_config;
- std::ostream& stream;
-
- LazyStat<TestRunInfo> currentTestRunInfo;
- LazyStat<GroupInfo> currentGroupInfo;
- LazyStat<TestCaseInfo> currentTestCaseInfo;
-
- std::vector<SectionInfo> m_sectionStack;
- ReporterPreferences m_reporterPrefs;
- };
-
- template<typename DerivedT>
- struct CumulativeReporterBase : IStreamingReporter {
- template<typename T, typename ChildNodeT>
- struct Node {
- explicit Node( T const& _value ) : value( _value ) {}
- virtual ~Node() {}
-
- using ChildNodes = std::vector<std::shared_ptr<ChildNodeT>>;
- T value;
- ChildNodes children;
- };
- struct SectionNode {
- explicit SectionNode(SectionStats const& _stats) : stats(_stats) {}
- virtual ~SectionNode() = default;
-
- bool operator == (SectionNode const& other) const {
- return stats.sectionInfo.lineInfo == other.stats.sectionInfo.lineInfo;
- }
- bool operator == (std::shared_ptr<SectionNode> const& other) const {
- return operator==(*other);
- }
-
- SectionStats stats;
- using ChildSections = std::vector<std::shared_ptr<SectionNode>>;
- using Assertions = std::vector<AssertionStats>;
- ChildSections childSections;
- Assertions assertions;
- std::string stdOut;
- std::string stdErr;
- };
-
- struct BySectionInfo {
- BySectionInfo( SectionInfo const& other ) : m_other( other ) {}
- BySectionInfo( BySectionInfo const& other ) : m_other( other.m_other ) {}
- bool operator() (std::shared_ptr<SectionNode> const& node) const {
- return ((node->stats.sectionInfo.name == m_other.name) &&
- (node->stats.sectionInfo.lineInfo == m_other.lineInfo));
- }
- void operator=(BySectionInfo const&) = delete;
-
- private:
- SectionInfo const& m_other;
- };
-
- using TestCaseNode = Node<TestCaseStats, SectionNode>;
- using TestGroupNode = Node<TestGroupStats, TestCaseNode>;
- using TestRunNode = Node<TestRunStats, TestGroupNode>;
-
- CumulativeReporterBase( ReporterConfig const& _config )
- : m_config( _config.fullConfig() ),
- stream( _config.stream() )
- {
- m_reporterPrefs.shouldRedirectStdOut = false;
- if( !DerivedT::getSupportedVerbosities().count( m_config->verbosity() ) )
- CATCH_ERROR( "Verbosity level not supported by this reporter" );
- }
- ~CumulativeReporterBase() override = default;
-
- ReporterPreferences getPreferences() const override {
- return m_reporterPrefs;
- }
-
- static std::set<Verbosity> getSupportedVerbosities() {
- return { Verbosity::Normal };
- }
-
- void testRunStarting( TestRunInfo const& ) override {}
- void testGroupStarting( GroupInfo const& ) override {}
-
- void testCaseStarting( TestCaseInfo const& ) override {}
-
- void sectionStarting( SectionInfo const& sectionInfo ) override {
- SectionStats incompleteStats( sectionInfo, Counts(), 0, false );
- std::shared_ptr<SectionNode> node;
- if( m_sectionStack.empty() ) {
- if( !m_rootSection )
- m_rootSection = std::make_shared<SectionNode>( incompleteStats );
- node = m_rootSection;
- }
- else {
- SectionNode& parentNode = *m_sectionStack.back();
- auto it =
- std::find_if( parentNode.childSections.begin(),
- parentNode.childSections.end(),
- BySectionInfo( sectionInfo ) );
- if( it == parentNode.childSections.end() ) {
- node = std::make_shared<SectionNode>( incompleteStats );
- parentNode.childSections.push_back( node );
- }
- else
- node = *it;
- }
- m_sectionStack.push_back( node );
- m_deepestSection = std::move(node);
- }
-
- void assertionStarting(AssertionInfo const&) override {}
-
- bool assertionEnded(AssertionStats const& assertionStats) override {
- assert(!m_sectionStack.empty());
- // AssertionResult holds a pointer to a temporary DecomposedExpression,
- // which getExpandedExpression() calls to build the expression string.
- // Our section stack copy of the assertionResult will likely outlive the
- // temporary, so it must be expanded or discarded now to avoid calling
- // a destroyed object later.
- prepareExpandedExpression(const_cast<AssertionResult&>( assertionStats.assertionResult ) );
- SectionNode& sectionNode = *m_sectionStack.back();
- sectionNode.assertions.push_back(assertionStats);
- return true;
- }
- void sectionEnded(SectionStats const& sectionStats) override {
- assert(!m_sectionStack.empty());
- SectionNode& node = *m_sectionStack.back();
- node.stats = sectionStats;
- m_sectionStack.pop_back();
- }
- void testCaseEnded(TestCaseStats const& testCaseStats) override {
- auto node = std::make_shared<TestCaseNode>(testCaseStats);
- assert(m_sectionStack.size() == 0);
- node->children.push_back(m_rootSection);
- m_testCases.push_back(node);
- m_rootSection.reset();
-
- assert(m_deepestSection);
- m_deepestSection->stdOut = testCaseStats.stdOut;
- m_deepestSection->stdErr = testCaseStats.stdErr;
- }
- void testGroupEnded(TestGroupStats const& testGroupStats) override {
- auto node = std::make_shared<TestGroupNode>(testGroupStats);
- node->children.swap(m_testCases);
- m_testGroups.push_back(node);
- }
- void testRunEnded(TestRunStats const& testRunStats) override {
- auto node = std::make_shared<TestRunNode>(testRunStats);
- node->children.swap(m_testGroups);
- m_testRuns.push_back(node);
- testRunEndedCumulative();
- }
- virtual void testRunEndedCumulative() = 0;
-
- void skipTest(TestCaseInfo const&) override {}
-
- IConfigPtr m_config;
- std::ostream& stream;
- std::vector<AssertionStats> m_assertions;
- std::vector<std::vector<std::shared_ptr<SectionNode>>> m_sections;
- std::vector<std::shared_ptr<TestCaseNode>> m_testCases;
- std::vector<std::shared_ptr<TestGroupNode>> m_testGroups;
-
- std::vector<std::shared_ptr<TestRunNode>> m_testRuns;
-
- std::shared_ptr<SectionNode> m_rootSection;
- std::shared_ptr<SectionNode> m_deepestSection;
- std::vector<std::shared_ptr<SectionNode>> m_sectionStack;
- ReporterPreferences m_reporterPrefs;
- };
-
- template<char C>
- char const* getLineOfChars() {
- static char line[CATCH_CONFIG_CONSOLE_WIDTH] = {0};
- if( !*line ) {
- std::memset( line, C, CATCH_CONFIG_CONSOLE_WIDTH-1 );
- line[CATCH_CONFIG_CONSOLE_WIDTH-1] = 0;
- }
- return line;
- }
-
- struct TestEventListenerBase : StreamingReporterBase<TestEventListenerBase> {
- TestEventListenerBase( ReporterConfig const& _config );
-
- static std::set<Verbosity> getSupportedVerbosities();
-
- void assertionStarting(AssertionInfo const&) override;
- bool assertionEnded(AssertionStats const&) override;
- };
-
-} // end namespace Catch
-
-// end catch_reporter_bases.hpp
-// start catch_console_colour.h
-
-namespace Catch {
-
- struct Colour {
- enum Code {
- None = 0,
-
- White,
- Red,
- Green,
- Blue,
- Cyan,
- Yellow,
- Grey,
-
- Bright = 0x10,
-
- BrightRed = Bright | Red,
- BrightGreen = Bright | Green,
- LightGrey = Bright | Grey,
- BrightWhite = Bright | White,
- BrightYellow = Bright | Yellow,
-
- // By intention
- FileName = LightGrey,
- Warning = BrightYellow,
- ResultError = BrightRed,
- ResultSuccess = BrightGreen,
- ResultExpectedFailure = Warning,
-
- Error = BrightRed,
- Success = Green,
-
- OriginalExpression = Cyan,
- ReconstructedExpression = BrightYellow,
-
- SecondaryText = LightGrey,
- Headers = White
- };
-
- // Use constructed object for RAII guard
- Colour( Code _colourCode );
- Colour( Colour&& other ) noexcept;
- Colour& operator=( Colour&& other ) noexcept;
- ~Colour();
-
- // Use static method for one-shot changes
- static void use( Code _colourCode );
-
- private:
- bool m_moved = false;
- };
-
- std::ostream& operator << ( std::ostream& os, Colour const& );
-
-} // end namespace Catch
-
-// end catch_console_colour.h
-// start catch_reporter_registrars.hpp
-
-
-namespace Catch {
-
- template<typename T>
- class ReporterRegistrar {
-
- class ReporterFactory : public IReporterFactory {
-
- IStreamingReporterPtr create( ReporterConfig const& config ) const override {
- return std::unique_ptr<T>( new T( config ) );
- }
-
- std::string getDescription() const override {
- return T::getDescription();
- }
- };
-
- public:
-
- explicit ReporterRegistrar( std::string const& name ) {
- getMutableRegistryHub().registerReporter( name, std::make_shared<ReporterFactory>() );
- }
- };
-
- template<typename T>
- class ListenerRegistrar {
-
- class ListenerFactory : public IReporterFactory {
-
- IStreamingReporterPtr create( ReporterConfig const& config ) const override {
- return std::unique_ptr<T>( new T( config ) );
- }
- std::string getDescription() const override {
- return std::string();
- }
- };
-
- public:
-
- ListenerRegistrar() {
- getMutableRegistryHub().registerListener( std::make_shared<ListenerFactory>() );
- }
- };
-}
-
-#if !defined(CATCH_CONFIG_DISABLE)
-
-#define CATCH_REGISTER_REPORTER( name, reporterType ) \
- CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
- namespace{ Catch::ReporterRegistrar<reporterType> catch_internal_RegistrarFor##reporterType( name ); } \
- CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
-
-#define CATCH_REGISTER_LISTENER( listenerType ) \
- CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
- namespace{ Catch::ListenerRegistrar<listenerType> catch_internal_RegistrarFor##listenerType; } \
- CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS
-#else // CATCH_CONFIG_DISABLE
-
-#define CATCH_REGISTER_REPORTER(name, reporterType)
-#define CATCH_REGISTER_LISTENER(listenerType)
-
-#endif // CATCH_CONFIG_DISABLE
-
-// end catch_reporter_registrars.hpp
-// Allow users to base their work off existing reporters
-// start catch_reporter_compact.h
-
-namespace Catch {
-
- struct CompactReporter : StreamingReporterBase<CompactReporter> {
-
- using StreamingReporterBase::StreamingReporterBase;
-
- ~CompactReporter() override;
-
- static std::string getDescription();
-
- ReporterPreferences getPreferences() const override;
-
- void noMatchingTestCases(std::string const& spec) override;
-
- void assertionStarting(AssertionInfo const&) override;
-
- bool assertionEnded(AssertionStats const& _assertionStats) override;
-
- void sectionEnded(SectionStats const& _sectionStats) override;
-
- void testRunEnded(TestRunStats const& _testRunStats) override;
-
- };
-
-} // end namespace Catch
-
-// end catch_reporter_compact.h
-// start catch_reporter_console.h
-
-#if defined(_MSC_VER)
-#pragma warning(push)
-#pragma warning(disable:4061) // Not all labels are EXPLICITLY handled in switch
- // Note that 4062 (not all labels are handled
- // and default is missing) is enabled
-#endif
-
-namespace Catch {
- // Fwd decls
- struct SummaryColumn;
- class TablePrinter;
-
- struct ConsoleReporter : StreamingReporterBase<ConsoleReporter> {
- std::unique_ptr<TablePrinter> m_tablePrinter;
-
- ConsoleReporter(ReporterConfig const& config);
- ~ConsoleReporter() override;
- static std::string getDescription();
-
- void noMatchingTestCases(std::string const& spec) override;
-
- void assertionStarting(AssertionInfo const&) override;
-
- bool assertionEnded(AssertionStats const& _assertionStats) override;
-
- void sectionStarting(SectionInfo const& _sectionInfo) override;
- void sectionEnded(SectionStats const& _sectionStats) override;
-
-#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
- void benchmarkPreparing(std::string const& name) override;
- void benchmarkStarting(BenchmarkInfo const& info) override;
- void benchmarkEnded(BenchmarkStats<> const& stats) override;
- void benchmarkFailed(std::string const& error) override;
-#endif // CATCH_CONFIG_ENABLE_BENCHMARKING
-
- void testCaseEnded(TestCaseStats const& _testCaseStats) override;
- void testGroupEnded(TestGroupStats const& _testGroupStats) override;
- void testRunEnded(TestRunStats const& _testRunStats) override;
- void testRunStarting(TestRunInfo const& _testRunInfo) override;
- private:
-
- void lazyPrint();
-
- void lazyPrintWithoutClosingBenchmarkTable();
- void lazyPrintRunInfo();
- void lazyPrintGroupInfo();
- void printTestCaseAndSectionHeader();
-
- void printClosedHeader(std::string const& _name);
- void printOpenHeader(std::string const& _name);
-
- // if string has a : in first line will set indent to follow it on
- // subsequent lines
- void printHeaderString(std::string const& _string, std::size_t indent = 0);
-
- void printTotals(Totals const& totals);
- void printSummaryRow(std::string const& label, std::vector<SummaryColumn> const& cols, std::size_t row);
-
- void printTotalsDivider(Totals const& totals);
- void printSummaryDivider();
- void printTestFilters();
-
- private:
- bool m_headerPrinted = false;
- };
-
-} // end namespace Catch
-
-#if defined(_MSC_VER)
-#pragma warning(pop)
-#endif
-
-// end catch_reporter_console.h
-// start catch_reporter_junit.h
-
-// start catch_xmlwriter.h
-
-#include <vector>
-
-namespace Catch {
-
- class XmlEncode {
- public:
- enum ForWhat { ForTextNodes, ForAttributes };
-
- XmlEncode( std::string const& str, ForWhat forWhat = ForTextNodes );
-
- void encodeTo( std::ostream& os ) const;
-
- friend std::ostream& operator << ( std::ostream& os, XmlEncode const& xmlEncode );
-
- private:
- std::string m_str;
- ForWhat m_forWhat;
- };
-
- class XmlWriter {
- public:
-
- class ScopedElement {
- public:
- ScopedElement( XmlWriter* writer );
-
- ScopedElement( ScopedElement&& other ) noexcept;
- ScopedElement& operator=( ScopedElement&& other ) noexcept;
-
- ~ScopedElement();
-
- ScopedElement& writeText( std::string const& text, bool indent = true );
-
- template<typename T>
- ScopedElement& writeAttribute( std::string const& name, T const& attribute ) {
- m_writer->writeAttribute( name, attribute );
- return *this;
- }
-
- private:
- mutable XmlWriter* m_writer = nullptr;
- };
-
- XmlWriter( std::ostream& os = Catch::cout() );
- ~XmlWriter();
-
- XmlWriter( XmlWriter const& ) = delete;
- XmlWriter& operator=( XmlWriter const& ) = delete;
-
- XmlWriter& startElement( std::string const& name );
-
- ScopedElement scopedElement( std::string const& name );
-
- XmlWriter& endElement();
-
- XmlWriter& writeAttribute( std::string const& name, std::string const& attribute );
-
- XmlWriter& writeAttribute( std::string const& name, bool attribute );
-
- template<typename T>
- XmlWriter& writeAttribute( std::string const& name, T const& attribute ) {
- ReusableStringStream rss;
- rss << attribute;
- return writeAttribute( name, rss.str() );
- }
-
- XmlWriter& writeText( std::string const& text, bool indent = true );
-
- XmlWriter& writeComment( std::string const& text );
-
- void writeStylesheetRef( std::string const& url );
-
- XmlWriter& writeBlankLine();
-
- void ensureTagClosed();
-
- private:
-
- void writeDeclaration();
-
- void newlineIfNecessary();
-
- bool m_tagIsOpen = false;
- bool m_needsNewline = false;
- std::vector<std::string> m_tags;
- std::string m_indent;
- std::ostream& m_os;
- };
-
-}
-
-// end catch_xmlwriter.h
-namespace Catch {
-
- class JunitReporter : public CumulativeReporterBase<JunitReporter> {
- public:
- JunitReporter(ReporterConfig const& _config);
-
- ~JunitReporter() override;
-
- static std::string getDescription();
-
- void noMatchingTestCases(std::string const& /*spec*/) override;
-
- void testRunStarting(TestRunInfo const& runInfo) override;
-
- void testGroupStarting(GroupInfo const& groupInfo) override;
-
- void testCaseStarting(TestCaseInfo const& testCaseInfo) override;
- bool assertionEnded(AssertionStats const& assertionStats) override;
-
- void testCaseEnded(TestCaseStats const& testCaseStats) override;
-
- void testGroupEnded(TestGroupStats const& testGroupStats) override;
-
- void testRunEndedCumulative() override;
-
- void writeGroup(TestGroupNode const& groupNode, double suiteTime);
-
- void writeTestCase(TestCaseNode const& testCaseNode);
-
- void writeSection(std::string const& className,
- std::string const& rootName,
- SectionNode const& sectionNode);
-
- void writeAssertions(SectionNode const& sectionNode);
- void writeAssertion(AssertionStats const& stats);
-
- XmlWriter xml;
- Timer suiteTimer;
- std::string stdOutForSuite;
- std::string stdErrForSuite;
- unsigned int unexpectedExceptions = 0;
- bool m_okToFail = false;
- };
-
-} // end namespace Catch
-
-// end catch_reporter_junit.h
-// start catch_reporter_xml.h
-
-namespace Catch {
- class XmlReporter : public StreamingReporterBase<XmlReporter> {
- public:
- XmlReporter(ReporterConfig const& _config);
-
- ~XmlReporter() override;
-
- static std::string getDescription();
-
- virtual std::string getStylesheetRef() const;
-
- void writeSourceInfo(SourceLineInfo const& sourceInfo);
-
- public: // StreamingReporterBase
-
- void noMatchingTestCases(std::string const& s) override;
-
- void testRunStarting(TestRunInfo const& testInfo) override;
-
- void testGroupStarting(GroupInfo const& groupInfo) override;
-
- void testCaseStarting(TestCaseInfo const& testInfo) override;
-
- void sectionStarting(SectionInfo const& sectionInfo) override;
-
- void assertionStarting(AssertionInfo const&) override;
-
- bool assertionEnded(AssertionStats const& assertionStats) override;
-
- void sectionEnded(SectionStats const& sectionStats) override;
-
- void testCaseEnded(TestCaseStats const& testCaseStats) override;
-
- void testGroupEnded(TestGroupStats const& testGroupStats) override;
-
- void testRunEnded(TestRunStats const& testRunStats) override;
-
-#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
- void benchmarkStarting(BenchmarkInfo const&) override;
- void benchmarkEnded(BenchmarkStats<> const&) override;
- void benchmarkFailed(std::string const&) override;
-#endif // CATCH_CONFIG_ENABLE_BENCHMARKING
-
- private:
- Timer m_testCaseTimer;
- XmlWriter m_xml;
- int m_sectionDepth = 0;
- };
-
-} // end namespace Catch
-
-// end catch_reporter_xml.h
-
-// end catch_external_interfaces.h
-#endif
-
-#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
-// start catch_benchmark.hpp
-
- // Benchmark
-
-// start catch_chronometer.hpp
-
-// User-facing chronometer
-
-
-// start catch_clock.hpp
-
-// Clocks
-
-
-#include <chrono>
-#include <ratio>
-
-namespace Catch {
- namespace Benchmark {
- template <typename Clock>
- using ClockDuration = typename Clock::duration;
- template <typename Clock>
- using FloatDuration = std::chrono::duration<double, typename Clock::period>;
-
- template <typename Clock>
- using TimePoint = typename Clock::time_point;
-
- using default_clock = std::chrono::steady_clock;
-
- template <typename Clock>
- struct now {
- TimePoint<Clock> operator()() const {
- return Clock::now();
- }
- };
-
- using fp_seconds = std::chrono::duration<double, std::ratio<1>>;
- } // namespace Benchmark
-} // namespace Catch
-
-// end catch_clock.hpp
-// start catch_optimizer.hpp
-
- // Hinting the optimizer
-
-
-#if defined(_MSC_VER)
-# include <atomic> // atomic_thread_fence
-#endif
-
-namespace Catch {
- namespace Benchmark {
-#if defined(__GNUC__) || defined(__clang__)
- template <typename T>
- inline void keep_memory(T* p) {
- asm volatile("" : : "g"(p) : "memory");
- }
- inline void keep_memory() {
- asm volatile("" : : : "memory");
- }
-
- namespace Detail {
- inline void optimizer_barrier() { keep_memory(); }
- } // namespace Detail
-#elif defined(_MSC_VER)
-
-#pragma optimize("", off)
- template <typename T>
- inline void keep_memory(T* p) {
- // thanks @milleniumbug
- *reinterpret_cast<char volatile*>(p) = *reinterpret_cast<char const volatile*>(p);
- }
- // TODO equivalent keep_memory()
-#pragma optimize("", on)
-
- namespace Detail {
- inline void optimizer_barrier() {
- std::atomic_thread_fence(std::memory_order_seq_cst);
- }
- } // namespace Detail
-
-#endif
-
- template <typename T>
- inline void deoptimize_value(T&& x) {
- keep_memory(&x);
- }
-
- template <typename Fn, typename... Args>
- inline auto invoke_deoptimized(Fn&& fn, Args&&... args) -> typename std::enable_if<!std::is_same<void, decltype(fn(args...))>::value>::type {
- deoptimize_value(std::forward<Fn>(fn) (std::forward<Args...>(args...)));
- }
-
- template <typename Fn, typename... Args>
- inline auto invoke_deoptimized(Fn&& fn, Args&&... args) -> typename std::enable_if<std::is_same<void, decltype(fn(args...))>::value>::type {
- std::forward<Fn>(fn) (std::forward<Args...>(args...));
- }
- } // namespace Benchmark
-} // namespace Catch
-
-// end catch_optimizer.hpp
-// start catch_complete_invoke.hpp
-
-// Invoke with a special case for void
-
-
-#include <type_traits>
-#include <utility>
-
-namespace Catch {
- namespace Benchmark {
- namespace Detail {
- template <typename T>
- struct CompleteType { using type = T; };
- template <>
- struct CompleteType<void> { struct type {}; };
-
- template <typename T>
- using CompleteType_t = typename CompleteType<T>::type;
-
- template <typename Result>
- struct CompleteInvoker {
- template <typename Fun, typename... Args>
- static Result invoke(Fun&& fun, Args&&... args) {
- return std::forward<Fun>(fun)(std::forward<Args>(args)...);
- }
- };
- template <>
- struct CompleteInvoker<void> {
- template <typename Fun, typename... Args>
- static CompleteType_t<void> invoke(Fun&& fun, Args&&... args) {
- std::forward<Fun>(fun)(std::forward<Args>(args)...);
- return {};
- }
- };
- template <typename Sig>
- using ResultOf_t = typename std::result_of<Sig>::type;
-
- // invoke and not return void :(
- template <typename Fun, typename... Args>
- CompleteType_t<ResultOf_t<Fun(Args...)>> complete_invoke(Fun&& fun, Args&&... args) {
- return CompleteInvoker<ResultOf_t<Fun(Args...)>>::invoke(std::forward<Fun>(fun), std::forward<Args>(args)...);
- }
-
- const std::string benchmarkErrorMsg = "a benchmark failed to run successfully";
- } // namespace Detail
-
- template <typename Fun>
- Detail::CompleteType_t<Detail::ResultOf_t<Fun()>> user_code(Fun&& fun) {
- CATCH_TRY{
- return Detail::complete_invoke(std::forward<Fun>(fun));
- } CATCH_CATCH_ALL{
- getResultCapture().benchmarkFailed(translateActiveException());
- CATCH_RUNTIME_ERROR(Detail::benchmarkErrorMsg);
- }
- }
- } // namespace Benchmark
-} // namespace Catch
-
-// end catch_complete_invoke.hpp
-namespace Catch {
- namespace Benchmark {
- namespace Detail {
- struct ChronometerConcept {
- virtual void start() = 0;
- virtual void finish() = 0;
- virtual ~ChronometerConcept() = default;
- };
- template <typename Clock>
- struct ChronometerModel final : public ChronometerConcept {
- void start() override { started = Clock::now(); }
- void finish() override { finished = Clock::now(); }
-
- ClockDuration<Clock> elapsed() const { return finished - started; }
-
- TimePoint<Clock> started;
- TimePoint<Clock> finished;
- };
- } // namespace Detail
-
- struct Chronometer {
- public:
- template <typename Fun>
- void measure(Fun&& fun) { measure(std::forward<Fun>(fun), is_callable<Fun(int)>()); }
-
- int runs() const { return k; }
-
- Chronometer(Detail::ChronometerConcept& meter, int k)
- : impl(&meter)
- , k(k) {}
-
- private:
- template <typename Fun>
- void measure(Fun&& fun, std::false_type) {
- measure([&fun](int) { return fun(); }, std::true_type());
- }
-
- template <typename Fun>
- void measure(Fun&& fun, std::true_type) {
- Detail::optimizer_barrier();
- impl->start();
- for (int i = 0; i < k; ++i) invoke_deoptimized(fun, i);
- impl->finish();
- Detail::optimizer_barrier();
- }
-
- Detail::ChronometerConcept* impl;
- int k;
- };
- } // namespace Benchmark
-} // namespace Catch
-
-// end catch_chronometer.hpp
-// start catch_environment.hpp
-
-// Environment information
-
-
-namespace Catch {
- namespace Benchmark {
- template <typename Duration>
- struct EnvironmentEstimate {
- Duration mean;
- OutlierClassification outliers;
-
- template <typename Duration2>
- operator EnvironmentEstimate<Duration2>() const {
- return { mean, outliers };
- }
- };
- template <typename Clock>
- struct Environment {
- using clock_type = Clock;
- EnvironmentEstimate<FloatDuration<Clock>> clock_resolution;
- EnvironmentEstimate<FloatDuration<Clock>> clock_cost;
- };
- } // namespace Benchmark
-} // namespace Catch
-
-// end catch_environment.hpp
-// start catch_execution_plan.hpp
-
- // Execution plan
-
-
-// start catch_benchmark_function.hpp
-
- // Dumb std::function implementation for consistent call overhead
-
-
-#include <cassert>
-#include <type_traits>
-#include <utility>
-#include <memory>
-
-namespace Catch {
- namespace Benchmark {
- namespace Detail {
- template <typename T>
- using Decay = typename std::decay<T>::type;
- template <typename T, typename U>
- struct is_related
- : std::is_same<Decay<T>, Decay<U>> {};
-
- /// We need to reinvent std::function because every piece of code that might add overhead
- /// in a measurement context needs to have consistent performance characteristics so that we
- /// can account for it in the measurement.
- /// Implementations of std::function with optimizations that aren't always applicable, like
- /// small buffer optimizations, are not uncommon.
- /// This is effectively an implementation of std::function without any such optimizations;
- /// it may be slow, but it is consistently slow.
- struct BenchmarkFunction {
- private:
- struct callable {
- virtual void call(Chronometer meter) const = 0;
- virtual callable* clone() const = 0;
- virtual ~callable() = default;
- };
- template <typename Fun>
- struct model : public callable {
- model(Fun&& fun) : fun(std::move(fun)) {}
- model(Fun const& fun) : fun(fun) {}
-
- model<Fun>* clone() const override { return new model<Fun>(*this); }
-
- void call(Chronometer meter) const override {
- call(meter, is_callable<Fun(Chronometer)>());
- }
- void call(Chronometer meter, std::true_type) const {
- fun(meter);
- }
- void call(Chronometer meter, std::false_type) const {
- meter.measure(fun);
- }
-
- Fun fun;
- };
-
- struct do_nothing { void operator()() const {} };
-
- template <typename T>
- BenchmarkFunction(model<T>* c) : f(c) {}
-
- public:
- BenchmarkFunction()
- : f(new model<do_nothing>{ {} }) {}
-
- template <typename Fun,
- typename std::enable_if<!is_related<Fun, BenchmarkFunction>::value, int>::type = 0>
- BenchmarkFunction(Fun&& fun)
- : f(new model<typename std::decay<Fun>::type>(std::forward<Fun>(fun))) {}
-
- BenchmarkFunction(BenchmarkFunction&& that)
- : f(std::move(that.f)) {}
-
- BenchmarkFunction(BenchmarkFunction const& that)
- : f(that.f->clone()) {}
-
- BenchmarkFunction& operator=(BenchmarkFunction&& that) {
- f = std::move(that.f);
- return *this;
- }
-
- BenchmarkFunction& operator=(BenchmarkFunction const& that) {
- f.reset(that.f->clone());
- return *this;
- }
-
- void operator()(Chronometer meter) const { f->call(meter); }
-
- private:
- std::unique_ptr<callable> f;
- };
- } // namespace Detail
- } // namespace Benchmark
-} // namespace Catch
-
-// end catch_benchmark_function.hpp
-// start catch_repeat.hpp
-
-// repeat algorithm
-
-
-#include <type_traits>
-#include <utility>
-
-namespace Catch {
- namespace Benchmark {
- namespace Detail {
- template <typename Fun>
- struct repeater {
- void operator()(int k) const {
- for (int i = 0; i < k; ++i) {
- fun();
- }
- }
- Fun fun;
- };
- template <typename Fun>
- repeater<typename std::decay<Fun>::type> repeat(Fun&& fun) {
- return { std::forward<Fun>(fun) };
- }
- } // namespace Detail
- } // namespace Benchmark
-} // namespace Catch
-
-// end catch_repeat.hpp
-// start catch_run_for_at_least.hpp
-
-// Run a function for a minimum amount of time
-
-
-// start catch_measure.hpp
-
-// Measure
-
-
-// start catch_timing.hpp
-
-// Timing
-
-
-#include <tuple>
-#include <type_traits>
-
-namespace Catch {
- namespace Benchmark {
- template <typename Duration, typename Result>
- struct Timing {
- Duration elapsed;
- Result result;
- int iterations;
- };
- template <typename Clock, typename Sig>
- using TimingOf = Timing<ClockDuration<Clock>, Detail::CompleteType_t<Detail::ResultOf_t<Sig>>>;
- } // namespace Benchmark
-} // namespace Catch
-
-// end catch_timing.hpp
-#include <utility>
-
-namespace Catch {
- namespace Benchmark {
- namespace Detail {
- template <typename Clock, typename Fun, typename... Args>
- TimingOf<Clock, Fun(Args...)> measure(Fun&& fun, Args&&... args) {
- auto start = Clock::now();
- auto&& r = Detail::complete_invoke(fun, std::forward<Args>(args)...);
- auto end = Clock::now();
- auto delta = end - start;
- return { delta, std::forward<decltype(r)>(r), 1 };
- }
- } // namespace Detail
- } // namespace Benchmark
-} // namespace Catch
-
-// end catch_measure.hpp
-#include <utility>
-#include <type_traits>
-
-namespace Catch {
- namespace Benchmark {
- namespace Detail {
- template <typename Clock, typename Fun>
- TimingOf<Clock, Fun(int)> measure_one(Fun&& fun, int iters, std::false_type) {
- return Detail::measure<Clock>(fun, iters);
- }
- template <typename Clock, typename Fun>
- TimingOf<Clock, Fun(Chronometer)> measure_one(Fun&& fun, int iters, std::true_type) {
- Detail::ChronometerModel<Clock> meter;
- auto&& result = Detail::complete_invoke(fun, Chronometer(meter, iters));
-
- return { meter.elapsed(), std::move(result), iters };
- }
-
- template <typename Clock, typename Fun>
- using run_for_at_least_argument_t = typename std::conditional<is_callable<Fun(Chronometer)>::value, Chronometer, int>::type;
-
- struct optimized_away_error : std::exception {
- const char* what() const noexcept override {
- return "could not measure benchmark, maybe it was optimized away";
- }
- };
-
- template <typename Clock, typename Fun>
- TimingOf<Clock, Fun(run_for_at_least_argument_t<Clock, Fun>)> run_for_at_least(ClockDuration<Clock> how_long, int seed, Fun&& fun) {
- auto iters = seed;
- while (iters < (1 << 30)) {
- auto&& Timing = measure_one<Clock>(fun, iters, is_callable<Fun(Chronometer)>());
-
- if (Timing.elapsed >= how_long) {
- return { Timing.elapsed, std::move(Timing.result), iters };
- }
- iters *= 2;
- }
- throw optimized_away_error{};
- }
- } // namespace Detail
- } // namespace Benchmark
-} // namespace Catch
-
-// end catch_run_for_at_least.hpp
-#include <algorithm>
-
-namespace Catch {
- namespace Benchmark {
- template <typename Duration>
- struct ExecutionPlan {
- int iterations_per_sample;
- Duration estimated_duration;
- Detail::BenchmarkFunction benchmark;
- Duration warmup_time;
- int warmup_iterations;
-
- template <typename Duration2>
- operator ExecutionPlan<Duration2>() const {
- return { iterations_per_sample, estimated_duration, benchmark, warmup_time, warmup_iterations };
- }
-
- template <typename Clock>
- std::vector<FloatDuration<Clock>> run(const IConfig &cfg, Environment<FloatDuration<Clock>> env) const {
- // warmup a bit
- Detail::run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(warmup_time), warmup_iterations, Detail::repeat(now<Clock>{}));
-
- std::vector<FloatDuration<Clock>> times;
- times.reserve(cfg.benchmarkSamples());
- std::generate_n(std::back_inserter(times), cfg.benchmarkSamples(), [this, env] {
- Detail::ChronometerModel<Clock> model;
- this->benchmark(Chronometer(model, iterations_per_sample));
- auto sample_time = model.elapsed() - env.clock_cost.mean;
- if (sample_time < FloatDuration<Clock>::zero()) sample_time = FloatDuration<Clock>::zero();
- return sample_time / iterations_per_sample;
- });
- return times;
- }
- };
- } // namespace Benchmark
-} // namespace Catch
-
-// end catch_execution_plan.hpp
-// start catch_estimate_clock.hpp
-
- // Environment measurement
-
-
-// start catch_stats.hpp
-
-// Statistical analysis tools
-
-
-#include <algorithm>
-#include <functional>
-#include <vector>
-#include <numeric>
-#include <tuple>
-#include <cmath>
-#include <utility>
-#include <cstddef>
-
-namespace Catch {
- namespace Benchmark {
- namespace Detail {
- using sample = std::vector<double>;
-
- double weighted_average_quantile(int k, int q, std::vector<double>::iterator first, std::vector<double>::iterator last);
-
- template <typename Iterator>
- OutlierClassification classify_outliers(Iterator first, Iterator last) {
- std::vector<double> copy(first, last);
-
- auto q1 = weighted_average_quantile(1, 4, copy.begin(), copy.end());
- auto q3 = weighted_average_quantile(3, 4, copy.begin(), copy.end());
- auto iqr = q3 - q1;
- auto los = q1 - (iqr * 3.);
- auto lom = q1 - (iqr * 1.5);
- auto him = q3 + (iqr * 1.5);
- auto his = q3 + (iqr * 3.);
-
- OutlierClassification o;
- for (; first != last; ++first) {
- auto&& t = *first;
- if (t < los) ++o.low_severe;
- else if (t < lom) ++o.low_mild;
- else if (t > his) ++o.high_severe;
- else if (t > him) ++o.high_mild;
- ++o.samples_seen;
- }
- return o;
- }
-
- template <typename Iterator>
- double mean(Iterator first, Iterator last) {
- auto count = last - first;
- double sum = std::accumulate(first, last, 0.);
- return sum / count;
- }
-
- template <typename URng, typename Iterator, typename Estimator>
- sample resample(URng& rng, int resamples, Iterator first, Iterator last, Estimator& estimator) {
- auto n = last - first;
- std::uniform_int_distribution<decltype(n)> dist(0, n - 1);
-
- sample out;
- out.reserve(resamples);
- std::generate_n(std::back_inserter(out), resamples, [n, first, &estimator, &dist, &rng] {
- std::vector<double> resampled;
- resampled.reserve(n);
- std::generate_n(std::back_inserter(resampled), n, [first, &dist, &rng] { return first[dist(rng)]; });
- return estimator(resampled.begin(), resampled.end());
- });
- std::sort(out.begin(), out.end());
- return out;
- }
-
- template <typename Estimator, typename Iterator>
- sample jackknife(Estimator&& estimator, Iterator first, Iterator last) {
- auto n = last - first;
- auto second = std::next(first);
- sample results;
- results.reserve(n);
-
- for (auto it = first; it != last; ++it) {
- std::iter_swap(it, first);
- results.push_back(estimator(second, last));
- }
-
- return results;
- }
-
- inline double normal_cdf(double x) {
- return std::erfc(-x / std::sqrt(2.0)) / 2.0;
- }
-
- double erfc_inv(double x);
-
- double normal_quantile(double p);
-
- template <typename Iterator, typename Estimator>
- Estimate<double> bootstrap(double confidence_level, Iterator first, Iterator last, sample const& resample, Estimator&& estimator) {
- auto n_samples = last - first;
-
- double point = estimator(first, last);
- // Degenerate case with a single sample
- if (n_samples == 1) return { point, point, point, confidence_level };
-
- sample jack = jackknife(estimator, first, last);
- double jack_mean = mean(jack.begin(), jack.end());
- double sum_squares, sum_cubes;
- std::tie(sum_squares, sum_cubes) = std::accumulate(jack.begin(), jack.end(), std::make_pair(0., 0.), [jack_mean](std::pair<double, double> sqcb, double x) -> std::pair<double, double> {
- auto d = jack_mean - x;
- auto d2 = d * d;
- auto d3 = d2 * d;
- return { sqcb.first + d2, sqcb.second + d3 };
- });
-
- double accel = sum_cubes / (6 * std::pow(sum_squares, 1.5));
- int n = static_cast<int>(resample.size());
- double prob_n = std::count_if(resample.begin(), resample.end(), [point](double x) { return x < point; }) / (double)n;
- // degenerate case with uniform samples
- if (prob_n == 0) return { point, point, point, confidence_level };
-
- double bias = normal_quantile(prob_n);
- double z1 = normal_quantile((1. - confidence_level) / 2.);
-
- auto cumn = [n](double x) -> int {
- return std::lround(normal_cdf(x) * n); };
- auto a = [bias, accel](double b) { return bias + b / (1. - accel * b); };
- double b1 = bias + z1;
- double b2 = bias - z1;
- double a1 = a(b1);
- double a2 = a(b2);
- auto lo = std::max(cumn(a1), 0);
- auto hi = std::min(cumn(a2), n - 1);
-
- return { point, resample[lo], resample[hi], confidence_level };
- }
-
- double outlier_variance(Estimate<double> mean, Estimate<double> stddev, int n);
-
- struct bootstrap_analysis {
- Estimate<double> mean;
- Estimate<double> standard_deviation;
- double outlier_variance;
- };
-
- bootstrap_analysis analyse_samples(double confidence_level, int n_resamples, std::vector<double>::iterator first, std::vector<double>::iterator last);
- } // namespace Detail
- } // namespace Benchmark
-} // namespace Catch
-
-// end catch_stats.hpp
-#include <algorithm>
-#include <iterator>
-#include <tuple>
-#include <vector>
-#include <cmath>
-
-namespace Catch {
- namespace Benchmark {
- namespace Detail {
- template <typename Clock>
- std::vector<double> resolution(int k) {
- std::vector<TimePoint<Clock>> times;
- times.reserve(k + 1);
- std::generate_n(std::back_inserter(times), k + 1, now<Clock>{});
-
- std::vector<double> deltas;
- deltas.reserve(k);
- std::transform(std::next(times.begin()), times.end(), times.begin(),
- std::back_inserter(deltas),
- [](TimePoint<Clock> a, TimePoint<Clock> b) { return static_cast<double>((a - b).count()); });
-
- return deltas;
- }
-
- const auto warmup_iterations = 10000;
- const auto warmup_time = std::chrono::milliseconds(100);
- const auto minimum_ticks = 1000;
- const auto warmup_seed = 10000;
- const auto clock_resolution_estimation_time = std::chrono::milliseconds(500);
- const auto clock_cost_estimation_time_limit = std::chrono::seconds(1);
- const auto clock_cost_estimation_tick_limit = 100000;
- const auto clock_cost_estimation_time = std::chrono::milliseconds(10);
- const auto clock_cost_estimation_iterations = 10000;
-
- template <typename Clock>
- int warmup() {
- return run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(warmup_time), warmup_seed, &resolution<Clock>)
- .iterations;
- }
- template <typename Clock>
- EnvironmentEstimate<FloatDuration<Clock>> estimate_clock_resolution(int iterations) {
- auto r = run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(clock_resolution_estimation_time), iterations, &resolution<Clock>)
- .result;
- return {
- FloatDuration<Clock>(mean(r.begin(), r.end())),
- classify_outliers(r.begin(), r.end()),
- };
- }
- template <typename Clock>
- EnvironmentEstimate<FloatDuration<Clock>> estimate_clock_cost(FloatDuration<Clock> resolution) {
- auto time_limit = std::min(resolution * clock_cost_estimation_tick_limit, FloatDuration<Clock>(clock_cost_estimation_time_limit));
- auto time_clock = [](int k) {
- return Detail::measure<Clock>([k] {
- for (int i = 0; i < k; ++i) {
- volatile auto ignored = Clock::now();
- (void)ignored;
- }
- }).elapsed;
- };
- time_clock(1);
- int iters = clock_cost_estimation_iterations;
- auto&& r = run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(clock_cost_estimation_time), iters, time_clock);
- std::vector<double> times;
- int nsamples = static_cast<int>(std::ceil(time_limit / r.elapsed));
- times.reserve(nsamples);
- std::generate_n(std::back_inserter(times), nsamples, [time_clock, &r] {
- return static_cast<double>((time_clock(r.iterations) / r.iterations).count());
- });
- return {
- FloatDuration<Clock>(mean(times.begin(), times.end())),
- classify_outliers(times.begin(), times.end()),
- };
- }
-
- template <typename Clock>
- Environment<FloatDuration<Clock>> measure_environment() {
- static Environment<FloatDuration<Clock>>* env = nullptr;
- if (env) {
- return *env;
- }
-
- auto iters = Detail::warmup<Clock>();
- auto resolution = Detail::estimate_clock_resolution<Clock>(iters);
- auto cost = Detail::estimate_clock_cost<Clock>(resolution.mean);
-
- env = new Environment<FloatDuration<Clock>>{ resolution, cost };
- return *env;
- }
- } // namespace Detail
- } // namespace Benchmark
-} // namespace Catch
-
-// end catch_estimate_clock.hpp
-// start catch_analyse.hpp
-
- // Run and analyse one benchmark
-
-
-// start catch_sample_analysis.hpp
-
-// Benchmark results
-
-
-#include <algorithm>
-#include <vector>
-#include <string>
-#include <iterator>
-
-namespace Catch {
- namespace Benchmark {
- template <typename Duration>
- struct SampleAnalysis {
- std::vector<Duration> samples;
- Estimate<Duration> mean;
- Estimate<Duration> standard_deviation;
- OutlierClassification outliers;
- double outlier_variance;
-
- template <typename Duration2>
- operator SampleAnalysis<Duration2>() const {
- std::vector<Duration2> samples2;
- samples2.reserve(samples.size());
- std::transform(samples.begin(), samples.end(), std::back_inserter(samples2), [](Duration d) { return Duration2(d); });
- return {
- std::move(samples2),
- mean,
- standard_deviation,
- outliers,
- outlier_variance,
- };
- }
- };
- } // namespace Benchmark
-} // namespace Catch
-
-// end catch_sample_analysis.hpp
-#include <algorithm>
-#include <iterator>
-#include <vector>
-
-namespace Catch {
- namespace Benchmark {
- namespace Detail {
- template <typename Duration, typename Iterator>
- SampleAnalysis<Duration> analyse(const IConfig &cfg, Environment<Duration>, Iterator first, Iterator last) {
- if (!cfg.benchmarkNoAnalysis()) {
- std::vector<double> samples;
- samples.reserve(last - first);
- std::transform(first, last, std::back_inserter(samples), [](Duration d) { return d.count(); });
-
- auto analysis = Catch::Benchmark::Detail::analyse_samples(cfg.benchmarkConfidenceInterval(), cfg.benchmarkResamples(), samples.begin(), samples.end());
- auto outliers = Catch::Benchmark::Detail::classify_outliers(samples.begin(), samples.end());
-
- auto wrap_estimate = [](Estimate<double> e) {
- return Estimate<Duration> {
- Duration(e.point),
- Duration(e.lower_bound),
- Duration(e.upper_bound),
- e.confidence_interval,
- };
- };
- std::vector<Duration> samples2;
- samples2.reserve(samples.size());
- std::transform(samples.begin(), samples.end(), std::back_inserter(samples2), [](double d) { return Duration(d); });
- return {
- std::move(samples2),
- wrap_estimate(analysis.mean),
- wrap_estimate(analysis.standard_deviation),
- outliers,
- analysis.outlier_variance,
- };
- } else {
- std::vector<Duration> samples;
- samples.reserve(last - first);
-
- Duration mean = Duration(0);
- int i = 0;
- for (auto it = first; it < last; ++it, ++i) {
- samples.push_back(Duration(*it));
- mean += Duration(*it);
- }
- mean /= i;
-
- return {
- std::move(samples),
- Estimate<Duration>{mean, mean, mean, 0.0},
- Estimate<Duration>{Duration(0), Duration(0), Duration(0), 0.0},
- OutlierClassification{},
- 0.0
- };
- }
- }
- } // namespace Detail
- } // namespace Benchmark
-} // namespace Catch
-
-// end catch_analyse.hpp
-#include <algorithm>
-#include <functional>
-#include <string>
-#include <vector>
-#include <cmath>
-
-namespace Catch {
- namespace Benchmark {
- struct Benchmark {
- Benchmark(std::string &&name)
- : name(std::move(name)) {}
-
- template <class FUN>
- Benchmark(std::string &&name, FUN &&func)
- : fun(std::move(func)), name(std::move(name)) {}
-
- template <typename Clock>
- ExecutionPlan<FloatDuration<Clock>> prepare(const IConfig &cfg, Environment<FloatDuration<Clock>> env) const {
- auto min_time = env.clock_resolution.mean * Detail::minimum_ticks;
- auto run_time = std::max(min_time, std::chrono::duration_cast<decltype(min_time)>(Detail::warmup_time));
- auto&& test = Detail::run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(run_time), 1, fun);
- int new_iters = static_cast<int>(std::ceil(min_time * test.iterations / test.elapsed));
- return { new_iters, test.elapsed / test.iterations * new_iters * cfg.benchmarkSamples(), fun, std::chrono::duration_cast<FloatDuration<Clock>>(Detail::warmup_time), Detail::warmup_iterations };
- }
-
- template <typename Clock = default_clock>
- void run() {
- IConfigPtr cfg = getCurrentContext().getConfig();
-
- auto env = Detail::measure_environment<Clock>();
-
- getResultCapture().benchmarkPreparing(name);
- CATCH_TRY{
- auto plan = user_code([&] {
- return prepare<Clock>(*cfg, env);
- });
-
- BenchmarkInfo info {
- name,
- plan.estimated_duration.count(),
- plan.iterations_per_sample,
- cfg->benchmarkSamples(),
- cfg->benchmarkResamples(),
- env.clock_resolution.mean.count(),
- env.clock_cost.mean.count()
- };
-
- getResultCapture().benchmarkStarting(info);
-
- auto samples = user_code([&] {
- return plan.template run<Clock>(*cfg, env);
- });
-
- auto analysis = Detail::analyse(*cfg, env, samples.begin(), samples.end());
- BenchmarkStats<std::chrono::duration<double, std::nano>> stats{ info, analysis.samples, analysis.mean, analysis.standard_deviation, analysis.outliers, analysis.outlier_variance };
- getResultCapture().benchmarkEnded(stats);
-
- } CATCH_CATCH_ALL{
- if (translateActiveException() != Detail::benchmarkErrorMsg) // benchmark errors have been reported, otherwise rethrow.
- std::rethrow_exception(std::current_exception());
- }
- }
-
- // sets lambda to be used in fun *and* executes benchmark!
- template <typename Fun,
- typename std::enable_if<!Detail::is_related<Fun, Benchmark>::value, int>::type = 0>
- Benchmark & operator=(Fun func) {
- fun = Detail::BenchmarkFunction(func);
- run();
- return *this;
- }
-
- explicit operator bool() {
- return true;
- }
-
- private:
- Detail::BenchmarkFunction fun;
- std::string name;
- };
- }
-} // namespace Catch
-
-#define INTERNAL_CATCH_GET_1_ARG(arg1, arg2, ...) arg1
-#define INTERNAL_CATCH_GET_2_ARG(arg1, arg2, ...) arg2
-
-#define INTERNAL_CATCH_BENCHMARK(BenchmarkName, name, benchmarkIndex)\
- if( Catch::Benchmark::Benchmark BenchmarkName{name} ) \
- BenchmarkName = [&](int benchmarkIndex)
-
-#define INTERNAL_CATCH_BENCHMARK_ADVANCED(BenchmarkName, name)\
- if( Catch::Benchmark::Benchmark BenchmarkName{name} ) \
- BenchmarkName = [&]
-
-// end catch_benchmark.hpp
-#endif
-
-#endif // ! CATCH_CONFIG_IMPL_ONLY
-
-#ifdef CATCH_IMPL
-// start catch_impl.hpp
-
-#ifdef __clang__
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wweak-vtables"
-#endif
-
-// Keep these here for external reporters
-// start catch_test_case_tracker.h
-
-#include <string>
-#include <vector>
-#include <memory>
-
-namespace Catch {
-namespace TestCaseTracking {
-
- struct NameAndLocation {
- std::string name;
- SourceLineInfo location;
-
- NameAndLocation( std::string const& _name, SourceLineInfo const& _location );
- };
-
- struct ITracker;
-
- using ITrackerPtr = std::shared_ptr<ITracker>;
-
- struct ITracker {
- virtual ~ITracker();
-
- // static queries
- virtual NameAndLocation const& nameAndLocation() const = 0;
-
- // dynamic queries
- virtual bool isComplete() const = 0; // Successfully completed or failed
- virtual bool isSuccessfullyCompleted() const = 0;
- virtual bool isOpen() const = 0; // Started but not complete
- virtual bool hasChildren() const = 0;
-
- virtual ITracker& parent() = 0;
-
- // actions
- virtual void close() = 0; // Successfully complete
- virtual void fail() = 0;
- virtual void markAsNeedingAnotherRun() = 0;
-
- virtual void addChild( ITrackerPtr const& child ) = 0;
- virtual ITrackerPtr findChild( NameAndLocation const& nameAndLocation ) = 0;
- virtual void openChild() = 0;
-
- // Debug/ checking
- virtual bool isSectionTracker() const = 0;
- virtual bool isGeneratorTracker() const = 0;
- };
-
- class TrackerContext {
-
- enum RunState {
- NotStarted,
- Executing,
- CompletedCycle
- };
-
- ITrackerPtr m_rootTracker;
- ITracker* m_currentTracker = nullptr;
- RunState m_runState = NotStarted;
-
- public:
-
- ITracker& startRun();
- void endRun();
-
- void startCycle();
- void completeCycle();
-
- bool completedCycle() const;
- ITracker& currentTracker();
- void setCurrentTracker( ITracker* tracker );
- };
-
- class TrackerBase : public ITracker {
- protected:
- enum CycleState {
- NotStarted,
- Executing,
- ExecutingChildren,
- NeedsAnotherRun,
- CompletedSuccessfully,
- Failed
- };
-
- using Children = std::vector<ITrackerPtr>;
- NameAndLocation m_nameAndLocation;
- TrackerContext& m_ctx;
- ITracker* m_parent;
- Children m_children;
- CycleState m_runState = NotStarted;
-
- public:
- TrackerBase( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent );
-
- NameAndLocation const& nameAndLocation() const override;
- bool isComplete() const override;
- bool isSuccessfullyCompleted() const override;
- bool isOpen() const override;
- bool hasChildren() const override;
-
- void addChild( ITrackerPtr const& child ) override;
-
- ITrackerPtr findChild( NameAndLocation const& nameAndLocation ) override;
- ITracker& parent() override;
-
- void openChild() override;
-
- bool isSectionTracker() const override;
- bool isGeneratorTracker() const override;
-
- void open();
-
- void close() override;
- void fail() override;
- void markAsNeedingAnotherRun() override;
-
- private:
- void moveToParent();
- void moveToThis();
- };
-
- class SectionTracker : public TrackerBase {
- std::vector<std::string> m_filters;
- public:
- SectionTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent );
-
- bool isSectionTracker() const override;
-
- bool isComplete() const override;
-
- static SectionTracker& acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation );
-
- void tryOpen();
-
- void addInitialFilters( std::vector<std::string> const& filters );
- void addNextFilters( std::vector<std::string> const& filters );
- };
-
-} // namespace TestCaseTracking
-
-using TestCaseTracking::ITracker;
-using TestCaseTracking::TrackerContext;
-using TestCaseTracking::SectionTracker;
-
-} // namespace Catch
-
-// end catch_test_case_tracker.h
-
-// start catch_leak_detector.h
-
-namespace Catch {
-
- struct LeakDetector {
- LeakDetector();
- ~LeakDetector();
- };
-
-}
-// end catch_leak_detector.h
-// Cpp files will be included in the single-header file here
-// start catch_stats.cpp
-
-// Statistical analysis tools
-
-#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
-
-#include <cassert>
-#include <random>
-
-#if defined(CATCH_CONFIG_USE_ASYNC)
-#include <future>
-#endif
-
-namespace {
- double erf_inv(double x) {
- // Code accompanying the article "Approximating the erfinv function" in GPU Computing Gems, Volume 2
- double w, p;
-
- w = -log((1.0 - x) * (1.0 + x));
-
- if (w < 6.250000) {
- w = w - 3.125000;
- p = -3.6444120640178196996e-21;
- p = -1.685059138182016589e-19 + p * w;
- p = 1.2858480715256400167e-18 + p * w;
- p = 1.115787767802518096e-17 + p * w;
- p = -1.333171662854620906e-16 + p * w;
- p = 2.0972767875968561637e-17 + p * w;
- p = 6.6376381343583238325e-15 + p * w;
- p = -4.0545662729752068639e-14 + p * w;
- p = -8.1519341976054721522e-14 + p * w;
- p = 2.6335093153082322977e-12 + p * w;
- p = -1.2975133253453532498e-11 + p * w;
- p = -5.4154120542946279317e-11 + p * w;
- p = 1.051212273321532285e-09 + p * w;
- p = -4.1126339803469836976e-09 + p * w;
- p = -2.9070369957882005086e-08 + p * w;
- p = 4.2347877827932403518e-07 + p * w;
- p = -1.3654692000834678645e-06 + p * w;
- p = -1.3882523362786468719e-05 + p * w;
- p = 0.0001867342080340571352 + p * w;
- p = -0.00074070253416626697512 + p * w;
- p = -0.0060336708714301490533 + p * w;
- p = 0.24015818242558961693 + p * w;
- p = 1.6536545626831027356 + p * w;
- } else if (w < 16.000000) {
- w = sqrt(w) - 3.250000;
- p = 2.2137376921775787049e-09;
- p = 9.0756561938885390979e-08 + p * w;
- p = -2.7517406297064545428e-07 + p * w;
- p = 1.8239629214389227755e-08 + p * w;
- p = 1.5027403968909827627e-06 + p * w;
- p = -4.013867526981545969e-06 + p * w;
- p = 2.9234449089955446044e-06 + p * w;
- p = 1.2475304481671778723e-05 + p * w;
- p = -4.7318229009055733981e-05 + p * w;
- p = 6.8284851459573175448e-05 + p * w;
- p = 2.4031110387097893999e-05 + p * w;
- p = -0.0003550375203628474796 + p * w;
- p = 0.00095328937973738049703 + p * w;
- p = -0.0016882755560235047313 + p * w;
- p = 0.0024914420961078508066 + p * w;
- p = -0.0037512085075692412107 + p * w;
- p = 0.005370914553590063617 + p * w;
- p = 1.0052589676941592334 + p * w;
- p = 3.0838856104922207635 + p * w;
- } else {
- w = sqrt(w) - 5.000000;
- p = -2.7109920616438573243e-11;
- p = -2.5556418169965252055e-10 + p * w;
- p = 1.5076572693500548083e-09 + p * w;
- p = -3.7894654401267369937e-09 + p * w;
- p = 7.6157012080783393804e-09 + p * w;
- p = -1.4960026627149240478e-08 + p * w;
- p = 2.9147953450901080826e-08 + p * w;
- p = -6.7711997758452339498e-08 + p * w;
- p = 2.2900482228026654717e-07 + p * w;
- p = -9.9298272942317002539e-07 + p * w;
- p = 4.5260625972231537039e-06 + p * w;
- p = -1.9681778105531670567e-05 + p * w;
- p = 7.5995277030017761139e-05 + p * w;
- p = -0.00021503011930044477347 + p * w;
- p = -0.00013871931833623122026 + p * w;
- p = 1.0103004648645343977 + p * w;
- p = 4.8499064014085844221 + p * w;
- }
- return p * x;
- }
-
- double standard_deviation(std::vector<double>::iterator first, std::vector<double>::iterator last) {
- auto m = Catch::Benchmark::Detail::mean(first, last);
- double variance = std::accumulate(first, last, 0., [m](double a, double b) {
- double diff = b - m;
- return a + diff * diff;
- }) / (last - first);
- return std::sqrt(variance);
- }
-
-}
-
-namespace Catch {
- namespace Benchmark {
- namespace Detail {
-
- double weighted_average_quantile(int k, int q, std::vector<double>::iterator first, std::vector<double>::iterator last) {
- auto count = last - first;
- double idx = (count - 1) * k / static_cast<double>(q);
- int j = static_cast<int>(idx);
- double g = idx - j;
- std::nth_element(first, first + j, last);
- auto xj = first[j];
- if (g == 0) return xj;
-
- auto xj1 = *std::min_element(first + (j + 1), last);
- return xj + g * (xj1 - xj);
- }
-
- double erfc_inv(double x) {
- return erf_inv(1.0 - x);
- }
-
- double normal_quantile(double p) {
- static const double ROOT_TWO = std::sqrt(2.0);
-
- double result = 0.0;
- assert(p >= 0 && p <= 1);
- if (p < 0 || p > 1) {
- return result;
- }
-
- result = -erfc_inv(2.0 * p);
- // result *= normal distribution standard deviation (1.0) * sqrt(2)
- result *= /*sd * */ ROOT_TWO;
- // result += normal disttribution mean (0)
- return result;
- }
-
- double outlier_variance(Estimate<double> mean, Estimate<double> stddev, int n) {
- double sb = stddev.point;
- double mn = mean.point / n;
- double mg_min = mn / 2.;
- double sg = std::min(mg_min / 4., sb / std::sqrt(n));
- double sg2 = sg * sg;
- double sb2 = sb * sb;
-
- auto c_max = [n, mn, sb2, sg2](double x) -> double {
- double k = mn - x;
- double d = k * k;
- double nd = n * d;
- double k0 = -n * nd;
- double k1 = sb2 - n * sg2 + nd;
- double det = k1 * k1 - 4 * sg2 * k0;
- return (int)(-2. * k0 / (k1 + std::sqrt(det)));
- };
-
- auto var_out = [n, sb2, sg2](double c) {
- double nc = n - c;
- return (nc / n) * (sb2 - nc * sg2);
- };
-
- return std::min(var_out(1), var_out(std::min(c_max(0.), c_max(mg_min)))) / sb2;
- }
-
- bootstrap_analysis analyse_samples(double confidence_level, int n_resamples, std::vector<double>::iterator first, std::vector<double>::iterator last) {
- CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS
- static std::random_device entropy;
- CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
-
- auto n = static_cast<int>(last - first); // seriously, one can't use integral types without hell in C++
-
- auto mean = &Detail::mean<std::vector<double>::iterator>;
- auto stddev = &standard_deviation;
-
-#if defined(CATCH_CONFIG_USE_ASYNC)
- auto Estimate = [=](double(*f)(std::vector<double>::iterator, std::vector<double>::iterator)) {
- auto seed = entropy();
- return std::async(std::launch::async, [=] {
- std::mt19937 rng(seed);
- auto resampled = resample(rng, n_resamples, first, last, f);
- return bootstrap(confidence_level, first, last, resampled, f);
- });
- };
-
- auto mean_future = Estimate(mean);
- auto stddev_future = Estimate(stddev);
-
- auto mean_estimate = mean_future.get();
- auto stddev_estimate = stddev_future.get();
-#else
- auto Estimate = [=](double(*f)(std::vector<double>::iterator, std::vector<double>::iterator)) {
- auto seed = entropy();
- std::mt19937 rng(seed);
- auto resampled = resample(rng, n_resamples, first, last, f);
- return bootstrap(confidence_level, first, last, resampled, f);
- };
-
- auto mean_estimate = Estimate(mean);
- auto stddev_estimate = Estimate(stddev);
-#endif // CATCH_USE_ASYNC
-
- double outlier_variance = Detail::outlier_variance(mean_estimate, stddev_estimate, n);
-
- return { mean_estimate, stddev_estimate, outlier_variance };
- }
- } // namespace Detail
- } // namespace Benchmark
-} // namespace Catch
-
-#endif // CATCH_CONFIG_ENABLE_BENCHMARKING
-// end catch_stats.cpp
-// start catch_approx.cpp
-
-#include <cmath>
-#include <limits>
-
-namespace {
-
-// Performs equivalent check of std::fabs(lhs - rhs) <= margin
-// But without the subtraction to allow for INFINITY in comparison
-bool marginComparison(double lhs, double rhs, double margin) {
- return (lhs + margin >= rhs) && (rhs + margin >= lhs);
-}
-
-}
-
-namespace Catch {
-namespace Detail {
-
- Approx::Approx ( double value )
- : m_epsilon( std::numeric_limits<float>::epsilon()*100 ),
- m_margin( 0.0 ),
- m_scale( 0.0 ),
- m_value( value )
- {}
-
- Approx Approx::custom() {
- return Approx( 0 );
- }
-
- Approx Approx::operator-() const {
- auto temp(*this);
- temp.m_value = -temp.m_value;
- return temp;
- }
-
- std::string Approx::toString() const {
- ReusableStringStream rss;
- rss << "Approx( " << ::Catch::Detail::stringify( m_value ) << " )";
- return rss.str();
- }
-
- bool Approx::equalityComparisonImpl(const double other) const {
- // First try with fixed margin, then compute margin based on epsilon, scale and Approx's value
- // Thanks to Richard Harris for his help refining the scaled margin value
- return marginComparison(m_value, other, m_margin) || marginComparison(m_value, other, m_epsilon * (m_scale + std::fabs(m_value)));
- }
-
- void Approx::setMargin(double newMargin) {
- CATCH_ENFORCE(newMargin >= 0,
- "Invalid Approx::margin: " << newMargin << '.'
- << " Approx::Margin has to be non-negative.");
- m_margin = newMargin;
- }
-
- void Approx::setEpsilon(double newEpsilon) {
- CATCH_ENFORCE(newEpsilon >= 0 && newEpsilon <= 1.0,
- "Invalid Approx::epsilon: " << newEpsilon << '.'
- << " Approx::epsilon has to be in [0, 1]");
- m_epsilon = newEpsilon;
- }
-
-} // end namespace Detail
-
-namespace literals {
- Detail::Approx operator "" _a(long double val) {
- return Detail::Approx(val);
- }
- Detail::Approx operator "" _a(unsigned long long val) {
- return Detail::Approx(val);
- }
-} // end namespace literals
-
-std::string StringMaker<Catch::Detail::Approx>::convert(Catch::Detail::Approx const& value) {
- return value.toString();
-}
-
-} // end namespace Catch
-// end catch_approx.cpp
-// start catch_assertionhandler.cpp
-
-// start catch_debugger.h
-
-namespace Catch {
- bool isDebuggerActive();
-}
-
-#ifdef CATCH_PLATFORM_MAC
-
- #define CATCH_TRAP() __asm__("int $3\n" : : ) /* NOLINT */
-
-#elif defined(CATCH_PLATFORM_LINUX)
- // If we can use inline assembler, do it because this allows us to break
- // directly at the location of the failing check instead of breaking inside
- // raise() called from it, i.e. one stack frame below.
- #if defined(__GNUC__) && (defined(__i386) || defined(__x86_64))
- #define CATCH_TRAP() asm volatile ("int $3") /* NOLINT */
- #else // Fall back to the generic way.
- #include <signal.h>
-
- #define CATCH_TRAP() raise(SIGTRAP)
- #endif
-#elif defined(_MSC_VER)
- #define CATCH_TRAP() __debugbreak()
-#elif defined(__MINGW32__)
- extern "C" __declspec(dllimport) void __stdcall DebugBreak();
- #define CATCH_TRAP() DebugBreak()
-#endif
-
-#ifdef CATCH_TRAP
- #define CATCH_BREAK_INTO_DEBUGGER() []{ if( Catch::isDebuggerActive() ) { CATCH_TRAP(); } }()
-#else
- #define CATCH_BREAK_INTO_DEBUGGER() []{}()
-#endif
-
-// end catch_debugger.h
-// start catch_run_context.h
-
-// start catch_fatal_condition.h
-
-// start catch_windows_h_proxy.h
-
-
-#if defined(CATCH_PLATFORM_WINDOWS)
-
-#if !defined(NOMINMAX) && !defined(CATCH_CONFIG_NO_NOMINMAX)
-# define CATCH_DEFINED_NOMINMAX
-# define NOMINMAX
-#endif
-#if !defined(WIN32_LEAN_AND_MEAN) && !defined(CATCH_CONFIG_NO_WIN32_LEAN_AND_MEAN)
-# define CATCH_DEFINED_WIN32_LEAN_AND_MEAN
-# define WIN32_LEAN_AND_MEAN
-#endif
-
-#ifdef __AFXDLL
-#include <AfxWin.h>
-#else
-#include <windows.h>
-#endif
-
-#ifdef CATCH_DEFINED_NOMINMAX
-# undef NOMINMAX
-#endif
-#ifdef CATCH_DEFINED_WIN32_LEAN_AND_MEAN
-# undef WIN32_LEAN_AND_MEAN
-#endif
-
-#endif // defined(CATCH_PLATFORM_WINDOWS)
-
-// end catch_windows_h_proxy.h
-#if defined( CATCH_CONFIG_WINDOWS_SEH )
-
-namespace Catch {
-
- struct FatalConditionHandler {
-
- static LONG CALLBACK handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo);
- FatalConditionHandler();
- static void reset();
- ~FatalConditionHandler();
-
- private:
- static bool isSet;
- static ULONG guaranteeSize;
- static PVOID exceptionHandlerHandle;
- };
-
-} // namespace Catch
-
-#elif defined ( CATCH_CONFIG_POSIX_SIGNALS )
-
-#include <signal.h>
-
-namespace Catch {
-
- struct FatalConditionHandler {
-
- static bool isSet;
- static struct sigaction oldSigActions[];
- static stack_t oldSigStack;
- static char altStackMem[];
-
- static void handleSignal( int sig );
-
- FatalConditionHandler();
- ~FatalConditionHandler();
- static void reset();
- };
-
-} // namespace Catch
-
-#else
-
-namespace Catch {
- struct FatalConditionHandler {
- void reset();
- };
-}
-
-#endif
-
-// end catch_fatal_condition.h
-#include <string>
-
-namespace Catch {
-
- struct IMutableContext;
-
- ///////////////////////////////////////////////////////////////////////////
-
- class RunContext : public IResultCapture, public IRunner {
-
- public:
- RunContext( RunContext const& ) = delete;
- RunContext& operator =( RunContext const& ) = delete;
-
- explicit RunContext( IConfigPtr const& _config, IStreamingReporterPtr&& reporter );
-
- ~RunContext() override;
-
- void testGroupStarting( std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount );
- void testGroupEnded( std::string const& testSpec, Totals const& totals, std::size_t groupIndex, std::size_t groupsCount );
-
- Totals runTest(TestCase const& testCase);
-
- IConfigPtr config() const;
- IStreamingReporter& reporter() const;
-
- public: // IResultCapture
-
- // Assertion handlers
- void handleExpr
- ( AssertionInfo const& info,
- ITransientExpression const& expr,
- AssertionReaction& reaction ) override;
- void handleMessage
- ( AssertionInfo const& info,
- ResultWas::OfType resultType,
- StringRef const& message,
- AssertionReaction& reaction ) override;
- void handleUnexpectedExceptionNotThrown
- ( AssertionInfo const& info,
- AssertionReaction& reaction ) override;
- void handleUnexpectedInflightException
- ( AssertionInfo const& info,
- std::string const& message,
- AssertionReaction& reaction ) override;
- void handleIncomplete
- ( AssertionInfo const& info ) override;
- void handleNonExpr
- ( AssertionInfo const &info,
- ResultWas::OfType resultType,
- AssertionReaction &reaction ) override;
-
- bool sectionStarted( SectionInfo const& sectionInfo, Counts& assertions ) override;
-
- void sectionEnded( SectionEndInfo const& endInfo ) override;
- void sectionEndedEarly( SectionEndInfo const& endInfo ) override;
-
- auto acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker& override;
-
-#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
- void benchmarkPreparing( std::string const& name ) override;
- void benchmarkStarting( BenchmarkInfo const& info ) override;
- void benchmarkEnded( BenchmarkStats<> const& stats ) override;
- void benchmarkFailed( std::string const& error ) override;
-#endif // CATCH_CONFIG_ENABLE_BENCHMARKING
-
- void pushScopedMessage( MessageInfo const& message ) override;
- void popScopedMessage( MessageInfo const& message ) override;
-
- void emplaceUnscopedMessage( MessageBuilder const& builder ) override;
-
- std::string getCurrentTestName() const override;
-
- const AssertionResult* getLastResult() const override;
-
- void exceptionEarlyReported() override;
-
- void handleFatalErrorCondition( StringRef message ) override;
-
- bool lastAssertionPassed() override;
-
- void assertionPassed() override;
-
- public:
- // !TBD We need to do this another way!
- bool aborting() const final;
-
- private:
-
- void runCurrentTest( std::string& redirectedCout, std::string& redirectedCerr );
- void invokeActiveTestCase();
-
- void resetAssertionInfo();
- bool testForMissingAssertions( Counts& assertions );
-
- void assertionEnded( AssertionResult const& result );
- void reportExpr
- ( AssertionInfo const &info,
- ResultWas::OfType resultType,
- ITransientExpression const *expr,
- bool negated );
-
- void populateReaction( AssertionReaction& reaction );
-
- private:
-
- void handleUnfinishedSections();
-
- TestRunInfo m_runInfo;
- IMutableContext& m_context;
- TestCase const* m_activeTestCase = nullptr;
- ITracker* m_testCaseTracker = nullptr;
- Option<AssertionResult> m_lastResult;
-
- IConfigPtr m_config;
- Totals m_totals;
- IStreamingReporterPtr m_reporter;
- std::vector<MessageInfo> m_messages;
- std::vector<ScopedMessage> m_messageScopes; /* Keeps owners of so-called unscoped messages. */
- AssertionInfo m_lastAssertionInfo;
- std::vector<SectionEndInfo> m_unfinishedSections;
- std::vector<ITracker*> m_activeSections;
- TrackerContext m_trackerContext;
- bool m_lastAssertionPassed = false;
- bool m_shouldReportUnexpected = true;
- bool m_includeSuccessfulResults;
- };
-
-} // end namespace Catch
-
-// end catch_run_context.h
-namespace Catch {
-
- namespace {
- auto operator <<( std::ostream& os, ITransientExpression const& expr ) -> std::ostream& {
- expr.streamReconstructedExpression( os );
- return os;
- }
- }
-
- LazyExpression::LazyExpression( bool isNegated )
- : m_isNegated( isNegated )
- {}
-
- LazyExpression::LazyExpression( LazyExpression const& other ) : m_isNegated( other.m_isNegated ) {}
-
- LazyExpression::operator bool() const {
- return m_transientExpression != nullptr;
- }
-
- auto operator << ( std::ostream& os, LazyExpression const& lazyExpr ) -> std::ostream& {
- if( lazyExpr.m_isNegated )
- os << "!";
-
- if( lazyExpr ) {
- if( lazyExpr.m_isNegated && lazyExpr.m_transientExpression->isBinaryExpression() )
- os << "(" << *lazyExpr.m_transientExpression << ")";
- else
- os << *lazyExpr.m_transientExpression;
- }
- else {
- os << "{** error - unchecked empty expression requested **}";
- }
- return os;
- }
-
- AssertionHandler::AssertionHandler
- ( StringRef const& macroName,
- SourceLineInfo const& lineInfo,
- StringRef capturedExpression,
- ResultDisposition::Flags resultDisposition )
- : m_assertionInfo{ macroName, lineInfo, capturedExpression, resultDisposition },
- m_resultCapture( getResultCapture() )
- {}
-
- void AssertionHandler::handleExpr( ITransientExpression const& expr ) {
- m_resultCapture.handleExpr( m_assertionInfo, expr, m_reaction );
- }
- void AssertionHandler::handleMessage(ResultWas::OfType resultType, StringRef const& message) {
- m_resultCapture.handleMessage( m_assertionInfo, resultType, message, m_reaction );
- }
-
- auto AssertionHandler::allowThrows() const -> bool {
- return getCurrentContext().getConfig()->allowThrows();
- }
-
- void AssertionHandler::complete() {
- setCompleted();
- if( m_reaction.shouldDebugBreak ) {
-
- // If you find your debugger stopping you here then go one level up on the
- // call-stack for the code that caused it (typically a failed assertion)
-
- // (To go back to the test and change execution, jump over the throw, next)
- CATCH_BREAK_INTO_DEBUGGER();
- }
- if (m_reaction.shouldThrow) {
-#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
- throw Catch::TestFailureException();
-#else
- CATCH_ERROR( "Test failure requires aborting test!" );
-#endif
- }
- }
- void AssertionHandler::setCompleted() {
- m_completed = true;
- }
-
- void AssertionHandler::handleUnexpectedInflightException() {
- m_resultCapture.handleUnexpectedInflightException( m_assertionInfo, Catch::translateActiveException(), m_reaction );
- }
-
- void AssertionHandler::handleExceptionThrownAsExpected() {
- m_resultCapture.handleNonExpr(m_assertionInfo, ResultWas::Ok, m_reaction);
- }
- void AssertionHandler::handleExceptionNotThrownAsExpected() {
- m_resultCapture.handleNonExpr(m_assertionInfo, ResultWas::Ok, m_reaction);
- }
-
- void AssertionHandler::handleUnexpectedExceptionNotThrown() {
- m_resultCapture.handleUnexpectedExceptionNotThrown( m_assertionInfo, m_reaction );
- }
-
- void AssertionHandler::handleThrowingCallSkipped() {
- m_resultCapture.handleNonExpr(m_assertionInfo, ResultWas::Ok, m_reaction);
- }
-
- // This is the overload that takes a string and infers the Equals matcher from it
- // The more general overload, that takes any string matcher, is in catch_capture_matchers.cpp
- void handleExceptionMatchExpr( AssertionHandler& handler, std::string const& str, StringRef const& matcherString ) {
- handleExceptionMatchExpr( handler, Matchers::Equals( str ), matcherString );
- }
-
-} // namespace Catch
-// end catch_assertionhandler.cpp
-// start catch_assertionresult.cpp
-
-namespace Catch {
- AssertionResultData::AssertionResultData(ResultWas::OfType _resultType, LazyExpression const & _lazyExpression):
- lazyExpression(_lazyExpression),
- resultType(_resultType) {}
-
- std::string AssertionResultData::reconstructExpression() const {
-
- if( reconstructedExpression.empty() ) {
- if( lazyExpression ) {
- ReusableStringStream rss;
- rss << lazyExpression;
- reconstructedExpression = rss.str();
- }
- }
- return reconstructedExpression;
- }
-
- AssertionResult::AssertionResult( AssertionInfo const& info, AssertionResultData const& data )
- : m_info( info ),
- m_resultData( data )
- {}
-
- // Result was a success
- bool AssertionResult::succeeded() const {
- return Catch::isOk( m_resultData.resultType );
- }
-
- // Result was a success, or failure is suppressed
- bool AssertionResult::isOk() const {
- return Catch::isOk( m_resultData.resultType ) || shouldSuppressFailure( m_info.resultDisposition );
- }
-
- ResultWas::OfType AssertionResult::getResultType() const {
- return m_resultData.resultType;
- }
-
- bool AssertionResult::hasExpression() const {
- return m_info.capturedExpression[0] != 0;
- }
-
- bool AssertionResult::hasMessage() const {
- return !m_resultData.message.empty();
- }
-
- std::string AssertionResult::getExpression() const {
- if( isFalseTest( m_info.resultDisposition ) )
- return "!(" + m_info.capturedExpression + ")";
- else
- return m_info.capturedExpression;
- }
-
- std::string AssertionResult::getExpressionInMacro() const {
- std::string expr;
- if( m_info.macroName[0] == 0 )
- expr = m_info.capturedExpression;
- else {
- expr.reserve( m_info.macroName.size() + m_info.capturedExpression.size() + 4 );
- expr += m_info.macroName;
- expr += "( ";
- expr += m_info.capturedExpression;
- expr += " )";
- }
- return expr;
- }
-
- bool AssertionResult::hasExpandedExpression() const {
- return hasExpression() && getExpandedExpression() != getExpression();
- }
-
- std::string AssertionResult::getExpandedExpression() const {
- std::string expr = m_resultData.reconstructExpression();
- return expr.empty()
- ? getExpression()
- : expr;
- }
-
- std::string AssertionResult::getMessage() const {
- return m_resultData.message;
- }
- SourceLineInfo AssertionResult::getSourceInfo() const {
- return m_info.lineInfo;
- }
-
- StringRef AssertionResult::getTestMacroName() const {
- return m_info.macroName;
- }
-
-} // end namespace Catch
-// end catch_assertionresult.cpp
-// start catch_capture_matchers.cpp
-
-namespace Catch {
-
- using StringMatcher = Matchers::Impl::MatcherBase<std::string>;
-
- // This is the general overload that takes a any string matcher
- // There is another overload, in catch_assertionhandler.h/.cpp, that only takes a string and infers
- // the Equals matcher (so the header does not mention matchers)
- void handleExceptionMatchExpr( AssertionHandler& handler, StringMatcher const& matcher, StringRef const& matcherString ) {
- std::string exceptionMessage = Catch::translateActiveException();
- MatchExpr<std::string, StringMatcher const&> expr( exceptionMessage, matcher, matcherString );
- handler.handleExpr( expr );
- }
-
-} // namespace Catch
-// end catch_capture_matchers.cpp
-// start catch_commandline.cpp
-
-// start catch_commandline.h
-
-// start catch_clara.h
-
-// Use Catch's value for console width (store Clara's off to the side, if present)
-#ifdef CLARA_CONFIG_CONSOLE_WIDTH
-#define CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH
-#undef CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH
-#endif
-#define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH-1
-
-#ifdef __clang__
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wweak-vtables"
-#pragma clang diagnostic ignored "-Wexit-time-destructors"
-#pragma clang diagnostic ignored "-Wshadow"
-#endif
-
-// start clara.hpp
-// Copyright 2017 Two Blue Cubes Ltd. All rights reserved.
-//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-// See https://github.com/philsquared/Clara for more details
-
-// Clara v1.1.5
-
-
-#ifndef CATCH_CLARA_CONFIG_CONSOLE_WIDTH
-#define CATCH_CLARA_CONFIG_CONSOLE_WIDTH 80
-#endif
-
-#ifndef CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH
-#define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_CLARA_CONFIG_CONSOLE_WIDTH
-#endif
-
-#ifndef CLARA_CONFIG_OPTIONAL_TYPE
-#ifdef __has_include
-#if __has_include(<optional>) && __cplusplus >= 201703L
-#include <optional>
-#define CLARA_CONFIG_OPTIONAL_TYPE std::optional
-#endif
-#endif
-#endif
-
-// ----------- #included from clara_textflow.hpp -----------
-
-// TextFlowCpp
-//
-// A single-header library for wrapping and laying out basic text, by Phil Nash
-//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
-// file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-// This project is hosted at https://github.com/philsquared/textflowcpp
-
-
-#include <cassert>
-#include <ostream>
-#include <sstream>
-#include <vector>
-
-#ifndef CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH
-#define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH 80
-#endif
-
-namespace Catch {
-namespace clara {
-namespace TextFlow {
-
-inline auto isWhitespace(char c) -> bool {
- static std::string chars = " \t\n\r";
- return chars.find(c) != std::string::npos;
-}
-inline auto isBreakableBefore(char c) -> bool {
- static std::string chars = "[({<|";
- return chars.find(c) != std::string::npos;
-}
-inline auto isBreakableAfter(char c) -> bool {
- static std::string chars = "])}>.,:;*+-=&/\\";
- return chars.find(c) != std::string::npos;
-}
-
-class Columns;
-
-class Column {
- std::vector<std::string> m_strings;
- size_t m_width = CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH;
- size_t m_indent = 0;
- size_t m_initialIndent = std::string::npos;
-
-public:
- class iterator {
- friend Column;
-
- Column const& m_column;
- size_t m_stringIndex = 0;
- size_t m_pos = 0;
-
- size_t m_len = 0;
- size_t m_end = 0;
- bool m_suffix = false;
-
- iterator(Column const& column, size_t stringIndex)
- : m_column(column),
- m_stringIndex(stringIndex) {}
-
- auto line() const -> std::string const& { return m_column.m_strings[m_stringIndex]; }
-
- auto isBoundary(size_t at) const -> bool {
- assert(at > 0);
- assert(at <= line().size());
-
- return at == line().size() ||
- (isWhitespace(line()[at]) && !isWhitespace(line()[at - 1])) ||
- isBreakableBefore(line()[at]) ||
- isBreakableAfter(line()[at - 1]);
- }
-
- void calcLength() {
- assert(m_stringIndex < m_column.m_strings.size());
-
- m_suffix = false;
- auto width = m_column.m_width - indent();
- m_end = m_pos;
- if (line()[m_pos] == '\n') {
- ++m_end;
- }
- while (m_end < line().size() && line()[m_end] != '\n')
- ++m_end;
-
- if (m_end < m_pos + width) {
- m_len = m_end - m_pos;
- } else {
- size_t len = width;
- while (len > 0 && !isBoundary(m_pos + len))
- --len;
- while (len > 0 && isWhitespace(line()[m_pos + len - 1]))
- --len;
-
- if (len > 0) {
- m_len = len;
- } else {
- m_suffix = true;
- m_len = width - 1;
- }
- }
- }
-
- auto indent() const -> size_t {
- auto initial = m_pos == 0 && m_stringIndex == 0 ? m_column.m_initialIndent : std::string::npos;
- return initial == std::string::npos ? m_column.m_indent : initial;
- }
-
- auto addIndentAndSuffix(std::string const &plain) const -> std::string {
- return std::string(indent(), ' ') + (m_suffix ? plain + "-" : plain);
- }
-
- public:
- using difference_type = std::ptrdiff_t;
- using value_type = std::string;
- using pointer = value_type * ;
- using reference = value_type & ;
- using iterator_category = std::forward_iterator_tag;
-
- explicit iterator(Column const& column) : m_column(column) {
- assert(m_column.m_width > m_column.m_indent);
- assert(m_column.m_initialIndent == std::string::npos || m_column.m_width > m_column.m_initialIndent);
- calcLength();
- if (m_len == 0)
- m_stringIndex++; // Empty string
- }
-
- auto operator *() const -> std::string {
- assert(m_stringIndex < m_column.m_strings.size());
- assert(m_pos <= m_end);
- return addIndentAndSuffix(line().substr(m_pos, m_len));
- }
-
- auto operator ++() -> iterator& {
- m_pos += m_len;
- if (m_pos < line().size() && line()[m_pos] == '\n')
- m_pos += 1;
- else
- while (m_pos < line().size() && isWhitespace(line()[m_pos]))
- ++m_pos;
-
- if (m_pos == line().size()) {
- m_pos = 0;
- ++m_stringIndex;
- }
- if (m_stringIndex < m_column.m_strings.size())
- calcLength();
- return *this;
- }
- auto operator ++(int) -> iterator {
- iterator prev(*this);
- operator++();
- return prev;
- }
-
- auto operator ==(iterator const& other) const -> bool {
- return
- m_pos == other.m_pos &&
- m_stringIndex == other.m_stringIndex &&
- &m_column == &other.m_column;
- }
- auto operator !=(iterator const& other) const -> bool {
- return !operator==(other);
- }
- };
- using const_iterator = iterator;
-
- explicit Column(std::string const& text) { m_strings.push_back(text); }
-
- auto width(size_t newWidth) -> Column& {
- assert(newWidth > 0);
- m_width = newWidth;
- return *this;
- }
- auto indent(size_t newIndent) -> Column& {
- m_indent = newIndent;
- return *this;
- }
- auto initialIndent(size_t newIndent) -> Column& {
- m_initialIndent = newIndent;
- return *this;
- }
-
- auto width() const -> size_t { return m_width; }
- auto begin() const -> iterator { return iterator(*this); }
- auto end() const -> iterator { return { *this, m_strings.size() }; }
-
- inline friend std::ostream& operator << (std::ostream& os, Column const& col) {
- bool first = true;
- for (auto line : col) {
- if (first)
- first = false;
- else
- os << "\n";
- os << line;
- }
- return os;
- }
-
- auto operator + (Column const& other)->Columns;
-
- auto toString() const -> std::string {
- std::ostringstream oss;
- oss << *this;
- return oss.str();
- }
-};
-
-class Spacer : public Column {
-
-public:
- explicit Spacer(size_t spaceWidth) : Column("") {
- width(spaceWidth);
- }
-};
-
-class Columns {
- std::vector<Column> m_columns;
-
-public:
-
- class iterator {
- friend Columns;
- struct EndTag {};
-
- std::vector<Column> const& m_columns;
- std::vector<Column::iterator> m_iterators;
- size_t m_activeIterators;
-
- iterator(Columns const& columns, EndTag)
- : m_columns(columns.m_columns),
- m_activeIterators(0) {
- m_iterators.reserve(m_columns.size());
-
- for (auto const& col : m_columns)
- m_iterators.push_back(col.end());
- }
-
- public:
- using difference_type = std::ptrdiff_t;
- using value_type = std::string;
- using pointer = value_type * ;
- using reference = value_type & ;
- using iterator_category = std::forward_iterator_tag;
-
- explicit iterator(Columns const& columns)
- : m_columns(columns.m_columns),
- m_activeIterators(m_columns.size()) {
- m_iterators.reserve(m_columns.size());
-
- for (auto const& col : m_columns)
- m_iterators.push_back(col.begin());
- }
-
- auto operator ==(iterator const& other) const -> bool {
- return m_iterators == other.m_iterators;
- }
- auto operator !=(iterator const& other) const -> bool {
- return m_iterators != other.m_iterators;
- }
- auto operator *() const -> std::string {
- std::string row, padding;
-
- for (size_t i = 0; i < m_columns.size(); ++i) {
- auto width = m_columns[i].width();
- if (m_iterators[i] != m_columns[i].end()) {
- std::string col = *m_iterators[i];
- row += padding + col;
- if (col.size() < width)
- padding = std::string(width - col.size(), ' ');
- else
- padding = "";
- } else {
- padding += std::string(width, ' ');
- }
- }
- return row;
- }
- auto operator ++() -> iterator& {
- for (size_t i = 0; i < m_columns.size(); ++i) {
- if (m_iterators[i] != m_columns[i].end())
- ++m_iterators[i];
- }
- return *this;
- }
- auto operator ++(int) -> iterator {
- iterator prev(*this);
- operator++();
- return prev;
- }
- };
- using const_iterator = iterator;
-
- auto begin() const -> iterator { return iterator(*this); }
- auto end() const -> iterator { return { *this, iterator::EndTag() }; }
-
- auto operator += (Column const& col) -> Columns& {
- m_columns.push_back(col);
- return *this;
- }
- auto operator + (Column const& col) -> Columns {
- Columns combined = *this;
- combined += col;
- return combined;
- }
-
- inline friend std::ostream& operator << (std::ostream& os, Columns const& cols) {
-
- bool first = true;
- for (auto line : cols) {
- if (first)
- first = false;
- else
- os << "\n";
- os << line;
- }
- return os;
- }
-
- auto toString() const -> std::string {
- std::ostringstream oss;
- oss << *this;
- return oss.str();
- }
-};
-
-inline auto Column::operator + (Column const& other) -> Columns {
- Columns cols;
- cols += *this;
- cols += other;
- return cols;
-}
-}
-
-}
-}
-
-// ----------- end of #include from clara_textflow.hpp -----------
-// ........... back in clara.hpp
-
-#include <cctype>
-#include <string>
-#include <memory>
-#include <set>
-#include <algorithm>
-
-#if !defined(CATCH_PLATFORM_WINDOWS) && ( defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) )
-#define CATCH_PLATFORM_WINDOWS
-#endif
-
-namespace Catch { namespace clara {
-namespace detail {
-
- // Traits for extracting arg and return type of lambdas (for single argument lambdas)
- template<typename L>
- struct UnaryLambdaTraits : UnaryLambdaTraits<decltype( &L::operator() )> {};
-
- template<typename ClassT, typename ReturnT, typename... Args>
- struct UnaryLambdaTraits<ReturnT( ClassT::* )( Args... ) const> {
- static const bool isValid = false;
- };
-
- template<typename ClassT, typename ReturnT, typename ArgT>
- struct UnaryLambdaTraits<ReturnT( ClassT::* )( ArgT ) const> {
- static const bool isValid = true;
- using ArgType = typename std::remove_const<typename std::remove_reference<ArgT>::type>::type;
- using ReturnType = ReturnT;
- };
-
- class TokenStream;
-
- // Transport for raw args (copied from main args, or supplied via init list for testing)
- class Args {
- friend TokenStream;
- std::string m_exeName;
- std::vector<std::string> m_args;
-
- public:
- Args( int argc, char const* const* argv )
- : m_exeName(argv[0]),
- m_args(argv + 1, argv + argc) {}
-
- Args( std::initializer_list<std::string> args )
- : m_exeName( *args.begin() ),
- m_args( args.begin()+1, args.end() )
- {}
-
- auto exeName() const -> std::string {
- return m_exeName;
- }
- };
-
- // Wraps a token coming from a token stream. These may not directly correspond to strings as a single string
- // may encode an option + its argument if the : or = form is used
- enum class TokenType {
- Option, Argument
- };
- struct Token {
- TokenType type;
- std::string token;
- };
-
- inline auto isOptPrefix( char c ) -> bool {
- return c == '-'
-#ifdef CATCH_PLATFORM_WINDOWS
- || c == '/'
-#endif
- ;
- }
-
- // Abstracts iterators into args as a stream of tokens, with option arguments uniformly handled
- class TokenStream {
- using Iterator = std::vector<std::string>::const_iterator;
- Iterator it;
- Iterator itEnd;
- std::vector<Token> m_tokenBuffer;
-
- void loadBuffer() {
- m_tokenBuffer.resize( 0 );
-
- // Skip any empty strings
- while( it != itEnd && it->empty() )
- ++it;
-
- if( it != itEnd ) {
- auto const &next = *it;
- if( isOptPrefix( next[0] ) ) {
- auto delimiterPos = next.find_first_of( " :=" );
- if( delimiterPos != std::string::npos ) {
- m_tokenBuffer.push_back( { TokenType::Option, next.substr( 0, delimiterPos ) } );
- m_tokenBuffer.push_back( { TokenType::Argument, next.substr( delimiterPos + 1 ) } );
- } else {
- if( next[1] != '-' && next.size() > 2 ) {
- std::string opt = "- ";
- for( size_t i = 1; i < next.size(); ++i ) {
- opt[1] = next[i];
- m_tokenBuffer.push_back( { TokenType::Option, opt } );
- }
- } else {
- m_tokenBuffer.push_back( { TokenType::Option, next } );
- }
- }
- } else {
- m_tokenBuffer.push_back( { TokenType::Argument, next } );
- }
- }
- }
-
- public:
- explicit TokenStream( Args const &args ) : TokenStream( args.m_args.begin(), args.m_args.end() ) {}
-
- TokenStream( Iterator it, Iterator itEnd ) : it( it ), itEnd( itEnd ) {
- loadBuffer();
- }
-
- explicit operator bool() const {
- return !m_tokenBuffer.empty() || it != itEnd;
- }
-
- auto count() const -> size_t { return m_tokenBuffer.size() + (itEnd - it); }
-
- auto operator*() const -> Token {
- assert( !m_tokenBuffer.empty() );
- return m_tokenBuffer.front();
- }
-
- auto operator->() const -> Token const * {
- assert( !m_tokenBuffer.empty() );
- return &m_tokenBuffer.front();
- }
-
- auto operator++() -> TokenStream & {
- if( m_tokenBuffer.size() >= 2 ) {
- m_tokenBuffer.erase( m_tokenBuffer.begin() );
- } else {
- if( it != itEnd )
- ++it;
- loadBuffer();
- }
- return *this;
- }
- };
-
- class ResultBase {
- public:
- enum Type {
- Ok, LogicError, RuntimeError
- };
-
- protected:
- ResultBase( Type type ) : m_type( type ) {}
- virtual ~ResultBase() = default;
-
- virtual void enforceOk() const = 0;
-
- Type m_type;
- };
-
- template<typename T>
- class ResultValueBase : public ResultBase {
- public:
- auto value() const -> T const & {
- enforceOk();
- return m_value;
- }
-
- protected:
- ResultValueBase( Type type ) : ResultBase( type ) {}
-
- ResultValueBase( ResultValueBase const &other ) : ResultBase( other ) {
- if( m_type == ResultBase::Ok )
- new( &m_value ) T( other.m_value );
- }
-
- ResultValueBase( Type, T const &value ) : ResultBase( Ok ) {
- new( &m_value ) T( value );
- }
-
- auto operator=( ResultValueBase const &other ) -> ResultValueBase & {
- if( m_type == ResultBase::Ok )
- m_value.~T();
- ResultBase::operator=(other);
- if( m_type == ResultBase::Ok )
- new( &m_value ) T( other.m_value );
- return *this;
- }
-
- ~ResultValueBase() override {
- if( m_type == Ok )
- m_value.~T();
- }
-
- union {
- T m_value;
- };
- };
-
- template<>
- class ResultValueBase<void> : public ResultBase {
- protected:
- using ResultBase::ResultBase;
- };
-
- template<typename T = void>
- class BasicResult : public ResultValueBase<T> {
- public:
- template<typename U>
- explicit BasicResult( BasicResult<U> const &other )
- : ResultValueBase<T>( other.type() ),
- m_errorMessage( other.errorMessage() )
- {
- assert( type() != ResultBase::Ok );
- }
-
- template<typename U>
- static auto ok( U const &value ) -> BasicResult { return { ResultBase::Ok, value }; }
- static auto ok() -> BasicResult { return { ResultBase::Ok }; }
- static auto logicError( std::string const &message ) -> BasicResult { return { ResultBase::LogicError, message }; }
- static auto runtimeError( std::string const &message ) -> BasicResult { return { ResultBase::RuntimeError, message }; }
-
- explicit operator bool() const { return m_type == ResultBase::Ok; }
- auto type() const -> ResultBase::Type { return m_type; }
- auto errorMessage() const -> std::string { return m_errorMessage; }
-
- protected:
- void enforceOk() const override {
-
- // Errors shouldn't reach this point, but if they do
- // the actual error message will be in m_errorMessage
- assert( m_type != ResultBase::LogicError );
- assert( m_type != ResultBase::RuntimeError );
- if( m_type != ResultBase::Ok )
- std::abort();
- }
-
- std::string m_errorMessage; // Only populated if resultType is an error
-
- BasicResult( ResultBase::Type type, std::string const &message )
- : ResultValueBase<T>(type),
- m_errorMessage(message)
- {
- assert( m_type != ResultBase::Ok );
- }
-
- using ResultValueBase<T>::ResultValueBase;
- using ResultBase::m_type;
- };
-
- enum class ParseResultType {
- Matched, NoMatch, ShortCircuitAll, ShortCircuitSame
- };
-
- class ParseState {
- public:
-
- ParseState( ParseResultType type, TokenStream const &remainingTokens )
- : m_type(type),
- m_remainingTokens( remainingTokens )
- {}
-
- auto type() const -> ParseResultType { return m_type; }
- auto remainingTokens() const -> TokenStream { return m_remainingTokens; }
-
- private:
- ParseResultType m_type;
- TokenStream m_remainingTokens;
- };
-
- using Result = BasicResult<void>;
- using ParserResult = BasicResult<ParseResultType>;
- using InternalParseResult = BasicResult<ParseState>;
-
- struct HelpColumns {
- std::string left;
- std::string right;
- };
-
- template<typename T>
- inline auto convertInto( std::string const &source, T& target ) -> ParserResult {
- std::stringstream ss;
- ss << source;
- ss >> target;
- if( ss.fail() )
- return ParserResult::runtimeError( "Unable to convert '" + source + "' to destination type" );
- else
- return ParserResult::ok( ParseResultType::Matched );
- }
- inline auto convertInto( std::string const &source, std::string& target ) -> ParserResult {
- target = source;
- return ParserResult::ok( ParseResultType::Matched );
- }
- inline auto convertInto( std::string const &source, bool &target ) -> ParserResult {
- std::string srcLC = source;
- std::transform( srcLC.begin(), srcLC.end(), srcLC.begin(), []( char c ) { return static_cast<char>( std::tolower(c) ); } );
- if (srcLC == "y" || srcLC == "1" || srcLC == "true" || srcLC == "yes" || srcLC == "on")
- target = true;
- else if (srcLC == "n" || srcLC == "0" || srcLC == "false" || srcLC == "no" || srcLC == "off")
- target = false;
- else
- return ParserResult::runtimeError( "Expected a boolean value but did not recognise: '" + source + "'" );
- return ParserResult::ok( ParseResultType::Matched );
- }
-#ifdef CLARA_CONFIG_OPTIONAL_TYPE
- template<typename T>
- inline auto convertInto( std::string const &source, CLARA_CONFIG_OPTIONAL_TYPE<T>& target ) -> ParserResult {
- T temp;
- auto result = convertInto( source, temp );
- if( result )
- target = std::move(temp);
- return result;
- }
-#endif // CLARA_CONFIG_OPTIONAL_TYPE
-
- struct NonCopyable {
- NonCopyable() = default;
- NonCopyable( NonCopyable const & ) = delete;
- NonCopyable( NonCopyable && ) = delete;
- NonCopyable &operator=( NonCopyable const & ) = delete;
- NonCopyable &operator=( NonCopyable && ) = delete;
- };
-
- struct BoundRef : NonCopyable {
- virtual ~BoundRef() = default;
- virtual auto isContainer() const -> bool { return false; }
- virtual auto isFlag() const -> bool { return false; }
- };
- struct BoundValueRefBase : BoundRef {
- virtual auto setValue( std::string const &arg ) -> ParserResult = 0;
- };
- struct BoundFlagRefBase : BoundRef {
- virtual auto setFlag( bool flag ) -> ParserResult = 0;
- virtual auto isFlag() const -> bool { return true; }
- };
-
- template<typename T>
- struct BoundValueRef : BoundValueRefBase {
- T &m_ref;
-
- explicit BoundValueRef( T &ref ) : m_ref( ref ) {}
-
- auto setValue( std::string const &arg ) -> ParserResult override {
- return convertInto( arg, m_ref );
- }
- };
-
- template<typename T>
- struct BoundValueRef<std::vector<T>> : BoundValueRefBase {
- std::vector<T> &m_ref;
-
- explicit BoundValueRef( std::vector<T> &ref ) : m_ref( ref ) {}
-
- auto isContainer() const -> bool override { return true; }
-
- auto setValue( std::string const &arg ) -> ParserResult override {
- T temp;
- auto result = convertInto( arg, temp );
- if( result )
- m_ref.push_back( temp );
- return result;
- }
- };
-
- struct BoundFlagRef : BoundFlagRefBase {
- bool &m_ref;
-
- explicit BoundFlagRef( bool &ref ) : m_ref( ref ) {}
-
- auto setFlag( bool flag ) -> ParserResult override {
- m_ref = flag;
- return ParserResult::ok( ParseResultType::Matched );
- }
- };
-
- template<typename ReturnType>
- struct LambdaInvoker {
- static_assert( std::is_same<ReturnType, ParserResult>::value, "Lambda must return void or clara::ParserResult" );
-
- template<typename L, typename ArgType>
- static auto invoke( L const &lambda, ArgType const &arg ) -> ParserResult {
- return lambda( arg );
- }
- };
-
- template<>
- struct LambdaInvoker<void> {
- template<typename L, typename ArgType>
- static auto invoke( L const &lambda, ArgType const &arg ) -> ParserResult {
- lambda( arg );
- return ParserResult::ok( ParseResultType::Matched );
- }
- };
-
- template<typename ArgType, typename L>
- inline auto invokeLambda( L const &lambda, std::string const &arg ) -> ParserResult {
- ArgType temp{};
- auto result = convertInto( arg, temp );
- return !result
- ? result
- : LambdaInvoker<typename UnaryLambdaTraits<L>::ReturnType>::invoke( lambda, temp );
- }
-
- template<typename L>
- struct BoundLambda : BoundValueRefBase {
- L m_lambda;
-
- static_assert( UnaryLambdaTraits<L>::isValid, "Supplied lambda must take exactly one argument" );
- explicit BoundLambda( L const &lambda ) : m_lambda( lambda ) {}
-
- auto setValue( std::string const &arg ) -> ParserResult override {
- return invokeLambda<typename UnaryLambdaTraits<L>::ArgType>( m_lambda, arg );
- }
- };
-
- template<typename L>
- struct BoundFlagLambda : BoundFlagRefBase {
- L m_lambda;
-
- static_assert( UnaryLambdaTraits<L>::isValid, "Supplied lambda must take exactly one argument" );
- static_assert( std::is_same<typename UnaryLambdaTraits<L>::ArgType, bool>::value, "flags must be boolean" );
-
- explicit BoundFlagLambda( L const &lambda ) : m_lambda( lambda ) {}
-
- auto setFlag( bool flag ) -> ParserResult override {
- return LambdaInvoker<typename UnaryLambdaTraits<L>::ReturnType>::invoke( m_lambda, flag );
- }
- };
-
- enum class Optionality { Optional, Required };
-
- struct Parser;
-
- class ParserBase {
- public:
- virtual ~ParserBase() = default;
- virtual auto validate() const -> Result { return Result::ok(); }
- virtual auto parse( std::string const& exeName, TokenStream const &tokens) const -> InternalParseResult = 0;
- virtual auto cardinality() const -> size_t { return 1; }
-
- auto parse( Args const &args ) const -> InternalParseResult {
- return parse( args.exeName(), TokenStream( args ) );
- }
- };
-
- template<typename DerivedT>
- class ComposableParserImpl : public ParserBase {
- public:
- template<typename T>
- auto operator|( T const &other ) const -> Parser;
-
- template<typename T>
- auto operator+( T const &other ) const -> Parser;
- };
-
- // Common code and state for Args and Opts
- template<typename DerivedT>
- class ParserRefImpl : public ComposableParserImpl<DerivedT> {
- protected:
- Optionality m_optionality = Optionality::Optional;
- std::shared_ptr<BoundRef> m_ref;
- std::string m_hint;
- std::string m_description;
-
- explicit ParserRefImpl( std::shared_ptr<BoundRef> const &ref ) : m_ref( ref ) {}
-
- public:
- template<typename T>
- ParserRefImpl( T &ref, std::string const &hint )
- : m_ref( std::make_shared<BoundValueRef<T>>( ref ) ),
- m_hint( hint )
- {}
-
- template<typename LambdaT>
- ParserRefImpl( LambdaT const &ref, std::string const &hint )
- : m_ref( std::make_shared<BoundLambda<LambdaT>>( ref ) ),
- m_hint(hint)
- {}
-
- auto operator()( std::string const &description ) -> DerivedT & {
- m_description = description;
- return static_cast<DerivedT &>( *this );
- }
-
- auto optional() -> DerivedT & {
- m_optionality = Optionality::Optional;
- return static_cast<DerivedT &>( *this );
- };
-
- auto required() -> DerivedT & {
- m_optionality = Optionality::Required;
- return static_cast<DerivedT &>( *this );
- };
-
- auto isOptional() const -> bool {
- return m_optionality == Optionality::Optional;
- }
-
- auto cardinality() const -> size_t override {
- if( m_ref->isContainer() )
- return 0;
- else
- return 1;
- }
-
- auto hint() const -> std::string { return m_hint; }
- };
-
- class ExeName : public ComposableParserImpl<ExeName> {
- std::shared_ptr<std::string> m_name;
- std::shared_ptr<BoundValueRefBase> m_ref;
-
- template<typename LambdaT>
- static auto makeRef(LambdaT const &lambda) -> std::shared_ptr<BoundValueRefBase> {
- return std::make_shared<BoundLambda<LambdaT>>( lambda) ;
- }
-
- public:
- ExeName() : m_name( std::make_shared<std::string>( "<executable>" ) ) {}
-
- explicit ExeName( std::string &ref ) : ExeName() {
- m_ref = std::make_shared<BoundValueRef<std::string>>( ref );
- }
-
- template<typename LambdaT>
- explicit ExeName( LambdaT const& lambda ) : ExeName() {
- m_ref = std::make_shared<BoundLambda<LambdaT>>( lambda );
- }
-
- // The exe name is not parsed out of the normal tokens, but is handled specially
- auto parse( std::string const&, TokenStream const &tokens ) const -> InternalParseResult override {
- return InternalParseResult::ok( ParseState( ParseResultType::NoMatch, tokens ) );
- }
-
- auto name() const -> std::string { return *m_name; }
- auto set( std::string const& newName ) -> ParserResult {
-
- auto lastSlash = newName.find_last_of( "\\/" );
- auto filename = ( lastSlash == std::string::npos )
- ? newName
- : newName.substr( lastSlash+1 );
-
- *m_name = filename;
- if( m_ref )
- return m_ref->setValue( filename );
- else
- return ParserResult::ok( ParseResultType::Matched );
- }
- };
-
- class Arg : public ParserRefImpl<Arg> {
- public:
- using ParserRefImpl::ParserRefImpl;
-
- auto parse( std::string const &, TokenStream const &tokens ) const -> InternalParseResult override {
- auto validationResult = validate();
- if( !validationResult )
- return InternalParseResult( validationResult );
-
- auto remainingTokens = tokens;
- auto const &token = *remainingTokens;
- if( token.type != TokenType::Argument )
- return InternalParseResult::ok( ParseState( ParseResultType::NoMatch, remainingTokens ) );
-
- assert( !m_ref->isFlag() );
- auto valueRef = static_cast<detail::BoundValueRefBase*>( m_ref.get() );
-
- auto result = valueRef->setValue( remainingTokens->token );
- if( !result )
- return InternalParseResult( result );
- else
- return InternalParseResult::ok( ParseState( ParseResultType::Matched, ++remainingTokens ) );
- }
- };
-
- inline auto normaliseOpt( std::string const &optName ) -> std::string {
-#ifdef CATCH_PLATFORM_WINDOWS
- if( optName[0] == '/' )
- return "-" + optName.substr( 1 );
- else
-#endif
- return optName;
- }
-
- class Opt : public ParserRefImpl<Opt> {
- protected:
- std::vector<std::string> m_optNames;
-
- public:
- template<typename LambdaT>
- explicit Opt( LambdaT const &ref ) : ParserRefImpl( std::make_shared<BoundFlagLambda<LambdaT>>( ref ) ) {}
-
- explicit Opt( bool &ref ) : ParserRefImpl( std::make_shared<BoundFlagRef>( ref ) ) {}
-
- template<typename LambdaT>
- Opt( LambdaT const &ref, std::string const &hint ) : ParserRefImpl( ref, hint ) {}
-
- template<typename T>
- Opt( T &ref, std::string const &hint ) : ParserRefImpl( ref, hint ) {}
-
- auto operator[]( std::string const &optName ) -> Opt & {
- m_optNames.push_back( optName );
- return *this;
- }
-
- auto getHelpColumns() const -> std::vector<HelpColumns> {
- std::ostringstream oss;
- bool first = true;
- for( auto const &opt : m_optNames ) {
- if (first)
- first = false;
- else
- oss << ", ";
- oss << opt;
- }
- if( !m_hint.empty() )
- oss << " <" << m_hint << ">";
- return { { oss.str(), m_description } };
- }
-
- auto isMatch( std::string const &optToken ) const -> bool {
- auto normalisedToken = normaliseOpt( optToken );
- for( auto const &name : m_optNames ) {
- if( normaliseOpt( name ) == normalisedToken )
- return true;
- }
- return false;
- }
-
- using ParserBase::parse;
-
- auto parse( std::string const&, TokenStream const &tokens ) const -> InternalParseResult override {
- auto validationResult = validate();
- if( !validationResult )
- return InternalParseResult( validationResult );
-
- auto remainingTokens = tokens;
- if( remainingTokens && remainingTokens->type == TokenType::Option ) {
- auto const &token = *remainingTokens;
- if( isMatch(token.token ) ) {
- if( m_ref->isFlag() ) {
- auto flagRef = static_cast<detail::BoundFlagRefBase*>( m_ref.get() );
- auto result = flagRef->setFlag( true );
- if( !result )
- return InternalParseResult( result );
- if( result.value() == ParseResultType::ShortCircuitAll )
- return InternalParseResult::ok( ParseState( result.value(), remainingTokens ) );
- } else {
- auto valueRef = static_cast<detail::BoundValueRefBase*>( m_ref.get() );
- ++remainingTokens;
- if( !remainingTokens )
- return InternalParseResult::runtimeError( "Expected argument following " + token.token );
- auto const &argToken = *remainingTokens;
- if( argToken.type != TokenType::Argument )
- return InternalParseResult::runtimeError( "Expected argument following " + token.token );
- auto result = valueRef->setValue( argToken.token );
- if( !result )
- return InternalParseResult( result );
- if( result.value() == ParseResultType::ShortCircuitAll )
- return InternalParseResult::ok( ParseState( result.value(), remainingTokens ) );
- }
- return InternalParseResult::ok( ParseState( ParseResultType::Matched, ++remainingTokens ) );
- }
- }
- return InternalParseResult::ok( ParseState( ParseResultType::NoMatch, remainingTokens ) );
- }
-
- auto validate() const -> Result override {
- if( m_optNames.empty() )
- return Result::logicError( "No options supplied to Opt" );
- for( auto const &name : m_optNames ) {
- if( name.empty() )
- return Result::logicError( "Option name cannot be empty" );
-#ifdef CATCH_PLATFORM_WINDOWS
- if( name[0] != '-' && name[0] != '/' )
- return Result::logicError( "Option name must begin with '-' or '/'" );
-#else
- if( name[0] != '-' )
- return Result::logicError( "Option name must begin with '-'" );
-#endif
- }
- return ParserRefImpl::validate();
- }
- };
-
- struct Help : Opt {
- Help( bool &showHelpFlag )
- : Opt([&]( bool flag ) {
- showHelpFlag = flag;
- return ParserResult::ok( ParseResultType::ShortCircuitAll );
- })
- {
- static_cast<Opt &>( *this )
- ("display usage information")
- ["-?"]["-h"]["--help"]
- .optional();
- }
- };
-
- struct Parser : ParserBase {
-
- mutable ExeName m_exeName;
- std::vector<Opt> m_options;
- std::vector<Arg> m_args;
-
- auto operator|=( ExeName const &exeName ) -> Parser & {
- m_exeName = exeName;
- return *this;
- }
-
- auto operator|=( Arg const &arg ) -> Parser & {
- m_args.push_back(arg);
- return *this;
- }
-
- auto operator|=( Opt const &opt ) -> Parser & {
- m_options.push_back(opt);
- return *this;
- }
-
- auto operator|=( Parser const &other ) -> Parser & {
- m_options.insert(m_options.end(), other.m_options.begin(), other.m_options.end());
- m_args.insert(m_args.end(), other.m_args.begin(), other.m_args.end());
- return *this;
- }
-
- template<typename T>
- auto operator|( T const &other ) const -> Parser {
- return Parser( *this ) |= other;
- }
-
- // Forward deprecated interface with '+' instead of '|'
- template<typename T>
- auto operator+=( T const &other ) -> Parser & { return operator|=( other ); }
- template<typename T>
- auto operator+( T const &other ) const -> Parser { return operator|( other ); }
-
- auto getHelpColumns() const -> std::vector<HelpColumns> {
- std::vector<HelpColumns> cols;
- for (auto const &o : m_options) {
- auto childCols = o.getHelpColumns();
- cols.insert( cols.end(), childCols.begin(), childCols.end() );
- }
- return cols;
- }
-
- void writeToStream( std::ostream &os ) const {
- if (!m_exeName.name().empty()) {
- os << "usage:\n" << " " << m_exeName.name() << " ";
- bool required = true, first = true;
- for( auto const &arg : m_args ) {
- if (first)
- first = false;
- else
- os << " ";
- if( arg.isOptional() && required ) {
- os << "[";
- required = false;
- }
- os << "<" << arg.hint() << ">";
- if( arg.cardinality() == 0 )
- os << " ... ";
- }
- if( !required )
- os << "]";
- if( !m_options.empty() )
- os << " options";
- os << "\n\nwhere options are:" << std::endl;
- }
-
- auto rows = getHelpColumns();
- size_t consoleWidth = CATCH_CLARA_CONFIG_CONSOLE_WIDTH;
- size_t optWidth = 0;
- for( auto const &cols : rows )
- optWidth = (std::max)(optWidth, cols.left.size() + 2);
-
- optWidth = (std::min)(optWidth, consoleWidth/2);
-
- for( auto const &cols : rows ) {
- auto row =
- TextFlow::Column( cols.left ).width( optWidth ).indent( 2 ) +
- TextFlow::Spacer(4) +
- TextFlow::Column( cols.right ).width( consoleWidth - 7 - optWidth );
- os << row << std::endl;
- }
- }
-
- friend auto operator<<( std::ostream &os, Parser const &parser ) -> std::ostream& {
- parser.writeToStream( os );
- return os;
- }
-
- auto validate() const -> Result override {
- for( auto const &opt : m_options ) {
- auto result = opt.validate();
- if( !result )
- return result;
- }
- for( auto const &arg : m_args ) {
- auto result = arg.validate();
- if( !result )
- return result;
- }
- return Result::ok();
- }
-
- using ParserBase::parse;
-
- auto parse( std::string const& exeName, TokenStream const &tokens ) const -> InternalParseResult override {
-
- struct ParserInfo {
- ParserBase const* parser = nullptr;
- size_t count = 0;
- };
- const size_t totalParsers = m_options.size() + m_args.size();
- assert( totalParsers < 512 );
- // ParserInfo parseInfos[totalParsers]; // <-- this is what we really want to do
- ParserInfo parseInfos[512];
-
- {
- size_t i = 0;
- for (auto const &opt : m_options) parseInfos[i++].parser = &opt;
- for (auto const &arg : m_args) parseInfos[i++].parser = &arg;
- }
-
- m_exeName.set( exeName );
-
- auto result = InternalParseResult::ok( ParseState( ParseResultType::NoMatch, tokens ) );
- while( result.value().remainingTokens() ) {
- bool tokenParsed = false;
-
- for( size_t i = 0; i < totalParsers; ++i ) {
- auto& parseInfo = parseInfos[i];
- if( parseInfo.parser->cardinality() == 0 || parseInfo.count < parseInfo.parser->cardinality() ) {
- result = parseInfo.parser->parse(exeName, result.value().remainingTokens());
- if (!result)
- return result;
- if (result.value().type() != ParseResultType::NoMatch) {
- tokenParsed = true;
- ++parseInfo.count;
- break;
- }
- }
- }
-
- if( result.value().type() == ParseResultType::ShortCircuitAll )
- return result;
- if( !tokenParsed )
- return InternalParseResult::runtimeError( "Unrecognised token: " + result.value().remainingTokens()->token );
- }
- // !TBD Check missing required options
- return result;
- }
- };
-
- template<typename DerivedT>
- template<typename T>
- auto ComposableParserImpl<DerivedT>::operator|( T const &other ) const -> Parser {
- return Parser() | static_cast<DerivedT const &>( *this ) | other;
- }
-} // namespace detail
-
-// A Combined parser
-using detail::Parser;
-
-// A parser for options
-using detail::Opt;
-
-// A parser for arguments
-using detail::Arg;
-
-// Wrapper for argc, argv from main()
-using detail::Args;
-
-// Specifies the name of the executable
-using detail::ExeName;
-
-// Convenience wrapper for option parser that specifies the help option
-using detail::Help;
-
-// enum of result types from a parse
-using detail::ParseResultType;
-
-// Result type for parser operation
-using detail::ParserResult;
-
-}} // namespace Catch::clara
-
-// end clara.hpp
-#ifdef __clang__
-#pragma clang diagnostic pop
-#endif
-
-// Restore Clara's value for console width, if present
-#ifdef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
-#define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
-#undef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
-#endif
-
-// end catch_clara.h
-namespace Catch {
-
- clara::Parser makeCommandLineParser( ConfigData& config );
-
-} // end namespace Catch
-
-// end catch_commandline.h
-#include <fstream>
-#include <ctime>
-
-namespace Catch {
-
- clara::Parser makeCommandLineParser( ConfigData& config ) {
-
- using namespace clara;
-
- auto const setWarning = [&]( std::string const& warning ) {
- auto warningSet = [&]() {
- if( warning == "NoAssertions" )
- return WarnAbout::NoAssertions;
-
- if ( warning == "NoTests" )
- return WarnAbout::NoTests;
-
- return WarnAbout::Nothing;
- }();
-
- if (warningSet == WarnAbout::Nothing)
- return ParserResult::runtimeError( "Unrecognised warning: '" + warning + "'" );
- config.warnings = static_cast<WarnAbout::What>( config.warnings | warningSet );
- return ParserResult::ok( ParseResultType::Matched );
- };
- auto const loadTestNamesFromFile = [&]( std::string const& filename ) {
- std::ifstream f( filename.c_str() );
- if( !f.is_open() )
- return ParserResult::runtimeError( "Unable to load input file: '" + filename + "'" );
-
- std::string line;
- while( std::getline( f, line ) ) {
- line = trim(line);
- if( !line.empty() && !startsWith( line, '#' ) ) {
- if( !startsWith( line, '"' ) )
- line = '"' + line + '"';
- config.testsOrTags.push_back( line + ',' );
- }
- }
- return ParserResult::ok( ParseResultType::Matched );
- };
- auto const setTestOrder = [&]( std::string const& order ) {
- if( startsWith( "declared", order ) )
- config.runOrder = RunTests::InDeclarationOrder;
- else if( startsWith( "lexical", order ) )
- config.runOrder = RunTests::InLexicographicalOrder;
- else if( startsWith( "random", order ) )
- config.runOrder = RunTests::InRandomOrder;
- else
- return clara::ParserResult::runtimeError( "Unrecognised ordering: '" + order + "'" );
- return ParserResult::ok( ParseResultType::Matched );
- };
- auto const setRngSeed = [&]( std::string const& seed ) {
- if( seed != "time" )
- return clara::detail::convertInto( seed, config.rngSeed );
- config.rngSeed = static_cast<unsigned int>( std::time(nullptr) );
- return ParserResult::ok( ParseResultType::Matched );
- };
- auto const setColourUsage = [&]( std::string const& useColour ) {
- auto mode = toLower( useColour );
-
- if( mode == "yes" )
- config.useColour = UseColour::Yes;
- else if( mode == "no" )
- config.useColour = UseColour::No;
- else if( mode == "auto" )
- config.useColour = UseColour::Auto;
- else
- return ParserResult::runtimeError( "colour mode must be one of: auto, yes or no. '" + useColour + "' not recognised" );
- return ParserResult::ok( ParseResultType::Matched );
- };
- auto const setWaitForKeypress = [&]( std::string const& keypress ) {
- auto keypressLc = toLower( keypress );
- if( keypressLc == "start" )
- config.waitForKeypress = WaitForKeypress::BeforeStart;
- else if( keypressLc == "exit" )
- config.waitForKeypress = WaitForKeypress::BeforeExit;
- else if( keypressLc == "both" )
- config.waitForKeypress = WaitForKeypress::BeforeStartAndExit;
- else
- return ParserResult::runtimeError( "keypress argument must be one of: start, exit or both. '" + keypress + "' not recognised" );
- return ParserResult::ok( ParseResultType::Matched );
- };
- auto const setVerbosity = [&]( std::string const& verbosity ) {
- auto lcVerbosity = toLower( verbosity );
- if( lcVerbosity == "quiet" )
- config.verbosity = Verbosity::Quiet;
- else if( lcVerbosity == "normal" )
- config.verbosity = Verbosity::Normal;
- else if( lcVerbosity == "high" )
- config.verbosity = Verbosity::High;
- else
- return ParserResult::runtimeError( "Unrecognised verbosity, '" + verbosity + "'" );
- return ParserResult::ok( ParseResultType::Matched );
- };
- auto const setReporter = [&]( std::string const& reporter ) {
- IReporterRegistry::FactoryMap const& factories = getRegistryHub().getReporterRegistry().getFactories();
-
- auto lcReporter = toLower( reporter );
- auto result = factories.find( lcReporter );
-
- if( factories.end() != result )
- config.reporterName = lcReporter;
- else
- return ParserResult::runtimeError( "Unrecognized reporter, '" + reporter + "'. Check available with --list-reporters" );
- return ParserResult::ok( ParseResultType::Matched );
- };
-
- auto cli
- = ExeName( config.processName )
- | Help( config.showHelp )
- | Opt( config.listTests )
- ["-l"]["--list-tests"]
- ( "list all/matching test cases" )
- | Opt( config.listTags )
- ["-t"]["--list-tags"]
- ( "list all/matching tags" )
- | Opt( config.showSuccessfulTests )
- ["-s"]["--success"]
- ( "include successful tests in output" )
- | Opt( config.shouldDebugBreak )
- ["-b"]["--break"]
- ( "break into debugger on failure" )
- | Opt( config.noThrow )
- ["-e"]["--nothrow"]
- ( "skip exception tests" )
- | Opt( config.showInvisibles )
- ["-i"]["--invisibles"]
- ( "show invisibles (tabs, newlines)" )
- | Opt( config.outputFilename, "filename" )
- ["-o"]["--out"]
- ( "output filename" )
- | Opt( setReporter, "name" )
- ["-r"]["--reporter"]
- ( "reporter to use (defaults to console)" )
- | Opt( config.name, "name" )
- ["-n"]["--name"]
- ( "suite name" )
- | Opt( [&]( bool ){ config.abortAfter = 1; } )
- ["-a"]["--abort"]
- ( "abort at first failure" )
- | Opt( [&]( int x ){ config.abortAfter = x; }, "no. failures" )
- ["-x"]["--abortx"]
- ( "abort after x failures" )
- | Opt( setWarning, "warning name" )
- ["-w"]["--warn"]
- ( "enable warnings" )
- | Opt( [&]( bool flag ) { config.showDurations = flag ? ShowDurations::Always : ShowDurations::Never; }, "yes|no" )
- ["-d"]["--durations"]
- ( "show test durations" )
- | Opt( loadTestNamesFromFile, "filename" )
- ["-f"]["--input-file"]
- ( "load test names to run from a file" )
- | Opt( config.filenamesAsTags )
- ["-#"]["--filenames-as-tags"]
- ( "adds a tag for the filename" )
- | Opt( config.sectionsToRun, "section name" )
- ["-c"]["--section"]
- ( "specify section to run" )
- | Opt( setVerbosity, "quiet|normal|high" )
- ["-v"]["--verbosity"]
- ( "set output verbosity" )
- | Opt( config.listTestNamesOnly )
- ["--list-test-names-only"]
- ( "list all/matching test cases names only" )
- | Opt( config.listReporters )
- ["--list-reporters"]
- ( "list all reporters" )
- | Opt( setTestOrder, "decl|lex|rand" )
- ["--order"]
- ( "test case order (defaults to decl)" )
- | Opt( setRngSeed, "'time'|number" )
- ["--rng-seed"]
- ( "set a specific seed for random numbers" )
- | Opt( setColourUsage, "yes|no" )
- ["--use-colour"]
- ( "should output be colourised" )
- | Opt( config.libIdentify )
- ["--libidentify"]
- ( "report name and version according to libidentify standard" )
- | Opt( setWaitForKeypress, "start|exit|both" )
- ["--wait-for-keypress"]
- ( "waits for a keypress before exiting" )
- | Opt( config.benchmarkSamples, "samples" )
- ["--benchmark-samples"]
- ( "number of samples to collect (default: 100)" )
- | Opt( config.benchmarkResamples, "resamples" )
- ["--benchmark-resamples"]
- ( "number of resamples for the bootstrap (default: 100000)" )
- | Opt( config.benchmarkConfidenceInterval, "confidence interval" )
- ["--benchmark-confidence-interval"]
- ( "confidence interval for the bootstrap (between 0 and 1, default: 0.95)" )
- | Opt( config.benchmarkNoAnalysis )
- ["--benchmark-no-analysis"]
- ( "perform only measurements; do not perform any analysis" )
- | Arg( config.testsOrTags, "test name|pattern|tags" )
- ( "which test or tests to use" );
-
- return cli;
- }
-
-} // end namespace Catch
-// end catch_commandline.cpp
-// start catch_common.cpp
-
-#include <cstring>
-#include <ostream>
-
-namespace Catch {
-
- bool SourceLineInfo::empty() const noexcept {
- return file[0] == '\0';
- }
- bool SourceLineInfo::operator == ( SourceLineInfo const& other ) const noexcept {
- return line == other.line && (file == other.file || std::strcmp(file, other.file) == 0);
- }
- bool SourceLineInfo::operator < ( SourceLineInfo const& other ) const noexcept {
- // We can assume that the same file will usually have the same pointer.
- // Thus, if the pointers are the same, there is no point in calling the strcmp
- return line < other.line || ( line == other.line && file != other.file && (std::strcmp(file, other.file) < 0));
- }
-
- std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ) {
-#ifndef __GNUG__
- os << info.file << '(' << info.line << ')';
-#else
- os << info.file << ':' << info.line;
-#endif
- return os;
- }
-
- std::string StreamEndStop::operator+() const {
- return std::string();
- }
-
- NonCopyable::NonCopyable() = default;
- NonCopyable::~NonCopyable() = default;
-
-}
-// end catch_common.cpp
-// start catch_config.cpp
-
-namespace Catch {
-
- Config::Config( ConfigData const& data )
- : m_data( data ),
- m_stream( openStream() )
- {
- TestSpecParser parser(ITagAliasRegistry::get());
- if (!data.testsOrTags.empty()) {
- m_hasTestFilters = true;
- for( auto const& testOrTags : data.testsOrTags )
- parser.parse( testOrTags );
- }
- m_testSpec = parser.testSpec();
- }
-
- std::string const& Config::getFilename() const {
- return m_data.outputFilename ;
- }
-
- bool Config::listTests() const { return m_data.listTests; }
- bool Config::listTestNamesOnly() const { return m_data.listTestNamesOnly; }
- bool Config::listTags() const { return m_data.listTags; }
- bool Config::listReporters() const { return m_data.listReporters; }
-
- std::string Config::getProcessName() const { return m_data.processName; }
- std::string const& Config::getReporterName() const { return m_data.reporterName; }
-
- std::vector<std::string> const& Config::getTestsOrTags() const { return m_data.testsOrTags; }
- std::vector<std::string> const& Config::getSectionsToRun() const { return m_data.sectionsToRun; }
-
- TestSpec const& Config::testSpec() const { return m_testSpec; }
- bool Config::hasTestFilters() const { return m_hasTestFilters; }
-
- bool Config::showHelp() const { return m_data.showHelp; }
-
- // IConfig interface
- bool Config::allowThrows() const { return !m_data.noThrow; }
- std::ostream& Config::stream() const { return m_stream->stream(); }
- std::string Config::name() const { return m_data.name.empty() ? m_data.processName : m_data.name; }
- bool Config::includeSuccessfulResults() const { return m_data.showSuccessfulTests; }
- bool Config::warnAboutMissingAssertions() const { return !!(m_data.warnings & WarnAbout::NoAssertions); }
- bool Config::warnAboutNoTests() const { return !!(m_data.warnings & WarnAbout::NoTests); }
- ShowDurations::OrNot Config::showDurations() const { return m_data.showDurations; }
- RunTests::InWhatOrder Config::runOrder() const { return m_data.runOrder; }
- unsigned int Config::rngSeed() const { return m_data.rngSeed; }
- UseColour::YesOrNo Config::useColour() const { return m_data.useColour; }
- bool Config::shouldDebugBreak() const { return m_data.shouldDebugBreak; }
- int Config::abortAfter() const { return m_data.abortAfter; }
- bool Config::showInvisibles() const { return m_data.showInvisibles; }
- Verbosity Config::verbosity() const { return m_data.verbosity; }
-
- bool Config::benchmarkNoAnalysis() const { return m_data.benchmarkNoAnalysis; }
- int Config::benchmarkSamples() const { return m_data.benchmarkSamples; }
- double Config::benchmarkConfidenceInterval() const { return m_data.benchmarkConfidenceInterval; }
- unsigned int Config::benchmarkResamples() const { return m_data.benchmarkResamples; }
-
- IStream const* Config::openStream() {
- return Catch::makeStream(m_data.outputFilename);
- }
-
-} // end namespace Catch
-// end catch_config.cpp
-// start catch_console_colour.cpp
-
-#if defined(__clang__)
-# pragma clang diagnostic push
-# pragma clang diagnostic ignored "-Wexit-time-destructors"
-#endif
-
-// start catch_errno_guard.h
-
-namespace Catch {
-
- class ErrnoGuard {
- public:
- ErrnoGuard();
- ~ErrnoGuard();
- private:
- int m_oldErrno;
- };
-
-}
-
-// end catch_errno_guard.h
-#include <sstream>
-
-namespace Catch {
- namespace {
-
- struct IColourImpl {
- virtual ~IColourImpl() = default;
- virtual void use( Colour::Code _colourCode ) = 0;
- };
-
- struct NoColourImpl : IColourImpl {
- void use( Colour::Code ) {}
-
- static IColourImpl* instance() {
- static NoColourImpl s_instance;
- return &s_instance;
- }
- };
-
- } // anon namespace
-} // namespace Catch
-
-#if !defined( CATCH_CONFIG_COLOUR_NONE ) && !defined( CATCH_CONFIG_COLOUR_WINDOWS ) && !defined( CATCH_CONFIG_COLOUR_ANSI )
-# ifdef CATCH_PLATFORM_WINDOWS
-# define CATCH_CONFIG_COLOUR_WINDOWS
-# else
-# define CATCH_CONFIG_COLOUR_ANSI
-# endif
-#endif
-
-#if defined ( CATCH_CONFIG_COLOUR_WINDOWS ) /////////////////////////////////////////
-
-namespace Catch {
-namespace {
-
- class Win32ColourImpl : public IColourImpl {
- public:
- Win32ColourImpl() : stdoutHandle( GetStdHandle(STD_OUTPUT_HANDLE) )
- {
- CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
- GetConsoleScreenBufferInfo( stdoutHandle, &csbiInfo );
- originalForegroundAttributes = csbiInfo.wAttributes & ~( BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_INTENSITY );
- originalBackgroundAttributes = csbiInfo.wAttributes & ~( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY );
- }
-
- void use( Colour::Code _colourCode ) override {
- switch( _colourCode ) {
- case Colour::None: return setTextAttribute( originalForegroundAttributes );
- case Colour::White: return setTextAttribute( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );
- case Colour::Red: return setTextAttribute( FOREGROUND_RED );
- case Colour::Green: return setTextAttribute( FOREGROUND_GREEN );
- case Colour::Blue: return setTextAttribute( FOREGROUND_BLUE );
- case Colour::Cyan: return setTextAttribute( FOREGROUND_BLUE | FOREGROUND_GREEN );
- case Colour::Yellow: return setTextAttribute( FOREGROUND_RED | FOREGROUND_GREEN );
- case Colour::Grey: return setTextAttribute( 0 );
-
- case Colour::LightGrey: return setTextAttribute( FOREGROUND_INTENSITY );
- case Colour::BrightRed: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_RED );
- case Colour::BrightGreen: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN );
- case Colour::BrightWhite: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );
- case Colour::BrightYellow: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN );
-
- case Colour::Bright: CATCH_INTERNAL_ERROR( "not a colour" );
-
- default:
- CATCH_ERROR( "Unknown colour requested" );
- }
- }
-
- private:
- void setTextAttribute( WORD _textAttribute ) {
- SetConsoleTextAttribute( stdoutHandle, _textAttribute | originalBackgroundAttributes );
- }
- HANDLE stdoutHandle;
- WORD originalForegroundAttributes;
- WORD originalBackgroundAttributes;
- };
-
- IColourImpl* platformColourInstance() {
- static Win32ColourImpl s_instance;
-
- IConfigPtr config = getCurrentContext().getConfig();
- UseColour::YesOrNo colourMode = config
- ? config->useColour()
- : UseColour::Auto;
- if( colourMode == UseColour::Auto )
- colourMode = UseColour::Yes;
- return colourMode == UseColour::Yes
- ? &s_instance
- : NoColourImpl::instance();
- }
-
-} // end anon namespace
-} // end namespace Catch
-
-#elif defined( CATCH_CONFIG_COLOUR_ANSI ) //////////////////////////////////////
-
-#include <unistd.h>
-
-namespace Catch {
-namespace {
-
- // use POSIX/ ANSI console terminal codes
- // Thanks to Adam Strzelecki for original contribution
- // (http://github.com/nanoant)
- // https://github.com/philsquared/Catch/pull/131
- class PosixColourImpl : public IColourImpl {
- public:
- void use( Colour::Code _colourCode ) override {
- switch( _colourCode ) {
- case Colour::None:
- case Colour::White: return setColour( "[0m" );
- case Colour::Red: return setColour( "[0;31m" );
- case Colour::Green: return setColour( "[0;32m" );
- case Colour::Blue: return setColour( "[0;34m" );
- case Colour::Cyan: return setColour( "[0;36m" );
- case Colour::Yellow: return setColour( "[0;33m" );
- case Colour::Grey: return setColour( "[1;30m" );
-
- case Colour::LightGrey: return setColour( "[0;37m" );
- case Colour::BrightRed: return setColour( "[1;31m" );
- case Colour::BrightGreen: return setColour( "[1;32m" );
- case Colour::BrightWhite: return setColour( "[1;37m" );
- case Colour::BrightYellow: return setColour( "[1;33m" );
-
- case Colour::Bright: CATCH_INTERNAL_ERROR( "not a colour" );
- default: CATCH_INTERNAL_ERROR( "Unknown colour requested" );
- }
- }
- static IColourImpl* instance() {
- static PosixColourImpl s_instance;
- return &s_instance;
- }
-
- private:
- void setColour( const char* _escapeCode ) {
- getCurrentContext().getConfig()->stream()
- << '\033' << _escapeCode;
- }
- };
-
- bool useColourOnPlatform() {
- return
-#ifdef CATCH_PLATFORM_MAC
- !isDebuggerActive() &&
-#endif
-#if !(defined(__DJGPP__) && defined(__STRICT_ANSI__))
- isatty(STDOUT_FILENO)
-#else
- false
-#endif
- ;
- }
- IColourImpl* platformColourInstance() {
- ErrnoGuard guard;
- IConfigPtr config = getCurrentContext().getConfig();
- UseColour::YesOrNo colourMode = config
- ? config->useColour()
- : UseColour::Auto;
- if( colourMode == UseColour::Auto )
- colourMode = useColourOnPlatform()
- ? UseColour::Yes
- : UseColour::No;
- return colourMode == UseColour::Yes
- ? PosixColourImpl::instance()
- : NoColourImpl::instance();
- }
-
-} // end anon namespace
-} // end namespace Catch
-
-#else // not Windows or ANSI ///////////////////////////////////////////////
-
-namespace Catch {
-
- static IColourImpl* platformColourInstance() { return NoColourImpl::instance(); }
-
-} // end namespace Catch
-
-#endif // Windows/ ANSI/ None
-
-namespace Catch {
-
- Colour::Colour( Code _colourCode ) { use( _colourCode ); }
- Colour::Colour( Colour&& rhs ) noexcept {
- m_moved = rhs.m_moved;
- rhs.m_moved = true;
- }
- Colour& Colour::operator=( Colour&& rhs ) noexcept {
- m_moved = rhs.m_moved;
- rhs.m_moved = true;
- return *this;
- }
-
- Colour::~Colour(){ if( !m_moved ) use( None ); }
-
- void Colour::use( Code _colourCode ) {
- static IColourImpl* impl = platformColourInstance();
- // Strictly speaking, this cannot possibly happen.
- // However, under some conditions it does happen (see #1626),
- // and this change is small enough that we can let practicality
- // triumph over purity in this case.
- if (impl != NULL) {
- impl->use( _colourCode );
- }
- }
-
- std::ostream& operator << ( std::ostream& os, Colour const& ) {
- return os;
- }
-
-} // end namespace Catch
-
-#if defined(__clang__)
-# pragma clang diagnostic pop
-#endif
-
-// end catch_console_colour.cpp
-// start catch_context.cpp
-
-namespace Catch {
-
- class Context : public IMutableContext, NonCopyable {
-
- public: // IContext
- IResultCapture* getResultCapture() override {
- return m_resultCapture;
- }
- IRunner* getRunner() override {
- return m_runner;
- }
-
- IConfigPtr const& getConfig() const override {
- return m_config;
- }
-
- ~Context() override;
-
- public: // IMutableContext
- void setResultCapture( IResultCapture* resultCapture ) override {
- m_resultCapture = resultCapture;
- }
- void setRunner( IRunner* runner ) override {
- m_runner = runner;
- }
- void setConfig( IConfigPtr const& config ) override {
- m_config = config;
- }
-
- friend IMutableContext& getCurrentMutableContext();
-
- private:
- IConfigPtr m_config;
- IRunner* m_runner = nullptr;
- IResultCapture* m_resultCapture = nullptr;
- };
-
- IMutableContext *IMutableContext::currentContext = nullptr;
-
- void IMutableContext::createContext()
- {
- currentContext = new Context();
- }
-
- void cleanUpContext() {
- delete IMutableContext::currentContext;
- IMutableContext::currentContext = nullptr;
- }
- IContext::~IContext() = default;
- IMutableContext::~IMutableContext() = default;
- Context::~Context() = default;
-}
-// end catch_context.cpp
-// start catch_debug_console.cpp
-
-// start catch_debug_console.h
-
-#include <string>
-
-namespace Catch {
- void writeToDebugConsole( std::string const& text );
-}
-
-// end catch_debug_console.h
-#ifdef CATCH_PLATFORM_WINDOWS
-
- namespace Catch {
- void writeToDebugConsole( std::string const& text ) {
- ::OutputDebugStringA( text.c_str() );
- }
- }
-
-#else
-
- namespace Catch {
- void writeToDebugConsole( std::string const& text ) {
- // !TBD: Need a version for Mac/ XCode and other IDEs
- Catch::cout() << text;
- }
- }
-
-#endif // Platform
-// end catch_debug_console.cpp
-// start catch_debugger.cpp
-
-#ifdef CATCH_PLATFORM_MAC
-
-# include <assert.h>
-# include <stdbool.h>
-# include <sys/types.h>
-# include <unistd.h>
-# include <cstddef>
-# include <ostream>
-
-#ifdef __apple_build_version__
- // These headers will only compile with AppleClang (XCode)
- // For other compilers (Clang, GCC, ... ) we need to exclude them
-# include <sys/sysctl.h>
-#endif
-
- namespace Catch {
- #ifdef __apple_build_version__
- // The following function is taken directly from the following technical note:
- // https://developer.apple.com/library/archive/qa/qa1361/_index.html
-
- // Returns true if the current process is being debugged (either
- // running under the debugger or has a debugger attached post facto).
- bool isDebuggerActive(){
- int mib[4];
- struct kinfo_proc info;
- std::size_t size;
-
- // Initialize the flags so that, if sysctl fails for some bizarre
- // reason, we get a predictable result.
-
- info.kp_proc.p_flag = 0;
-
- // Initialize mib, which tells sysctl the info we want, in this case
- // we're looking for information about a specific process ID.
-
- mib[0] = CTL_KERN;
- mib[1] = KERN_PROC;
- mib[2] = KERN_PROC_PID;
- mib[3] = getpid();
-
- // Call sysctl.
-
- size = sizeof(info);
- if( sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, nullptr, 0) != 0 ) {
- Catch::cerr() << "\n** Call to sysctl failed - unable to determine if debugger is active **\n" << std::endl;
- return false;
- }
-
- // We're being debugged if the P_TRACED flag is set.
-
- return ( (info.kp_proc.p_flag & P_TRACED) != 0 );
- }
- #else
- bool isDebuggerActive() {
- // We need to find another way to determine this for non-appleclang compilers on macOS
- return false;
- }
- #endif
- } // namespace Catch
-
-#elif defined(CATCH_PLATFORM_LINUX)
- #include <fstream>
- #include <string>
-
- namespace Catch{
- // The standard POSIX way of detecting a debugger is to attempt to
- // ptrace() the process, but this needs to be done from a child and not
- // this process itself to still allow attaching to this process later
- // if wanted, so is rather heavy. Under Linux we have the PID of the
- // "debugger" (which doesn't need to be gdb, of course, it could also
- // be strace, for example) in /proc/$PID/status, so just get it from
- // there instead.
- bool isDebuggerActive(){
- // Libstdc++ has a bug, where std::ifstream sets errno to 0
- // This way our users can properly assert over errno values
- ErrnoGuard guard;
- std::ifstream in("/proc/self/status");
- for( std::string line; std::getline(in, line); ) {
- static const int PREFIX_LEN = 11;
- if( line.compare(0, PREFIX_LEN, "TracerPid:\t") == 0 ) {
- // We're traced if the PID is not 0 and no other PID starts
- // with 0 digit, so it's enough to check for just a single
- // character.
- return line.length() > PREFIX_LEN && line[PREFIX_LEN] != '0';
- }
- }
-
- return false;
- }
- } // namespace Catch
-#elif defined(_MSC_VER)
- extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent();
- namespace Catch {
- bool isDebuggerActive() {
- return IsDebuggerPresent() != 0;
- }
- }
-#elif defined(__MINGW32__)
- extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent();
- namespace Catch {
- bool isDebuggerActive() {
- return IsDebuggerPresent() != 0;
- }
- }
-#else
- namespace Catch {
- bool isDebuggerActive() { return false; }
- }
-#endif // Platform
-// end catch_debugger.cpp
-// start catch_decomposer.cpp
-
-namespace Catch {
-
- ITransientExpression::~ITransientExpression() = default;
-
- void formatReconstructedExpression( std::ostream &os, std::string const& lhs, StringRef op, std::string const& rhs ) {
- if( lhs.size() + rhs.size() < 40 &&
- lhs.find('\n') == std::string::npos &&
- rhs.find('\n') == std::string::npos )
- os << lhs << " " << op << " " << rhs;
- else
- os << lhs << "\n" << op << "\n" << rhs;
- }
-}
-// end catch_decomposer.cpp
-// start catch_enforce.cpp
-
-#include <stdexcept>
-
-namespace Catch {
-#if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) && !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS_CUSTOM_HANDLER)
- [[noreturn]]
- void throw_exception(std::exception const& e) {
- Catch::cerr() << "Catch will terminate because it needed to throw an exception.\n"
- << "The message was: " << e.what() << '\n';
- std::terminate();
- }
-#endif
-
- [[noreturn]]
- void throw_logic_error(std::string const& msg) {
- throw_exception(std::logic_error(msg));
- }
-
- [[noreturn]]
- void throw_domain_error(std::string const& msg) {
- throw_exception(std::domain_error(msg));
- }
-
- [[noreturn]]
- void throw_runtime_error(std::string const& msg) {
- throw_exception(std::runtime_error(msg));
- }
-
-} // namespace Catch;
-// end catch_enforce.cpp
-// start catch_enum_values_registry.cpp
-// start catch_enum_values_registry.h
-
-#include <vector>
-#include <memory>
-
-namespace Catch {
-
- namespace Detail {
-
- std::unique_ptr<EnumInfo> makeEnumInfo( StringRef enumName, StringRef allValueNames, std::vector<int> const& values );
-
- class EnumValuesRegistry : public IMutableEnumValuesRegistry {
-
- std::vector<std::unique_ptr<EnumInfo>> m_enumInfos;
-
- EnumInfo const& registerEnum( StringRef enumName, StringRef allEnums, std::vector<int> const& values) override;
- };
-
- std::vector<std::string> parseEnums( StringRef enums );
-
- } // Detail
-
-} // Catch
-
-// end catch_enum_values_registry.h
-
-#include <map>
-#include <cassert>
-
-namespace Catch {
-
- IMutableEnumValuesRegistry::~IMutableEnumValuesRegistry() {}
-
- namespace Detail {
-
- std::vector<std::string> parseEnums( StringRef enums ) {
- auto enumValues = splitStringRef( enums, ',' );
- std::vector<std::string> parsed;
- parsed.reserve( enumValues.size() );
- for( auto const& enumValue : enumValues ) {
- auto identifiers = splitStringRef( enumValue, ':' );
- parsed.push_back( Catch::trim( identifiers.back() ) );
- }
- return parsed;
- }
-
- EnumInfo::~EnumInfo() {}
-
- StringRef EnumInfo::lookup( int value ) const {
- for( auto const& valueToName : m_values ) {
- if( valueToName.first == value )
- return valueToName.second;
- }
- return "{** unexpected enum value **}";
- }
-
- std::unique_ptr<EnumInfo> makeEnumInfo( StringRef enumName, StringRef allValueNames, std::vector<int> const& values ) {
- std::unique_ptr<EnumInfo> enumInfo( new EnumInfo );
- enumInfo->m_name = enumName;
- enumInfo->m_values.reserve( values.size() );
-
- const auto valueNames = Catch::Detail::parseEnums( allValueNames );
- assert( valueNames.size() == values.size() );
- std::size_t i = 0;
- for( auto value : values )
- enumInfo->m_values.push_back({ value, valueNames[i++] });
-
- return enumInfo;
- }
-
- EnumInfo const& EnumValuesRegistry::registerEnum( StringRef enumName, StringRef allValueNames, std::vector<int> const& values ) {
- auto enumInfo = makeEnumInfo( enumName, allValueNames, values );
- EnumInfo* raw = enumInfo.get();
- m_enumInfos.push_back( std::move( enumInfo ) );
- return *raw;
- }
-
- } // Detail
-} // Catch
-
-// end catch_enum_values_registry.cpp
-// start catch_errno_guard.cpp
-
-#include <cerrno>
-
-namespace Catch {
- ErrnoGuard::ErrnoGuard():m_oldErrno(errno){}
- ErrnoGuard::~ErrnoGuard() { errno = m_oldErrno; }
-}
-// end catch_errno_guard.cpp
-// start catch_exception_translator_registry.cpp
-
-// start catch_exception_translator_registry.h
-
-#include <vector>
-#include <string>
-#include <memory>
-
-namespace Catch {
-
- class ExceptionTranslatorRegistry : public IExceptionTranslatorRegistry {
- public:
- ~ExceptionTranslatorRegistry();
- virtual void registerTranslator( const IExceptionTranslator* translator );
- std::string translateActiveException() const override;
- std::string tryTranslators() const;
-
- private:
- std::vector<std::unique_ptr<IExceptionTranslator const>> m_translators;
- };
-}
-
-// end catch_exception_translator_registry.h
-#ifdef __OBJC__
-#import "Foundation/Foundation.h"
-#endif
-
-namespace Catch {
-
- ExceptionTranslatorRegistry::~ExceptionTranslatorRegistry() {
- }
-
- void ExceptionTranslatorRegistry::registerTranslator( const IExceptionTranslator* translator ) {
- m_translators.push_back( std::unique_ptr<const IExceptionTranslator>( translator ) );
- }
-
-#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
- std::string ExceptionTranslatorRegistry::translateActiveException() const {
- try {
-#ifdef __OBJC__
- // In Objective-C try objective-c exceptions first
- @try {
- return tryTranslators();
- }
- @catch (NSException *exception) {
- return Catch::Detail::stringify( [exception description] );
- }
-#else
- // Compiling a mixed mode project with MSVC means that CLR
- // exceptions will be caught in (...) as well. However, these
- // do not fill-in std::current_exception and thus lead to crash
- // when attempting rethrow.
- // /EHa switch also causes structured exceptions to be caught
- // here, but they fill-in current_exception properly, so
- // at worst the output should be a little weird, instead of
- // causing a crash.
- if (std::current_exception() == nullptr) {
- return "Non C++ exception. Possibly a CLR exception.";
- }
- return tryTranslators();
-#endif
- }
- catch( TestFailureException& ) {
- std::rethrow_exception(std::current_exception());
- }
- catch( std::exception& ex ) {
- return ex.what();
- }
- catch( std::string& msg ) {
- return msg;
- }
- catch( const char* msg ) {
- return msg;
- }
- catch(...) {
- return "Unknown exception";
- }
- }
-
- std::string ExceptionTranslatorRegistry::tryTranslators() const {
- if (m_translators.empty()) {
- std::rethrow_exception(std::current_exception());
- } else {
- return m_translators[0]->translate(m_translators.begin() + 1, m_translators.end());
- }
- }
-
-#else // ^^ Exceptions are enabled // Exceptions are disabled vv
- std::string ExceptionTranslatorRegistry::translateActiveException() const {
- CATCH_INTERNAL_ERROR("Attempted to translate active exception under CATCH_CONFIG_DISABLE_EXCEPTIONS!");
- }
-
- std::string ExceptionTranslatorRegistry::tryTranslators() const {
- CATCH_INTERNAL_ERROR("Attempted to use exception translators under CATCH_CONFIG_DISABLE_EXCEPTIONS!");
- }
-#endif
-
-}
-// end catch_exception_translator_registry.cpp
-// start catch_fatal_condition.cpp
-
-#if defined(__GNUC__)
-# pragma GCC diagnostic push
-# pragma GCC diagnostic ignored "-Wmissing-field-initializers"
-#endif
-
-#if defined( CATCH_CONFIG_WINDOWS_SEH ) || defined( CATCH_CONFIG_POSIX_SIGNALS )
-
-namespace {
- // Report the error condition
- void reportFatal( char const * const message ) {
- Catch::getCurrentContext().getResultCapture()->handleFatalErrorCondition( message );
- }
-}
-
-#endif // signals/SEH handling
-
-#if defined( CATCH_CONFIG_WINDOWS_SEH )
-
-namespace Catch {
- struct SignalDefs { DWORD id; const char* name; };
-
- // There is no 1-1 mapping between signals and windows exceptions.
- // Windows can easily distinguish between SO and SigSegV,
- // but SigInt, SigTerm, etc are handled differently.
- static SignalDefs signalDefs[] = {
- { static_cast<DWORD>(EXCEPTION_ILLEGAL_INSTRUCTION), "SIGILL - Illegal instruction signal" },
- { static_cast<DWORD>(EXCEPTION_STACK_OVERFLOW), "SIGSEGV - Stack overflow" },
- { static_cast<DWORD>(EXCEPTION_ACCESS_VIOLATION), "SIGSEGV - Segmentation violation signal" },
- { static_cast<DWORD>(EXCEPTION_INT_DIVIDE_BY_ZERO), "Divide by zero error" },
- };
-
- LONG CALLBACK FatalConditionHandler::handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo) {
- for (auto const& def : signalDefs) {
- if (ExceptionInfo->ExceptionRecord->ExceptionCode == def.id) {
- reportFatal(def.name);
- }
- }
- // If its not an exception we care about, pass it along.
- // This stops us from eating debugger breaks etc.
- return EXCEPTION_CONTINUE_SEARCH;
- }
-
- FatalConditionHandler::FatalConditionHandler() {
- isSet = true;
- // 32k seems enough for Catch to handle stack overflow,
- // but the value was found experimentally, so there is no strong guarantee
- guaranteeSize = 32 * 1024;
- exceptionHandlerHandle = nullptr;
- // Register as first handler in current chain
- exceptionHandlerHandle = AddVectoredExceptionHandler(1, handleVectoredException);
- // Pass in guarantee size to be filled
- SetThreadStackGuarantee(&guaranteeSize);
- }
-
- void FatalConditionHandler::reset() {
- if (isSet) {
- RemoveVectoredExceptionHandler(exceptionHandlerHandle);
- SetThreadStackGuarantee(&guaranteeSize);
- exceptionHandlerHandle = nullptr;
- isSet = false;
- }
- }
-
- FatalConditionHandler::~FatalConditionHandler() {
- reset();
- }
-
-bool FatalConditionHandler::isSet = false;
-ULONG FatalConditionHandler::guaranteeSize = 0;
-PVOID FatalConditionHandler::exceptionHandlerHandle = nullptr;
-
-} // namespace Catch
-
-#elif defined( CATCH_CONFIG_POSIX_SIGNALS )
-
-namespace Catch {
-
- struct SignalDefs {
- int id;
- const char* name;
- };
-
- // 32kb for the alternate stack seems to be sufficient. However, this value
- // is experimentally determined, so that's not guaranteed.
- constexpr static std::size_t sigStackSize = 32768 >= MINSIGSTKSZ ? 32768 : MINSIGSTKSZ;
-
- static SignalDefs signalDefs[] = {
- { SIGINT, "SIGINT - Terminal interrupt signal" },
- { SIGILL, "SIGILL - Illegal instruction signal" },
- { SIGFPE, "SIGFPE - Floating point error signal" },
- { SIGSEGV, "SIGSEGV - Segmentation violation signal" },
- { SIGTERM, "SIGTERM - Termination request signal" },
- { SIGABRT, "SIGABRT - Abort (abnormal termination) signal" }
- };
-
- void FatalConditionHandler::handleSignal( int sig ) {
- char const * name = "<unknown signal>";
- for (auto const& def : signalDefs) {
- if (sig == def.id) {
- name = def.name;
- break;
- }
- }
- reset();
- reportFatal(name);
- raise( sig );
- }
-
- FatalConditionHandler::FatalConditionHandler() {
- isSet = true;
- stack_t sigStack;
- sigStack.ss_sp = altStackMem;
- sigStack.ss_size = sigStackSize;
- sigStack.ss_flags = 0;
- sigaltstack(&sigStack, &oldSigStack);
- struct sigaction sa = { };
-
- sa.sa_handler = handleSignal;
- sa.sa_flags = SA_ONSTACK;
- for (std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i) {
- sigaction(signalDefs[i].id, &sa, &oldSigActions[i]);
- }
- }
-
- FatalConditionHandler::~FatalConditionHandler() {
- reset();
- }
-
- void FatalConditionHandler::reset() {
- if( isSet ) {
- // Set signals back to previous values -- hopefully nobody overwrote them in the meantime
- for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i ) {
- sigaction(signalDefs[i].id, &oldSigActions[i], nullptr);
- }
- // Return the old stack
- sigaltstack(&oldSigStack, nullptr);
- isSet = false;
- }
- }
-
- bool FatalConditionHandler::isSet = false;
- struct sigaction FatalConditionHandler::oldSigActions[sizeof(signalDefs)/sizeof(SignalDefs)] = {};
- stack_t FatalConditionHandler::oldSigStack = {};
- char FatalConditionHandler::altStackMem[sigStackSize] = {};
-
-} // namespace Catch
-
-#else
-
-namespace Catch {
- void FatalConditionHandler::reset() {}
-}
-
-#endif // signals/SEH handling
-
-#if defined(__GNUC__)
-# pragma GCC diagnostic pop
-#endif
-// end catch_fatal_condition.cpp
-// start catch_generators.cpp
-
-// start catch_random_number_generator.h
-
-#include <algorithm>
-#include <random>
-
-namespace Catch {
-
- struct IConfig;
-
- std::mt19937& rng();
- void seedRng( IConfig const& config );
- unsigned int rngSeed();
-
-}
-
-// end catch_random_number_generator.h
-#include <limits>
-#include <set>
-
-namespace Catch {
-
-IGeneratorTracker::~IGeneratorTracker() {}
-
-const char* GeneratorException::what() const noexcept {
- return m_msg;
-}
-
-namespace Generators {
-
- GeneratorUntypedBase::~GeneratorUntypedBase() {}
-
- auto acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker& {
- return getResultCapture().acquireGeneratorTracker( lineInfo );
- }
-
-} // namespace Generators
-} // namespace Catch
-// end catch_generators.cpp
-// start catch_interfaces_capture.cpp
-
-namespace Catch {
- IResultCapture::~IResultCapture() = default;
-}
-// end catch_interfaces_capture.cpp
-// start catch_interfaces_config.cpp
-
-namespace Catch {
- IConfig::~IConfig() = default;
-}
-// end catch_interfaces_config.cpp
-// start catch_interfaces_exception.cpp
-
-namespace Catch {
- IExceptionTranslator::~IExceptionTranslator() = default;
- IExceptionTranslatorRegistry::~IExceptionTranslatorRegistry() = default;
-}
-// end catch_interfaces_exception.cpp
-// start catch_interfaces_registry_hub.cpp
-
-namespace Catch {
- IRegistryHub::~IRegistryHub() = default;
- IMutableRegistryHub::~IMutableRegistryHub() = default;
-}
-// end catch_interfaces_registry_hub.cpp
-// start catch_interfaces_reporter.cpp
-
-// start catch_reporter_listening.h
-
-namespace Catch {
-
- class ListeningReporter : public IStreamingReporter {
- using Reporters = std::vector<IStreamingReporterPtr>;
- Reporters m_listeners;
- IStreamingReporterPtr m_reporter = nullptr;
- ReporterPreferences m_preferences;
-
- public:
- ListeningReporter();
-
- void addListener( IStreamingReporterPtr&& listener );
- void addReporter( IStreamingReporterPtr&& reporter );
-
- public: // IStreamingReporter
-
- ReporterPreferences getPreferences() const override;
-
- void noMatchingTestCases( std::string const& spec ) override;
-
- static std::set<Verbosity> getSupportedVerbosities();
-
-#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
- void benchmarkPreparing(std::string const& name) override;
- void benchmarkStarting( BenchmarkInfo const& benchmarkInfo ) override;
- void benchmarkEnded( BenchmarkStats<> const& benchmarkStats ) override;
- void benchmarkFailed(std::string const&) override;
-#endif // CATCH_CONFIG_ENABLE_BENCHMARKING
-
- void testRunStarting( TestRunInfo const& testRunInfo ) override;
- void testGroupStarting( GroupInfo const& groupInfo ) override;
- void testCaseStarting( TestCaseInfo const& testInfo ) override;
- void sectionStarting( SectionInfo const& sectionInfo ) override;
- void assertionStarting( AssertionInfo const& assertionInfo ) override;
-
- // The return value indicates if the messages buffer should be cleared:
- bool assertionEnded( AssertionStats const& assertionStats ) override;
- void sectionEnded( SectionStats const& sectionStats ) override;
- void testCaseEnded( TestCaseStats const& testCaseStats ) override;
- void testGroupEnded( TestGroupStats const& testGroupStats ) override;
- void testRunEnded( TestRunStats const& testRunStats ) override;
-
- void skipTest( TestCaseInfo const& testInfo ) override;
- bool isMulti() const override;
-
- };
-
-} // end namespace Catch
-
-// end catch_reporter_listening.h
-namespace Catch {
-
- ReporterConfig::ReporterConfig( IConfigPtr const& _fullConfig )
- : m_stream( &_fullConfig->stream() ), m_fullConfig( _fullConfig ) {}
-
- ReporterConfig::ReporterConfig( IConfigPtr const& _fullConfig, std::ostream& _stream )
- : m_stream( &_stream ), m_fullConfig( _fullConfig ) {}
-
- std::ostream& ReporterConfig::stream() const { return *m_stream; }
- IConfigPtr ReporterConfig::fullConfig() const { return m_fullConfig; }
-
- TestRunInfo::TestRunInfo( std::string const& _name ) : name( _name ) {}
-
- GroupInfo::GroupInfo( std::string const& _name,
- std::size_t _groupIndex,
- std::size_t _groupsCount )
- : name( _name ),
- groupIndex( _groupIndex ),
- groupsCounts( _groupsCount )
- {}
-
- AssertionStats::AssertionStats( AssertionResult const& _assertionResult,
- std::vector<MessageInfo> const& _infoMessages,
- Totals const& _totals )
- : assertionResult( _assertionResult ),
- infoMessages( _infoMessages ),
- totals( _totals )
- {
- assertionResult.m_resultData.lazyExpression.m_transientExpression = _assertionResult.m_resultData.lazyExpression.m_transientExpression;
-
- if( assertionResult.hasMessage() ) {
- // Copy message into messages list.
- // !TBD This should have been done earlier, somewhere
- MessageBuilder builder( assertionResult.getTestMacroName(), assertionResult.getSourceInfo(), assertionResult.getResultType() );
- builder << assertionResult.getMessage();
- builder.m_info.message = builder.m_stream.str();
-
- infoMessages.push_back( builder.m_info );
- }
- }
-
- AssertionStats::~AssertionStats() = default;
-
- SectionStats::SectionStats( SectionInfo const& _sectionInfo,
- Counts const& _assertions,
- double _durationInSeconds,
- bool _missingAssertions )
- : sectionInfo( _sectionInfo ),
- assertions( _assertions ),
- durationInSeconds( _durationInSeconds ),
- missingAssertions( _missingAssertions )
- {}
-
- SectionStats::~SectionStats() = default;
-
- TestCaseStats::TestCaseStats( TestCaseInfo const& _testInfo,
- Totals const& _totals,
- std::string const& _stdOut,
- std::string const& _stdErr,
- bool _aborting )
- : testInfo( _testInfo ),
- totals( _totals ),
- stdOut( _stdOut ),
- stdErr( _stdErr ),
- aborting( _aborting )
- {}
-
- TestCaseStats::~TestCaseStats() = default;
-
- TestGroupStats::TestGroupStats( GroupInfo const& _groupInfo,
- Totals const& _totals,
- bool _aborting )
- : groupInfo( _groupInfo ),
- totals( _totals ),
- aborting( _aborting )
- {}
-
- TestGroupStats::TestGroupStats( GroupInfo const& _groupInfo )
- : groupInfo( _groupInfo ),
- aborting( false )
- {}
-
- TestGroupStats::~TestGroupStats() = default;
-
- TestRunStats::TestRunStats( TestRunInfo const& _runInfo,
- Totals const& _totals,
- bool _aborting )
- : runInfo( _runInfo ),
- totals( _totals ),
- aborting( _aborting )
- {}
-
- TestRunStats::~TestRunStats() = default;
-
- void IStreamingReporter::fatalErrorEncountered( StringRef ) {}
- bool IStreamingReporter::isMulti() const { return false; }
-
- IReporterFactory::~IReporterFactory() = default;
- IReporterRegistry::~IReporterRegistry() = default;
-
-} // end namespace Catch
-// end catch_interfaces_reporter.cpp
-// start catch_interfaces_runner.cpp
-
-namespace Catch {
- IRunner::~IRunner() = default;
-}
-// end catch_interfaces_runner.cpp
-// start catch_interfaces_testcase.cpp
-
-namespace Catch {
- ITestInvoker::~ITestInvoker() = default;
- ITestCaseRegistry::~ITestCaseRegistry() = default;
-}
-// end catch_interfaces_testcase.cpp
-// start catch_leak_detector.cpp
-
-#ifdef CATCH_CONFIG_WINDOWS_CRTDBG
-#include <crtdbg.h>
-
-namespace Catch {
-
- LeakDetector::LeakDetector() {
- int flag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
- flag |= _CRTDBG_LEAK_CHECK_DF;
- flag |= _CRTDBG_ALLOC_MEM_DF;
- _CrtSetDbgFlag(flag);
- _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);
- _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
- // Change this to leaking allocation's number to break there
- _CrtSetBreakAlloc(-1);
- }
-}
-
-#else
-
- Catch::LeakDetector::LeakDetector() {}
-
-#endif
-
-Catch::LeakDetector::~LeakDetector() {
- Catch::cleanUp();
-}
-// end catch_leak_detector.cpp
-// start catch_list.cpp
-
-// start catch_list.h
-
-#include <set>
-
-namespace Catch {
-
- std::size_t listTests( Config const& config );
-
- std::size_t listTestsNamesOnly( Config const& config );
-
- struct TagInfo {
- void add( std::string const& spelling );
- std::string all() const;
-
- std::set<std::string> spellings;
- std::size_t count = 0;
- };
-
- std::size_t listTags( Config const& config );
-
- std::size_t listReporters();
-
- Option<std::size_t> list( std::shared_ptr<Config> const& config );
-
-} // end namespace Catch
-
-// end catch_list.h
-// start catch_text.h
-
-namespace Catch {
- using namespace clara::TextFlow;
-}
-
-// end catch_text.h
-#include <limits>
-#include <algorithm>
-#include <iomanip>
-
-namespace Catch {
-
- std::size_t listTests( Config const& config ) {
- TestSpec testSpec = config.testSpec();
- if( config.hasTestFilters() )
- Catch::cout() << "Matching test cases:\n";
- else {
- Catch::cout() << "All available test cases:\n";
- }
-
- auto matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );
- for( auto const& testCaseInfo : matchedTestCases ) {
- Colour::Code colour = testCaseInfo.isHidden()
- ? Colour::SecondaryText
- : Colour::None;
- Colour colourGuard( colour );
-
- Catch::cout() << Column( testCaseInfo.name ).initialIndent( 2 ).indent( 4 ) << "\n";
- if( config.verbosity() >= Verbosity::High ) {
- Catch::cout() << Column( Catch::Detail::stringify( testCaseInfo.lineInfo ) ).indent(4) << std::endl;
- std::string description = testCaseInfo.description;
- if( description.empty() )
- description = "(NO DESCRIPTION)";
- Catch::cout() << Column( description ).indent(4) << std::endl;
- }
- if( !testCaseInfo.tags.empty() )
- Catch::cout() << Column( testCaseInfo.tagsAsString() ).indent( 6 ) << "\n";
- }
-
- if( !config.hasTestFilters() )
- Catch::cout() << pluralise( matchedTestCases.size(), "test case" ) << '\n' << std::endl;
- else
- Catch::cout() << pluralise( matchedTestCases.size(), "matching test case" ) << '\n' << std::endl;
- return matchedTestCases.size();
- }
-
- std::size_t listTestsNamesOnly( Config const& config ) {
- TestSpec testSpec = config.testSpec();
- std::size_t matchedTests = 0;
- std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );
- for( auto const& testCaseInfo : matchedTestCases ) {
- matchedTests++;
- if( startsWith( testCaseInfo.name, '#' ) )
- Catch::cout() << '"' << testCaseInfo.name << '"';
- else
- Catch::cout() << testCaseInfo.name;
- if ( config.verbosity() >= Verbosity::High )
- Catch::cout() << "\t@" << testCaseInfo.lineInfo;
- Catch::cout() << std::endl;
- }
- return matchedTests;
- }
-
- void TagInfo::add( std::string const& spelling ) {
- ++count;
- spellings.insert( spelling );
- }
-
- std::string TagInfo::all() const {
- std::string out;
- for( auto const& spelling : spellings )
- out += "[" + spelling + "]";
- return out;
- }
-
- std::size_t listTags( Config const& config ) {
- TestSpec testSpec = config.testSpec();
- if( config.hasTestFilters() )
- Catch::cout() << "Tags for matching test cases:\n";
- else {
- Catch::cout() << "All available tags:\n";
- }
-
- std::map<std::string, TagInfo> tagCounts;
-
- std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );
- for( auto const& testCase : matchedTestCases ) {
- for( auto const& tagName : testCase.getTestCaseInfo().tags ) {
- std::string lcaseTagName = toLower( tagName );
- auto countIt = tagCounts.find( lcaseTagName );
- if( countIt == tagCounts.end() )
- countIt = tagCounts.insert( std::make_pair( lcaseTagName, TagInfo() ) ).first;
- countIt->second.add( tagName );
- }
- }
-
- for( auto const& tagCount : tagCounts ) {
- ReusableStringStream rss;
- rss << " " << std::setw(2) << tagCount.second.count << " ";
- auto str = rss.str();
- auto wrapper = Column( tagCount.second.all() )
- .initialIndent( 0 )
- .indent( str.size() )
- .width( CATCH_CONFIG_CONSOLE_WIDTH-10 );
- Catch::cout() << str << wrapper << '\n';
- }
- Catch::cout() << pluralise( tagCounts.size(), "tag" ) << '\n' << std::endl;
- return tagCounts.size();
- }
-
- std::size_t listReporters() {
- Catch::cout() << "Available reporters:\n";
- IReporterRegistry::FactoryMap const& factories = getRegistryHub().getReporterRegistry().getFactories();
- std::size_t maxNameLen = 0;
- for( auto const& factoryKvp : factories )
- maxNameLen = (std::max)( maxNameLen, factoryKvp.first.size() );
-
- for( auto const& factoryKvp : factories ) {
- Catch::cout()
- << Column( factoryKvp.first + ":" )
- .indent(2)
- .width( 5+maxNameLen )
- + Column( factoryKvp.second->getDescription() )
- .initialIndent(0)
- .indent(2)
- .width( CATCH_CONFIG_CONSOLE_WIDTH - maxNameLen-8 )
- << "\n";
- }
- Catch::cout() << std::endl;
- return factories.size();
- }
-
- Option<std::size_t> list( std::shared_ptr<Config> const& config ) {
- Option<std::size_t> listedCount;
- getCurrentMutableContext().setConfig( config );
- if( config->listTests() )
- listedCount = listedCount.valueOr(0) + listTests( *config );
- if( config->listTestNamesOnly() )
- listedCount = listedCount.valueOr(0) + listTestsNamesOnly( *config );
- if( config->listTags() )
- listedCount = listedCount.valueOr(0) + listTags( *config );
- if( config->listReporters() )
- listedCount = listedCount.valueOr(0) + listReporters();
- return listedCount;
- }
-
-} // end namespace Catch
-// end catch_list.cpp
-// start catch_matchers.cpp
-
-namespace Catch {
-namespace Matchers {
- namespace Impl {
-
- std::string MatcherUntypedBase::toString() const {
- if( m_cachedToString.empty() )
- m_cachedToString = describe();
- return m_cachedToString;
- }
-
- MatcherUntypedBase::~MatcherUntypedBase() = default;
-
- } // namespace Impl
-} // namespace Matchers
-
-using namespace Matchers;
-using Matchers::Impl::MatcherBase;
-
-} // namespace Catch
-// end catch_matchers.cpp
-// start catch_matchers_floating.cpp
-
-// start catch_polyfills.hpp
-
-namespace Catch {
- bool isnan(float f);
- bool isnan(double d);
-}
-
-// end catch_polyfills.hpp
-// start catch_to_string.hpp
-
-#include <string>
-
-namespace Catch {
- template <typename T>
- std::string to_string(T const& t) {
-#if defined(CATCH_CONFIG_CPP11_TO_STRING)
- return std::to_string(t);
-#else
- ReusableStringStream rss;
- rss << t;
- return rss.str();
-#endif
- }
-} // end namespace Catch
-
-// end catch_to_string.hpp
-#include <cstdlib>
-#include <cstdint>
-#include <cstring>
-#include <sstream>
-#include <iomanip>
-#include <limits>
-
-namespace Catch {
-namespace Matchers {
-namespace Floating {
-enum class FloatingPointKind : uint8_t {
- Float,
- Double
-};
-}
-}
-}
-
-namespace {
-
-template <typename T>
-struct Converter;
-
-template <>
-struct Converter<float> {
- static_assert(sizeof(float) == sizeof(int32_t), "Important ULP matcher assumption violated");
- Converter(float f) {
- std::memcpy(&i, &f, sizeof(f));
- }
- int32_t i;
-};
-
-template <>
-struct Converter<double> {
- static_assert(sizeof(double) == sizeof(int64_t), "Important ULP matcher assumption violated");
- Converter(double d) {
- std::memcpy(&i, &d, sizeof(d));
- }
- int64_t i;
-};
-
-template <typename T>
-auto convert(T t) -> Converter<T> {
- return Converter<T>(t);
-}
-
-template <typename FP>
-bool almostEqualUlps(FP lhs, FP rhs, int maxUlpDiff) {
- // Comparison with NaN should always be false.
- // This way we can rule it out before getting into the ugly details
- if (Catch::isnan(lhs) || Catch::isnan(rhs)) {
- return false;
- }
-
- auto lc = convert(lhs);
- auto rc = convert(rhs);
-
- if ((lc.i < 0) != (rc.i < 0)) {
- // Potentially we can have +0 and -0
- return lhs == rhs;
- }
-
- auto ulpDiff = std::abs(lc.i - rc.i);
- return ulpDiff <= maxUlpDiff;
-}
-
-template <typename FP>
-FP step(FP start, FP direction, int steps) {
- for (int i = 0; i < steps; ++i) {
- start = std::nextafter(start, direction);
- }
- return start;
-}
-
-} // end anonymous namespace
-
-namespace Catch {
-namespace Matchers {
-namespace Floating {
- WithinAbsMatcher::WithinAbsMatcher(double target, double margin)
- :m_target{ target }, m_margin{ margin } {
- CATCH_ENFORCE(margin >= 0, "Invalid margin: " << margin << '.'
- << " Margin has to be non-negative.");
- }
-
- // Performs equivalent check of std::fabs(lhs - rhs) <= margin
- // But without the subtraction to allow for INFINITY in comparison
- bool WithinAbsMatcher::match(double const& matchee) const {
- return (matchee + m_margin >= m_target) && (m_target + m_margin >= matchee);
- }
-
- std::string WithinAbsMatcher::describe() const {
- return "is within " + ::Catch::Detail::stringify(m_margin) + " of " + ::Catch::Detail::stringify(m_target);
- }
-
- WithinUlpsMatcher::WithinUlpsMatcher(double target, int ulps, FloatingPointKind baseType)
- :m_target{ target }, m_ulps{ ulps }, m_type{ baseType } {
- CATCH_ENFORCE(ulps >= 0, "Invalid ULP setting: " << ulps << '.'
- << " ULPs have to be non-negative.");
- }
-
-#if defined(__clang__)
-#pragma clang diagnostic push
-// Clang <3.5 reports on the default branch in the switch below
-#pragma clang diagnostic ignored "-Wunreachable-code"
-#endif
-
- bool WithinUlpsMatcher::match(double const& matchee) const {
- switch (m_type) {
- case FloatingPointKind::Float:
- return almostEqualUlps<float>(static_cast<float>(matchee), static_cast<float>(m_target), m_ulps);
- case FloatingPointKind::Double:
- return almostEqualUlps<double>(matchee, m_target, m_ulps);
- default:
- CATCH_INTERNAL_ERROR( "Unknown FloatingPointKind value" );
- }
- }
-
-#if defined(__clang__)
-#pragma clang diagnostic pop
-#endif
-
- std::string WithinUlpsMatcher::describe() const {
- std::stringstream ret;
-
- ret << "is within " << m_ulps << " ULPs of " << ::Catch::Detail::stringify(m_target);
-
- if (m_type == FloatingPointKind::Float) {
- ret << 'f';
- }
-
- ret << " ([";
- ret << std::fixed << std::setprecision(std::numeric_limits<double>::max_digits10);
- if (m_type == FloatingPointKind::Double) {
- ret << step(m_target, static_cast<double>(-INFINITY), m_ulps)
- << ", "
- << step(m_target, static_cast<double>(INFINITY), m_ulps);
- } else {
- ret << step<float>(static_cast<float>(m_target), -INFINITY, m_ulps)
- << ", "
- << step<float>(static_cast<float>(m_target), INFINITY, m_ulps);
- }
- ret << "])";
-
- return ret.str();
- //return "is within " + Catch::to_string(m_ulps) + " ULPs of " + ::Catch::Detail::stringify(m_target) + ((m_type == FloatingPointKind::Float)? "f" : "");
- }
-
-}// namespace Floating
-
-Floating::WithinUlpsMatcher WithinULP(double target, int maxUlpDiff) {
- return Floating::WithinUlpsMatcher(target, maxUlpDiff, Floating::FloatingPointKind::Double);
-}
-
-Floating::WithinUlpsMatcher WithinULP(float target, int maxUlpDiff) {
- return Floating::WithinUlpsMatcher(target, maxUlpDiff, Floating::FloatingPointKind::Float);
-}
-
-Floating::WithinAbsMatcher WithinAbs(double target, double margin) {
- return Floating::WithinAbsMatcher(target, margin);
-}
-
-} // namespace Matchers
-} // namespace Catch
-
-// end catch_matchers_floating.cpp
-// start catch_matchers_generic.cpp
-
-std::string Catch::Matchers::Generic::Detail::finalizeDescription(const std::string& desc) {
- if (desc.empty()) {
- return "matches undescribed predicate";
- } else {
- return "matches predicate: \"" + desc + '"';
- }
-}
-// end catch_matchers_generic.cpp
-// start catch_matchers_string.cpp
-
-#include <regex>
-
-namespace Catch {
-namespace Matchers {
-
- namespace StdString {
-
- CasedString::CasedString( std::string const& str, CaseSensitive::Choice caseSensitivity )
- : m_caseSensitivity( caseSensitivity ),
- m_str( adjustString( str ) )
- {}
- std::string CasedString::adjustString( std::string const& str ) const {
- return m_caseSensitivity == CaseSensitive::No
- ? toLower( str )
- : str;
- }
- std::string CasedString::caseSensitivitySuffix() const {
- return m_caseSensitivity == CaseSensitive::No
- ? " (case insensitive)"
- : std::string();
- }
-
- StringMatcherBase::StringMatcherBase( std::string const& operation, CasedString const& comparator )
- : m_comparator( comparator ),
- m_operation( operation ) {
- }
-
- std::string StringMatcherBase::describe() const {
- std::string description;
- description.reserve(5 + m_operation.size() + m_comparator.m_str.size() +
- m_comparator.caseSensitivitySuffix().size());
- description += m_operation;
- description += ": \"";
- description += m_comparator.m_str;
- description += "\"";
- description += m_comparator.caseSensitivitySuffix();
- return description;
- }
-
- EqualsMatcher::EqualsMatcher( CasedString const& comparator ) : StringMatcherBase( "equals", comparator ) {}
-
- bool EqualsMatcher::match( std::string const& source ) const {
- return m_comparator.adjustString( source ) == m_comparator.m_str;
- }
-
- ContainsMatcher::ContainsMatcher( CasedString const& comparator ) : StringMatcherBase( "contains", comparator ) {}
-
- bool ContainsMatcher::match( std::string const& source ) const {
- return contains( m_comparator.adjustString( source ), m_comparator.m_str );
- }
-
- StartsWithMatcher::StartsWithMatcher( CasedString const& comparator ) : StringMatcherBase( "starts with", comparator ) {}
-
- bool StartsWithMatcher::match( std::string const& source ) const {
- return startsWith( m_comparator.adjustString( source ), m_comparator.m_str );
- }
-
- EndsWithMatcher::EndsWithMatcher( CasedString const& comparator ) : StringMatcherBase( "ends with", comparator ) {}
-
- bool EndsWithMatcher::match( std::string const& source ) const {
- return endsWith( m_comparator.adjustString( source ), m_comparator.m_str );
- }
-
- RegexMatcher::RegexMatcher(std::string regex, CaseSensitive::Choice caseSensitivity): m_regex(std::move(regex)), m_caseSensitivity(caseSensitivity) {}
-
- bool RegexMatcher::match(std::string const& matchee) const {
- auto flags = std::regex::ECMAScript; // ECMAScript is the default syntax option anyway
- if (m_caseSensitivity == CaseSensitive::Choice::No) {
- flags |= std::regex::icase;
- }
- auto reg = std::regex(m_regex, flags);
- return std::regex_match(matchee, reg);
- }
-
- std::string RegexMatcher::describe() const {
- return "matches " + ::Catch::Detail::stringify(m_regex) + ((m_caseSensitivity == CaseSensitive::Choice::Yes)? " case sensitively" : " case insensitively");
- }
-
- } // namespace StdString
-
- StdString::EqualsMatcher Equals( std::string const& str, CaseSensitive::Choice caseSensitivity ) {
- return StdString::EqualsMatcher( StdString::CasedString( str, caseSensitivity) );
- }
- StdString::ContainsMatcher Contains( std::string const& str, CaseSensitive::Choice caseSensitivity ) {
- return StdString::ContainsMatcher( StdString::CasedString( str, caseSensitivity) );
- }
- StdString::EndsWithMatcher EndsWith( std::string const& str, CaseSensitive::Choice caseSensitivity ) {
- return StdString::EndsWithMatcher( StdString::CasedString( str, caseSensitivity) );
- }
- StdString::StartsWithMatcher StartsWith( std::string const& str, CaseSensitive::Choice caseSensitivity ) {
- return StdString::StartsWithMatcher( StdString::CasedString( str, caseSensitivity) );
- }
-
- StdString::RegexMatcher Matches(std::string const& regex, CaseSensitive::Choice caseSensitivity) {
- return StdString::RegexMatcher(regex, caseSensitivity);
- }
-
-} // namespace Matchers
-} // namespace Catch
-// end catch_matchers_string.cpp
-// start catch_message.cpp
-
-// start catch_uncaught_exceptions.h
-
-namespace Catch {
- bool uncaught_exceptions();
-} // end namespace Catch
-
-// end catch_uncaught_exceptions.h
-#include <cassert>
-#include <stack>
-
-namespace Catch {
-
- MessageInfo::MessageInfo( StringRef const& _macroName,
- SourceLineInfo const& _lineInfo,
- ResultWas::OfType _type )
- : macroName( _macroName ),
- lineInfo( _lineInfo ),
- type( _type ),
- sequence( ++globalCount )
- {}
-
- bool MessageInfo::operator==( MessageInfo const& other ) const {
- return sequence == other.sequence;
- }
-
- bool MessageInfo::operator<( MessageInfo const& other ) const {
- return sequence < other.sequence;
- }
-
- // This may need protecting if threading support is added
- unsigned int MessageInfo::globalCount = 0;
-
- ////////////////////////////////////////////////////////////////////////////
-
- Catch::MessageBuilder::MessageBuilder( StringRef const& macroName,
- SourceLineInfo const& lineInfo,
- ResultWas::OfType type )
- :m_info(macroName, lineInfo, type) {}
-
- ////////////////////////////////////////////////////////////////////////////
-
- ScopedMessage::ScopedMessage( MessageBuilder const& builder )
- : m_info( builder.m_info ), m_moved()
- {
- m_info.message = builder.m_stream.str();
- getResultCapture().pushScopedMessage( m_info );
- }
-
- ScopedMessage::ScopedMessage( ScopedMessage&& old )
- : m_info( old.m_info ), m_moved()
- {
- old.m_moved = true;
- }
-
- ScopedMessage::~ScopedMessage() {
- if ( !uncaught_exceptions() && !m_moved ){
- getResultCapture().popScopedMessage(m_info);
- }
- }
-
- Capturer::Capturer( StringRef macroName, SourceLineInfo const& lineInfo, ResultWas::OfType resultType, StringRef names ) {
- auto trimmed = [&] (size_t start, size_t end) {
- while (names[start] == ',' || isspace(static_cast<unsigned char>(names[start]))) {
- ++start;
- }
- while (names[end] == ',' || isspace(static_cast<unsigned char>(names[end]))) {
- --end;
- }
- return names.substr(start, end - start + 1);
- };
- auto skipq = [&] (size_t start, char quote) {
- for (auto i = start + 1; i < names.size() ; ++i) {
- if (names[i] == quote)
- return i;
- if (names[i] == '\\')
- ++i;
- }
- CATCH_INTERNAL_ERROR("CAPTURE parsing encountered unmatched quote");
- };
-
- size_t start = 0;
- std::stack<char> openings;
- for (size_t pos = 0; pos < names.size(); ++pos) {
- char c = names[pos];
- switch (c) {
- case '[':
- case '{':
- case '(':
- // It is basically impossible to disambiguate between
- // comparison and start of template args in this context
-// case '<':
- openings.push(c);
- break;
- case ']':
- case '}':
- case ')':
-// case '>':
- openings.pop();
- break;
- case '"':
- case '\'':
- pos = skipq(pos, c);
- break;
- case ',':
- if (start != pos && openings.size() == 0) {
- m_messages.emplace_back(macroName, lineInfo, resultType);
- m_messages.back().message = trimmed(start, pos);
- m_messages.back().message += " := ";
- start = pos;
- }
- }
- }
- assert(openings.size() == 0 && "Mismatched openings");
- m_messages.emplace_back(macroName, lineInfo, resultType);
- m_messages.back().message = trimmed(start, names.size() - 1);
- m_messages.back().message += " := ";
- }
- Capturer::~Capturer() {
- if ( !uncaught_exceptions() ){
- assert( m_captured == m_messages.size() );
- for( size_t i = 0; i < m_captured; ++i )
- m_resultCapture.popScopedMessage( m_messages[i] );
- }
- }
-
- void Capturer::captureValue( size_t index, std::string const& value ) {
- assert( index < m_messages.size() );
- m_messages[index].message += value;
- m_resultCapture.pushScopedMessage( m_messages[index] );
- m_captured++;
- }
-
-} // end namespace Catch
-// end catch_message.cpp
-// start catch_output_redirect.cpp
-
-// start catch_output_redirect.h
-#ifndef TWOBLUECUBES_CATCH_OUTPUT_REDIRECT_H
-#define TWOBLUECUBES_CATCH_OUTPUT_REDIRECT_H
-
-#include <cstdio>
-#include <iosfwd>
-#include <string>
-
-namespace Catch {
-
- class RedirectedStream {
- std::ostream& m_originalStream;
- std::ostream& m_redirectionStream;
- std::streambuf* m_prevBuf;
-
- public:
- RedirectedStream( std::ostream& originalStream, std::ostream& redirectionStream );
- ~RedirectedStream();
- };
-
- class RedirectedStdOut {
- ReusableStringStream m_rss;
- RedirectedStream m_cout;
- public:
- RedirectedStdOut();
- auto str() const -> std::string;
- };
-
- // StdErr has two constituent streams in C++, std::cerr and std::clog
- // This means that we need to redirect 2 streams into 1 to keep proper
- // order of writes
- class RedirectedStdErr {
- ReusableStringStream m_rss;
- RedirectedStream m_cerr;
- RedirectedStream m_clog;
- public:
- RedirectedStdErr();
- auto str() const -> std::string;
- };
-
- class RedirectedStreams {
- public:
- RedirectedStreams(RedirectedStreams const&) = delete;
- RedirectedStreams& operator=(RedirectedStreams const&) = delete;
- RedirectedStreams(RedirectedStreams&&) = delete;
- RedirectedStreams& operator=(RedirectedStreams&&) = delete;
-
- RedirectedStreams(std::string& redirectedCout, std::string& redirectedCerr);
- ~RedirectedStreams();
- private:
- std::string& m_redirectedCout;
- std::string& m_redirectedCerr;
- RedirectedStdOut m_redirectedStdOut;
- RedirectedStdErr m_redirectedStdErr;
- };
-
-#if defined(CATCH_CONFIG_NEW_CAPTURE)
-
- // Windows's implementation of std::tmpfile is terrible (it tries
- // to create a file inside system folder, thus requiring elevated
- // privileges for the binary), so we have to use tmpnam(_s) and
- // create the file ourselves there.
- class TempFile {
- public:
- TempFile(TempFile const&) = delete;
- TempFile& operator=(TempFile const&) = delete;
- TempFile(TempFile&&) = delete;
- TempFile& operator=(TempFile&&) = delete;
-
- TempFile();
- ~TempFile();
-
- std::FILE* getFile();
- std::string getContents();
-
- private:
- std::FILE* m_file = nullptr;
- #if defined(_MSC_VER)
- char m_buffer[L_tmpnam] = { 0 };
- #endif
- };
-
- class OutputRedirect {
- public:
- OutputRedirect(OutputRedirect const&) = delete;
- OutputRedirect& operator=(OutputRedirect const&) = delete;
- OutputRedirect(OutputRedirect&&) = delete;
- OutputRedirect& operator=(OutputRedirect&&) = delete;
-
- OutputRedirect(std::string& stdout_dest, std::string& stderr_dest);
- ~OutputRedirect();
-
- private:
- int m_originalStdout = -1;
- int m_originalStderr = -1;
- TempFile m_stdoutFile;
- TempFile m_stderrFile;
- std::string& m_stdoutDest;
- std::string& m_stderrDest;
- };
-
-#endif
-
-} // end namespace Catch
-
-#endif // TWOBLUECUBES_CATCH_OUTPUT_REDIRECT_H
-// end catch_output_redirect.h
-#include <cstdio>
-#include <cstring>
-#include <fstream>
-#include <sstream>
-#include <stdexcept>
-
-#if defined(CATCH_CONFIG_NEW_CAPTURE)
- #if defined(_MSC_VER)
- #include <io.h> //_dup and _dup2
- #define dup _dup
- #define dup2 _dup2
- #define fileno _fileno
- #else
- #include <unistd.h> // dup and dup2
- #endif
-#endif
-
-namespace Catch {
-
- RedirectedStream::RedirectedStream( std::ostream& originalStream, std::ostream& redirectionStream )
- : m_originalStream( originalStream ),
- m_redirectionStream( redirectionStream ),
- m_prevBuf( m_originalStream.rdbuf() )
- {
- m_originalStream.rdbuf( m_redirectionStream.rdbuf() );
- }
-
- RedirectedStream::~RedirectedStream() {
- m_originalStream.rdbuf( m_prevBuf );
- }
-
- RedirectedStdOut::RedirectedStdOut() : m_cout( Catch::cout(), m_rss.get() ) {}
- auto RedirectedStdOut::str() const -> std::string { return m_rss.str(); }
-
- RedirectedStdErr::RedirectedStdErr()
- : m_cerr( Catch::cerr(), m_rss.get() ),
- m_clog( Catch::clog(), m_rss.get() )
- {}
- auto RedirectedStdErr::str() const -> std::string { return m_rss.str(); }
-
- RedirectedStreams::RedirectedStreams(std::string& redirectedCout, std::string& redirectedCerr)
- : m_redirectedCout(redirectedCout),
- m_redirectedCerr(redirectedCerr)
- {}
-
- RedirectedStreams::~RedirectedStreams() {
- m_redirectedCout += m_redirectedStdOut.str();
- m_redirectedCerr += m_redirectedStdErr.str();
- }
-
-#if defined(CATCH_CONFIG_NEW_CAPTURE)
-
-#if defined(_MSC_VER)
- TempFile::TempFile() {
- if (tmpnam_s(m_buffer)) {
- CATCH_RUNTIME_ERROR("Could not get a temp filename");
- }
- if (fopen_s(&m_file, m_buffer, "w")) {
- char buffer[100];
- if (strerror_s(buffer, errno)) {
- CATCH_RUNTIME_ERROR("Could not translate errno to a string");
- }
- CATCH_RUNTIME_ERROR("Could not open the temp file: '" << m_buffer << "' because: " << buffer);
- }
- }
-#else
- TempFile::TempFile() {
- m_file = std::tmpfile();
- if (!m_file) {
- CATCH_RUNTIME_ERROR("Could not create a temp file.");
- }
- }
-
-#endif
-
- TempFile::~TempFile() {
- // TBD: What to do about errors here?
- std::fclose(m_file);
- // We manually create the file on Windows only, on Linux
- // it will be autodeleted
-#if defined(_MSC_VER)
- std::remove(m_buffer);
-#endif
- }
-
- FILE* TempFile::getFile() {
- return m_file;
- }
-
- std::string TempFile::getContents() {
- std::stringstream sstr;
- char buffer[100] = {};
- std::rewind(m_file);
- while (std::fgets(buffer, sizeof(buffer), m_file)) {
- sstr << buffer;
- }
- return sstr.str();
- }
-
- OutputRedirect::OutputRedirect(std::string& stdout_dest, std::string& stderr_dest) :
- m_originalStdout(dup(1)),
- m_originalStderr(dup(2)),
- m_stdoutDest(stdout_dest),
- m_stderrDest(stderr_dest) {
- dup2(fileno(m_stdoutFile.getFile()), 1);
- dup2(fileno(m_stderrFile.getFile()), 2);
- }
-
- OutputRedirect::~OutputRedirect() {
- Catch::cout() << std::flush;
- fflush(stdout);
- // Since we support overriding these streams, we flush cerr
- // even though std::cerr is unbuffered
- Catch::cerr() << std::flush;
- Catch::clog() << std::flush;
- fflush(stderr);
-
- dup2(m_originalStdout, 1);
- dup2(m_originalStderr, 2);
-
- m_stdoutDest += m_stdoutFile.getContents();
- m_stderrDest += m_stderrFile.getContents();
- }
-
-#endif // CATCH_CONFIG_NEW_CAPTURE
-
-} // namespace Catch
-
-#if defined(CATCH_CONFIG_NEW_CAPTURE)
- #if defined(_MSC_VER)
- #undef dup
- #undef dup2
- #undef fileno
- #endif
-#endif
-// end catch_output_redirect.cpp
-// start catch_polyfills.cpp
-
-#include <cmath>
-
-namespace Catch {
-
-#if !defined(CATCH_CONFIG_POLYFILL_ISNAN)
- bool isnan(float f) {
- return std::isnan(f);
- }
- bool isnan(double d) {
- return std::isnan(d);
- }
-#else
- // For now we only use this for embarcadero
- bool isnan(float f) {
- return std::_isnan(f);
- }
- bool isnan(double d) {
- return std::_isnan(d);
- }
-#endif
-
-} // end namespace Catch
-// end catch_polyfills.cpp
-// start catch_random_number_generator.cpp
-
-namespace Catch {
-
- std::mt19937& rng() {
- static std::mt19937 s_rng;
- return s_rng;
- }
-
- void seedRng( IConfig const& config ) {
- if( config.rngSeed() != 0 ) {
- std::srand( config.rngSeed() );
- rng().seed( config.rngSeed() );
- }
- }
-
- unsigned int rngSeed() {
- return getCurrentContext().getConfig()->rngSeed();
- }
-}
-// end catch_random_number_generator.cpp
-// start catch_registry_hub.cpp
-
-// start catch_test_case_registry_impl.h
-
-#include <vector>
-#include <set>
-#include <algorithm>
-#include <ios>
-
-namespace Catch {
-
- class TestCase;
- struct IConfig;
-
- std::vector<TestCase> sortTests( IConfig const& config, std::vector<TestCase> const& unsortedTestCases );
- bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config );
-
- void enforceNoDuplicateTestCases( std::vector<TestCase> const& functions );
-
- std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config );
- std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config );
-
- class TestRegistry : public ITestCaseRegistry {
- public:
- virtual ~TestRegistry() = default;
-
- virtual void registerTest( TestCase const& testCase );
-
- std::vector<TestCase> const& getAllTests() const override;
- std::vector<TestCase> const& getAllTestsSorted( IConfig const& config ) const override;
-
- private:
- std::vector<TestCase> m_functions;
- mutable RunTests::InWhatOrder m_currentSortOrder = RunTests::InDeclarationOrder;
- mutable std::vector<TestCase> m_sortedFunctions;
- std::size_t m_unnamedCount = 0;
- std::ios_base::Init m_ostreamInit; // Forces cout/ cerr to be initialised
- };
-
- ///////////////////////////////////////////////////////////////////////////
-
- class TestInvokerAsFunction : public ITestInvoker {
- void(*m_testAsFunction)();
- public:
- TestInvokerAsFunction( void(*testAsFunction)() ) noexcept;
-
- void invoke() const override;
- };
-
- std::string extractClassName( StringRef const& classOrQualifiedMethodName );
-
- ///////////////////////////////////////////////////////////////////////////
-
-} // end namespace Catch
-
-// end catch_test_case_registry_impl.h
-// start catch_reporter_registry.h
-
-#include <map>
-
-namespace Catch {
-
- class ReporterRegistry : public IReporterRegistry {
-
- public:
-
- ~ReporterRegistry() override;
-
- IStreamingReporterPtr create( std::string const& name, IConfigPtr const& config ) const override;
-
- void registerReporter( std::string const& name, IReporterFactoryPtr const& factory );
- void registerListener( IReporterFactoryPtr const& factory );
-
- FactoryMap const& getFactories() const override;
- Listeners const& getListeners() const override;
-
- private:
- FactoryMap m_factories;
- Listeners m_listeners;
- };
-}
-
-// end catch_reporter_registry.h
-// start catch_tag_alias_registry.h
-
-// start catch_tag_alias.h
-
-#include <string>
-
-namespace Catch {
-
- struct TagAlias {
- TagAlias(std::string const& _tag, SourceLineInfo _lineInfo);
-
- std::string tag;
- SourceLineInfo lineInfo;
- };
-
-} // end namespace Catch
-
-// end catch_tag_alias.h
-#include <map>
-
-namespace Catch {
-
- class TagAliasRegistry : public ITagAliasRegistry {
- public:
- ~TagAliasRegistry() override;
- TagAlias const* find( std::string const& alias ) const override;
- std::string expandAliases( std::string const& unexpandedTestSpec ) const override;
- void add( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo );
-
- private:
- std::map<std::string, TagAlias> m_registry;
- };
-
-} // end namespace Catch
-
-// end catch_tag_alias_registry.h
-// start catch_startup_exception_registry.h
-
-#include <vector>
-#include <exception>
-
-namespace Catch {
-
- class StartupExceptionRegistry {
- public:
- void add(std::exception_ptr const& exception) noexcept;
- std::vector<std::exception_ptr> const& getExceptions() const noexcept;
- private:
- std::vector<std::exception_ptr> m_exceptions;
- };
-
-} // end namespace Catch
-
-// end catch_startup_exception_registry.h
-// start catch_singletons.hpp
-
-namespace Catch {
-
- struct ISingleton {
- virtual ~ISingleton();
- };
-
- void addSingleton( ISingleton* singleton );
- void cleanupSingletons();
-
- template<typename SingletonImplT, typename InterfaceT = SingletonImplT, typename MutableInterfaceT = InterfaceT>
- class Singleton : SingletonImplT, public ISingleton {
-
- static auto getInternal() -> Singleton* {
- static Singleton* s_instance = nullptr;
- if( !s_instance ) {
- s_instance = new Singleton;
- addSingleton( s_instance );
- }
- return s_instance;
- }
-
- public:
- static auto get() -> InterfaceT const& {
- return *getInternal();
- }
- static auto getMutable() -> MutableInterfaceT& {
- return *getInternal();
- }
- };
-
-} // namespace Catch
-
-// end catch_singletons.hpp
-namespace Catch {
-
- namespace {
-
- class RegistryHub : public IRegistryHub, public IMutableRegistryHub,
- private NonCopyable {
-
- public: // IRegistryHub
- RegistryHub() = default;
- IReporterRegistry const& getReporterRegistry() const override {
- return m_reporterRegistry;
- }
- ITestCaseRegistry const& getTestCaseRegistry() const override {
- return m_testCaseRegistry;
- }
- IExceptionTranslatorRegistry const& getExceptionTranslatorRegistry() const override {
- return m_exceptionTranslatorRegistry;
- }
- ITagAliasRegistry const& getTagAliasRegistry() const override {
- return m_tagAliasRegistry;
- }
- StartupExceptionRegistry const& getStartupExceptionRegistry() const override {
- return m_exceptionRegistry;
- }
-
- public: // IMutableRegistryHub
- void registerReporter( std::string const& name, IReporterFactoryPtr const& factory ) override {
- m_reporterRegistry.registerReporter( name, factory );
- }
- void registerListener( IReporterFactoryPtr const& factory ) override {
- m_reporterRegistry.registerListener( factory );
- }
- void registerTest( TestCase const& testInfo ) override {
- m_testCaseRegistry.registerTest( testInfo );
- }
- void registerTranslator( const IExceptionTranslator* translator ) override {
- m_exceptionTranslatorRegistry.registerTranslator( translator );
- }
- void registerTagAlias( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) override {
- m_tagAliasRegistry.add( alias, tag, lineInfo );
- }
- void registerStartupException() noexcept override {
- m_exceptionRegistry.add(std::current_exception());
- }
- IMutableEnumValuesRegistry& getMutableEnumValuesRegistry() override {
- return m_enumValuesRegistry;
- }
-
- private:
- TestRegistry m_testCaseRegistry;
- ReporterRegistry m_reporterRegistry;
- ExceptionTranslatorRegistry m_exceptionTranslatorRegistry;
- TagAliasRegistry m_tagAliasRegistry;
- StartupExceptionRegistry m_exceptionRegistry;
- Detail::EnumValuesRegistry m_enumValuesRegistry;
- };
- }
-
- using RegistryHubSingleton = Singleton<RegistryHub, IRegistryHub, IMutableRegistryHub>;
-
- IRegistryHub const& getRegistryHub() {
- return RegistryHubSingleton::get();
- }
- IMutableRegistryHub& getMutableRegistryHub() {
- return RegistryHubSingleton::getMutable();
- }
- void cleanUp() {
- cleanupSingletons();
- cleanUpContext();
- }
- std::string translateActiveException() {
- return getRegistryHub().getExceptionTranslatorRegistry().translateActiveException();
- }
-
-} // end namespace Catch
-// end catch_registry_hub.cpp
-// start catch_reporter_registry.cpp
-
-namespace Catch {
-
- ReporterRegistry::~ReporterRegistry() = default;
-
- IStreamingReporterPtr ReporterRegistry::create( std::string const& name, IConfigPtr const& config ) const {
- auto it = m_factories.find( name );
- if( it == m_factories.end() )
- return nullptr;
- return it->second->create( ReporterConfig( config ) );
- }
-
- void ReporterRegistry::registerReporter( std::string const& name, IReporterFactoryPtr const& factory ) {
- m_factories.emplace(name, factory);
- }
- void ReporterRegistry::registerListener( IReporterFactoryPtr const& factory ) {
- m_listeners.push_back( factory );
- }
-
- IReporterRegistry::FactoryMap const& ReporterRegistry::getFactories() const {
- return m_factories;
- }
- IReporterRegistry::Listeners const& ReporterRegistry::getListeners() const {
- return m_listeners;
- }
-
-}
-// end catch_reporter_registry.cpp
-// start catch_result_type.cpp
-
-namespace Catch {
-
- bool isOk( ResultWas::OfType resultType ) {
- return ( resultType & ResultWas::FailureBit ) == 0;
- }
- bool isJustInfo( int flags ) {
- return flags == ResultWas::Info;
- }
-
- ResultDisposition::Flags operator | ( ResultDisposition::Flags lhs, ResultDisposition::Flags rhs ) {
- return static_cast<ResultDisposition::Flags>( static_cast<int>( lhs ) | static_cast<int>( rhs ) );
- }
-
- bool shouldContinueOnFailure( int flags ) { return ( flags & ResultDisposition::ContinueOnFailure ) != 0; }
- bool shouldSuppressFailure( int flags ) { return ( flags & ResultDisposition::SuppressFail ) != 0; }
-
-} // end namespace Catch
-// end catch_result_type.cpp
-// start catch_run_context.cpp
-
-#include <cassert>
-#include <algorithm>
-#include <sstream>
-
-namespace Catch {
-
- namespace Generators {
- struct GeneratorTracker : TestCaseTracking::TrackerBase, IGeneratorTracker {
- GeneratorBasePtr m_generator;
-
- GeneratorTracker( TestCaseTracking::NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent )
- : TrackerBase( nameAndLocation, ctx, parent )
- {}
- ~GeneratorTracker();
-
- static GeneratorTracker& acquire( TrackerContext& ctx, TestCaseTracking::NameAndLocation const& nameAndLocation ) {
- std::shared_ptr<GeneratorTracker> tracker;
-
- ITracker& currentTracker = ctx.currentTracker();
- if( TestCaseTracking::ITrackerPtr childTracker = currentTracker.findChild( nameAndLocation ) ) {
- assert( childTracker );
- assert( childTracker->isGeneratorTracker() );
- tracker = std::static_pointer_cast<GeneratorTracker>( childTracker );
- }
- else {
- tracker = std::make_shared<GeneratorTracker>( nameAndLocation, ctx, &currentTracker );
- currentTracker.addChild( tracker );
- }
-
- if( !ctx.completedCycle() && !tracker->isComplete() ) {
- tracker->open();
- }
-
- return *tracker;
- }
-
- // TrackerBase interface
- bool isGeneratorTracker() const override { return true; }
- auto hasGenerator() const -> bool override {
- return !!m_generator;
- }
- void close() override {
- TrackerBase::close();
- // Generator interface only finds out if it has another item on atual move
- if (m_runState == CompletedSuccessfully && m_generator->next()) {
- m_children.clear();
- m_runState = Executing;
- }
- }
-
- // IGeneratorTracker interface
- auto getGenerator() const -> GeneratorBasePtr const& override {
- return m_generator;
- }
- void setGenerator( GeneratorBasePtr&& generator ) override {
- m_generator = std::move( generator );
- }
- };
- GeneratorTracker::~GeneratorTracker() {}
- }
-
- RunContext::RunContext(IConfigPtr const& _config, IStreamingReporterPtr&& reporter)
- : m_runInfo(_config->name()),
- m_context(getCurrentMutableContext()),
- m_config(_config),
- m_reporter(std::move(reporter)),
- m_lastAssertionInfo{ StringRef(), SourceLineInfo("",0), StringRef(), ResultDisposition::Normal },
- m_includeSuccessfulResults( m_config->includeSuccessfulResults() || m_reporter->getPreferences().shouldReportAllAssertions )
- {
- m_context.setRunner(this);
- m_context.setConfig(m_config);
- m_context.setResultCapture(this);
- m_reporter->testRunStarting(m_runInfo);
- }
-
- RunContext::~RunContext() {
- m_reporter->testRunEnded(TestRunStats(m_runInfo, m_totals, aborting()));
- }
-
- void RunContext::testGroupStarting(std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount) {
- m_reporter->testGroupStarting(GroupInfo(testSpec, groupIndex, groupsCount));
- }
-
- void RunContext::testGroupEnded(std::string const& testSpec, Totals const& totals, std::size_t groupIndex, std::size_t groupsCount) {
- m_reporter->testGroupEnded(TestGroupStats(GroupInfo(testSpec, groupIndex, groupsCount), totals, aborting()));
- }
-
- Totals RunContext::runTest(TestCase const& testCase) {
- Totals prevTotals = m_totals;
-
- std::string redirectedCout;
- std::string redirectedCerr;
-
- auto const& testInfo = testCase.getTestCaseInfo();
-
- m_reporter->testCaseStarting(testInfo);
-
- m_activeTestCase = &testCase;
-
- ITracker& rootTracker = m_trackerContext.startRun();
- assert(rootTracker.isSectionTracker());
- static_cast<SectionTracker&>(rootTracker).addInitialFilters(m_config->getSectionsToRun());
- do {
- m_trackerContext.startCycle();
- m_testCaseTracker = &SectionTracker::acquire(m_trackerContext, TestCaseTracking::NameAndLocation(testInfo.name, testInfo.lineInfo));
- runCurrentTest(redirectedCout, redirectedCerr);
- } while (!m_testCaseTracker->isSuccessfullyCompleted() && !aborting());
-
- Totals deltaTotals = m_totals.delta(prevTotals);
- if (testInfo.expectedToFail() && deltaTotals.testCases.passed > 0) {
- deltaTotals.assertions.failed++;
- deltaTotals.testCases.passed--;
- deltaTotals.testCases.failed++;
- }
- m_totals.testCases += deltaTotals.testCases;
- m_reporter->testCaseEnded(TestCaseStats(testInfo,
- deltaTotals,
- redirectedCout,
- redirectedCerr,
- aborting()));
-
- m_activeTestCase = nullptr;
- m_testCaseTracker = nullptr;
-
- return deltaTotals;
- }
-
- IConfigPtr RunContext::config() const {
- return m_config;
- }
-
- IStreamingReporter& RunContext::reporter() const {
- return *m_reporter;
- }
-
- void RunContext::assertionEnded(AssertionResult const & result) {
- if (result.getResultType() == ResultWas::Ok) {
- m_totals.assertions.passed++;
- m_lastAssertionPassed = true;
- } else if (!result.isOk()) {
- m_lastAssertionPassed = false;
- if( m_activeTestCase->getTestCaseInfo().okToFail() )
- m_totals.assertions.failedButOk++;
- else
- m_totals.assertions.failed++;
- }
- else {
- m_lastAssertionPassed = true;
- }
-
- // We have no use for the return value (whether messages should be cleared), because messages were made scoped
- // and should be let to clear themselves out.
- static_cast<void>(m_reporter->assertionEnded(AssertionStats(result, m_messages, m_totals)));
-
- if (result.getResultType() != ResultWas::Warning)
- m_messageScopes.clear();
-
- // Reset working state
- resetAssertionInfo();
- m_lastResult = result;
- }
- void RunContext::resetAssertionInfo() {
- m_lastAssertionInfo.macroName = StringRef();
- m_lastAssertionInfo.capturedExpression = "{Unknown expression after the reported line}"_sr;
- }
-
- bool RunContext::sectionStarted(SectionInfo const & sectionInfo, Counts & assertions) {
- ITracker& sectionTracker = SectionTracker::acquire(m_trackerContext, TestCaseTracking::NameAndLocation(sectionInfo.name, sectionInfo.lineInfo));
- if (!sectionTracker.isOpen())
- return false;
- m_activeSections.push_back(&sectionTracker);
-
- m_lastAssertionInfo.lineInfo = sectionInfo.lineInfo;
-
- m_reporter->sectionStarting(sectionInfo);
-
- assertions = m_totals.assertions;
-
- return true;
- }
- auto RunContext::acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker& {
- using namespace Generators;
- GeneratorTracker& tracker = GeneratorTracker::acquire( m_trackerContext, TestCaseTracking::NameAndLocation( "generator", lineInfo ) );
- assert( tracker.isOpen() );
- m_lastAssertionInfo.lineInfo = lineInfo;
- return tracker;
- }
-
- bool RunContext::testForMissingAssertions(Counts& assertions) {
- if (assertions.total() != 0)
- return false;
- if (!m_config->warnAboutMissingAssertions())
- return false;
- if (m_trackerContext.currentTracker().hasChildren())
- return false;
- m_totals.assertions.failed++;
- assertions.failed++;
- return true;
- }
-
- void RunContext::sectionEnded(SectionEndInfo const & endInfo) {
- Counts assertions = m_totals.assertions - endInfo.prevAssertions;
- bool missingAssertions = testForMissingAssertions(assertions);
-
- if (!m_activeSections.empty()) {
- m_activeSections.back()->close();
- m_activeSections.pop_back();
- }
-
- m_reporter->sectionEnded(SectionStats(endInfo.sectionInfo, assertions, endInfo.durationInSeconds, missingAssertions));
- m_messages.clear();
- m_messageScopes.clear();
- }
-
- void RunContext::sectionEndedEarly(SectionEndInfo const & endInfo) {
- if (m_unfinishedSections.empty())
- m_activeSections.back()->fail();
- else
- m_activeSections.back()->close();
- m_activeSections.pop_back();
-
- m_unfinishedSections.push_back(endInfo);
- }
-
-#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
- void RunContext::benchmarkPreparing(std::string const& name) {
- m_reporter->benchmarkPreparing(name);
- }
- void RunContext::benchmarkStarting( BenchmarkInfo const& info ) {
- m_reporter->benchmarkStarting( info );
- }
- void RunContext::benchmarkEnded( BenchmarkStats<> const& stats ) {
- m_reporter->benchmarkEnded( stats );
- }
- void RunContext::benchmarkFailed(std::string const & error) {
- m_reporter->benchmarkFailed(error);
- }
-#endif // CATCH_CONFIG_ENABLE_BENCHMARKING
-
- void RunContext::pushScopedMessage(MessageInfo const & message) {
- m_messages.push_back(message);
- }
-
- void RunContext::popScopedMessage(MessageInfo const & message) {
- m_messages.erase(std::remove(m_messages.begin(), m_messages.end(), message), m_messages.end());
- }
-
- void RunContext::emplaceUnscopedMessage( MessageBuilder const& builder ) {
- m_messageScopes.emplace_back( builder );
- }
-
- std::string RunContext::getCurrentTestName() const {
- return m_activeTestCase
- ? m_activeTestCase->getTestCaseInfo().name
- : std::string();
- }
-
- const AssertionResult * RunContext::getLastResult() const {
- return &(*m_lastResult);
- }
-
- void RunContext::exceptionEarlyReported() {
- m_shouldReportUnexpected = false;
- }
-
- void RunContext::handleFatalErrorCondition( StringRef message ) {
- // First notify reporter that bad things happened
- m_reporter->fatalErrorEncountered(message);
-
- // Don't rebuild the result -- the stringification itself can cause more fatal errors
- // Instead, fake a result data.
- AssertionResultData tempResult( ResultWas::FatalErrorCondition, { false } );
- tempResult.message = message;
- AssertionResult result(m_lastAssertionInfo, tempResult);
-
- assertionEnded(result);
-
- handleUnfinishedSections();
-
- // Recreate section for test case (as we will lose the one that was in scope)
- auto const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
- SectionInfo testCaseSection(testCaseInfo.lineInfo, testCaseInfo.name);
-
- Counts assertions;
- assertions.failed = 1;
- SectionStats testCaseSectionStats(testCaseSection, assertions, 0, false);
- m_reporter->sectionEnded(testCaseSectionStats);
-
- auto const& testInfo = m_activeTestCase->getTestCaseInfo();
-
- Totals deltaTotals;
- deltaTotals.testCases.failed = 1;
- deltaTotals.assertions.failed = 1;
- m_reporter->testCaseEnded(TestCaseStats(testInfo,
- deltaTotals,
- std::string(),
- std::string(),
- false));
- m_totals.testCases.failed++;
- testGroupEnded(std::string(), m_totals, 1, 1);
- m_reporter->testRunEnded(TestRunStats(m_runInfo, m_totals, false));
- }
-
- bool RunContext::lastAssertionPassed() {
- return m_lastAssertionPassed;
- }
-
- void RunContext::assertionPassed() {
- m_lastAssertionPassed = true;
- ++m_totals.assertions.passed;
- resetAssertionInfo();
- m_messageScopes.clear();
- }
-
- bool RunContext::aborting() const {
- return m_totals.assertions.failed >= static_cast<std::size_t>(m_config->abortAfter());
- }
-
- void RunContext::runCurrentTest(std::string & redirectedCout, std::string & redirectedCerr) {
- auto const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
- SectionInfo testCaseSection(testCaseInfo.lineInfo, testCaseInfo.name);
- m_reporter->sectionStarting(testCaseSection);
- Counts prevAssertions = m_totals.assertions;
- double duration = 0;
- m_shouldReportUnexpected = true;
- m_lastAssertionInfo = { "TEST_CASE"_sr, testCaseInfo.lineInfo, StringRef(), ResultDisposition::Normal };
-
- seedRng(*m_config);
-
- Timer timer;
- CATCH_TRY {
- if (m_reporter->getPreferences().shouldRedirectStdOut) {
-#if !defined(CATCH_CONFIG_EXPERIMENTAL_REDIRECT)
- RedirectedStreams redirectedStreams(redirectedCout, redirectedCerr);
-
- timer.start();
- invokeActiveTestCase();
-#else
- OutputRedirect r(redirectedCout, redirectedCerr);
- timer.start();
- invokeActiveTestCase();
-#endif
- } else {
- timer.start();
- invokeActiveTestCase();
- }
- duration = timer.getElapsedSeconds();
- } CATCH_CATCH_ANON (TestFailureException&) {
- // This just means the test was aborted due to failure
- } CATCH_CATCH_ALL {
- // Under CATCH_CONFIG_FAST_COMPILE, unexpected exceptions under REQUIRE assertions
- // are reported without translation at the point of origin.
- if( m_shouldReportUnexpected ) {
- AssertionReaction dummyReaction;
- handleUnexpectedInflightException( m_lastAssertionInfo, translateActiveException(), dummyReaction );
- }
- }
- Counts assertions = m_totals.assertions - prevAssertions;
- bool missingAssertions = testForMissingAssertions(assertions);
-
- m_testCaseTracker->close();
- handleUnfinishedSections();
- m_messages.clear();
- m_messageScopes.clear();
-
- SectionStats testCaseSectionStats(testCaseSection, assertions, duration, missingAssertions);
- m_reporter->sectionEnded(testCaseSectionStats);
- }
-
- void RunContext::invokeActiveTestCase() {
- FatalConditionHandler fatalConditionHandler; // Handle signals
- m_activeTestCase->invoke();
- fatalConditionHandler.reset();
- }
-
- void RunContext::handleUnfinishedSections() {
- // If sections ended prematurely due to an exception we stored their
- // infos here so we can tear them down outside the unwind process.
- for (auto it = m_unfinishedSections.rbegin(),
- itEnd = m_unfinishedSections.rend();
- it != itEnd;
- ++it)
- sectionEnded(*it);
- m_unfinishedSections.clear();
- }
-
- void RunContext::handleExpr(
- AssertionInfo const& info,
- ITransientExpression const& expr,
- AssertionReaction& reaction
- ) {
- m_reporter->assertionStarting( info );
-
- bool negated = isFalseTest( info.resultDisposition );
- bool result = expr.getResult() != negated;
-
- if( result ) {
- if (!m_includeSuccessfulResults) {
- assertionPassed();
- }
- else {
- reportExpr(info, ResultWas::Ok, &expr, negated);
- }
- }
- else {
- reportExpr(info, ResultWas::ExpressionFailed, &expr, negated );
- populateReaction( reaction );
- }
- }
- void RunContext::reportExpr(
- AssertionInfo const &info,
- ResultWas::OfType resultType,
- ITransientExpression const *expr,
- bool negated ) {
-
- m_lastAssertionInfo = info;
- AssertionResultData data( resultType, LazyExpression( negated ) );
-
- AssertionResult assertionResult{ info, data };
- assertionResult.m_resultData.lazyExpression.m_transientExpression = expr;
-
- assertionEnded( assertionResult );
- }
-
- void RunContext::handleMessage(
- AssertionInfo const& info,
- ResultWas::OfType resultType,
- StringRef const& message,
- AssertionReaction& reaction
- ) {
- m_reporter->assertionStarting( info );
-
- m_lastAssertionInfo = info;
-
- AssertionResultData data( resultType, LazyExpression( false ) );
- data.message = message;
- AssertionResult assertionResult{ m_lastAssertionInfo, data };
- assertionEnded( assertionResult );
- if( !assertionResult.isOk() )
- populateReaction( reaction );
- }
- void RunContext::handleUnexpectedExceptionNotThrown(
- AssertionInfo const& info,
- AssertionReaction& reaction
- ) {
- handleNonExpr(info, Catch::ResultWas::DidntThrowException, reaction);
- }
-
- void RunContext::handleUnexpectedInflightException(
- AssertionInfo const& info,
- std::string const& message,
- AssertionReaction& reaction
- ) {
- m_lastAssertionInfo = info;
-
- AssertionResultData data( ResultWas::ThrewException, LazyExpression( false ) );
- data.message = message;
- AssertionResult assertionResult{ info, data };
- assertionEnded( assertionResult );
- populateReaction( reaction );
- }
-
- void RunContext::populateReaction( AssertionReaction& reaction ) {
- reaction.shouldDebugBreak = m_config->shouldDebugBreak();
- reaction.shouldThrow = aborting() || (m_lastAssertionInfo.resultDisposition & ResultDisposition::Normal);
- }
-
- void RunContext::handleIncomplete(
- AssertionInfo const& info
- ) {
- m_lastAssertionInfo = info;
-
- AssertionResultData data( ResultWas::ThrewException, LazyExpression( false ) );
- data.message = "Exception translation was disabled by CATCH_CONFIG_FAST_COMPILE";
- AssertionResult assertionResult{ info, data };
- assertionEnded( assertionResult );
- }
- void RunContext::handleNonExpr(
- AssertionInfo const &info,
- ResultWas::OfType resultType,
- AssertionReaction &reaction
- ) {
- m_lastAssertionInfo = info;
-
- AssertionResultData data( resultType, LazyExpression( false ) );
- AssertionResult assertionResult{ info, data };
- assertionEnded( assertionResult );
-
- if( !assertionResult.isOk() )
- populateReaction( reaction );
- }
-
- IResultCapture& getResultCapture() {
- if (auto* capture = getCurrentContext().getResultCapture())
- return *capture;
- else
- CATCH_INTERNAL_ERROR("No result capture instance");
- }
-}
-// end catch_run_context.cpp
-// start catch_section.cpp
-
-namespace Catch {
-
- Section::Section( SectionInfo const& info )
- : m_info( info ),
- m_sectionIncluded( getResultCapture().sectionStarted( m_info, m_assertions ) )
- {
- m_timer.start();
- }
-
- Section::~Section() {
- if( m_sectionIncluded ) {
- SectionEndInfo endInfo{ m_info, m_assertions, m_timer.getElapsedSeconds() };
- if( uncaught_exceptions() )
- getResultCapture().sectionEndedEarly( endInfo );
- else
- getResultCapture().sectionEnded( endInfo );
- }
- }
-
- // This indicates whether the section should be executed or not
- Section::operator bool() const {
- return m_sectionIncluded;
- }
-
-} // end namespace Catch
-// end catch_section.cpp
-// start catch_section_info.cpp
-
-namespace Catch {
-
- SectionInfo::SectionInfo
- ( SourceLineInfo const& _lineInfo,
- std::string const& _name )
- : name( _name ),
- lineInfo( _lineInfo )
- {}
-
-} // end namespace Catch
-// end catch_section_info.cpp
-// start catch_session.cpp
-
-// start catch_session.h
-
-#include <memory>
-
-namespace Catch {
-
- class Session : NonCopyable {
- public:
-
- Session();
- ~Session() override;
-
- void showHelp() const;
- void libIdentify();
-
- int applyCommandLine( int argc, char const * const * argv );
- #if defined(CATCH_CONFIG_WCHAR) && defined(WIN32) && defined(UNICODE)
- int applyCommandLine( int argc, wchar_t const * const * argv );
- #endif
-
- void useConfigData( ConfigData const& configData );
-
- template<typename CharT>
- int run(int argc, CharT const * const argv[]) {
- if (m_startupExceptions)
- return 1;
- int returnCode = applyCommandLine(argc, argv);
- if (returnCode == 0)
- returnCode = run();
- return returnCode;
- }
-
- int run();
-
- clara::Parser const& cli() const;
- void cli( clara::Parser const& newParser );
- ConfigData& configData();
- Config& config();
- private:
- int runInternal();
-
- clara::Parser m_cli;
- ConfigData m_configData;
- std::shared_ptr<Config> m_config;
- bool m_startupExceptions = false;
- };
-
-} // end namespace Catch
-
-// end catch_session.h
-// start catch_version.h
-
-#include <iosfwd>
-
-namespace Catch {
-
- // Versioning information
- struct Version {
- Version( Version const& ) = delete;
- Version& operator=( Version const& ) = delete;
- Version( unsigned int _majorVersion,
- unsigned int _minorVersion,
- unsigned int _patchNumber,
- char const * const _branchName,
- unsigned int _buildNumber );
-
- unsigned int const majorVersion;
- unsigned int const minorVersion;
- unsigned int const patchNumber;
-
- // buildNumber is only used if branchName is not null
- char const * const branchName;
- unsigned int const buildNumber;
-
- friend std::ostream& operator << ( std::ostream& os, Version const& version );
- };
-
- Version const& libraryVersion();
-}
-
-// end catch_version.h
-#include <cstdlib>
-#include <iomanip>
-
-namespace Catch {
-
- namespace {
- const int MaxExitCode = 255;
-
- IStreamingReporterPtr createReporter(std::string const& reporterName, IConfigPtr const& config) {
- auto reporter = Catch::getRegistryHub().getReporterRegistry().create(reporterName, config);
- CATCH_ENFORCE(reporter, "No reporter registered with name: '" << reporterName << "'");
-
- return reporter;
- }
-
- IStreamingReporterPtr makeReporter(std::shared_ptr<Config> const& config) {
- if (Catch::getRegistryHub().getReporterRegistry().getListeners().empty()) {
- return createReporter(config->getReporterName(), config);
- }
-
- // On older platforms, returning std::unique_ptr<ListeningReporter>
- // when the return type is std::unique_ptr<IStreamingReporter>
- // doesn't compile without a std::move call. However, this causes
- // a warning on newer platforms. Thus, we have to work around
- // it a bit and downcast the pointer manually.
- auto ret = std::unique_ptr<IStreamingReporter>(new ListeningReporter);
- auto& multi = static_cast<ListeningReporter&>(*ret);
- auto const& listeners = Catch::getRegistryHub().getReporterRegistry().getListeners();
- for (auto const& listener : listeners) {
- multi.addListener(listener->create(Catch::ReporterConfig(config)));
- }
- multi.addReporter(createReporter(config->getReporterName(), config));
- return ret;
- }
-
- Catch::Totals runTests(std::shared_ptr<Config> const& config) {
- auto reporter = makeReporter(config);
-
- RunContext context(config, std::move(reporter));
-
- Totals totals;
-
- context.testGroupStarting(config->name(), 1, 1);
-
- TestSpec testSpec = config->testSpec();
-
- auto const& allTestCases = getAllTestCasesSorted(*config);
- for (auto const& testCase : allTestCases) {
- bool matching = (!testSpec.hasFilters() && !testCase.isHidden()) ||
- (testSpec.hasFilters() && matchTest(testCase, testSpec, *config));
-
- if (!context.aborting() && matching)
- totals += context.runTest(testCase);
- else
- context.reporter().skipTest(testCase);
- }
-
- if (config->warnAboutNoTests() && totals.testCases.total() == 0) {
- ReusableStringStream testConfig;
-
- bool first = true;
- for (const auto& input : config->getTestsOrTags()) {
- if (!first) { testConfig << ' '; }
- first = false;
- testConfig << input;
- }
-
- context.reporter().noMatchingTestCases(testConfig.str());
- totals.error = -1;
- }
-
- context.testGroupEnded(config->name(), totals, 1, 1);
- return totals;
- }
-
- void applyFilenamesAsTags(Catch::IConfig const& config) {
- auto& tests = const_cast<std::vector<TestCase>&>(getAllTestCasesSorted(config));
- for (auto& testCase : tests) {
- auto tags = testCase.tags;
-
- std::string filename = testCase.lineInfo.file;
- auto lastSlash = filename.find_last_of("\\/");
- if (lastSlash != std::string::npos) {
- filename.erase(0, lastSlash);
- filename[0] = '#';
- }
-
- auto lastDot = filename.find_last_of('.');
- if (lastDot != std::string::npos) {
- filename.erase(lastDot);
- }
-
- tags.push_back(std::move(filename));
- setTags(testCase, tags);
- }
- }
-
- } // anon namespace
-
- Session::Session() {
- static bool alreadyInstantiated = false;
- if( alreadyInstantiated ) {
- CATCH_TRY { CATCH_INTERNAL_ERROR( "Only one instance of Catch::Session can ever be used" ); }
- CATCH_CATCH_ALL { getMutableRegistryHub().registerStartupException(); }
- }
-
- // There cannot be exceptions at startup in no-exception mode.
-#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
- const auto& exceptions = getRegistryHub().getStartupExceptionRegistry().getExceptions();
- if ( !exceptions.empty() ) {
- config();
- getCurrentMutableContext().setConfig(m_config);
-
- m_startupExceptions = true;
- Colour colourGuard( Colour::Red );
- Catch::cerr() << "Errors occurred during startup!" << '\n';
- // iterate over all exceptions and notify user
- for ( const auto& ex_ptr : exceptions ) {
- try {
- std::rethrow_exception(ex_ptr);
- } catch ( std::exception const& ex ) {
- Catch::cerr() << Column( ex.what() ).indent(2) << '\n';
- }
- }
- }
-#endif
-
- alreadyInstantiated = true;
- m_cli = makeCommandLineParser( m_configData );
- }
- Session::~Session() {
- Catch::cleanUp();
- }
-
- void Session::showHelp() const {
- Catch::cout()
- << "\nCatch v" << libraryVersion() << "\n"
- << m_cli << std::endl
- << "For more detailed usage please see the project docs\n" << std::endl;
- }
- void Session::libIdentify() {
- Catch::cout()
- << std::left << std::setw(16) << "description: " << "A Catch test executable\n"
- << std::left << std::setw(16) << "category: " << "testframework\n"
- << std::left << std::setw(16) << "framework: " << "Catch Test\n"
- << std::left << std::setw(16) << "version: " << libraryVersion() << std::endl;
- }
-
- int Session::applyCommandLine( int argc, char const * const * argv ) {
- if( m_startupExceptions )
- return 1;
-
- auto result = m_cli.parse( clara::Args( argc, argv ) );
- if( !result ) {
- config();
- getCurrentMutableContext().setConfig(m_config);
- Catch::cerr()
- << Colour( Colour::Red )
- << "\nError(s) in input:\n"
- << Column( result.errorMessage() ).indent( 2 )
- << "\n\n";
- Catch::cerr() << "Run with -? for usage\n" << std::endl;
- return MaxExitCode;
- }
-
- if( m_configData.showHelp )
- showHelp();
- if( m_configData.libIdentify )
- libIdentify();
- m_config.reset();
- return 0;
- }
-
-#if defined(CATCH_CONFIG_WCHAR) && defined(WIN32) && defined(UNICODE)
- int Session::applyCommandLine( int argc, wchar_t const * const * argv ) {
-
- char **utf8Argv = new char *[ argc ];
-
- for ( int i = 0; i < argc; ++i ) {
- int bufSize = WideCharToMultiByte( CP_UTF8, 0, argv[i], -1, NULL, 0, NULL, NULL );
-
- utf8Argv[ i ] = new char[ bufSize ];
-
- WideCharToMultiByte( CP_UTF8, 0, argv[i], -1, utf8Argv[i], bufSize, NULL, NULL );
- }
-
- int returnCode = applyCommandLine( argc, utf8Argv );
-
- for ( int i = 0; i < argc; ++i )
- delete [] utf8Argv[ i ];
-
- delete [] utf8Argv;
-
- return returnCode;
- }
-#endif
-
- void Session::useConfigData( ConfigData const& configData ) {
- m_configData = configData;
- m_config.reset();
- }
-
- int Session::run() {
- if( ( m_configData.waitForKeypress & WaitForKeypress::BeforeStart ) != 0 ) {
- Catch::cout() << "...waiting for enter/ return before starting" << std::endl;
- static_cast<void>(std::getchar());
- }
- int exitCode = runInternal();
- if( ( m_configData.waitForKeypress & WaitForKeypress::BeforeExit ) != 0 ) {
- Catch::cout() << "...waiting for enter/ return before exiting, with code: " << exitCode << std::endl;
- static_cast<void>(std::getchar());
- }
- return exitCode;
- }
-
- clara::Parser const& Session::cli() const {
- return m_cli;
- }
- void Session::cli( clara::Parser const& newParser ) {
- m_cli = newParser;
- }
- ConfigData& Session::configData() {
- return m_configData;
- }
- Config& Session::config() {
- if( !m_config )
- m_config = std::make_shared<Config>( m_configData );
- return *m_config;
- }
-
- int Session::runInternal() {
- if( m_startupExceptions )
- return 1;
-
- if (m_configData.showHelp || m_configData.libIdentify) {
- return 0;
- }
-
- CATCH_TRY {
- config(); // Force config to be constructed
-
- seedRng( *m_config );
-
- if( m_configData.filenamesAsTags )
- applyFilenamesAsTags( *m_config );
-
- // Handle list request
- if( Option<std::size_t> listed = list( m_config ) )
- return static_cast<int>( *listed );
-
- auto totals = runTests( m_config );
- // Note that on unices only the lower 8 bits are usually used, clamping
- // the return value to 255 prevents false negative when some multiple
- // of 256 tests has failed
- return (std::min) (MaxExitCode, (std::max) (totals.error, static_cast<int>(totals.assertions.failed)));
- }
-#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
- catch( std::exception& ex ) {
- Catch::cerr() << ex.what() << std::endl;
- return MaxExitCode;
- }
-#endif
- }
-
-} // end namespace Catch
-// end catch_session.cpp
-// start catch_singletons.cpp
-
-#include <vector>
-
-namespace Catch {
-
- namespace {
- static auto getSingletons() -> std::vector<ISingleton*>*& {
- static std::vector<ISingleton*>* g_singletons = nullptr;
- if( !g_singletons )
- g_singletons = new std::vector<ISingleton*>();
- return g_singletons;
- }
- }
-
- ISingleton::~ISingleton() {}
-
- void addSingleton(ISingleton* singleton ) {
- getSingletons()->push_back( singleton );
- }
- void cleanupSingletons() {
- auto& singletons = getSingletons();
- for( auto singleton : *singletons )
- delete singleton;
- delete singletons;
- singletons = nullptr;
- }
-
-} // namespace Catch
-// end catch_singletons.cpp
-// start catch_startup_exception_registry.cpp
-
-namespace Catch {
-void StartupExceptionRegistry::add( std::exception_ptr const& exception ) noexcept {
- CATCH_TRY {
- m_exceptions.push_back(exception);
- } CATCH_CATCH_ALL {
- // If we run out of memory during start-up there's really not a lot more we can do about it
- std::terminate();
- }
- }
-
- std::vector<std::exception_ptr> const& StartupExceptionRegistry::getExceptions() const noexcept {
- return m_exceptions;
- }
-
-} // end namespace Catch
-// end catch_startup_exception_registry.cpp
-// start catch_stream.cpp
-
-#include <cstdio>
-#include <iostream>
-#include <fstream>
-#include <sstream>
-#include <vector>
-#include <memory>
-
-namespace Catch {
-
- Catch::IStream::~IStream() = default;
-
- namespace Detail { namespace {
- template<typename WriterF, std::size_t bufferSize=256>
- class StreamBufImpl : public std::streambuf {
- char data[bufferSize];
- WriterF m_writer;
-
- public:
- StreamBufImpl() {
- setp( data, data + sizeof(data) );
- }
-
- ~StreamBufImpl() noexcept {
- StreamBufImpl::sync();
- }
-
- private:
- int overflow( int c ) override {
- sync();
-
- if( c != EOF ) {
- if( pbase() == epptr() )
- m_writer( std::string( 1, static_cast<char>( c ) ) );
- else
- sputc( static_cast<char>( c ) );
- }
- return 0;
- }
-
- int sync() override {
- if( pbase() != pptr() ) {
- m_writer( std::string( pbase(), static_cast<std::string::size_type>( pptr() - pbase() ) ) );
- setp( pbase(), epptr() );
- }
- return 0;
- }
- };
-
- ///////////////////////////////////////////////////////////////////////////
-
- struct OutputDebugWriter {
-
- void operator()( std::string const&str ) {
- writeToDebugConsole( str );
- }
- };
-
- ///////////////////////////////////////////////////////////////////////////
-
- class FileStream : public IStream {
- mutable std::ofstream m_ofs;
- public:
- FileStream( StringRef filename ) {
- m_ofs.open( filename.c_str() );
- CATCH_ENFORCE( !m_ofs.fail(), "Unable to open file: '" << filename << "'" );
- }
- ~FileStream() override = default;
- public: // IStream
- std::ostream& stream() const override {
- return m_ofs;
- }
- };
-
- ///////////////////////////////////////////////////////////////////////////
-
- class CoutStream : public IStream {
- mutable std::ostream m_os;
- public:
- // Store the streambuf from cout up-front because
- // cout may get redirected when running tests
- CoutStream() : m_os( Catch::cout().rdbuf() ) {}
- ~CoutStream() override = default;
-
- public: // IStream
- std::ostream& stream() const override { return m_os; }
- };
-
- ///////////////////////////////////////////////////////////////////////////
-
- class DebugOutStream : public IStream {
- std::unique_ptr<StreamBufImpl<OutputDebugWriter>> m_streamBuf;
- mutable std::ostream m_os;
- public:
- DebugOutStream()
- : m_streamBuf( new StreamBufImpl<OutputDebugWriter>() ),
- m_os( m_streamBuf.get() )
- {}
-
- ~DebugOutStream() override = default;
-
- public: // IStream
- std::ostream& stream() const override { return m_os; }
- };
-
- }} // namespace anon::detail
-
- ///////////////////////////////////////////////////////////////////////////
-
- auto makeStream( StringRef const &filename ) -> IStream const* {
- if( filename.empty() )
- return new Detail::CoutStream();
- else if( filename[0] == '%' ) {
- if( filename == "%debug" )
- return new Detail::DebugOutStream();
- else
- CATCH_ERROR( "Unrecognised stream: '" << filename << "'" );
- }
- else
- return new Detail::FileStream( filename );
- }
-
- // This class encapsulates the idea of a pool of ostringstreams that can be reused.
- struct StringStreams {
- std::vector<std::unique_ptr<std::ostringstream>> m_streams;
- std::vector<std::size_t> m_unused;
- std::ostringstream m_referenceStream; // Used for copy state/ flags from
-
- auto add() -> std::size_t {
- if( m_unused.empty() ) {
- m_streams.push_back( std::unique_ptr<std::ostringstream>( new std::ostringstream ) );
- return m_streams.size()-1;
- }
- else {
- auto index = m_unused.back();
- m_unused.pop_back();
- return index;
- }
- }
-
- void release( std::size_t index ) {
- m_streams[index]->copyfmt( m_referenceStream ); // Restore initial flags and other state
- m_unused.push_back(index);
- }
- };
-
- ReusableStringStream::ReusableStringStream()
- : m_index( Singleton<StringStreams>::getMutable().add() ),
- m_oss( Singleton<StringStreams>::getMutable().m_streams[m_index].get() )
- {}
-
- ReusableStringStream::~ReusableStringStream() {
- static_cast<std::ostringstream*>( m_oss )->str("");
- m_oss->clear();
- Singleton<StringStreams>::getMutable().release( m_index );
- }
-
- auto ReusableStringStream::str() const -> std::string {
- return static_cast<std::ostringstream*>( m_oss )->str();
- }
-
- ///////////////////////////////////////////////////////////////////////////
-
-#ifndef CATCH_CONFIG_NOSTDOUT // If you #define this you must implement these functions
- std::ostream& cout() { return std::cout; }
- std::ostream& cerr() { return std::cerr; }
- std::ostream& clog() { return std::clog; }
-#endif
-}
-// end catch_stream.cpp
-// start catch_string_manip.cpp
-
-#include <algorithm>
-#include <ostream>
-#include <cstring>
-#include <cctype>
-#include <vector>
-
-namespace Catch {
-
- namespace {
- char toLowerCh(char c) {
- return static_cast<char>( std::tolower( c ) );
- }
- }
-
- bool startsWith( std::string const& s, std::string const& prefix ) {
- return s.size() >= prefix.size() && std::equal(prefix.begin(), prefix.end(), s.begin());
- }
- bool startsWith( std::string const& s, char prefix ) {
- return !s.empty() && s[0] == prefix;
- }
- bool endsWith( std::string const& s, std::string const& suffix ) {
- return s.size() >= suffix.size() && std::equal(suffix.rbegin(), suffix.rend(), s.rbegin());
- }
- bool endsWith( std::string const& s, char suffix ) {
- return !s.empty() && s[s.size()-1] == suffix;
- }
- bool contains( std::string const& s, std::string const& infix ) {
- return s.find( infix ) != std::string::npos;
- }
- void toLowerInPlace( std::string& s ) {
- std::transform( s.begin(), s.end(), s.begin(), toLowerCh );
- }
- std::string toLower( std::string const& s ) {
- std::string lc = s;
- toLowerInPlace( lc );
- return lc;
- }
- std::string trim( std::string const& str ) {
- static char const* whitespaceChars = "\n\r\t ";
- std::string::size_type start = str.find_first_not_of( whitespaceChars );
- std::string::size_type end = str.find_last_not_of( whitespaceChars );
-
- return start != std::string::npos ? str.substr( start, 1+end-start ) : std::string();
- }
-
- bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis ) {
- bool replaced = false;
- std::size_t i = str.find( replaceThis );
- while( i != std::string::npos ) {
- replaced = true;
- str = str.substr( 0, i ) + withThis + str.substr( i+replaceThis.size() );
- if( i < str.size()-withThis.size() )
- i = str.find( replaceThis, i+withThis.size() );
- else
- i = std::string::npos;
- }
- return replaced;
- }
-
- std::vector<StringRef> splitStringRef( StringRef str, char delimiter ) {
- std::vector<StringRef> subStrings;
- std::size_t start = 0;
- for(std::size_t pos = 0; pos < str.size(); ++pos ) {
- if( str[pos] == delimiter ) {
- if( pos - start > 1 )
- subStrings.push_back( str.substr( start, pos-start ) );
- start = pos+1;
- }
- }
- if( start < str.size() )
- subStrings.push_back( str.substr( start, str.size()-start ) );
- return subStrings;
- }
-
- pluralise::pluralise( std::size_t count, std::string const& label )
- : m_count( count ),
- m_label( label )
- {}
-
- std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser ) {
- os << pluraliser.m_count << ' ' << pluraliser.m_label;
- if( pluraliser.m_count != 1 )
- os << 's';
- return os;
- }
-
-}
-// end catch_string_manip.cpp
-// start catch_stringref.cpp
-
-#if defined(__clang__)
-# pragma clang diagnostic push
-# pragma clang diagnostic ignored "-Wexit-time-destructors"
-#endif
-
-#include <ostream>
-#include <cstring>
-#include <cstdint>
-
-namespace {
- const uint32_t byte_2_lead = 0xC0;
- const uint32_t byte_3_lead = 0xE0;
- const uint32_t byte_4_lead = 0xF0;
-}
-
-namespace Catch {
- StringRef::StringRef( char const* rawChars ) noexcept
- : StringRef( rawChars, static_cast<StringRef::size_type>(std::strlen(rawChars) ) )
- {}
-
- StringRef::operator std::string() const {
- return std::string( m_start, m_size );
- }
-
- void StringRef::swap( StringRef& other ) noexcept {
- std::swap( m_start, other.m_start );
- std::swap( m_size, other.m_size );
- std::swap( m_data, other.m_data );
- }
-
- auto StringRef::c_str() const -> char const* {
- if( !isSubstring() )
- return m_start;
-
- const_cast<StringRef *>( this )->takeOwnership();
- return m_data;
- }
- auto StringRef::currentData() const noexcept -> char const* {
- return m_start;
- }
-
- auto StringRef::isOwned() const noexcept -> bool {
- return m_data != nullptr;
- }
- auto StringRef::isSubstring() const noexcept -> bool {
- return m_start[m_size] != '\0';
- }
-
- void StringRef::takeOwnership() {
- if( !isOwned() ) {
- m_data = new char[m_size+1];
- memcpy( m_data, m_start, m_size );
- m_data[m_size] = '\0';
- }
- }
- auto StringRef::substr( size_type start, size_type size ) const noexcept -> StringRef {
- if( start < m_size )
- return StringRef( m_start+start, size );
- else
- return StringRef();
- }
- auto StringRef::operator == ( StringRef const& other ) const noexcept -> bool {
- return
- size() == other.size() &&
- (std::strncmp( m_start, other.m_start, size() ) == 0);
- }
- auto StringRef::operator != ( StringRef const& other ) const noexcept -> bool {
- return !operator==( other );
- }
-
- auto StringRef::operator[](size_type index) const noexcept -> char {
- return m_start[index];
- }
-
- auto StringRef::numberOfCharacters() const noexcept -> size_type {
- size_type noChars = m_size;
- // Make adjustments for uft encodings
- for( size_type i=0; i < m_size; ++i ) {
- char c = m_start[i];
- if( ( c & byte_2_lead ) == byte_2_lead ) {
- noChars--;
- if (( c & byte_3_lead ) == byte_3_lead )
- noChars--;
- if( ( c & byte_4_lead ) == byte_4_lead )
- noChars--;
- }
- }
- return noChars;
- }
-
- auto operator + ( StringRef const& lhs, StringRef const& rhs ) -> std::string {
- std::string str;
- str.reserve( lhs.size() + rhs.size() );
- str += lhs;
- str += rhs;
- return str;
- }
- auto operator + ( StringRef const& lhs, const char* rhs ) -> std::string {
- return std::string( lhs ) + std::string( rhs );
- }
- auto operator + ( char const* lhs, StringRef const& rhs ) -> std::string {
- return std::string( lhs ) + std::string( rhs );
- }
-
- auto operator << ( std::ostream& os, StringRef const& str ) -> std::ostream& {
- return os.write(str.currentData(), str.size());
- }
-
- auto operator+=( std::string& lhs, StringRef const& rhs ) -> std::string& {
- lhs.append(rhs.currentData(), rhs.size());
- return lhs;
- }
-
-} // namespace Catch
-
-#if defined(__clang__)
-# pragma clang diagnostic pop
-#endif
-// end catch_stringref.cpp
-// start catch_tag_alias.cpp
-
-namespace Catch {
- TagAlias::TagAlias(std::string const & _tag, SourceLineInfo _lineInfo): tag(_tag), lineInfo(_lineInfo) {}
-}
-// end catch_tag_alias.cpp
-// start catch_tag_alias_autoregistrar.cpp
-
-namespace Catch {
-
- RegistrarForTagAliases::RegistrarForTagAliases(char const* alias, char const* tag, SourceLineInfo const& lineInfo) {
- CATCH_TRY {
- getMutableRegistryHub().registerTagAlias(alias, tag, lineInfo);
- } CATCH_CATCH_ALL {
- // Do not throw when constructing global objects, instead register the exception to be processed later
- getMutableRegistryHub().registerStartupException();
- }
- }
-
-}
-// end catch_tag_alias_autoregistrar.cpp
-// start catch_tag_alias_registry.cpp
-
-#include <sstream>
-
-namespace Catch {
-
- TagAliasRegistry::~TagAliasRegistry() {}
-
- TagAlias const* TagAliasRegistry::find( std::string const& alias ) const {
- auto it = m_registry.find( alias );
- if( it != m_registry.end() )
- return &(it->second);
- else
- return nullptr;
- }
-
- std::string TagAliasRegistry::expandAliases( std::string const& unexpandedTestSpec ) const {
- std::string expandedTestSpec = unexpandedTestSpec;
- for( auto const& registryKvp : m_registry ) {
- std::size_t pos = expandedTestSpec.find( registryKvp.first );
- if( pos != std::string::npos ) {
- expandedTestSpec = expandedTestSpec.substr( 0, pos ) +
- registryKvp.second.tag +
- expandedTestSpec.substr( pos + registryKvp.first.size() );
- }
- }
- return expandedTestSpec;
- }
-
- void TagAliasRegistry::add( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) {
- CATCH_ENFORCE( startsWith(alias, "[@") && endsWith(alias, ']'),
- "error: tag alias, '" << alias << "' is not of the form [@alias name].\n" << lineInfo );
-
- CATCH_ENFORCE( m_registry.insert(std::make_pair(alias, TagAlias(tag, lineInfo))).second,
- "error: tag alias, '" << alias << "' already registered.\n"
- << "\tFirst seen at: " << find(alias)->lineInfo << "\n"
- << "\tRedefined at: " << lineInfo );
- }
-
- ITagAliasRegistry::~ITagAliasRegistry() {}
-
- ITagAliasRegistry const& ITagAliasRegistry::get() {
- return getRegistryHub().getTagAliasRegistry();
- }
-
-} // end namespace Catch
-// end catch_tag_alias_registry.cpp
-// start catch_test_case_info.cpp
-
-#include <cctype>
-#include <exception>
-#include <algorithm>
-#include <sstream>
-
-namespace Catch {
-
- namespace {
- TestCaseInfo::SpecialProperties parseSpecialTag( std::string const& tag ) {
- if( startsWith( tag, '.' ) ||
- tag == "!hide" )
- return TestCaseInfo::IsHidden;
- else if( tag == "!throws" )
- return TestCaseInfo::Throws;
- else if( tag == "!shouldfail" )
- return TestCaseInfo::ShouldFail;
- else if( tag == "!mayfail" )
- return TestCaseInfo::MayFail;
- else if( tag == "!nonportable" )
- return TestCaseInfo::NonPortable;
- else if( tag == "!benchmark" )
- return static_cast<TestCaseInfo::SpecialProperties>( TestCaseInfo::Benchmark | TestCaseInfo::IsHidden );
- else
- return TestCaseInfo::None;
- }
- bool isReservedTag( std::string const& tag ) {
- return parseSpecialTag( tag ) == TestCaseInfo::None && tag.size() > 0 && !std::isalnum( static_cast<unsigned char>(tag[0]) );
- }
- void enforceNotReservedTag( std::string const& tag, SourceLineInfo const& _lineInfo ) {
- CATCH_ENFORCE( !isReservedTag(tag),
- "Tag name: [" << tag << "] is not allowed.\n"
- << "Tag names starting with non alphanumeric characters are reserved\n"
- << _lineInfo );
- }
- }
-
- TestCase makeTestCase( ITestInvoker* _testCase,
- std::string const& _className,
- NameAndTags const& nameAndTags,
- SourceLineInfo const& _lineInfo )
- {
- bool isHidden = false;
-
- // Parse out tags
- std::vector<std::string> tags;
- std::string desc, tag;
- bool inTag = false;
- std::string _descOrTags = nameAndTags.tags;
- for (char c : _descOrTags) {
- if( !inTag ) {
- if( c == '[' )
- inTag = true;
- else
- desc += c;
- }
- else {
- if( c == ']' ) {
- TestCaseInfo::SpecialProperties prop = parseSpecialTag( tag );
- if( ( prop & TestCaseInfo::IsHidden ) != 0 )
- isHidden = true;
- else if( prop == TestCaseInfo::None )
- enforceNotReservedTag( tag, _lineInfo );
-
- // Merged hide tags like `[.approvals]` should be added as
- // `[.][approvals]`. The `[.]` is added at later point, so
- // we only strip the prefix
- if (startsWith(tag, '.') && tag.size() > 1) {
- tag.erase(0, 1);
- }
- tags.push_back( tag );
- tag.clear();
- inTag = false;
- }
- else
- tag += c;
- }
- }
- if( isHidden ) {
- tags.push_back( "." );
- }
-
- TestCaseInfo info( nameAndTags.name, _className, desc, tags, _lineInfo );
- return TestCase( _testCase, std::move(info) );
- }
-
- void setTags( TestCaseInfo& testCaseInfo, std::vector<std::string> tags ) {
- std::sort(begin(tags), end(tags));
- tags.erase(std::unique(begin(tags), end(tags)), end(tags));
- testCaseInfo.lcaseTags.clear();
-
- for( auto const& tag : tags ) {
- std::string lcaseTag = toLower( tag );
- testCaseInfo.properties = static_cast<TestCaseInfo::SpecialProperties>( testCaseInfo.properties | parseSpecialTag( lcaseTag ) );
- testCaseInfo.lcaseTags.push_back( lcaseTag );
- }
- testCaseInfo.tags = std::move(tags);
- }
-
- TestCaseInfo::TestCaseInfo( std::string const& _name,
- std::string const& _className,
- std::string const& _description,
- std::vector<std::string> const& _tags,
- SourceLineInfo const& _lineInfo )
- : name( _name ),
- className( _className ),
- description( _description ),
- lineInfo( _lineInfo ),
- properties( None )
- {
- setTags( *this, _tags );
- }
-
- bool TestCaseInfo::isHidden() const {
- return ( properties & IsHidden ) != 0;
- }
- bool TestCaseInfo::throws() const {
- return ( properties & Throws ) != 0;
- }
- bool TestCaseInfo::okToFail() const {
- return ( properties & (ShouldFail | MayFail ) ) != 0;
- }
- bool TestCaseInfo::expectedToFail() const {
- return ( properties & (ShouldFail ) ) != 0;
- }
-
- std::string TestCaseInfo::tagsAsString() const {
- std::string ret;
- // '[' and ']' per tag
- std::size_t full_size = 2 * tags.size();
- for (const auto& tag : tags) {
- full_size += tag.size();
- }
- ret.reserve(full_size);
- for (const auto& tag : tags) {
- ret.push_back('[');
- ret.append(tag);
- ret.push_back(']');
- }
-
- return ret;
- }
-
- TestCase::TestCase( ITestInvoker* testCase, TestCaseInfo&& info ) : TestCaseInfo( std::move(info) ), test( testCase ) {}
-
- TestCase TestCase::withName( std::string const& _newName ) const {
- TestCase other( *this );
- other.name = _newName;
- return other;
- }
-
- void TestCase::invoke() const {
- test->invoke();
- }
-
- bool TestCase::operator == ( TestCase const& other ) const {
- return test.get() == other.test.get() &&
- name == other.name &&
- className == other.className;
- }
-
- bool TestCase::operator < ( TestCase const& other ) const {
- return name < other.name;
- }
-
- TestCaseInfo const& TestCase::getTestCaseInfo() const
- {
- return *this;
- }
-
-} // end namespace Catch
-// end catch_test_case_info.cpp
-// start catch_test_case_registry_impl.cpp
-
-#include <sstream>
-
-namespace Catch {
-
- std::vector<TestCase> sortTests( IConfig const& config, std::vector<TestCase> const& unsortedTestCases ) {
-
- std::vector<TestCase> sorted = unsortedTestCases;
-
- switch( config.runOrder() ) {
- case RunTests::InLexicographicalOrder:
- std::sort( sorted.begin(), sorted.end() );
- break;
- case RunTests::InRandomOrder:
- seedRng( config );
- std::shuffle( sorted.begin(), sorted.end(), rng() );
- break;
- case RunTests::InDeclarationOrder:
- // already in declaration order
- break;
- }
- return sorted;
- }
- bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config ) {
- return testSpec.matches( testCase ) && ( config.allowThrows() || !testCase.throws() );
- }
-
- void enforceNoDuplicateTestCases( std::vector<TestCase> const& functions ) {
- std::set<TestCase> seenFunctions;
- for( auto const& function : functions ) {
- auto prev = seenFunctions.insert( function );
- CATCH_ENFORCE( prev.second,
- "error: TEST_CASE( \"" << function.name << "\" ) already defined.\n"
- << "\tFirst seen at " << prev.first->getTestCaseInfo().lineInfo << "\n"
- << "\tRedefined at " << function.getTestCaseInfo().lineInfo );
- }
- }
-
- std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config ) {
- std::vector<TestCase> filtered;
- filtered.reserve( testCases.size() );
- for (auto const& testCase : testCases) {
- if ((!testSpec.hasFilters() && !testCase.isHidden()) ||
- (testSpec.hasFilters() && matchTest(testCase, testSpec, config))) {
- filtered.push_back(testCase);
- }
- }
- return filtered;
- }
- std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config ) {
- return getRegistryHub().getTestCaseRegistry().getAllTestsSorted( config );
- }
-
- void TestRegistry::registerTest( TestCase const& testCase ) {
- std::string name = testCase.getTestCaseInfo().name;
- if( name.empty() ) {
- ReusableStringStream rss;
- rss << "Anonymous test case " << ++m_unnamedCount;
- return registerTest( testCase.withName( rss.str() ) );
- }
- m_functions.push_back( testCase );
- }
-
- std::vector<TestCase> const& TestRegistry::getAllTests() const {
- return m_functions;
- }
- std::vector<TestCase> const& TestRegistry::getAllTestsSorted( IConfig const& config ) const {
- if( m_sortedFunctions.empty() )
- enforceNoDuplicateTestCases( m_functions );
-
- if( m_currentSortOrder != config.runOrder() || m_sortedFunctions.empty() ) {
- m_sortedFunctions = sortTests( config, m_functions );
- m_currentSortOrder = config.runOrder();
- }
- return m_sortedFunctions;
- }
-
- ///////////////////////////////////////////////////////////////////////////
- TestInvokerAsFunction::TestInvokerAsFunction( void(*testAsFunction)() ) noexcept : m_testAsFunction( testAsFunction ) {}
-
- void TestInvokerAsFunction::invoke() const {
- m_testAsFunction();
- }
-
- std::string extractClassName( StringRef const& classOrQualifiedMethodName ) {
- std::string className = classOrQualifiedMethodName;
- if( startsWith( className, '&' ) )
- {
- std::size_t lastColons = className.rfind( "::" );
- std::size_t penultimateColons = className.rfind( "::", lastColons-1 );
- if( penultimateColons == std::string::npos )
- penultimateColons = 1;
- className = className.substr( penultimateColons, lastColons-penultimateColons );
- }
- return className;
- }
-
-} // end namespace Catch
-// end catch_test_case_registry_impl.cpp
-// start catch_test_case_tracker.cpp
-
-#include <algorithm>
-#include <cassert>
-#include <stdexcept>
-#include <memory>
-#include <sstream>
-
-#if defined(__clang__)
-# pragma clang diagnostic push
-# pragma clang diagnostic ignored "-Wexit-time-destructors"
-#endif
-
-namespace Catch {
-namespace TestCaseTracking {
-
- NameAndLocation::NameAndLocation( std::string const& _name, SourceLineInfo const& _location )
- : name( _name ),
- location( _location )
- {}
-
- ITracker::~ITracker() = default;
-
- ITracker& TrackerContext::startRun() {
- m_rootTracker = std::make_shared<SectionTracker>( NameAndLocation( "{root}", CATCH_INTERNAL_LINEINFO ), *this, nullptr );
- m_currentTracker = nullptr;
- m_runState = Executing;
- return *m_rootTracker;
- }
-
- void TrackerContext::endRun() {
- m_rootTracker.reset();
- m_currentTracker = nullptr;
- m_runState = NotStarted;
- }
-
- void TrackerContext::startCycle() {
- m_currentTracker = m_rootTracker.get();
- m_runState = Executing;
- }
- void TrackerContext::completeCycle() {
- m_runState = CompletedCycle;
- }
-
- bool TrackerContext::completedCycle() const {
- return m_runState == CompletedCycle;
- }
- ITracker& TrackerContext::currentTracker() {
- return *m_currentTracker;
- }
- void TrackerContext::setCurrentTracker( ITracker* tracker ) {
- m_currentTracker = tracker;
- }
-
- TrackerBase::TrackerBase( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent )
- : m_nameAndLocation( nameAndLocation ),
- m_ctx( ctx ),
- m_parent( parent )
- {}
-
- NameAndLocation const& TrackerBase::nameAndLocation() const {
- return m_nameAndLocation;
- }
- bool TrackerBase::isComplete() const {
- return m_runState == CompletedSuccessfully || m_runState == Failed;
- }
- bool TrackerBase::isSuccessfullyCompleted() const {
- return m_runState == CompletedSuccessfully;
- }
- bool TrackerBase::isOpen() const {
- return m_runState != NotStarted && !isComplete();
- }
- bool TrackerBase::hasChildren() const {
- return !m_children.empty();
- }
-
- void TrackerBase::addChild( ITrackerPtr const& child ) {
- m_children.push_back( child );
- }
-
- ITrackerPtr TrackerBase::findChild( NameAndLocation const& nameAndLocation ) {
- auto it = std::find_if( m_children.begin(), m_children.end(),
- [&nameAndLocation]( ITrackerPtr const& tracker ){
- return
- tracker->nameAndLocation().location == nameAndLocation.location &&
- tracker->nameAndLocation().name == nameAndLocation.name;
- } );
- return( it != m_children.end() )
- ? *it
- : nullptr;
- }
- ITracker& TrackerBase::parent() {
- assert( m_parent ); // Should always be non-null except for root
- return *m_parent;
- }
-
- void TrackerBase::openChild() {
- if( m_runState != ExecutingChildren ) {
- m_runState = ExecutingChildren;
- if( m_parent )
- m_parent->openChild();
- }
- }
-
- bool TrackerBase::isSectionTracker() const { return false; }
- bool TrackerBase::isGeneratorTracker() const { return false; }
-
- void TrackerBase::open() {
- m_runState = Executing;
- moveToThis();
- if( m_parent )
- m_parent->openChild();
- }
-
- void TrackerBase::close() {
-
- // Close any still open children (e.g. generators)
- while( &m_ctx.currentTracker() != this )
- m_ctx.currentTracker().close();
-
- switch( m_runState ) {
- case NeedsAnotherRun:
- break;
-
- case Executing:
- m_runState = CompletedSuccessfully;
- break;
- case ExecutingChildren:
- if( m_children.empty() || m_children.back()->isComplete() )
- m_runState = CompletedSuccessfully;
- break;
-
- case NotStarted:
- case CompletedSuccessfully:
- case Failed:
- CATCH_INTERNAL_ERROR( "Illogical state: " << m_runState );
-
- default:
- CATCH_INTERNAL_ERROR( "Unknown state: " << m_runState );
- }
- moveToParent();
- m_ctx.completeCycle();
- }
- void TrackerBase::fail() {
- m_runState = Failed;
- if( m_parent )
- m_parent->markAsNeedingAnotherRun();
- moveToParent();
- m_ctx.completeCycle();
- }
- void TrackerBase::markAsNeedingAnotherRun() {
- m_runState = NeedsAnotherRun;
- }
-
- void TrackerBase::moveToParent() {
- assert( m_parent );
- m_ctx.setCurrentTracker( m_parent );
- }
- void TrackerBase::moveToThis() {
- m_ctx.setCurrentTracker( this );
- }
-
- SectionTracker::SectionTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent )
- : TrackerBase( nameAndLocation, ctx, parent )
- {
- if( parent ) {
- while( !parent->isSectionTracker() )
- parent = &parent->parent();
-
- SectionTracker& parentSection = static_cast<SectionTracker&>( *parent );
- addNextFilters( parentSection.m_filters );
- }
- }
-
- bool SectionTracker::isComplete() const {
- bool complete = true;
-
- if ((m_filters.empty() || m_filters[0] == "") ||
- std::find(m_filters.begin(), m_filters.end(),
- m_nameAndLocation.name) != m_filters.end())
- complete = TrackerBase::isComplete();
- return complete;
-
- }
-
- bool SectionTracker::isSectionTracker() const { return true; }
-
- SectionTracker& SectionTracker::acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation ) {
- std::shared_ptr<SectionTracker> section;
-
- ITracker& currentTracker = ctx.currentTracker();
- if( ITrackerPtr childTracker = currentTracker.findChild( nameAndLocation ) ) {
- assert( childTracker );
- assert( childTracker->isSectionTracker() );
- section = std::static_pointer_cast<SectionTracker>( childTracker );
- }
- else {
- section = std::make_shared<SectionTracker>( nameAndLocation, ctx, &currentTracker );
- currentTracker.addChild( section );
- }
- if( !ctx.completedCycle() )
- section->tryOpen();
- return *section;
- }
-
- void SectionTracker::tryOpen() {
- if( !isComplete() && (m_filters.empty() || m_filters[0].empty() || m_filters[0] == m_nameAndLocation.name ) )
- open();
- }
-
- void SectionTracker::addInitialFilters( std::vector<std::string> const& filters ) {
- if( !filters.empty() ) {
- m_filters.push_back(""); // Root - should never be consulted
- m_filters.push_back(""); // Test Case - not a section filter
- m_filters.insert( m_filters.end(), filters.begin(), filters.end() );
- }
- }
- void SectionTracker::addNextFilters( std::vector<std::string> const& filters ) {
- if( filters.size() > 1 )
- m_filters.insert( m_filters.end(), ++filters.begin(), filters.end() );
- }
-
-} // namespace TestCaseTracking
-
-using TestCaseTracking::ITracker;
-using TestCaseTracking::TrackerContext;
-using TestCaseTracking::SectionTracker;
-
-} // namespace Catch
-
-#if defined(__clang__)
-# pragma clang diagnostic pop
-#endif
-// end catch_test_case_tracker.cpp
-// start catch_test_registry.cpp
-
-namespace Catch {
-
- auto makeTestInvoker( void(*testAsFunction)() ) noexcept -> ITestInvoker* {
- return new(std::nothrow) TestInvokerAsFunction( testAsFunction );
- }
-
- NameAndTags::NameAndTags( StringRef const& name_ , StringRef const& tags_ ) noexcept : name( name_ ), tags( tags_ ) {}
-
- AutoReg::AutoReg( ITestInvoker* invoker, SourceLineInfo const& lineInfo, StringRef const& classOrMethod, NameAndTags const& nameAndTags ) noexcept {
- CATCH_TRY {
- getMutableRegistryHub()
- .registerTest(
- makeTestCase(
- invoker,
- extractClassName( classOrMethod ),
- nameAndTags,
- lineInfo));
- } CATCH_CATCH_ALL {
- // Do not throw when constructing global objects, instead register the exception to be processed later
- getMutableRegistryHub().registerStartupException();
- }
- }
-
- AutoReg::~AutoReg() = default;
-}
-// end catch_test_registry.cpp
-// start catch_test_spec.cpp
-
-#include <algorithm>
-#include <string>
-#include <vector>
-#include <memory>
-
-namespace Catch {
-
- TestSpec::Pattern::~Pattern() = default;
- TestSpec::NamePattern::~NamePattern() = default;
- TestSpec::TagPattern::~TagPattern() = default;
- TestSpec::ExcludedPattern::~ExcludedPattern() = default;
-
- TestSpec::NamePattern::NamePattern( std::string const& name )
- : m_wildcardPattern( toLower( name ), CaseSensitive::No )
- {}
- bool TestSpec::NamePattern::matches( TestCaseInfo const& testCase ) const {
- return m_wildcardPattern.matches( toLower( testCase.name ) );
- }
-
- TestSpec::TagPattern::TagPattern( std::string const& tag ) : m_tag( toLower( tag ) ) {}
- bool TestSpec::TagPattern::matches( TestCaseInfo const& testCase ) const {
- return std::find(begin(testCase.lcaseTags),
- end(testCase.lcaseTags),
- m_tag) != end(testCase.lcaseTags);
- }
-
- TestSpec::ExcludedPattern::ExcludedPattern( PatternPtr const& underlyingPattern ) : m_underlyingPattern( underlyingPattern ) {}
- bool TestSpec::ExcludedPattern::matches( TestCaseInfo const& testCase ) const { return !m_underlyingPattern->matches( testCase ); }
-
- bool TestSpec::Filter::matches( TestCaseInfo const& testCase ) const {
- // All patterns in a filter must match for the filter to be a match
- for( auto const& pattern : m_patterns ) {
- if( !pattern->matches( testCase ) )
- return false;
- }
- return true;
- }
-
- bool TestSpec::hasFilters() const {
- return !m_filters.empty();
- }
- bool TestSpec::matches( TestCaseInfo const& testCase ) const {
- // A TestSpec matches if any filter matches
- for( auto const& filter : m_filters )
- if( filter.matches( testCase ) )
- return true;
- return false;
- }
-}
-// end catch_test_spec.cpp
-// start catch_test_spec_parser.cpp
-
-namespace Catch {
-
- TestSpecParser::TestSpecParser( ITagAliasRegistry const& tagAliases ) : m_tagAliases( &tagAliases ) {}
-
- TestSpecParser& TestSpecParser::parse( std::string const& arg ) {
- m_mode = None;
- m_exclusion = false;
- m_start = std::string::npos;
- m_arg = m_tagAliases->expandAliases( arg );
- m_escapeChars.clear();
- for( m_pos = 0; m_pos < m_arg.size(); ++m_pos )
- visitChar( m_arg[m_pos] );
- if( m_mode == Name )
- addPattern<TestSpec::NamePattern>();
- return *this;
- }
- TestSpec TestSpecParser::testSpec() {
- addFilter();
- return m_testSpec;
- }
-
- void TestSpecParser::visitChar( char c ) {
- if( m_mode == None ) {
- switch( c ) {
- case ' ': return;
- case '~': m_exclusion = true; return;
- case '[': return startNewMode( Tag, ++m_pos );
- case '"': return startNewMode( QuotedName, ++m_pos );
- case '\\': return escape();
- default: startNewMode( Name, m_pos ); break;
- }
- }
- if( m_mode == Name ) {
- if( c == ',' ) {
- addPattern<TestSpec::NamePattern>();
- addFilter();
- }
- else if( c == '[' ) {
- if( subString() == "exclude:" )
- m_exclusion = true;
- else
- addPattern<TestSpec::NamePattern>();
- startNewMode( Tag, ++m_pos );
- }
- else if( c == '\\' )
- escape();
- }
- else if( m_mode == EscapedName )
- m_mode = Name;
- else if( m_mode == QuotedName && c == '"' )
- addPattern<TestSpec::NamePattern>();
- else if( m_mode == Tag && c == ']' )
- addPattern<TestSpec::TagPattern>();
- }
- void TestSpecParser::startNewMode( Mode mode, std::size_t start ) {
- m_mode = mode;
- m_start = start;
- }
- void TestSpecParser::escape() {
- if( m_mode == None )
- m_start = m_pos;
- m_mode = EscapedName;
- m_escapeChars.push_back( m_pos );
- }
- std::string TestSpecParser::subString() const { return m_arg.substr( m_start, m_pos - m_start ); }
-
- void TestSpecParser::addFilter() {
- if( !m_currentFilter.m_patterns.empty() ) {
- m_testSpec.m_filters.push_back( m_currentFilter );
- m_currentFilter = TestSpec::Filter();
- }
- }
-
- TestSpec parseTestSpec( std::string const& arg ) {
- return TestSpecParser( ITagAliasRegistry::get() ).parse( arg ).testSpec();
- }
-
-} // namespace Catch
-// end catch_test_spec_parser.cpp
-// start catch_timer.cpp
-
-#include <chrono>
-
-static const uint64_t nanosecondsInSecond = 1000000000;
-
-namespace Catch {
-
- auto getCurrentNanosecondsSinceEpoch() -> uint64_t {
- return std::chrono::duration_cast<std::chrono::nanoseconds>( std::chrono::high_resolution_clock::now().time_since_epoch() ).count();
- }
-
- namespace {
- auto estimateClockResolution() -> uint64_t {
- uint64_t sum = 0;
- static const uint64_t iterations = 1000000;
-
- auto startTime = getCurrentNanosecondsSinceEpoch();
-
- for( std::size_t i = 0; i < iterations; ++i ) {
-
- uint64_t ticks;
- uint64_t baseTicks = getCurrentNanosecondsSinceEpoch();
- do {
- ticks = getCurrentNanosecondsSinceEpoch();
- } while( ticks == baseTicks );
-
- auto delta = ticks - baseTicks;
- sum += delta;
-
- // If we have been calibrating for over 3 seconds -- the clock
- // is terrible and we should move on.
- // TBD: How to signal that the measured resolution is probably wrong?
- if (ticks > startTime + 3 * nanosecondsInSecond) {
- return sum / ( i + 1u );
- }
- }
-
- // We're just taking the mean, here. To do better we could take the std. dev and exclude outliers
- // - and potentially do more iterations if there's a high variance.
- return sum/iterations;
- }
- }
- auto getEstimatedClockResolution() -> uint64_t {
- static auto s_resolution = estimateClockResolution();
- return s_resolution;
- }
-
- void Timer::start() {
- m_nanoseconds = getCurrentNanosecondsSinceEpoch();
- }
- auto Timer::getElapsedNanoseconds() const -> uint64_t {
- return getCurrentNanosecondsSinceEpoch() - m_nanoseconds;
- }
- auto Timer::getElapsedMicroseconds() const -> uint64_t {
- return getElapsedNanoseconds()/1000;
- }
- auto Timer::getElapsedMilliseconds() const -> unsigned int {
- return static_cast<unsigned int>(getElapsedMicroseconds()/1000);
- }
- auto Timer::getElapsedSeconds() const -> double {
- return getElapsedMicroseconds()/1000000.0;
- }
-
-} // namespace Catch
-// end catch_timer.cpp
-// start catch_tostring.cpp
-
-#if defined(__clang__)
-# pragma clang diagnostic push
-# pragma clang diagnostic ignored "-Wexit-time-destructors"
-# pragma clang diagnostic ignored "-Wglobal-constructors"
-#endif
-
-// Enable specific decls locally
-#if !defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER)
-#define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
-#endif
-
-#include <cmath>
-#include <iomanip>
-
-namespace Catch {
-
-namespace Detail {
-
- const std::string unprintableString = "{?}";
-
- namespace {
- const int hexThreshold = 255;
-
- struct Endianness {
- enum Arch { Big, Little };
-
- static Arch which() {
- union _{
- int asInt;
- char asChar[sizeof (int)];
- } u;
-
- u.asInt = 1;
- return ( u.asChar[sizeof(int)-1] == 1 ) ? Big : Little;
- }
- };
- }
-
- std::string rawMemoryToString( const void *object, std::size_t size ) {
- // Reverse order for little endian architectures
- int i = 0, end = static_cast<int>( size ), inc = 1;
- if( Endianness::which() == Endianness::Little ) {
- i = end-1;
- end = inc = -1;
- }
-
- unsigned char const *bytes = static_cast<unsigned char const *>(object);
- ReusableStringStream rss;
- rss << "0x" << std::setfill('0') << std::hex;
- for( ; i != end; i += inc )
- rss << std::setw(2) << static_cast<unsigned>(bytes[i]);
- return rss.str();
- }
-}
-
-template<typename T>
-std::string fpToString( T value, int precision ) {
- if (Catch::isnan(value)) {
- return "nan";
- }
-
- ReusableStringStream rss;
- rss << std::setprecision( precision )
- << std::fixed
- << value;
- std::string d = rss.str();
- std::size_t i = d.find_last_not_of( '0' );
- if( i != std::string::npos && i != d.size()-1 ) {
- if( d[i] == '.' )
- i++;
- d = d.substr( 0, i+1 );
- }
- return d;
-}
-
-//// ======================================================= ////
-//
-// Out-of-line defs for full specialization of StringMaker
-//
-//// ======================================================= ////
-
-std::string StringMaker<std::string>::convert(const std::string& str) {
- if (!getCurrentContext().getConfig()->showInvisibles()) {
- return '"' + str + '"';
- }
-
- std::string s("\"");
- for (char c : str) {
- switch (c) {
- case '\n':
- s.append("\\n");
- break;
- case '\t':
- s.append("\\t");
- break;
- default:
- s.push_back(c);
- break;
- }
- }
- s.append("\"");
- return s;
-}
-
-#ifdef CATCH_CONFIG_CPP17_STRING_VIEW
-std::string StringMaker<std::string_view>::convert(std::string_view str) {
- return ::Catch::Detail::stringify(std::string{ str });
-}
-#endif
-
-std::string StringMaker<char const*>::convert(char const* str) {
- if (str) {
- return ::Catch::Detail::stringify(std::string{ str });
- } else {
- return{ "{null string}" };
- }
-}
-std::string StringMaker<char*>::convert(char* str) {
- if (str) {
- return ::Catch::Detail::stringify(std::string{ str });
- } else {
- return{ "{null string}" };
- }
-}
-
-#ifdef CATCH_CONFIG_WCHAR
-std::string StringMaker<std::wstring>::convert(const std::wstring& wstr) {
- std::string s;
- s.reserve(wstr.size());
- for (auto c : wstr) {
- s += (c <= 0xff) ? static_cast<char>(c) : '?';
- }
- return ::Catch::Detail::stringify(s);
-}
-
-# ifdef CATCH_CONFIG_CPP17_STRING_VIEW
-std::string StringMaker<std::wstring_view>::convert(std::wstring_view str) {
- return StringMaker<std::wstring>::convert(std::wstring(str));
-}
-# endif
-
-std::string StringMaker<wchar_t const*>::convert(wchar_t const * str) {
- if (str) {
- return ::Catch::Detail::stringify(std::wstring{ str });
- } else {
- return{ "{null string}" };
- }
-}
-std::string StringMaker<wchar_t *>::convert(wchar_t * str) {
- if (str) {
- return ::Catch::Detail::stringify(std::wstring{ str });
- } else {
- return{ "{null string}" };
- }
-}
-#endif
-
-std::string StringMaker<int>::convert(int value) {
- return ::Catch::Detail::stringify(static_cast<long long>(value));
-}
-std::string StringMaker<long>::convert(long value) {
- return ::Catch::Detail::stringify(static_cast<long long>(value));
-}
-std::string StringMaker<long long>::convert(long long value) {
- ReusableStringStream rss;
- rss << value;
- if (value > Detail::hexThreshold) {
- rss << " (0x" << std::hex << value << ')';
- }
- return rss.str();
-}
-
-std::string StringMaker<unsigned int>::convert(unsigned int value) {
- return ::Catch::Detail::stringify(static_cast<unsigned long long>(value));
-}
-std::string StringMaker<unsigned long>::convert(unsigned long value) {
- return ::Catch::Detail::stringify(static_cast<unsigned long long>(value));
-}
-std::string StringMaker<unsigned long long>::convert(unsigned long long value) {
- ReusableStringStream rss;
- rss << value;
- if (value > Detail::hexThreshold) {
- rss << " (0x" << std::hex << value << ')';
- }
- return rss.str();
-}
-
-std::string StringMaker<bool>::convert(bool b) {
- return b ? "true" : "false";
-}
-
-std::string StringMaker<signed char>::convert(signed char value) {
- if (value == '\r') {
- return "'\\r'";
- } else if (value == '\f') {
- return "'\\f'";
- } else if (value == '\n') {
- return "'\\n'";
- } else if (value == '\t') {
- return "'\\t'";
- } else if ('\0' <= value && value < ' ') {
- return ::Catch::Detail::stringify(static_cast<unsigned int>(value));
- } else {
- char chstr[] = "' '";
- chstr[1] = value;
- return chstr;
- }
-}
-std::string StringMaker<char>::convert(char c) {
- return ::Catch::Detail::stringify(static_cast<signed char>(c));
-}
-std::string StringMaker<unsigned char>::convert(unsigned char c) {
- return ::Catch::Detail::stringify(static_cast<char>(c));
-}
-
-std::string StringMaker<std::nullptr_t>::convert(std::nullptr_t) {
- return "nullptr";
-}
-
-int StringMaker<float>::precision = 5;
-
-std::string StringMaker<float>::convert(float value) {
- return fpToString(value, precision) + 'f';
-}
-
-int StringMaker<double>::precision = 10;
-
-std::string StringMaker<double>::convert(double value) {
- return fpToString(value, precision);
-}
-
-std::string ratio_string<std::atto>::symbol() { return "a"; }
-std::string ratio_string<std::femto>::symbol() { return "f"; }
-std::string ratio_string<std::pico>::symbol() { return "p"; }
-std::string ratio_string<std::nano>::symbol() { return "n"; }
-std::string ratio_string<std::micro>::symbol() { return "u"; }
-std::string ratio_string<std::milli>::symbol() { return "m"; }
-
-} // end namespace Catch
-
-#if defined(__clang__)
-# pragma clang diagnostic pop
-#endif
-
-// end catch_tostring.cpp
-// start catch_totals.cpp
-
-namespace Catch {
-
- Counts Counts::operator - ( Counts const& other ) const {
- Counts diff;
- diff.passed = passed - other.passed;
- diff.failed = failed - other.failed;
- diff.failedButOk = failedButOk - other.failedButOk;
- return diff;
- }
-
- Counts& Counts::operator += ( Counts const& other ) {
- passed += other.passed;
- failed += other.failed;
- failedButOk += other.failedButOk;
- return *this;
- }
-
- std::size_t Counts::total() const {
- return passed + failed + failedButOk;
- }
- bool Counts::allPassed() const {
- return failed == 0 && failedButOk == 0;
- }
- bool Counts::allOk() const {
- return failed == 0;
- }
-
- Totals Totals::operator - ( Totals const& other ) const {
- Totals diff;
- diff.assertions = assertions - other.assertions;
- diff.testCases = testCases - other.testCases;
- return diff;
- }
-
- Totals& Totals::operator += ( Totals const& other ) {
- assertions += other.assertions;
- testCases += other.testCases;
- return *this;
- }
-
- Totals Totals::delta( Totals const& prevTotals ) const {
- Totals diff = *this - prevTotals;
- if( diff.assertions.failed > 0 )
- ++diff.testCases.failed;
- else if( diff.assertions.failedButOk > 0 )
- ++diff.testCases.failedButOk;
- else
- ++diff.testCases.passed;
- return diff;
- }
-
-}
-// end catch_totals.cpp
-// start catch_uncaught_exceptions.cpp
-
-#include <exception>
-
-namespace Catch {
- bool uncaught_exceptions() {
-#if defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS)
- return std::uncaught_exceptions() > 0;
-#else
- return std::uncaught_exception();
-#endif
- }
-} // end namespace Catch
-// end catch_uncaught_exceptions.cpp
-// start catch_version.cpp
-
-#include <ostream>
-
-namespace Catch {
-
- Version::Version
- ( unsigned int _majorVersion,
- unsigned int _minorVersion,
- unsigned int _patchNumber,
- char const * const _branchName,
- unsigned int _buildNumber )
- : majorVersion( _majorVersion ),
- minorVersion( _minorVersion ),
- patchNumber( _patchNumber ),
- branchName( _branchName ),
- buildNumber( _buildNumber )
- {}
-
- std::ostream& operator << ( std::ostream& os, Version const& version ) {
- os << version.majorVersion << '.'
- << version.minorVersion << '.'
- << version.patchNumber;
- // branchName is never null -> 0th char is \0 if it is empty
- if (version.branchName[0]) {
- os << '-' << version.branchName
- << '.' << version.buildNumber;
- }
- return os;
- }
-
- Version const& libraryVersion() {
- static Version version( 2, 9, 1, "", 0 );
- return version;
- }
-
-}
-// end catch_version.cpp
-// start catch_wildcard_pattern.cpp
-
-#include <sstream>
-
-namespace Catch {
-
- WildcardPattern::WildcardPattern( std::string const& pattern,
- CaseSensitive::Choice caseSensitivity )
- : m_caseSensitivity( caseSensitivity ),
- m_pattern( adjustCase( pattern ) )
- {
- if( startsWith( m_pattern, '*' ) ) {
- m_pattern = m_pattern.substr( 1 );
- m_wildcard = WildcardAtStart;
- }
- if( endsWith( m_pattern, '*' ) ) {
- m_pattern = m_pattern.substr( 0, m_pattern.size()-1 );
- m_wildcard = static_cast<WildcardPosition>( m_wildcard | WildcardAtEnd );
- }
- }
-
- bool WildcardPattern::matches( std::string const& str ) const {
- switch( m_wildcard ) {
- case NoWildcard:
- return m_pattern == adjustCase( str );
- case WildcardAtStart:
- return endsWith( adjustCase( str ), m_pattern );
- case WildcardAtEnd:
- return startsWith( adjustCase( str ), m_pattern );
- case WildcardAtBothEnds:
- return contains( adjustCase( str ), m_pattern );
- default:
- CATCH_INTERNAL_ERROR( "Unknown enum" );
- }
- }
-
- std::string WildcardPattern::adjustCase( std::string const& str ) const {
- return m_caseSensitivity == CaseSensitive::No ? toLower( str ) : str;
- }
-}
-// end catch_wildcard_pattern.cpp
-// start catch_xmlwriter.cpp
-
-#include <iomanip>
-
-using uchar = unsigned char;
-
-namespace Catch {
-
-namespace {
-
- size_t trailingBytes(unsigned char c) {
- if ((c & 0xE0) == 0xC0) {
- return 2;
- }
- if ((c & 0xF0) == 0xE0) {
- return 3;
- }
- if ((c & 0xF8) == 0xF0) {
- return 4;
- }
- CATCH_INTERNAL_ERROR("Invalid multibyte utf-8 start byte encountered");
- }
-
- uint32_t headerValue(unsigned char c) {
- if ((c & 0xE0) == 0xC0) {
- return c & 0x1F;
- }
- if ((c & 0xF0) == 0xE0) {
- return c & 0x0F;
- }
- if ((c & 0xF8) == 0xF0) {
- return c & 0x07;
- }
- CATCH_INTERNAL_ERROR("Invalid multibyte utf-8 start byte encountered");
- }
-
- void hexEscapeChar(std::ostream& os, unsigned char c) {
- std::ios_base::fmtflags f(os.flags());
- os << "\\x"
- << std::uppercase << std::hex << std::setfill('0') << std::setw(2)
- << static_cast<int>(c);
- os.flags(f);
- }
-
-} // anonymous namespace
-
- XmlEncode::XmlEncode( std::string const& str, ForWhat forWhat )
- : m_str( str ),
- m_forWhat( forWhat )
- {}
-
- void XmlEncode::encodeTo( std::ostream& os ) const {
- // Apostrophe escaping not necessary if we always use " to write attributes
- // (see: http://www.w3.org/TR/xml/#syntax)
-
- for( std::size_t idx = 0; idx < m_str.size(); ++ idx ) {
- uchar c = m_str[idx];
- switch (c) {
- case '<': os << "&lt;"; break;
- case '&': os << "&amp;"; break;
-
- case '>':
- // See: http://www.w3.org/TR/xml/#syntax
- if (idx > 2 && m_str[idx - 1] == ']' && m_str[idx - 2] == ']')
- os << "&gt;";
- else
- os << c;
- break;
-
- case '\"':
- if (m_forWhat == ForAttributes)
- os << "&quot;";
- else
- os << c;
- break;
-
- default:
- // Check for control characters and invalid utf-8
-
- // Escape control characters in standard ascii
- // see http://stackoverflow.com/questions/404107/why-are-control-characters-illegal-in-xml-1-0
- if (c < 0x09 || (c > 0x0D && c < 0x20) || c == 0x7F) {
- hexEscapeChar(os, c);
- break;
- }
-
- // Plain ASCII: Write it to stream
- if (c < 0x7F) {
- os << c;
- break;
- }
-
- // UTF-8 territory
- // Check if the encoding is valid and if it is not, hex escape bytes.
- // Important: We do not check the exact decoded values for validity, only the encoding format
- // First check that this bytes is a valid lead byte:
- // This means that it is not encoded as 1111 1XXX
- // Or as 10XX XXXX
- if (c < 0xC0 ||
- c >= 0xF8) {
- hexEscapeChar(os, c);
- break;
- }
-
- auto encBytes = trailingBytes(c);
- // Are there enough bytes left to avoid accessing out-of-bounds memory?
- if (idx + encBytes - 1 >= m_str.size()) {
- hexEscapeChar(os, c);
- break;
- }
- // The header is valid, check data
- // The next encBytes bytes must together be a valid utf-8
- // This means: bitpattern 10XX XXXX and the extracted value is sane (ish)
- bool valid = true;
- uint32_t value = headerValue(c);
- for (std::size_t n = 1; n < encBytes; ++n) {
- uchar nc = m_str[idx + n];
- valid &= ((nc & 0xC0) == 0x80);
- value = (value << 6) | (nc & 0x3F);
- }
-
- if (
- // Wrong bit pattern of following bytes
- (!valid) ||
- // Overlong encodings
- (value < 0x80) ||
- (0x80 <= value && value < 0x800 && encBytes > 2) ||
- (0x800 < value && value < 0x10000 && encBytes > 3) ||
- // Encoded value out of range
- (value >= 0x110000)
- ) {
- hexEscapeChar(os, c);
- break;
- }
-
- // If we got here, this is in fact a valid(ish) utf-8 sequence
- for (std::size_t n = 0; n < encBytes; ++n) {
- os << m_str[idx + n];
- }
- idx += encBytes - 1;
- break;
- }
- }
- }
-
- std::ostream& operator << ( std::ostream& os, XmlEncode const& xmlEncode ) {
- xmlEncode.encodeTo( os );
- return os;
- }
-
- XmlWriter::ScopedElement::ScopedElement( XmlWriter* writer )
- : m_writer( writer )
- {}
-
- XmlWriter::ScopedElement::ScopedElement( ScopedElement&& other ) noexcept
- : m_writer( other.m_writer ){
- other.m_writer = nullptr;
- }
- XmlWriter::ScopedElement& XmlWriter::ScopedElement::operator=( ScopedElement&& other ) noexcept {
- if ( m_writer ) {
- m_writer->endElement();
- }
- m_writer = other.m_writer;
- other.m_writer = nullptr;
- return *this;
- }
-
- XmlWriter::ScopedElement::~ScopedElement() {
- if( m_writer )
- m_writer->endElement();
- }
-
- XmlWriter::ScopedElement& XmlWriter::ScopedElement::writeText( std::string const& text, bool indent ) {
- m_writer->writeText( text, indent );
- return *this;
- }
-
- XmlWriter::XmlWriter( std::ostream& os ) : m_os( os )
- {
- writeDeclaration();
- }
-
- XmlWriter::~XmlWriter() {
- while( !m_tags.empty() )
- endElement();
- }
-
- XmlWriter& XmlWriter::startElement( std::string const& name ) {
- ensureTagClosed();
- newlineIfNecessary();
- m_os << m_indent << '<' << name;
- m_tags.push_back( name );
- m_indent += " ";
- m_tagIsOpen = true;
- return *this;
- }
-
- XmlWriter::ScopedElement XmlWriter::scopedElement( std::string const& name ) {
- ScopedElement scoped( this );
- startElement( name );
- return scoped;
- }
-
- XmlWriter& XmlWriter::endElement() {
- newlineIfNecessary();
- m_indent = m_indent.substr( 0, m_indent.size()-2 );
- if( m_tagIsOpen ) {
- m_os << "/>";
- m_tagIsOpen = false;
- }
- else {
- m_os << m_indent << "</" << m_tags.back() << ">";
- }
- m_os << std::endl;
- m_tags.pop_back();
- return *this;
- }
-
- XmlWriter& XmlWriter::writeAttribute( std::string const& name, std::string const& attribute ) {
- if( !name.empty() && !attribute.empty() )
- m_os << ' ' << name << "=\"" << XmlEncode( attribute, XmlEncode::ForAttributes ) << '"';
- return *this;
- }
-
- XmlWriter& XmlWriter::writeAttribute( std::string const& name, bool attribute ) {
- m_os << ' ' << name << "=\"" << ( attribute ? "true" : "false" ) << '"';
- return *this;
- }
-
- XmlWriter& XmlWriter::writeText( std::string const& text, bool indent ) {
- if( !text.empty() ){
- bool tagWasOpen = m_tagIsOpen;
- ensureTagClosed();
- if( tagWasOpen && indent )
- m_os << m_indent;
- m_os << XmlEncode( text );
- m_needsNewline = true;
- }
- return *this;
- }
-
- XmlWriter& XmlWriter::writeComment( std::string const& text ) {
- ensureTagClosed();
- m_os << m_indent << "<!--" << text << "-->";
- m_needsNewline = true;
- return *this;
- }
-
- void XmlWriter::writeStylesheetRef( std::string const& url ) {
- m_os << "<?xml-stylesheet type=\"text/xsl\" href=\"" << url << "\"?>\n";
- }
-
- XmlWriter& XmlWriter::writeBlankLine() {
- ensureTagClosed();
- m_os << '\n';
- return *this;
- }
-
- void XmlWriter::ensureTagClosed() {
- if( m_tagIsOpen ) {
- m_os << ">" << std::endl;
- m_tagIsOpen = false;
- }
- }
-
- void XmlWriter::writeDeclaration() {
- m_os << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
- }
-
- void XmlWriter::newlineIfNecessary() {
- if( m_needsNewline ) {
- m_os << std::endl;
- m_needsNewline = false;
- }
- }
-}
-// end catch_xmlwriter.cpp
-// start catch_reporter_bases.cpp
-
-#include <cstring>
-#include <cfloat>
-#include <cstdio>
-#include <cassert>
-#include <memory>
-
-namespace Catch {
- void prepareExpandedExpression(AssertionResult& result) {
- result.getExpandedExpression();
- }
-
- // Because formatting using c++ streams is stateful, drop down to C is required
- // Alternatively we could use stringstream, but its performance is... not good.
- std::string getFormattedDuration( double duration ) {
- // Max exponent + 1 is required to represent the whole part
- // + 1 for decimal point
- // + 3 for the 3 decimal places
- // + 1 for null terminator
- const std::size_t maxDoubleSize = DBL_MAX_10_EXP + 1 + 1 + 3 + 1;
- char buffer[maxDoubleSize];
-
- // Save previous errno, to prevent sprintf from overwriting it
- ErrnoGuard guard;
-#ifdef _MSC_VER
- sprintf_s(buffer, "%.3f", duration);
-#else
- std::sprintf(buffer, "%.3f", duration);
-#endif
- return std::string(buffer);
- }
-
- std::string serializeFilters( std::vector<std::string> const& container ) {
- ReusableStringStream oss;
- bool first = true;
- for (auto&& filter : container)
- {
- if (!first)
- oss << ' ';
- else
- first = false;
-
- oss << filter;
- }
- return oss.str();
- }
-
- TestEventListenerBase::TestEventListenerBase(ReporterConfig const & _config)
- :StreamingReporterBase(_config) {}
-
- std::set<Verbosity> TestEventListenerBase::getSupportedVerbosities() {
- return { Verbosity::Quiet, Verbosity::Normal, Verbosity::High };
- }
-
- void TestEventListenerBase::assertionStarting(AssertionInfo const &) {}
-
- bool TestEventListenerBase::assertionEnded(AssertionStats const &) {
- return false;
- }
-
-} // end namespace Catch
-// end catch_reporter_bases.cpp
-// start catch_reporter_compact.cpp
-
-namespace {
-
-#ifdef CATCH_PLATFORM_MAC
- const char* failedString() { return "FAILED"; }
- const char* passedString() { return "PASSED"; }
-#else
- const char* failedString() { return "failed"; }
- const char* passedString() { return "passed"; }
-#endif
-
- // Colour::LightGrey
- Catch::Colour::Code dimColour() { return Catch::Colour::FileName; }
-
- std::string bothOrAll( std::size_t count ) {
- return count == 1 ? std::string() :
- count == 2 ? "both " : "all " ;
- }
-
-} // anon namespace
-
-namespace Catch {
-namespace {
-// Colour, message variants:
-// - white: No tests ran.
-// - red: Failed [both/all] N test cases, failed [both/all] M assertions.
-// - white: Passed [both/all] N test cases (no assertions).
-// - red: Failed N tests cases, failed M assertions.
-// - green: Passed [both/all] N tests cases with M assertions.
-void printTotals(std::ostream& out, const Totals& totals) {
- if (totals.testCases.total() == 0) {
- out << "No tests ran.";
- } else if (totals.testCases.failed == totals.testCases.total()) {
- Colour colour(Colour::ResultError);
- const std::string qualify_assertions_failed =
- totals.assertions.failed == totals.assertions.total() ?
- bothOrAll(totals.assertions.failed) : std::string();
- out <<
- "Failed " << bothOrAll(totals.testCases.failed)
- << pluralise(totals.testCases.failed, "test case") << ", "
- "failed " << qualify_assertions_failed <<
- pluralise(totals.assertions.failed, "assertion") << '.';
- } else if (totals.assertions.total() == 0) {
- out <<
- "Passed " << bothOrAll(totals.testCases.total())
- << pluralise(totals.testCases.total(), "test case")
- << " (no assertions).";
- } else if (totals.assertions.failed) {
- Colour colour(Colour::ResultError);
- out <<
- "Failed " << pluralise(totals.testCases.failed, "test case") << ", "
- "failed " << pluralise(totals.assertions.failed, "assertion") << '.';
- } else {
- Colour colour(Colour::ResultSuccess);
- out <<
- "Passed " << bothOrAll(totals.testCases.passed)
- << pluralise(totals.testCases.passed, "test case") <<
- " with " << pluralise(totals.assertions.passed, "assertion") << '.';
- }
-}
-
-// Implementation of CompactReporter formatting
-class AssertionPrinter {
-public:
- AssertionPrinter& operator= (AssertionPrinter const&) = delete;
- AssertionPrinter(AssertionPrinter const&) = delete;
- AssertionPrinter(std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages)
- : stream(_stream)
- , result(_stats.assertionResult)
- , messages(_stats.infoMessages)
- , itMessage(_stats.infoMessages.begin())
- , printInfoMessages(_printInfoMessages) {}
-
- void print() {
- printSourceInfo();
-
- itMessage = messages.begin();
-
- switch (result.getResultType()) {
- case ResultWas::Ok:
- printResultType(Colour::ResultSuccess, passedString());
- printOriginalExpression();
- printReconstructedExpression();
- if (!result.hasExpression())
- printRemainingMessages(Colour::None);
- else
- printRemainingMessages();
- break;
- case ResultWas::ExpressionFailed:
- if (result.isOk())
- printResultType(Colour::ResultSuccess, failedString() + std::string(" - but was ok"));
- else
- printResultType(Colour::Error, failedString());
- printOriginalExpression();
- printReconstructedExpression();
- printRemainingMessages();
- break;
- case ResultWas::ThrewException:
- printResultType(Colour::Error, failedString());
- printIssue("unexpected exception with message:");
- printMessage();
- printExpressionWas();
- printRemainingMessages();
- break;
- case ResultWas::FatalErrorCondition:
- printResultType(Colour::Error, failedString());
- printIssue("fatal error condition with message:");
- printMessage();
- printExpressionWas();
- printRemainingMessages();
- break;
- case ResultWas::DidntThrowException:
- printResultType(Colour::Error, failedString());
- printIssue("expected exception, got none");
- printExpressionWas();
- printRemainingMessages();
- break;
- case ResultWas::Info:
- printResultType(Colour::None, "info");
- printMessage();
- printRemainingMessages();
- break;
- case ResultWas::Warning:
- printResultType(Colour::None, "warning");
- printMessage();
- printRemainingMessages();
- break;
- case ResultWas::ExplicitFailure:
- printResultType(Colour::Error, failedString());
- printIssue("explicitly");
- printRemainingMessages(Colour::None);
- break;
- // These cases are here to prevent compiler warnings
- case ResultWas::Unknown:
- case ResultWas::FailureBit:
- case ResultWas::Exception:
- printResultType(Colour::Error, "** internal error **");
- break;
- }
- }
-
-private:
- void printSourceInfo() const {
- Colour colourGuard(Colour::FileName);
- stream << result.getSourceInfo() << ':';
- }
-
- void printResultType(Colour::Code colour, std::string const& passOrFail) const {
- if (!passOrFail.empty()) {
- {
- Colour colourGuard(colour);
- stream << ' ' << passOrFail;
- }
- stream << ':';
- }
- }
-
- void printIssue(std::string const& issue) const {
- stream << ' ' << issue;
- }
-
- void printExpressionWas() {
- if (result.hasExpression()) {
- stream << ';';
- {
- Colour colour(dimColour());
- stream << " expression was:";
- }
- printOriginalExpression();
- }
- }
-
- void printOriginalExpression() const {
- if (result.hasExpression()) {
- stream << ' ' << result.getExpression();
- }
- }
-
- void printReconstructedExpression() const {
- if (result.hasExpandedExpression()) {
- {
- Colour colour(dimColour());
- stream << " for: ";
- }
- stream << result.getExpandedExpression();
- }
- }
-
- void printMessage() {
- if (itMessage != messages.end()) {
- stream << " '" << itMessage->message << '\'';
- ++itMessage;
- }
- }
-
- void printRemainingMessages(Colour::Code colour = dimColour()) {
- if (itMessage == messages.end())
- return;
-
- // using messages.end() directly yields (or auto) compilation error:
- std::vector<MessageInfo>::const_iterator itEnd = messages.end();
- const std::size_t N = static_cast<std::size_t>(std::distance(itMessage, itEnd));
-
- {
- Colour colourGuard(colour);
- stream << " with " << pluralise(N, "message") << ':';
- }
-
- for (; itMessage != itEnd; ) {
- // If this assertion is a warning ignore any INFO messages
- if (printInfoMessages || itMessage->type != ResultWas::Info) {
- stream << " '" << itMessage->message << '\'';
- if (++itMessage != itEnd) {
- Colour colourGuard(dimColour());
- stream << " and";
- }
- }
- }
- }
-
-private:
- std::ostream& stream;
- AssertionResult const& result;
- std::vector<MessageInfo> messages;
- std::vector<MessageInfo>::const_iterator itMessage;
- bool printInfoMessages;
-};
-
-} // anon namespace
-
- std::string CompactReporter::getDescription() {
- return "Reports test results on a single line, suitable for IDEs";
- }
-
- ReporterPreferences CompactReporter::getPreferences() const {
- return m_reporterPrefs;
- }
-
- void CompactReporter::noMatchingTestCases( std::string const& spec ) {
- stream << "No test cases matched '" << spec << '\'' << std::endl;
- }
-
- void CompactReporter::assertionStarting( AssertionInfo const& ) {}
-
- bool CompactReporter::assertionEnded( AssertionStats const& _assertionStats ) {
- AssertionResult const& result = _assertionStats.assertionResult;
-
- bool printInfoMessages = true;
-
- // Drop out if result was successful and we're not printing those
- if( !m_config->includeSuccessfulResults() && result.isOk() ) {
- if( result.getResultType() != ResultWas::Warning )
- return false;
- printInfoMessages = false;
- }
-
- AssertionPrinter printer( stream, _assertionStats, printInfoMessages );
- printer.print();
-
- stream << std::endl;
- return true;
- }
-
- void CompactReporter::sectionEnded(SectionStats const& _sectionStats) {
- if (m_config->showDurations() == ShowDurations::Always) {
- stream << getFormattedDuration(_sectionStats.durationInSeconds) << " s: " << _sectionStats.sectionInfo.name << std::endl;
- }
- }
-
- void CompactReporter::testRunEnded( TestRunStats const& _testRunStats ) {
- printTotals( stream, _testRunStats.totals );
- stream << '\n' << std::endl;
- StreamingReporterBase::testRunEnded( _testRunStats );
- }
-
- CompactReporter::~CompactReporter() {}
-
- CATCH_REGISTER_REPORTER( "compact", CompactReporter )
-
-} // end namespace Catch
-// end catch_reporter_compact.cpp
-// start catch_reporter_console.cpp
-
-#include <cfloat>
-#include <cstdio>
-
-#if defined(_MSC_VER)
-#pragma warning(push)
-#pragma warning(disable:4061) // Not all labels are EXPLICITLY handled in switch
- // Note that 4062 (not all labels are handled and default is missing) is enabled
-#endif
-
-#if defined(__clang__)
-# pragma clang diagnostic push
-// For simplicity, benchmarking-only helpers are always enabled
-# pragma clang diagnostic ignored "-Wunused-function"
-#endif
-
-namespace Catch {
-
-namespace {
-
-// Formatter impl for ConsoleReporter
-class ConsoleAssertionPrinter {
-public:
- ConsoleAssertionPrinter& operator= (ConsoleAssertionPrinter const&) = delete;
- ConsoleAssertionPrinter(ConsoleAssertionPrinter const&) = delete;
- ConsoleAssertionPrinter(std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages)
- : stream(_stream),
- stats(_stats),
- result(_stats.assertionResult),
- colour(Colour::None),
- message(result.getMessage()),
- messages(_stats.infoMessages),
- printInfoMessages(_printInfoMessages) {
- switch (result.getResultType()) {
- case ResultWas::Ok:
- colour = Colour::Success;
- passOrFail = "PASSED";
- //if( result.hasMessage() )
- if (_stats.infoMessages.size() == 1)
- messageLabel = "with message";
- if (_stats.infoMessages.size() > 1)
- messageLabel = "with messages";
- break;
- case ResultWas::ExpressionFailed:
- if (result.isOk()) {
- colour = Colour::Success;
- passOrFail = "FAILED - but was ok";
- } else {
- colour = Colour::Error;
- passOrFail = "FAILED";
- }
- if (_stats.infoMessages.size() == 1)
- messageLabel = "with message";
- if (_stats.infoMessages.size() > 1)
- messageLabel = "with messages";
- break;
- case ResultWas::ThrewException:
- colour = Colour::Error;
- passOrFail = "FAILED";
- messageLabel = "due to unexpected exception with ";
- if (_stats.infoMessages.size() == 1)
- messageLabel += "message";
- if (_stats.infoMessages.size() > 1)
- messageLabel += "messages";
- break;
- case ResultWas::FatalErrorCondition:
- colour = Colour::Error;
- passOrFail = "FAILED";
- messageLabel = "due to a fatal error condition";
- break;
- case ResultWas::DidntThrowException:
- colour = Colour::Error;
- passOrFail = "FAILED";
- messageLabel = "because no exception was thrown where one was expected";
- break;
- case ResultWas::Info:
- messageLabel = "info";
- break;
- case ResultWas::Warning:
- messageLabel = "warning";
- break;
- case ResultWas::ExplicitFailure:
- passOrFail = "FAILED";
- colour = Colour::Error;
- if (_stats.infoMessages.size() == 1)
- messageLabel = "explicitly with message";
- if (_stats.infoMessages.size() > 1)
- messageLabel = "explicitly with messages";
- break;
- // These cases are here to prevent compiler warnings
- case ResultWas::Unknown:
- case ResultWas::FailureBit:
- case ResultWas::Exception:
- passOrFail = "** internal error **";
- colour = Colour::Error;
- break;
- }
- }
-
- void print() const {
- printSourceInfo();
- if (stats.totals.assertions.total() > 0) {
- printResultType();
- printOriginalExpression();
- printReconstructedExpression();
- } else {
- stream << '\n';
- }
- printMessage();
- }
-
-private:
- void printResultType() const {
- if (!passOrFail.empty()) {
- Colour colourGuard(colour);
- stream << passOrFail << ":\n";
- }
- }
- void printOriginalExpression() const {
- if (result.hasExpression()) {
- Colour colourGuard(Colour::OriginalExpression);
- stream << " ";
- stream << result.getExpressionInMacro();
- stream << '\n';
- }
- }
- void printReconstructedExpression() const {
- if (result.hasExpandedExpression()) {
- stream << "with expansion:\n";
- Colour colourGuard(Colour::ReconstructedExpression);
- stream << Column(result.getExpandedExpression()).indent(2) << '\n';
- }
- }
- void printMessage() const {
- if (!messageLabel.empty())
- stream << messageLabel << ':' << '\n';
- for (auto const& msg : messages) {
- // If this assertion is a warning ignore any INFO messages
- if (printInfoMessages || msg.type != ResultWas::Info)
- stream << Column(msg.message).indent(2) << '\n';
- }
- }
- void printSourceInfo() const {
- Colour colourGuard(Colour::FileName);
- stream << result.getSourceInfo() << ": ";
- }
-
- std::ostream& stream;
- AssertionStats const& stats;
- AssertionResult const& result;
- Colour::Code colour;
- std::string passOrFail;
- std::string messageLabel;
- std::string message;
- std::vector<MessageInfo> messages;
- bool printInfoMessages;
-};
-
-std::size_t makeRatio(std::size_t number, std::size_t total) {
- std::size_t ratio = total > 0 ? CATCH_CONFIG_CONSOLE_WIDTH * number / total : 0;
- return (ratio == 0 && number > 0) ? 1 : ratio;
-}
-
-std::size_t& findMax(std::size_t& i, std::size_t& j, std::size_t& k) {
- if (i > j && i > k)
- return i;
- else if (j > k)
- return j;
- else
- return k;
-}
-
-struct ColumnInfo {
- enum Justification { Left, Right };
- std::string name;
- int width;
- Justification justification;
-};
-struct ColumnBreak {};
-struct RowBreak {};
-
-class Duration {
- enum class Unit {
- Auto,
- Nanoseconds,
- Microseconds,
- Milliseconds,
- Seconds,
- Minutes
- };
- static const uint64_t s_nanosecondsInAMicrosecond = 1000;
- static const uint64_t s_nanosecondsInAMillisecond = 1000 * s_nanosecondsInAMicrosecond;
- static const uint64_t s_nanosecondsInASecond = 1000 * s_nanosecondsInAMillisecond;
- static const uint64_t s_nanosecondsInAMinute = 60 * s_nanosecondsInASecond;
-
- uint64_t m_inNanoseconds;
- Unit m_units;
-
-public:
- explicit Duration(double inNanoseconds, Unit units = Unit::Auto)
- : Duration(static_cast<uint64_t>(inNanoseconds), units) {
- }
-
- explicit Duration(uint64_t inNanoseconds, Unit units = Unit::Auto)
- : m_inNanoseconds(inNanoseconds),
- m_units(units) {
- if (m_units == Unit::Auto) {
- if (m_inNanoseconds < s_nanosecondsInAMicrosecond)
- m_units = Unit::Nanoseconds;
- else if (m_inNanoseconds < s_nanosecondsInAMillisecond)
- m_units = Unit::Microseconds;
- else if (m_inNanoseconds < s_nanosecondsInASecond)
- m_units = Unit::Milliseconds;
- else if (m_inNanoseconds < s_nanosecondsInAMinute)
- m_units = Unit::Seconds;
- else
- m_units = Unit::Minutes;
- }
-
- }
-
- auto value() const -> double {
- switch (m_units) {
- case Unit::Microseconds:
- return m_inNanoseconds / static_cast<double>(s_nanosecondsInAMicrosecond);
- case Unit::Milliseconds:
- return m_inNanoseconds / static_cast<double>(s_nanosecondsInAMillisecond);
- case Unit::Seconds:
- return m_inNanoseconds / static_cast<double>(s_nanosecondsInASecond);
- case Unit::Minutes:
- return m_inNanoseconds / static_cast<double>(s_nanosecondsInAMinute);
- default:
- return static_cast<double>(m_inNanoseconds);
- }
- }
- auto unitsAsString() const -> std::string {
- switch (m_units) {
- case Unit::Nanoseconds:
- return "ns";
- case Unit::Microseconds:
- return "us";
- case Unit::Milliseconds:
- return "ms";
- case Unit::Seconds:
- return "s";
- case Unit::Minutes:
- return "m";
- default:
- return "** internal error **";
- }
-
- }
- friend auto operator << (std::ostream& os, Duration const& duration) -> std::ostream& {
- return os << duration.value() << " " << duration.unitsAsString();
- }
-};
-} // end anon namespace
-
-class TablePrinter {
- std::ostream& m_os;
- std::vector<ColumnInfo> m_columnInfos;
- std::ostringstream m_oss;
- int m_currentColumn = -1;
- bool m_isOpen = false;
-
-public:
- TablePrinter( std::ostream& os, std::vector<ColumnInfo> columnInfos )
- : m_os( os ),
- m_columnInfos( std::move( columnInfos ) ) {}
-
- auto columnInfos() const -> std::vector<ColumnInfo> const& {
- return m_columnInfos;
- }
-
- void open() {
- if (!m_isOpen) {
- m_isOpen = true;
- *this << RowBreak();
-
- Columns headerCols;
- Spacer spacer(2);
- for (auto const& info : m_columnInfos) {
- headerCols += Column(info.name).width(static_cast<std::size_t>(info.width - 2));
- headerCols += spacer;
- }
- m_os << headerCols << "\n";
-
- m_os << Catch::getLineOfChars<'-'>() << "\n";
- }
- }
- void close() {
- if (m_isOpen) {
- *this << RowBreak();
- m_os << std::endl;
- m_isOpen = false;
- }
- }
-
- template<typename T>
- friend TablePrinter& operator << (TablePrinter& tp, T const& value) {
- tp.m_oss << value;
- return tp;
- }
-
- friend TablePrinter& operator << (TablePrinter& tp, ColumnBreak) {
- auto colStr = tp.m_oss.str();
- // This takes account of utf8 encodings
- auto strSize = Catch::StringRef(colStr).numberOfCharacters();
- tp.m_oss.str("");
- tp.open();
- if (tp.m_currentColumn == static_cast<int>(tp.m_columnInfos.size() - 1)) {
- tp.m_currentColumn = -1;
- tp.m_os << "\n";
- }
- tp.m_currentColumn++;
-
- auto colInfo = tp.m_columnInfos[tp.m_currentColumn];
- auto padding = (strSize + 2 < static_cast<std::size_t>(colInfo.width))
- ? std::string(colInfo.width - (strSize + 2), ' ')
- : std::string();
- if (colInfo.justification == ColumnInfo::Left)
- tp.m_os << colStr << padding << " ";
- else
- tp.m_os << padding << colStr << " ";
- return tp;
- }
-
- friend TablePrinter& operator << (TablePrinter& tp, RowBreak) {
- if (tp.m_currentColumn > 0) {
- tp.m_os << "\n";
- tp.m_currentColumn = -1;
- }
- return tp;
- }
-};
-
-ConsoleReporter::ConsoleReporter(ReporterConfig const& config)
- : StreamingReporterBase(config),
- m_tablePrinter(new TablePrinter(config.stream(),
- {
- { "benchmark name", CATCH_CONFIG_CONSOLE_WIDTH - 32, ColumnInfo::Left },
- { "samples mean std dev", 14, ColumnInfo::Right },
- { "iterations low mean low std dev", 14, ColumnInfo::Right },
- { "estimated high mean high std dev", 14, ColumnInfo::Right }
- })) {}
-ConsoleReporter::~ConsoleReporter() = default;
-
-std::string ConsoleReporter::getDescription() {
- return "Reports test results as plain lines of text";
-}
-
-void ConsoleReporter::noMatchingTestCases(std::string const& spec) {
- stream << "No test cases matched '" << spec << '\'' << std::endl;
-}
-
-void ConsoleReporter::assertionStarting(AssertionInfo const&) {}
-
-bool ConsoleReporter::assertionEnded(AssertionStats const& _assertionStats) {
- AssertionResult const& result = _assertionStats.assertionResult;
-
- bool includeResults = m_config->includeSuccessfulResults() || !result.isOk();
-
- // Drop out if result was successful but we're not printing them.
- if (!includeResults && result.getResultType() != ResultWas::Warning)
- return false;
-
- lazyPrint();
-
- ConsoleAssertionPrinter printer(stream, _assertionStats, includeResults);
- printer.print();
- stream << std::endl;
- return true;
-}
-
-void ConsoleReporter::sectionStarting(SectionInfo const& _sectionInfo) {
- m_tablePrinter->close();
- m_headerPrinted = false;
- StreamingReporterBase::sectionStarting(_sectionInfo);
-}
-void ConsoleReporter::sectionEnded(SectionStats const& _sectionStats) {
- m_tablePrinter->close();
- if (_sectionStats.missingAssertions) {
- lazyPrint();
- Colour colour(Colour::ResultError);
- if (m_sectionStack.size() > 1)
- stream << "\nNo assertions in section";
- else
- stream << "\nNo assertions in test case";
- stream << " '" << _sectionStats.sectionInfo.name << "'\n" << std::endl;
- }
- if (m_config->showDurations() == ShowDurations::Always) {
- stream << getFormattedDuration(_sectionStats.durationInSeconds) << " s: " << _sectionStats.sectionInfo.name << std::endl;
- }
- if (m_headerPrinted) {
- m_headerPrinted = false;
- }
- StreamingReporterBase::sectionEnded(_sectionStats);
-}
-
-#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
-void ConsoleReporter::benchmarkPreparing(std::string const& name) {
- lazyPrintWithoutClosingBenchmarkTable();
-
- auto nameCol = Column(name).width(static_cast<std::size_t>(m_tablePrinter->columnInfos()[0].width - 2));
-
- bool firstLine = true;
- for (auto line : nameCol) {
- if (!firstLine)
- (*m_tablePrinter) << ColumnBreak() << ColumnBreak() << ColumnBreak();
- else
- firstLine = false;
-
- (*m_tablePrinter) << line << ColumnBreak();
- }
-}
-
-void ConsoleReporter::benchmarkStarting(BenchmarkInfo const& info) {
- (*m_tablePrinter) << info.samples << ColumnBreak()
- << info.iterations << ColumnBreak()
- << Duration(info.estimatedDuration) << ColumnBreak();
-}
-void ConsoleReporter::benchmarkEnded(BenchmarkStats<> const& stats) {
- (*m_tablePrinter) << ColumnBreak()
- << Duration(stats.mean.point.count()) << ColumnBreak()
- << Duration(stats.mean.lower_bound.count()) << ColumnBreak()
- << Duration(stats.mean.upper_bound.count()) << ColumnBreak() << ColumnBreak()
- << Duration(stats.standardDeviation.point.count()) << ColumnBreak()
- << Duration(stats.standardDeviation.lower_bound.count()) << ColumnBreak()
- << Duration(stats.standardDeviation.upper_bound.count()) << ColumnBreak() << ColumnBreak() << ColumnBreak() << ColumnBreak() << ColumnBreak();
-}
-
-void ConsoleReporter::benchmarkFailed(std::string const& error) {
- Colour colour(Colour::Red);
- (*m_tablePrinter)
- << "Benchmark failed (" << error << ")"
- << ColumnBreak() << RowBreak();
-}
-#endif // CATCH_CONFIG_ENABLE_BENCHMARKING
-
-void ConsoleReporter::testCaseEnded(TestCaseStats const& _testCaseStats) {
- m_tablePrinter->close();
- StreamingReporterBase::testCaseEnded(_testCaseStats);
- m_headerPrinted = false;
-}
-void ConsoleReporter::testGroupEnded(TestGroupStats const& _testGroupStats) {
- if (currentGroupInfo.used) {
- printSummaryDivider();
- stream << "Summary for group '" << _testGroupStats.groupInfo.name << "':\n";
- printTotals(_testGroupStats.totals);
- stream << '\n' << std::endl;
- }
- StreamingReporterBase::testGroupEnded(_testGroupStats);
-}
-void ConsoleReporter::testRunEnded(TestRunStats const& _testRunStats) {
- printTotalsDivider(_testRunStats.totals);
- printTotals(_testRunStats.totals);
- stream << std::endl;
- StreamingReporterBase::testRunEnded(_testRunStats);
-}
-void ConsoleReporter::testRunStarting(TestRunInfo const& _testInfo) {
- StreamingReporterBase::testRunStarting(_testInfo);
- printTestFilters();
-}
-
-void ConsoleReporter::lazyPrint() {
-
- m_tablePrinter->close();
- lazyPrintWithoutClosingBenchmarkTable();
-}
-
-void ConsoleReporter::lazyPrintWithoutClosingBenchmarkTable() {
-
- if (!currentTestRunInfo.used)
- lazyPrintRunInfo();
- if (!currentGroupInfo.used)
- lazyPrintGroupInfo();
-
- if (!m_headerPrinted) {
- printTestCaseAndSectionHeader();
- m_headerPrinted = true;
- }
-}
-void ConsoleReporter::lazyPrintRunInfo() {
- stream << '\n' << getLineOfChars<'~'>() << '\n';
- Colour colour(Colour::SecondaryText);
- stream << currentTestRunInfo->name
- << " is a Catch v" << libraryVersion() << " host application.\n"
- << "Run with -? for options\n\n";
-
- if (m_config->rngSeed() != 0)
- stream << "Randomness seeded to: " << m_config->rngSeed() << "\n\n";
-
- currentTestRunInfo.used = true;
-}
-void ConsoleReporter::lazyPrintGroupInfo() {
- if (!currentGroupInfo->name.empty() && currentGroupInfo->groupsCounts > 1) {
- printClosedHeader("Group: " + currentGroupInfo->name);
- currentGroupInfo.used = true;
- }
-}
-void ConsoleReporter::printTestCaseAndSectionHeader() {
- assert(!m_sectionStack.empty());
- printOpenHeader(currentTestCaseInfo->name);
-
- if (m_sectionStack.size() > 1) {
- Colour colourGuard(Colour::Headers);
-
- auto
- it = m_sectionStack.begin() + 1, // Skip first section (test case)
- itEnd = m_sectionStack.end();
- for (; it != itEnd; ++it)
- printHeaderString(it->name, 2);
- }
-
- SourceLineInfo lineInfo = m_sectionStack.back().lineInfo;
-
- if (!lineInfo.empty()) {
- stream << getLineOfChars<'-'>() << '\n';
- Colour colourGuard(Colour::FileName);
- stream << lineInfo << '\n';
- }
- stream << getLineOfChars<'.'>() << '\n' << std::endl;
-}
-
-void ConsoleReporter::printClosedHeader(std::string const& _name) {
- printOpenHeader(_name);
- stream << getLineOfChars<'.'>() << '\n';
-}
-void ConsoleReporter::printOpenHeader(std::string const& _name) {
- stream << getLineOfChars<'-'>() << '\n';
- {
- Colour colourGuard(Colour::Headers);
- printHeaderString(_name);
- }
-}
-
-// if string has a : in first line will set indent to follow it on
-// subsequent lines
-void ConsoleReporter::printHeaderString(std::string const& _string, std::size_t indent) {
- std::size_t i = _string.find(": ");
- if (i != std::string::npos)
- i += 2;
- else
- i = 0;
- stream << Column(_string).indent(indent + i).initialIndent(indent) << '\n';
-}
-
-struct SummaryColumn {
-
- SummaryColumn( std::string _label, Colour::Code _colour )
- : label( std::move( _label ) ),
- colour( _colour ) {}
- SummaryColumn addRow( std::size_t count ) {
- ReusableStringStream rss;
- rss << count;
- std::string row = rss.str();
- for (auto& oldRow : rows) {
- while (oldRow.size() < row.size())
- oldRow = ' ' + oldRow;
- while (oldRow.size() > row.size())
- row = ' ' + row;
- }
- rows.push_back(row);
- return *this;
- }
-
- std::string label;
- Colour::Code colour;
- std::vector<std::string> rows;
-
-};
-
-void ConsoleReporter::printTotals( Totals const& totals ) {
- if (totals.testCases.total() == 0) {
- stream << Colour(Colour::Warning) << "No tests ran\n";
- } else if (totals.assertions.total() > 0 && totals.testCases.allPassed()) {
- stream << Colour(Colour::ResultSuccess) << "All tests passed";
- stream << " ("
- << pluralise(totals.assertions.passed, "assertion") << " in "
- << pluralise(totals.testCases.passed, "test case") << ')'
- << '\n';
- } else {
-
- std::vector<SummaryColumn> columns;
- columns.push_back(SummaryColumn("", Colour::None)
- .addRow(totals.testCases.total())
- .addRow(totals.assertions.total()));
- columns.push_back(SummaryColumn("passed", Colour::Success)
- .addRow(totals.testCases.passed)
- .addRow(totals.assertions.passed));
- columns.push_back(SummaryColumn("failed", Colour::ResultError)
- .addRow(totals.testCases.failed)
- .addRow(totals.assertions.failed));
- columns.push_back(SummaryColumn("failed as expected", Colour::ResultExpectedFailure)
- .addRow(totals.testCases.failedButOk)
- .addRow(totals.assertions.failedButOk));
-
- printSummaryRow("test cases", columns, 0);
- printSummaryRow("assertions", columns, 1);
- }
-}
-void ConsoleReporter::printSummaryRow(std::string const& label, std::vector<SummaryColumn> const& cols, std::size_t row) {
- for (auto col : cols) {
- std::string value = col.rows[row];
- if (col.label.empty()) {
- stream << label << ": ";
- if (value != "0")
- stream << value;
- else
- stream << Colour(Colour::Warning) << "- none -";
- } else if (value != "0") {
- stream << Colour(Colour::LightGrey) << " | ";
- stream << Colour(col.colour)
- << value << ' ' << col.label;
- }
- }
- stream << '\n';
-}
-
-void ConsoleReporter::printTotalsDivider(Totals const& totals) {
- if (totals.testCases.total() > 0) {
- std::size_t failedRatio = makeRatio(totals.testCases.failed, totals.testCases.total());
- std::size_t failedButOkRatio = makeRatio(totals.testCases.failedButOk, totals.testCases.total());
- std::size_t passedRatio = makeRatio(totals.testCases.passed, totals.testCases.total());
- while (failedRatio + failedButOkRatio + passedRatio < CATCH_CONFIG_CONSOLE_WIDTH - 1)
- findMax(failedRatio, failedButOkRatio, passedRatio)++;
- while (failedRatio + failedButOkRatio + passedRatio > CATCH_CONFIG_CONSOLE_WIDTH - 1)
- findMax(failedRatio, failedButOkRatio, passedRatio)--;
-
- stream << Colour(Colour::Error) << std::string(failedRatio, '=');
- stream << Colour(Colour::ResultExpectedFailure) << std::string(failedButOkRatio, '=');
- if (totals.testCases.allPassed())
- stream << Colour(Colour::ResultSuccess) << std::string(passedRatio, '=');
- else
- stream << Colour(Colour::Success) << std::string(passedRatio, '=');
- } else {
- stream << Colour(Colour::Warning) << std::string(CATCH_CONFIG_CONSOLE_WIDTH - 1, '=');
- }
- stream << '\n';
-}
-void ConsoleReporter::printSummaryDivider() {
- stream << getLineOfChars<'-'>() << '\n';
-}
-
-void ConsoleReporter::printTestFilters() {
- if (m_config->testSpec().hasFilters())
- stream << Colour(Colour::BrightYellow) << "Filters: " << serializeFilters( m_config->getTestsOrTags() ) << '\n';
-}
-
-CATCH_REGISTER_REPORTER("console", ConsoleReporter)
-
-} // end namespace Catch
-
-#if defined(_MSC_VER)
-#pragma warning(pop)
-#endif
-
-#if defined(__clang__)
-# pragma clang diagnostic pop
-#endif
-// end catch_reporter_console.cpp
-// start catch_reporter_junit.cpp
-
-#include <cassert>
-#include <sstream>
-#include <ctime>
-#include <algorithm>
-
-namespace Catch {
-
- namespace {
- std::string getCurrentTimestamp() {
- // Beware, this is not reentrant because of backward compatibility issues
- // Also, UTC only, again because of backward compatibility (%z is C++11)
- time_t rawtime;
- std::time(&rawtime);
- auto const timeStampSize = sizeof("2017-01-16T17:06:45Z");
-
-#ifdef _MSC_VER
- std::tm timeInfo = {};
- gmtime_s(&timeInfo, &rawtime);
-#else
- std::tm* timeInfo;
- timeInfo = std::gmtime(&rawtime);
-#endif
-
- char timeStamp[timeStampSize];
- const char * const fmt = "%Y-%m-%dT%H:%M:%SZ";
-
-#ifdef _MSC_VER
- std::strftime(timeStamp, timeStampSize, fmt, &timeInfo);
-#else
- std::strftime(timeStamp, timeStampSize, fmt, timeInfo);
-#endif
- return std::string(timeStamp);
- }
-
- std::string fileNameTag(const std::vector<std::string> &tags) {
- auto it = std::find_if(begin(tags),
- end(tags),
- [] (std::string const& tag) {return tag.front() == '#'; });
- if (it != tags.end())
- return it->substr(1);
- return std::string();
- }
- } // anonymous namespace
-
- JunitReporter::JunitReporter( ReporterConfig const& _config )
- : CumulativeReporterBase( _config ),
- xml( _config.stream() )
- {
- m_reporterPrefs.shouldRedirectStdOut = true;
- m_reporterPrefs.shouldReportAllAssertions = true;
- }
-
- JunitReporter::~JunitReporter() {}
-
- std::string JunitReporter::getDescription() {
- return "Reports test results in an XML format that looks like Ant's junitreport target";
- }
-
- void JunitReporter::noMatchingTestCases( std::string const& /*spec*/ ) {}
-
- void JunitReporter::testRunStarting( TestRunInfo const& runInfo ) {
- CumulativeReporterBase::testRunStarting( runInfo );
- xml.startElement( "testsuites" );
- }
-
- void JunitReporter::testGroupStarting( GroupInfo const& groupInfo ) {
- suiteTimer.start();
- stdOutForSuite.clear();
- stdErrForSuite.clear();
- unexpectedExceptions = 0;
- CumulativeReporterBase::testGroupStarting( groupInfo );
- }
-
- void JunitReporter::testCaseStarting( TestCaseInfo const& testCaseInfo ) {
- m_okToFail = testCaseInfo.okToFail();
- }
-
- bool JunitReporter::assertionEnded( AssertionStats const& assertionStats ) {
- if( assertionStats.assertionResult.getResultType() == ResultWas::ThrewException && !m_okToFail )
- unexpectedExceptions++;
- return CumulativeReporterBase::assertionEnded( assertionStats );
- }
-
- void JunitReporter::testCaseEnded( TestCaseStats const& testCaseStats ) {
- stdOutForSuite += testCaseStats.stdOut;
- stdErrForSuite += testCaseStats.stdErr;
- CumulativeReporterBase::testCaseEnded( testCaseStats );
- }
-
- void JunitReporter::testGroupEnded( TestGroupStats const& testGroupStats ) {
- double suiteTime = suiteTimer.getElapsedSeconds();
- CumulativeReporterBase::testGroupEnded( testGroupStats );
- writeGroup( *m_testGroups.back(), suiteTime );
- }
-
- void JunitReporter::testRunEndedCumulative() {
- xml.endElement();
- }
-
- void JunitReporter::writeGroup( TestGroupNode const& groupNode, double suiteTime ) {
- XmlWriter::ScopedElement e = xml.scopedElement( "testsuite" );
-
- TestGroupStats const& stats = groupNode.value;
- xml.writeAttribute( "name", stats.groupInfo.name );
- xml.writeAttribute( "errors", unexpectedExceptions );
- xml.writeAttribute( "failures", stats.totals.assertions.failed-unexpectedExceptions );
- xml.writeAttribute( "tests", stats.totals.assertions.total() );
- xml.writeAttribute( "hostname", "tbd" ); // !TBD
- if( m_config->showDurations() == ShowDurations::Never )
- xml.writeAttribute( "time", "" );
- else
- xml.writeAttribute( "time", suiteTime );
- xml.writeAttribute( "timestamp", getCurrentTimestamp() );
-
- // Write properties if there are any
- if (m_config->hasTestFilters() || m_config->rngSeed() != 0) {
- auto properties = xml.scopedElement("properties");
- if (m_config->hasTestFilters()) {
- xml.scopedElement("property")
- .writeAttribute("name", "filters")
- .writeAttribute("value", serializeFilters(m_config->getTestsOrTags()));
- }
- if (m_config->rngSeed() != 0) {
- xml.scopedElement("property")
- .writeAttribute("name", "random-seed")
- .writeAttribute("value", m_config->rngSeed());
- }
- }
-
- // Write test cases
- for( auto const& child : groupNode.children )
- writeTestCase( *child );
-
- xml.scopedElement( "system-out" ).writeText( trim( stdOutForSuite ), false );
- xml.scopedElement( "system-err" ).writeText( trim( stdErrForSuite ), false );
- }
-
- void JunitReporter::writeTestCase( TestCaseNode const& testCaseNode ) {
- TestCaseStats const& stats = testCaseNode.value;
-
- // All test cases have exactly one section - which represents the
- // test case itself. That section may have 0-n nested sections
- assert( testCaseNode.children.size() == 1 );
- SectionNode const& rootSection = *testCaseNode.children.front();
-
- std::string className = stats.testInfo.className;
-
- if( className.empty() ) {
- className = fileNameTag(stats.testInfo.tags);
- if ( className.empty() )
- className = "global";
- }
-
- if ( !m_config->name().empty() )
- className = m_config->name() + "." + className;
-
- writeSection( className, "", rootSection );
- }
-
- void JunitReporter::writeSection( std::string const& className,
- std::string const& rootName,
- SectionNode const& sectionNode ) {
- std::string name = trim( sectionNode.stats.sectionInfo.name );
- if( !rootName.empty() )
- name = rootName + '/' + name;
-
- if( !sectionNode.assertions.empty() ||
- !sectionNode.stdOut.empty() ||
- !sectionNode.stdErr.empty() ) {
- XmlWriter::ScopedElement e = xml.scopedElement( "testcase" );
- if( className.empty() ) {
- xml.writeAttribute( "classname", name );
- xml.writeAttribute( "name", "root" );
- }
- else {
- xml.writeAttribute( "classname", className );
- xml.writeAttribute( "name", name );
- }
- xml.writeAttribute( "time", ::Catch::Detail::stringify( sectionNode.stats.durationInSeconds ) );
-
- writeAssertions( sectionNode );
-
- if( !sectionNode.stdOut.empty() )
- xml.scopedElement( "system-out" ).writeText( trim( sectionNode.stdOut ), false );
- if( !sectionNode.stdErr.empty() )
- xml.scopedElement( "system-err" ).writeText( trim( sectionNode.stdErr ), false );
- }
- for( auto const& childNode : sectionNode.childSections )
- if( className.empty() )
- writeSection( name, "", *childNode );
- else
- writeSection( className, name, *childNode );
- }
-
- void JunitReporter::writeAssertions( SectionNode const& sectionNode ) {
- for( auto const& assertion : sectionNode.assertions )
- writeAssertion( assertion );
- }
-
- void JunitReporter::writeAssertion( AssertionStats const& stats ) {
- AssertionResult const& result = stats.assertionResult;
- if( !result.isOk() ) {
- std::string elementName;
- switch( result.getResultType() ) {
- case ResultWas::ThrewException:
- case ResultWas::FatalErrorCondition:
- elementName = "error";
- break;
- case ResultWas::ExplicitFailure:
- elementName = "failure";
- break;
- case ResultWas::ExpressionFailed:
- elementName = "failure";
- break;
- case ResultWas::DidntThrowException:
- elementName = "failure";
- break;
-
- // We should never see these here:
- case ResultWas::Info:
- case ResultWas::Warning:
- case ResultWas::Ok:
- case ResultWas::Unknown:
- case ResultWas::FailureBit:
- case ResultWas::Exception:
- elementName = "internalError";
- break;
- }
-
- XmlWriter::ScopedElement e = xml.scopedElement( elementName );
-
- xml.writeAttribute( "message", result.getExpandedExpression() );
- xml.writeAttribute( "type", result.getTestMacroName() );
-
- ReusableStringStream rss;
- if( !result.getMessage().empty() )
- rss << result.getMessage() << '\n';
- for( auto const& msg : stats.infoMessages )
- if( msg.type == ResultWas::Info )
- rss << msg.message << '\n';
-
- rss << "at " << result.getSourceInfo();
- xml.writeText( rss.str(), false );
- }
- }
-
- CATCH_REGISTER_REPORTER( "junit", JunitReporter )
-
-} // end namespace Catch
-// end catch_reporter_junit.cpp
-// start catch_reporter_listening.cpp
-
-#include <cassert>
-
-namespace Catch {
-
- ListeningReporter::ListeningReporter() {
- // We will assume that listeners will always want all assertions
- m_preferences.shouldReportAllAssertions = true;
- }
-
- void ListeningReporter::addListener( IStreamingReporterPtr&& listener ) {
- m_listeners.push_back( std::move( listener ) );
- }
-
- void ListeningReporter::addReporter(IStreamingReporterPtr&& reporter) {
- assert(!m_reporter && "Listening reporter can wrap only 1 real reporter");
- m_reporter = std::move( reporter );
- m_preferences.shouldRedirectStdOut = m_reporter->getPreferences().shouldRedirectStdOut;
- }
-
- ReporterPreferences ListeningReporter::getPreferences() const {
- return m_preferences;
- }
-
- std::set<Verbosity> ListeningReporter::getSupportedVerbosities() {
- return std::set<Verbosity>{ };
- }
-
- void ListeningReporter::noMatchingTestCases( std::string const& spec ) {
- for ( auto const& listener : m_listeners ) {
- listener->noMatchingTestCases( spec );
- }
- m_reporter->noMatchingTestCases( spec );
- }
-
-#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
- void ListeningReporter::benchmarkPreparing( std::string const& name ) {
- for (auto const& listener : m_listeners) {
- listener->benchmarkPreparing(name);
- }
- m_reporter->benchmarkPreparing(name);
- }
- void ListeningReporter::benchmarkStarting( BenchmarkInfo const& benchmarkInfo ) {
- for ( auto const& listener : m_listeners ) {
- listener->benchmarkStarting( benchmarkInfo );
- }
- m_reporter->benchmarkStarting( benchmarkInfo );
- }
- void ListeningReporter::benchmarkEnded( BenchmarkStats<> const& benchmarkStats ) {
- for ( auto const& listener : m_listeners ) {
- listener->benchmarkEnded( benchmarkStats );
- }
- m_reporter->benchmarkEnded( benchmarkStats );
- }
-
- void ListeningReporter::benchmarkFailed( std::string const& error ) {
- for (auto const& listener : m_listeners) {
- listener->benchmarkFailed(error);
- }
- m_reporter->benchmarkFailed(error);
- }
-#endif // CATCH_CONFIG_ENABLE_BENCHMARKING
-
- void ListeningReporter::testRunStarting( TestRunInfo const& testRunInfo ) {
- for ( auto const& listener : m_listeners ) {
- listener->testRunStarting( testRunInfo );
- }
- m_reporter->testRunStarting( testRunInfo );
- }
-
- void ListeningReporter::testGroupStarting( GroupInfo const& groupInfo ) {
- for ( auto const& listener : m_listeners ) {
- listener->testGroupStarting( groupInfo );
- }
- m_reporter->testGroupStarting( groupInfo );
- }
-
- void ListeningReporter::testCaseStarting( TestCaseInfo const& testInfo ) {
- for ( auto const& listener : m_listeners ) {
- listener->testCaseStarting( testInfo );
- }
- m_reporter->testCaseStarting( testInfo );
- }
-
- void ListeningReporter::sectionStarting( SectionInfo const& sectionInfo ) {
- for ( auto const& listener : m_listeners ) {
- listener->sectionStarting( sectionInfo );
- }
- m_reporter->sectionStarting( sectionInfo );
- }
-
- void ListeningReporter::assertionStarting( AssertionInfo const& assertionInfo ) {
- for ( auto const& listener : m_listeners ) {
- listener->assertionStarting( assertionInfo );
- }
- m_reporter->assertionStarting( assertionInfo );
- }
-
- // The return value indicates if the messages buffer should be cleared:
- bool ListeningReporter::assertionEnded( AssertionStats const& assertionStats ) {
- for( auto const& listener : m_listeners ) {
- static_cast<void>( listener->assertionEnded( assertionStats ) );
- }
- return m_reporter->assertionEnded( assertionStats );
- }
-
- void ListeningReporter::sectionEnded( SectionStats const& sectionStats ) {
- for ( auto const& listener : m_listeners ) {
- listener->sectionEnded( sectionStats );
- }
- m_reporter->sectionEnded( sectionStats );
- }
-
- void ListeningReporter::testCaseEnded( TestCaseStats const& testCaseStats ) {
- for ( auto const& listener : m_listeners ) {
- listener->testCaseEnded( testCaseStats );
- }
- m_reporter->testCaseEnded( testCaseStats );
- }
-
- void ListeningReporter::testGroupEnded( TestGroupStats const& testGroupStats ) {
- for ( auto const& listener : m_listeners ) {
- listener->testGroupEnded( testGroupStats );
- }
- m_reporter->testGroupEnded( testGroupStats );
- }
-
- void ListeningReporter::testRunEnded( TestRunStats const& testRunStats ) {
- for ( auto const& listener : m_listeners ) {
- listener->testRunEnded( testRunStats );
- }
- m_reporter->testRunEnded( testRunStats );
- }
-
- void ListeningReporter::skipTest( TestCaseInfo const& testInfo ) {
- for ( auto const& listener : m_listeners ) {
- listener->skipTest( testInfo );
- }
- m_reporter->skipTest( testInfo );
- }
-
- bool ListeningReporter::isMulti() const {
- return true;
- }
-
-} // end namespace Catch
-// end catch_reporter_listening.cpp
-// start catch_reporter_xml.cpp
-
-#if defined(_MSC_VER)
-#pragma warning(push)
-#pragma warning(disable:4061) // Not all labels are EXPLICITLY handled in switch
- // Note that 4062 (not all labels are handled
- // and default is missing) is enabled
-#endif
-
-namespace Catch {
- XmlReporter::XmlReporter( ReporterConfig const& _config )
- : StreamingReporterBase( _config ),
- m_xml(_config.stream())
- {
- m_reporterPrefs.shouldRedirectStdOut = true;
- m_reporterPrefs.shouldReportAllAssertions = true;
- }
-
- XmlReporter::~XmlReporter() = default;
-
- std::string XmlReporter::getDescription() {
- return "Reports test results as an XML document";
- }
-
- std::string XmlReporter::getStylesheetRef() const {
- return std::string();
- }
-
- void XmlReporter::writeSourceInfo( SourceLineInfo const& sourceInfo ) {
- m_xml
- .writeAttribute( "filename", sourceInfo.file )
- .writeAttribute( "line", sourceInfo.line );
- }
-
- void XmlReporter::noMatchingTestCases( std::string const& s ) {
- StreamingReporterBase::noMatchingTestCases( s );
- }
-
- void XmlReporter::testRunStarting( TestRunInfo const& testInfo ) {
- StreamingReporterBase::testRunStarting( testInfo );
- std::string stylesheetRef = getStylesheetRef();
- if( !stylesheetRef.empty() )
- m_xml.writeStylesheetRef( stylesheetRef );
- m_xml.startElement( "Catch" );
- if( !m_config->name().empty() )
- m_xml.writeAttribute( "name", m_config->name() );
- if (m_config->testSpec().hasFilters())
- m_xml.writeAttribute( "filters", serializeFilters( m_config->getTestsOrTags() ) );
- if( m_config->rngSeed() != 0 )
- m_xml.scopedElement( "Randomness" )
- .writeAttribute( "seed", m_config->rngSeed() );
- }
-
- void XmlReporter::testGroupStarting( GroupInfo const& groupInfo ) {
- StreamingReporterBase::testGroupStarting( groupInfo );
- m_xml.startElement( "Group" )
- .writeAttribute( "name", groupInfo.name );
- }
-
- void XmlReporter::testCaseStarting( TestCaseInfo const& testInfo ) {
- StreamingReporterBase::testCaseStarting(testInfo);
- m_xml.startElement( "TestCase" )
- .writeAttribute( "name", trim( testInfo.name ) )
- .writeAttribute( "description", testInfo.description )
- .writeAttribute( "tags", testInfo.tagsAsString() );
-
- writeSourceInfo( testInfo.lineInfo );
-
- if ( m_config->showDurations() == ShowDurations::Always )
- m_testCaseTimer.start();
- m_xml.ensureTagClosed();
- }
-
- void XmlReporter::sectionStarting( SectionInfo const& sectionInfo ) {
- StreamingReporterBase::sectionStarting( sectionInfo );
- if( m_sectionDepth++ > 0 ) {
- m_xml.startElement( "Section" )
- .writeAttribute( "name", trim( sectionInfo.name ) );
- writeSourceInfo( sectionInfo.lineInfo );
- m_xml.ensureTagClosed();
- }
- }
-
- void XmlReporter::assertionStarting( AssertionInfo const& ) { }
-
- bool XmlReporter::assertionEnded( AssertionStats const& assertionStats ) {
-
- AssertionResult const& result = assertionStats.assertionResult;
-
- bool includeResults = m_config->includeSuccessfulResults() || !result.isOk();
-
- if( includeResults || result.getResultType() == ResultWas::Warning ) {
- // Print any info messages in <Info> tags.
- for( auto const& msg : assertionStats.infoMessages ) {
- if( msg.type == ResultWas::Info && includeResults ) {
- m_xml.scopedElement( "Info" )
- .writeText( msg.message );
- } else if ( msg.type == ResultWas::Warning ) {
- m_xml.scopedElement( "Warning" )
- .writeText( msg.message );
- }
- }
- }
-
- // Drop out if result was successful but we're not printing them.
- if( !includeResults && result.getResultType() != ResultWas::Warning )
- return true;
-
- // Print the expression if there is one.
- if( result.hasExpression() ) {
- m_xml.startElement( "Expression" )
- .writeAttribute( "success", result.succeeded() )
- .writeAttribute( "type", result.getTestMacroName() );
-
- writeSourceInfo( result.getSourceInfo() );
-
- m_xml.scopedElement( "Original" )
- .writeText( result.getExpression() );
- m_xml.scopedElement( "Expanded" )
- .writeText( result.getExpandedExpression() );
- }
-
- // And... Print a result applicable to each result type.
- switch( result.getResultType() ) {
- case ResultWas::ThrewException:
- m_xml.startElement( "Exception" );
- writeSourceInfo( result.getSourceInfo() );
- m_xml.writeText( result.getMessage() );
- m_xml.endElement();
- break;
- case ResultWas::FatalErrorCondition:
- m_xml.startElement( "FatalErrorCondition" );
- writeSourceInfo( result.getSourceInfo() );
- m_xml.writeText( result.getMessage() );
- m_xml.endElement();
- break;
- case ResultWas::Info:
- m_xml.scopedElement( "Info" )
- .writeText( result.getMessage() );
- break;
- case ResultWas::Warning:
- // Warning will already have been written
- break;
- case ResultWas::ExplicitFailure:
- m_xml.startElement( "Failure" );
- writeSourceInfo( result.getSourceInfo() );
- m_xml.writeText( result.getMessage() );
- m_xml.endElement();
- break;
- default:
- break;
- }
-
- if( result.hasExpression() )
- m_xml.endElement();
-
- return true;
- }
-
- void XmlReporter::sectionEnded( SectionStats const& sectionStats ) {
- StreamingReporterBase::sectionEnded( sectionStats );
- if( --m_sectionDepth > 0 ) {
- XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResults" );
- e.writeAttribute( "successes", sectionStats.assertions.passed );
- e.writeAttribute( "failures", sectionStats.assertions.failed );
- e.writeAttribute( "expectedFailures", sectionStats.assertions.failedButOk );
-
- if ( m_config->showDurations() == ShowDurations::Always )
- e.writeAttribute( "durationInSeconds", sectionStats.durationInSeconds );
-
- m_xml.endElement();
- }
- }
-
- void XmlReporter::testCaseEnded( TestCaseStats const& testCaseStats ) {
- StreamingReporterBase::testCaseEnded( testCaseStats );
- XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResult" );
- e.writeAttribute( "success", testCaseStats.totals.assertions.allOk() );
-
- if ( m_config->showDurations() == ShowDurations::Always )
- e.writeAttribute( "durationInSeconds", m_testCaseTimer.getElapsedSeconds() );
-
- if( !testCaseStats.stdOut.empty() )
- m_xml.scopedElement( "StdOut" ).writeText( trim( testCaseStats.stdOut ), false );
- if( !testCaseStats.stdErr.empty() )
- m_xml.scopedElement( "StdErr" ).writeText( trim( testCaseStats.stdErr ), false );
-
- m_xml.endElement();
- }
-
- void XmlReporter::testGroupEnded( TestGroupStats const& testGroupStats ) {
- StreamingReporterBase::testGroupEnded( testGroupStats );
- // TODO: Check testGroupStats.aborting and act accordingly.
- m_xml.scopedElement( "OverallResults" )
- .writeAttribute( "successes", testGroupStats.totals.assertions.passed )
- .writeAttribute( "failures", testGroupStats.totals.assertions.failed )
- .writeAttribute( "expectedFailures", testGroupStats.totals.assertions.failedButOk );
- m_xml.endElement();
- }
-
- void XmlReporter::testRunEnded( TestRunStats const& testRunStats ) {
- StreamingReporterBase::testRunEnded( testRunStats );
- m_xml.scopedElement( "OverallResults" )
- .writeAttribute( "successes", testRunStats.totals.assertions.passed )
- .writeAttribute( "failures", testRunStats.totals.assertions.failed )
- .writeAttribute( "expectedFailures", testRunStats.totals.assertions.failedButOk );
- m_xml.endElement();
- }
-
-#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
- void XmlReporter::benchmarkStarting(BenchmarkInfo const &info) {
- m_xml.startElement("BenchmarkResults")
- .writeAttribute("name", info.name)
- .writeAttribute("samples", info.samples)
- .writeAttribute("resamples", info.resamples)
- .writeAttribute("iterations", info.iterations)
- .writeAttribute("clockResolution", static_cast<uint64_t>(info.clockResolution))
- .writeAttribute("estimatedDuration", static_cast<uint64_t>(info.estimatedDuration))
- .writeComment("All values in nano seconds");
- }
-
- void XmlReporter::benchmarkEnded(BenchmarkStats<> const& benchmarkStats) {
- m_xml.startElement("mean")
- .writeAttribute("value", static_cast<uint64_t>(benchmarkStats.mean.point.count()))
- .writeAttribute("lowerBound", static_cast<uint64_t>(benchmarkStats.mean.lower_bound.count()))
- .writeAttribute("upperBound", static_cast<uint64_t>(benchmarkStats.mean.upper_bound.count()))
- .writeAttribute("ci", benchmarkStats.mean.confidence_interval);
- m_xml.endElement();
- m_xml.startElement("standardDeviation")
- .writeAttribute("value", benchmarkStats.standardDeviation.point.count())
- .writeAttribute("lowerBound", benchmarkStats.standardDeviation.lower_bound.count())
- .writeAttribute("upperBound", benchmarkStats.standardDeviation.upper_bound.count())
- .writeAttribute("ci", benchmarkStats.standardDeviation.confidence_interval);
- m_xml.endElement();
- m_xml.startElement("outliers")
- .writeAttribute("variance", benchmarkStats.outlierVariance)
- .writeAttribute("lowMild", benchmarkStats.outliers.low_mild)
- .writeAttribute("lowSevere", benchmarkStats.outliers.low_severe)
- .writeAttribute("highMild", benchmarkStats.outliers.high_mild)
- .writeAttribute("highSevere", benchmarkStats.outliers.high_severe);
- m_xml.endElement();
- m_xml.endElement();
- }
-
- void XmlReporter::benchmarkFailed(std::string const &error) {
- m_xml.scopedElement("failed").
- writeAttribute("message", error);
- m_xml.endElement();
- }
-#endif // CATCH_CONFIG_ENABLE_BENCHMARKING
-
- CATCH_REGISTER_REPORTER( "xml", XmlReporter )
-
-} // end namespace Catch
-
-#if defined(_MSC_VER)
-#pragma warning(pop)
-#endif
-// end catch_reporter_xml.cpp
-
-namespace Catch {
- LeakDetector leakDetector;
-}
-
-#ifdef __clang__
-#pragma clang diagnostic pop
-#endif
-
-// end catch_impl.hpp
-#endif
-
-#ifdef CATCH_CONFIG_MAIN
-// start catch_default_main.hpp
-
-#ifndef __OBJC__
-
-#if defined(CATCH_CONFIG_WCHAR) && defined(WIN32) && defined(_UNICODE) && !defined(DO_NOT_USE_WMAIN)
-// Standard C/C++ Win32 Unicode wmain entry point
-extern "C" int wmain (int argc, wchar_t * argv[], wchar_t * []) {
-#else
-// Standard C/C++ main entry point
-int main (int argc, char * argv[]) {
-#endif
-
- return Catch::Session().run( argc, argv );
-}
-
-#else // __OBJC__
-
-// Objective-C entry point
-int main (int argc, char * const argv[]) {
-#if !CATCH_ARC_ENABLED
- NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
-#endif
-
- Catch::registerTestMethods();
- int result = Catch::Session().run( argc, (char**)argv );
-
-#if !CATCH_ARC_ENABLED
- [pool drain];
-#endif
-
- return result;
-}
-
-#endif // __OBJC__
-
-// end catch_default_main.hpp
-#endif
-
-#if !defined(CATCH_CONFIG_IMPL_ONLY)
-
-#ifdef CLARA_CONFIG_MAIN_NOT_DEFINED
-# undef CLARA_CONFIG_MAIN
-#endif
-
-#if !defined(CATCH_CONFIG_DISABLE)
-//////
-// If this config identifier is defined then all CATCH macros are prefixed with CATCH_
-#ifdef CATCH_CONFIG_PREFIX_ALL
-
-#define CATCH_REQUIRE( ... ) INTERNAL_CATCH_TEST( "CATCH_REQUIRE", Catch::ResultDisposition::Normal, __VA_ARGS__ )
-#define CATCH_REQUIRE_FALSE( ... ) INTERNAL_CATCH_TEST( "CATCH_REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )
-
-#define CATCH_REQUIRE_THROWS( ... ) INTERNAL_CATCH_THROWS( "CATCH_REQUIRE_THROWS", Catch::ResultDisposition::Normal, __VA_ARGS__ )
-#define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CATCH_REQUIRE_THROWS_AS", exceptionType, Catch::ResultDisposition::Normal, expr )
-#define CATCH_REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "CATCH_REQUIRE_THROWS_WITH", Catch::ResultDisposition::Normal, matcher, expr )
-#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
-#define CATCH_REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "CATCH_REQUIRE_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::Normal, matcher, expr )
-#endif// CATCH_CONFIG_DISABLE_MATCHERS
-#define CATCH_REQUIRE_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "CATCH_REQUIRE_NOTHROW", Catch::ResultDisposition::Normal, __VA_ARGS__ )
-
-#define CATCH_CHECK( ... ) INTERNAL_CATCH_TEST( "CATCH_CHECK", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
-#define CATCH_CHECK_FALSE( ... ) INTERNAL_CATCH_TEST( "CATCH_CHECK_FALSE", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )
-#define CATCH_CHECKED_IF( ... ) INTERNAL_CATCH_IF( "CATCH_CHECKED_IF", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
-#define CATCH_CHECKED_ELSE( ... ) INTERNAL_CATCH_ELSE( "CATCH_CHECKED_ELSE", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
-#define CATCH_CHECK_NOFAIL( ... ) INTERNAL_CATCH_TEST( "CATCH_CHECK_NOFAIL", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, __VA_ARGS__ )
-
-#define CATCH_CHECK_THROWS( ... ) INTERNAL_CATCH_THROWS( "CATCH_CHECK_THROWS", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
-#define CATCH_CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CATCH_CHECK_THROWS_AS", exceptionType, Catch::ResultDisposition::ContinueOnFailure, expr )
-#define CATCH_CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "CATCH_CHECK_THROWS_WITH", Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
-#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
-#define CATCH_CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "CATCH_CHECK_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
-#endif // CATCH_CONFIG_DISABLE_MATCHERS
-#define CATCH_CHECK_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "CATCH_CHECK_NOTHROW", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
-
-#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
-#define CATCH_CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CATCH_CHECK_THAT", matcher, Catch::ResultDisposition::ContinueOnFailure, arg )
-
-#define CATCH_REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CATCH_REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg )
-#endif // CATCH_CONFIG_DISABLE_MATCHERS
-
-#define CATCH_INFO( msg ) INTERNAL_CATCH_INFO( "CATCH_INFO", msg )
-#define CATCH_UNSCOPED_INFO( msg ) INTERNAL_CATCH_UNSCOPED_INFO( "CATCH_UNSCOPED_INFO", msg )
-#define CATCH_WARN( msg ) INTERNAL_CATCH_MSG( "CATCH_WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg )
-#define CATCH_CAPTURE( ... ) INTERNAL_CATCH_CAPTURE( INTERNAL_CATCH_UNIQUE_NAME(capturer), "CATCH_CAPTURE",__VA_ARGS__ )
-
-#define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
-#define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )
-#define CATCH_METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
-#define CATCH_REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ )
-#define CATCH_SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
-#define CATCH_DYNAMIC_SECTION( ... ) INTERNAL_CATCH_DYNAMIC_SECTION( __VA_ARGS__ )
-#define CATCH_FAIL( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ )
-#define CATCH_FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
-#define CATCH_SUCCEED( ... ) INTERNAL_CATCH_MSG( "CATCH_SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
-
-#define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE()
-
-#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
-#define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )
-#define CATCH_TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG( __VA_ARGS__ )
-#define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
-#define CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ )
-#define CATCH_TEMPLATE_PRODUCT_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE( __VA_ARGS__ )
-#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( __VA_ARGS__ )
-#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, __VA_ARGS__ )
-#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ )
-#else
-#define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ ) )
-#define CATCH_TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG( __VA_ARGS__ ) )
-#define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ ) )
-#define CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ ) )
-#define CATCH_TEMPLATE_PRODUCT_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE( __VA_ARGS__ ) )
-#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( __VA_ARGS__ ) )
-#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, __VA_ARGS__ ) )
-#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ ) )
-#endif
-
-#if !defined(CATCH_CONFIG_RUNTIME_STATIC_REQUIRE)
-#define CATCH_STATIC_REQUIRE( ... ) static_assert( __VA_ARGS__ , #__VA_ARGS__ ); CATCH_SUCCEED( #__VA_ARGS__ )
-#define CATCH_STATIC_REQUIRE_FALSE( ... ) static_assert( !(__VA_ARGS__), "!(" #__VA_ARGS__ ")" ); CATCH_SUCCEED( #__VA_ARGS__ )
-#else
-#define CATCH_STATIC_REQUIRE( ... ) CATCH_REQUIRE( __VA_ARGS__ )
-#define CATCH_STATIC_REQUIRE_FALSE( ... ) CATCH_REQUIRE_FALSE( __VA_ARGS__ )
-#endif
-
-// "BDD-style" convenience wrappers
-#define CATCH_SCENARIO( ... ) CATCH_TEST_CASE( "Scenario: " __VA_ARGS__ )
-#define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
-#define CATCH_GIVEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " Given: " << desc )
-#define CATCH_AND_GIVEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( "And given: " << desc )
-#define CATCH_WHEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " When: " << desc )
-#define CATCH_AND_WHEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " And when: " << desc )
-#define CATCH_THEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " Then: " << desc )
-#define CATCH_AND_THEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " And: " << desc )
-
-#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
-#define CATCH_BENCHMARK(...) \
- INTERNAL_CATCH_BENCHMARK(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____B_E_N_C_H____), INTERNAL_CATCH_GET_1_ARG(__VA_ARGS__,,), INTERNAL_CATCH_GET_2_ARG(__VA_ARGS__,,))
-#define CATCH_BENCHMARK_ADVANCED(name) \
- INTERNAL_CATCH_BENCHMARK_ADVANCED(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____B_E_N_C_H____), name)
-#endif // CATCH_CONFIG_ENABLE_BENCHMARKING
-
-// If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required
-#else
-
-#define REQUIRE( ... ) INTERNAL_CATCH_TEST( "REQUIRE", Catch::ResultDisposition::Normal, __VA_ARGS__ )
-#define REQUIRE_FALSE( ... ) INTERNAL_CATCH_TEST( "REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )
-
-#define REQUIRE_THROWS( ... ) INTERNAL_CATCH_THROWS( "REQUIRE_THROWS", Catch::ResultDisposition::Normal, __VA_ARGS__ )
-#define REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "REQUIRE_THROWS_AS", exceptionType, Catch::ResultDisposition::Normal, expr )
-#define REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "REQUIRE_THROWS_WITH", Catch::ResultDisposition::Normal, matcher, expr )
-#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
-#define REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "REQUIRE_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::Normal, matcher, expr )
-#endif // CATCH_CONFIG_DISABLE_MATCHERS
-#define REQUIRE_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "REQUIRE_NOTHROW", Catch::ResultDisposition::Normal, __VA_ARGS__ )
-
-#define CHECK( ... ) INTERNAL_CATCH_TEST( "CHECK", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
-#define CHECK_FALSE( ... ) INTERNAL_CATCH_TEST( "CHECK_FALSE", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )
-#define CHECKED_IF( ... ) INTERNAL_CATCH_IF( "CHECKED_IF", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
-#define CHECKED_ELSE( ... ) INTERNAL_CATCH_ELSE( "CHECKED_ELSE", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
-#define CHECK_NOFAIL( ... ) INTERNAL_CATCH_TEST( "CHECK_NOFAIL", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, __VA_ARGS__ )
-
-#define CHECK_THROWS( ... ) INTERNAL_CATCH_THROWS( "CHECK_THROWS", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
-#define CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CHECK_THROWS_AS", exceptionType, Catch::ResultDisposition::ContinueOnFailure, expr )
-#define CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "CHECK_THROWS_WITH", Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
-#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
-#define CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "CHECK_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
-#endif // CATCH_CONFIG_DISABLE_MATCHERS
-#define CHECK_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "CHECK_NOTHROW", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
-
-#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
-#define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CHECK_THAT", matcher, Catch::ResultDisposition::ContinueOnFailure, arg )
-
-#define REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg )
-#endif // CATCH_CONFIG_DISABLE_MATCHERS
-
-#define INFO( msg ) INTERNAL_CATCH_INFO( "INFO", msg )
-#define UNSCOPED_INFO( msg ) INTERNAL_CATCH_UNSCOPED_INFO( "UNSCOPED_INFO", msg )
-#define WARN( msg ) INTERNAL_CATCH_MSG( "WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg )
-#define CAPTURE( ... ) INTERNAL_CATCH_CAPTURE( INTERNAL_CATCH_UNIQUE_NAME(capturer), "CAPTURE",__VA_ARGS__ )
-
-#define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
-#define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )
-#define METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
-#define REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ )
-#define SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
-#define DYNAMIC_SECTION( ... ) INTERNAL_CATCH_DYNAMIC_SECTION( __VA_ARGS__ )
-#define FAIL( ... ) INTERNAL_CATCH_MSG( "FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ )
-#define FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( "FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
-#define SUCCEED( ... ) INTERNAL_CATCH_MSG( "SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
-#define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE()
-
-#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
-#define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )
-#define TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG( __VA_ARGS__ )
-#define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
-#define TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ )
-#define TEMPLATE_PRODUCT_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE( __VA_ARGS__ )
-#define TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( __VA_ARGS__ )
-#define TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, __VA_ARGS__ )
-#define TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ )
-#define TEMPLATE_LIST_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE(__VA_ARGS__)
-#define TEMPLATE_LIST_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD( className, __VA_ARGS__ )
-#else
-#define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ ) )
-#define TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG( __VA_ARGS__ ) )
-#define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ ) )
-#define TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ ) )
-#define TEMPLATE_PRODUCT_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE( __VA_ARGS__ ) )
-#define TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( __VA_ARGS__ ) )
-#define TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, __VA_ARGS__ ) )
-#define TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ ) )
-#define TEMPLATE_LIST_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE( __VA_ARGS__ ) )
-#define TEMPLATE_LIST_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD( className, __VA_ARGS__ ) )
-#endif
-
-#if !defined(CATCH_CONFIG_RUNTIME_STATIC_REQUIRE)
-#define STATIC_REQUIRE( ... ) static_assert( __VA_ARGS__, #__VA_ARGS__ ); SUCCEED( #__VA_ARGS__ )
-#define STATIC_REQUIRE_FALSE( ... ) static_assert( !(__VA_ARGS__), "!(" #__VA_ARGS__ ")" ); SUCCEED( "!(" #__VA_ARGS__ ")" )
-#else
-#define STATIC_REQUIRE( ... ) REQUIRE( __VA_ARGS__ )
-#define STATIC_REQUIRE_FALSE( ... ) REQUIRE_FALSE( __VA_ARGS__ )
-#endif
-
-#endif
-
-#define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature )
-
-// "BDD-style" convenience wrappers
-#define SCENARIO( ... ) TEST_CASE( "Scenario: " __VA_ARGS__ )
-#define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
-
-#define GIVEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " Given: " << desc )
-#define AND_GIVEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( "And given: " << desc )
-#define WHEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " When: " << desc )
-#define AND_WHEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " And when: " << desc )
-#define THEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " Then: " << desc )
-#define AND_THEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " And: " << desc )
-
-#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
-#define BENCHMARK(...) \
- INTERNAL_CATCH_BENCHMARK(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____B_E_N_C_H____), INTERNAL_CATCH_GET_1_ARG(__VA_ARGS__,,), INTERNAL_CATCH_GET_2_ARG(__VA_ARGS__,,))
-#define BENCHMARK_ADVANCED(name) \
- INTERNAL_CATCH_BENCHMARK_ADVANCED(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____B_E_N_C_H____), name)
-#endif // CATCH_CONFIG_ENABLE_BENCHMARKING
-
-using Catch::Detail::Approx;
-
-#else // CATCH_CONFIG_DISABLE
-
-//////
-// If this config identifier is defined then all CATCH macros are prefixed with CATCH_
-#ifdef CATCH_CONFIG_PREFIX_ALL
-
-#define CATCH_REQUIRE( ... ) (void)(0)
-#define CATCH_REQUIRE_FALSE( ... ) (void)(0)
-
-#define CATCH_REQUIRE_THROWS( ... ) (void)(0)
-#define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) (void)(0)
-#define CATCH_REQUIRE_THROWS_WITH( expr, matcher ) (void)(0)
-#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
-#define CATCH_REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
-#endif// CATCH_CONFIG_DISABLE_MATCHERS
-#define CATCH_REQUIRE_NOTHROW( ... ) (void)(0)
-
-#define CATCH_CHECK( ... ) (void)(0)
-#define CATCH_CHECK_FALSE( ... ) (void)(0)
-#define CATCH_CHECKED_IF( ... ) if (__VA_ARGS__)
-#define CATCH_CHECKED_ELSE( ... ) if (!(__VA_ARGS__))
-#define CATCH_CHECK_NOFAIL( ... ) (void)(0)
-
-#define CATCH_CHECK_THROWS( ... ) (void)(0)
-#define CATCH_CHECK_THROWS_AS( expr, exceptionType ) (void)(0)
-#define CATCH_CHECK_THROWS_WITH( expr, matcher ) (void)(0)
-#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
-#define CATCH_CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
-#endif // CATCH_CONFIG_DISABLE_MATCHERS
-#define CATCH_CHECK_NOTHROW( ... ) (void)(0)
-
-#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
-#define CATCH_CHECK_THAT( arg, matcher ) (void)(0)
-
-#define CATCH_REQUIRE_THAT( arg, matcher ) (void)(0)
-#endif // CATCH_CONFIG_DISABLE_MATCHERS
-
-#define CATCH_INFO( msg ) (void)(0)
-#define CATCH_UNSCOPED_INFO( msg ) (void)(0)
-#define CATCH_WARN( msg ) (void)(0)
-#define CATCH_CAPTURE( msg ) (void)(0)
-
-#define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
-#define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
-#define CATCH_METHOD_AS_TEST_CASE( method, ... )
-#define CATCH_REGISTER_TEST_CASE( Function, ... ) (void)(0)
-#define CATCH_SECTION( ... )
-#define CATCH_DYNAMIC_SECTION( ... )
-#define CATCH_FAIL( ... ) (void)(0)
-#define CATCH_FAIL_CHECK( ... ) (void)(0)
-#define CATCH_SUCCEED( ... ) (void)(0)
-
-#define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
-
-#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
-#define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__)
-#define CATCH_TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(__VA_ARGS__)
-#define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(className, __VA_ARGS__)
-#define CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION(className, __VA_ARGS__ )
-#define CATCH_TEMPLATE_PRODUCT_TEST_CASE( ... ) CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )
-#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )
-#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
-#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
-#else
-#define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__) )
-#define CATCH_TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(__VA_ARGS__) )
-#define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(className, __VA_ARGS__ ) )
-#define CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION(className, __VA_ARGS__ ) )
-#define CATCH_TEMPLATE_PRODUCT_TEST_CASE( ... ) CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )
-#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )
-#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
-#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
-#endif
-
-// "BDD-style" convenience wrappers
-#define CATCH_SCENARIO( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
-#define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), className )
-#define CATCH_GIVEN( desc )
-#define CATCH_AND_GIVEN( desc )
-#define CATCH_WHEN( desc )
-#define CATCH_AND_WHEN( desc )
-#define CATCH_THEN( desc )
-#define CATCH_AND_THEN( desc )
-
-#define CATCH_STATIC_REQUIRE( ... ) (void)(0)
-#define CATCH_STATIC_REQUIRE_FALSE( ... ) (void)(0)
-
-// If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required
-#else
-
-#define REQUIRE( ... ) (void)(0)
-#define REQUIRE_FALSE( ... ) (void)(0)
-
-#define REQUIRE_THROWS( ... ) (void)(0)
-#define REQUIRE_THROWS_AS( expr, exceptionType ) (void)(0)
-#define REQUIRE_THROWS_WITH( expr, matcher ) (void)(0)
-#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
-#define REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
-#endif // CATCH_CONFIG_DISABLE_MATCHERS
-#define REQUIRE_NOTHROW( ... ) (void)(0)
-
-#define CHECK( ... ) (void)(0)
-#define CHECK_FALSE( ... ) (void)(0)
-#define CHECKED_IF( ... ) if (__VA_ARGS__)
-#define CHECKED_ELSE( ... ) if (!(__VA_ARGS__))
-#define CHECK_NOFAIL( ... ) (void)(0)
-
-#define CHECK_THROWS( ... ) (void)(0)
-#define CHECK_THROWS_AS( expr, exceptionType ) (void)(0)
-#define CHECK_THROWS_WITH( expr, matcher ) (void)(0)
-#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
-#define CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
-#endif // CATCH_CONFIG_DISABLE_MATCHERS
-#define CHECK_NOTHROW( ... ) (void)(0)
-
-#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
-#define CHECK_THAT( arg, matcher ) (void)(0)
-
-#define REQUIRE_THAT( arg, matcher ) (void)(0)
-#endif // CATCH_CONFIG_DISABLE_MATCHERS
-
-#define INFO( msg ) (void)(0)
-#define UNSCOPED_INFO( msg ) (void)(0)
-#define WARN( msg ) (void)(0)
-#define CAPTURE( msg ) (void)(0)
-
-#define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
-#define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
-#define METHOD_AS_TEST_CASE( method, ... )
-#define REGISTER_TEST_CASE( Function, ... ) (void)(0)
-#define SECTION( ... )
-#define DYNAMIC_SECTION( ... )
-#define FAIL( ... ) (void)(0)
-#define FAIL_CHECK( ... ) (void)(0)
-#define SUCCEED( ... ) (void)(0)
-#define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
-
-#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
-#define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__)
-#define TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(__VA_ARGS__)
-#define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(className, __VA_ARGS__)
-#define TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION(className, __VA_ARGS__ )
-#define TEMPLATE_PRODUCT_TEST_CASE( ... ) TEMPLATE_TEST_CASE( __VA_ARGS__ )
-#define TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) TEMPLATE_TEST_CASE( __VA_ARGS__ )
-#define TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
-#define TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
-#else
-#define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__) )
-#define TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(__VA_ARGS__) )
-#define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(className, __VA_ARGS__ ) )
-#define TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION(className, __VA_ARGS__ ) )
-#define TEMPLATE_PRODUCT_TEST_CASE( ... ) TEMPLATE_TEST_CASE( __VA_ARGS__ )
-#define TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) TEMPLATE_TEST_CASE( __VA_ARGS__ )
-#define TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
-#define TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
-#endif
-
-#define STATIC_REQUIRE( ... ) (void)(0)
-#define STATIC_REQUIRE_FALSE( ... ) (void)(0)
-
-#endif
-
-#define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION_NO_REG( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature )
-
-// "BDD-style" convenience wrappers
-#define SCENARIO( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ) )
-#define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), className )
-
-#define GIVEN( desc )
-#define AND_GIVEN( desc )
-#define WHEN( desc )
-#define AND_WHEN( desc )
-#define THEN( desc )
-#define AND_THEN( desc )
-
-using Catch::Detail::Approx;
-
-#endif
-
-#endif // ! CATCH_CONFIG_IMPL_ONLY
-
-// start catch_reenable_warnings.h
-
-
-#ifdef __clang__
-# ifdef __ICC // icpc defines the __clang__ macro
-# pragma warning(pop)
-# else
-# pragma clang diagnostic pop
-# endif
-#elif defined __GNUC__
-# pragma GCC diagnostic pop
-#endif
-
-// end catch_reenable_warnings.h
-// end catch.hpp
-#endif // TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
-
diff --git a/toolsrc/include/pch.h b/toolsrc/include/pch.h
deleted file mode 100644
index b22c0a140..000000000
--- a/toolsrc/include/pch.h
+++ /dev/null
@@ -1,55 +0,0 @@
-#pragma once
-
-#include <vcpkg/base/system_headers.h>
-
-#include <vcpkg/base/files.h>
-#include <vcpkg/base/pragmas.h>
-
-#if defined(_WIN32)
-#include <process.h>
-#include <shellapi.h>
-#include <winhttp.h>
-#endif
-
-#include <math.h>
-#include <stdarg.h>
-#include <stddef.h>
-#include <stdint.h>
-#include <string.h>
-
-#include <algorithm>
-#include <array>
-#include <atomic>
-#include <cassert>
-#include <cctype>
-#include <chrono>
-#include <codecvt>
-#include <fstream>
-#include <functional>
-#include <iomanip>
-#include <iostream>
-#include <iterator>
-#include <limits>
-#include <map>
-#include <memory>
-#include <mutex>
-#include <random>
-#include <regex>
-#include <set>
-#include <stdexcept>
-#include <string>
-#if defined(_WIN32)
-#include <sys/timeb.h>
-#else
-#include <sys/time.h>
-#endif
-
-#include <time.h>
-
-#include <system_error>
-#include <thread>
-#include <type_traits>
-#include <unordered_map>
-#include <unordered_set>
-#include <utility>
-#include <vector>
diff --git a/toolsrc/include/vcpkg-test/mockcmakevarprovider.h b/toolsrc/include/vcpkg-test/mockcmakevarprovider.h
deleted file mode 100644
index 6017457b6..000000000
--- a/toolsrc/include/vcpkg-test/mockcmakevarprovider.h
+++ /dev/null
@@ -1,42 +0,0 @@
-#pragma once
-
-#include <vcpkg/cmakevars.h>
-
-namespace vcpkg::Test
-{
- struct MockCMakeVarProvider : CMakeVars::CMakeVarProvider
- {
- using SMap = std::unordered_map<std::string, std::string>;
- void load_generic_triplet_vars(Triplet triplet) const override
- {
- generic_triplet_vars.emplace(triplet, SMap{});
- }
-
- void load_dep_info_vars(Span<const PackageSpec> specs) const override
- {
- for (auto&& spec : specs)
- dep_info_vars.emplace(spec, SMap{});
- }
-
- void load_tag_vars(Span<const FullPackageSpec> specs,
- const PortFileProvider::PortFileProvider& port_provider) const override
- {
- for (auto&& spec : specs)
- tag_vars.emplace(spec.package_spec, SMap{});
- (void)(port_provider);
- }
-
- Optional<const std::unordered_map<std::string, std::string>&> get_generic_triplet_vars(
- Triplet triplet) const override;
-
- Optional<const std::unordered_map<std::string, std::string>&> get_dep_info_vars(
- const PackageSpec& spec) const override;
-
- Optional<const std::unordered_map<std::string, std::string>&> get_tag_vars(
- const PackageSpec& spec) const override;
-
- mutable std::unordered_map<PackageSpec, std::unordered_map<std::string, std::string>> dep_info_vars;
- mutable std::unordered_map<PackageSpec, std::unordered_map<std::string, std::string>> tag_vars;
- mutable std::unordered_map<Triplet, std::unordered_map<std::string, std::string>> generic_triplet_vars;
- };
-}
diff --git a/toolsrc/include/vcpkg-test/util.h b/toolsrc/include/vcpkg-test/util.h
deleted file mode 100644
index 1e20531fc..000000000
--- a/toolsrc/include/vcpkg-test/util.h
+++ /dev/null
@@ -1,132 +0,0 @@
-#include <vcpkg/base/system_headers.h>
-
-#include <catch2/catch.hpp>
-
-#include <vcpkg/base/files.h>
-#include <vcpkg/base/pragmas.h>
-
-#include <vcpkg/statusparagraph.h>
-
-#include <memory>
-
-#define CHECK_EC(ec) \
- do \
- { \
- if (ec) \
- { \
- FAIL(ec.message()); \
- } \
- } while (0)
-
-namespace Catch
-{
- template<>
- struct StringMaker<vcpkg::FullPackageSpec>
- {
- static std::string convert(vcpkg::FullPackageSpec const& value)
- {
- return vcpkg::Strings::concat(value.package_spec.name(),
- '[',
- vcpkg::Strings::join(",", value.features),
- "]:",
- value.package_spec.triplet());
- }
- };
-
- template<>
- struct StringMaker<vcpkg::Triplet>
- {
- static const std::string& convert(const vcpkg::Triplet& triplet) { return triplet.canonical_name(); }
- };
-}
-
-namespace vcpkg::Test
-{
- std::unique_ptr<SourceControlFile> make_control_file(
- const char* name,
- const char* depends,
- const std::vector<std::pair<const char*, const char*>>& features = {},
- const std::vector<const char*>& default_features = {});
-
- inline auto test_parse_control_file(const std::vector<std::unordered_map<std::string, std::string>>& v)
- {
- std::vector<vcpkg::Parse::Paragraph> pghs;
- for (auto&& p : v)
- {
- pghs.emplace_back();
- for (auto&& kv : p)
- pghs.back().emplace(kv.first, std::make_pair(kv.second, vcpkg::Parse::TextRowCol{}));
- }
- return vcpkg::SourceControlFile::parse_control_file("", std::move(pghs));
- }
-
- std::unique_ptr<vcpkg::StatusParagraph> make_status_pgh(const char* name,
- const char* depends = "",
- const char* default_features = "",
- const char* triplet = "x86-windows");
-
- std::unique_ptr<vcpkg::StatusParagraph> make_status_feature_pgh(const char* name,
- const char* feature,
- const char* depends = "",
- const char* triplet = "x86-windows");
-
- extern const Triplet X86_WINDOWS;
- extern const Triplet X64_WINDOWS;
- extern const Triplet X86_UWP;
- extern const Triplet ARM_UWP;
- extern const Triplet X64_ANDROID;
-
- /// <summary>
- /// Map of source control files by their package name.
- /// </summary>
- struct PackageSpecMap
- {
- std::unordered_map<std::string, SourceControlFileLocation> map;
- Triplet triplet;
- PackageSpecMap(Triplet t = X86_WINDOWS) noexcept : triplet(t) { }
-
- PackageSpec emplace(const char* name,
- const char* depends = "",
- const std::vector<std::pair<const char*, const char*>>& features = {},
- const std::vector<const char*>& default_features = {});
-
- PackageSpec emplace(vcpkg::SourceControlFileLocation&& scfl);
- };
-
- template<class T, class S>
- T&& unwrap(vcpkg::ExpectedT<T, S>&& p)
- {
- REQUIRE(p.has_value());
- return std::move(*p.get());
- }
-
- template<class T>
- T&& unwrap(vcpkg::Optional<T>&& opt)
- {
- REQUIRE(opt.has_value());
- return std::move(*opt.get());
- }
-
- struct AllowSymlinks
- {
- enum Tag : bool
- {
- No = false,
- Yes = true,
- } tag;
-
- constexpr AllowSymlinks(Tag tag) noexcept : tag(tag) { }
-
- constexpr explicit AllowSymlinks(bool b) noexcept : tag(b ? Yes : No) { }
-
- constexpr operator bool() const noexcept { return tag == Yes; }
- };
-
- AllowSymlinks can_create_symlinks() noexcept;
-
- const fs::path& base_temporary_directory() noexcept;
-
- void create_symlink(const fs::path& file, const fs::path& target, std::error_code& ec);
-
- void create_directory_symlink(const fs::path& file, const fs::path& target, std::error_code& ec);
-}
diff --git a/toolsrc/include/vcpkg/archives.h b/toolsrc/include/vcpkg/archives.h
deleted file mode 100644
index be2523dfb..000000000
--- a/toolsrc/include/vcpkg/archives.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#pragma once
-
-#include <vcpkg/fwd/vcpkgpaths.h>
-
-#include <vcpkg/base/files.h>
-
-namespace vcpkg::Archives
-{
- void extract_archive(const VcpkgPaths& paths, const fs::path& archive, const fs::path& to_path);
-}
diff --git a/toolsrc/include/vcpkg/base/basic_checks.h b/toolsrc/include/vcpkg/base/basic_checks.h
deleted file mode 100644
index 2ea714599..000000000
--- a/toolsrc/include/vcpkg/base/basic_checks.h
+++ /dev/null
@@ -1,41 +0,0 @@
-#pragma once
-
-#include <vcpkg/base/lineinfo.h>
-#include <vcpkg/base/stringview.h>
-
-namespace vcpkg::Checks
-{
- void register_global_shutdown_handler(void (*func)());
-
- // Note: for internal use
- [[noreturn]] void final_cleanup_and_exit(const int exit_code);
-
- // Indicate that an internal error has occurred and exit the tool. This should be used when invariants have been
- // broken.
- [[noreturn]] void unreachable(const LineInfo& line_info);
-
- [[noreturn]] void exit_with_code(const LineInfo& line_info, const int exit_code);
-
- // Exit the tool without an error message.
- [[noreturn]] void exit_fail(const LineInfo& line_info);
-
- // Exit the tool successfully.
- [[noreturn]] void exit_success(const LineInfo& line_info);
-
- // Display an error message to the user and exit the tool.
- [[noreturn]] void exit_with_message(const LineInfo& line_info, StringView error_message);
-
- // If expression is false, call exit_fail.
- void check_exit(const LineInfo& line_info, bool expression);
-
- // if expression is false, call exit_with_message.
- void check_exit(const LineInfo& line_info, bool expression, StringView error_message);
-
- // Display a message indicating that vcpkg should be upgraded and exit.
- [[noreturn]] void exit_maybe_upgrade(const LineInfo& line_info);
- [[noreturn]] void exit_maybe_upgrade(const LineInfo& line_info, StringView error_message);
-
- // Check the indicated condition and call exit_maybe_upgrade if it is false.
- void check_maybe_upgrade(const LineInfo& line_info, bool condition);
- void check_maybe_upgrade(const LineInfo& line_info, bool condition, StringView error_message);
-}
diff --git a/toolsrc/include/vcpkg/base/cache.h b/toolsrc/include/vcpkg/base/cache.h
deleted file mode 100644
index 7efae1361..000000000
--- a/toolsrc/include/vcpkg/base/cache.h
+++ /dev/null
@@ -1,21 +0,0 @@
-#pragma once
-
-#include <map>
-
-namespace vcpkg
-{
- template<class Key, class Value, class Less = std::less<Key>>
- struct Cache
- {
- template<class F>
- Value const& get_lazy(const Key& k, const F& f) const
- {
- auto it = m_cache.find(k);
- if (it != m_cache.end()) return it->second;
- return m_cache.emplace(k, f()).first->second;
- }
-
- private:
- mutable std::map<Key, Value, Less> m_cache;
- };
-}
diff --git a/toolsrc/include/vcpkg/base/checks.h b/toolsrc/include/vcpkg/base/checks.h
deleted file mode 100644
index f360fcb36..000000000
--- a/toolsrc/include/vcpkg/base/checks.h
+++ /dev/null
@@ -1,60 +0,0 @@
-#pragma once
-
-#include <vcpkg/base/basic_checks.h>
-#include <vcpkg/base/strings.h>
-
-namespace vcpkg::Checks
-{
- // Additional convenience overloads on top of basic_checks.h that do formatting.
-
- template<class Arg1, class... Args>
- // Display an error message to the user and exit the tool.
- [[noreturn]] void exit_with_message(const LineInfo& line_info,
- const char* error_message_template,
- const Arg1& error_message_arg1,
- const Args&... error_message_args)
- {
- exit_with_message(line_info,
- Strings::format(error_message_template, error_message_arg1, error_message_args...));
- }
-
- template<class Conditional, class Arg1, class... Args>
- void check_exit(const LineInfo& line_info,
- Conditional&& expression,
- const char* error_message_template,
- const Arg1& error_message_arg1,
- const Args&... error_message_args)
- {
- if (!expression)
- {
- // Only create the string if the expression is false
- exit_with_message(line_info,
- Strings::format(error_message_template, error_message_arg1, error_message_args...));
- }
- }
-
- template<class Arg1, class... Args>
- [[noreturn]] void exit_maybe_upgrade(const LineInfo& line_info,
- const char* error_message_template,
- const Arg1& error_message_arg1,
- const Args&... error_message_args)
- {
- exit_maybe_upgrade(line_info,
- Strings::format(error_message_template, error_message_arg1, error_message_args...));
- }
-
- template<class Conditional, class Arg1, class... Args>
- void check_maybe_upgrade(const LineInfo& line_info,
- Conditional&& expression,
- const char* error_message_template,
- const Arg1& error_message_arg1,
- const Args&... error_message_args)
- {
- if (!expression)
- {
- // Only create the string if the expression is false
- exit_maybe_upgrade(line_info,
- Strings::format(error_message_template, error_message_arg1, error_message_args...));
- }
- }
-}
diff --git a/toolsrc/include/vcpkg/base/chrono.h b/toolsrc/include/vcpkg/base/chrono.h
deleted file mode 100644
index 0505192a0..000000000
--- a/toolsrc/include/vcpkg/base/chrono.h
+++ /dev/null
@@ -1,75 +0,0 @@
-#pragma once
-
-#include <vcpkg/base/cstringview.h>
-#include <vcpkg/base/optional.h>
-
-#include <chrono>
-#include <string>
-
-namespace vcpkg::Chrono
-{
- class ElapsedTime
- {
- using duration = std::chrono::high_resolution_clock::time_point::duration;
-
- public:
- constexpr ElapsedTime() noexcept : m_duration() { }
- constexpr ElapsedTime(duration d) noexcept : m_duration(d) { }
-
- template<class TimeUnit>
- TimeUnit as() const
- {
- return std::chrono::duration_cast<TimeUnit>(m_duration);
- }
-
- std::string to_string() const;
- void to_string(std::string& into) const;
-
- private:
- std::chrono::high_resolution_clock::time_point::duration m_duration;
- };
-
- class ElapsedTimer
- {
- public:
- static ElapsedTimer create_started();
-
- constexpr ElapsedTimer() noexcept : m_start_tick() { }
-
- ElapsedTime elapsed() const
- {
- return ElapsedTime(std::chrono::high_resolution_clock::now() - this->m_start_tick);
- }
-
- double microseconds() const { return elapsed().as<std::chrono::duration<double, std::micro>>().count(); }
-
- std::string to_string() const;
- void to_string(std::string& into) const;
-
- private:
- std::chrono::high_resolution_clock::time_point m_start_tick;
- };
-
- class CTime
- {
- public:
- static Optional<CTime> get_current_date_time();
- static Optional<CTime> parse(CStringView str);
-
- constexpr CTime() noexcept : m_tm{} { }
- explicit constexpr CTime(tm t) noexcept : m_tm{t} { }
-
- CTime add_hours(const int hours) const;
-
- std::string to_string() const;
-
- std::chrono::system_clock::time_point to_time_point() const;
-
- private:
- mutable tm m_tm;
- };
-
- tm get_current_date_time();
-
- tm get_current_date_time_local();
-}
diff --git a/toolsrc/include/vcpkg/base/cofffilereader.h b/toolsrc/include/vcpkg/base/cofffilereader.h
deleted file mode 100644
index e0ad69b33..000000000
--- a/toolsrc/include/vcpkg/base/cofffilereader.h
+++ /dev/null
@@ -1,25 +0,0 @@
-#pragma once
-
-#include <vcpkg/base/files.h>
-#include <vcpkg/base/machinetype.h>
-
-#include <vector>
-
-namespace vcpkg::CoffFileReader
-{
- struct DllInfo
- {
- MachineType machine_type;
- };
-
- struct LibInfo
- {
- std::vector<MachineType> machine_types;
- };
-
-#if defined(_WIN32)
- DllInfo read_dll(const fs::path& path);
-
- LibInfo read_lib(const fs::path& path);
-#endif
-}
diff --git a/toolsrc/include/vcpkg/base/cstringview.h b/toolsrc/include/vcpkg/base/cstringview.h
deleted file mode 100644
index 94c806ae4..000000000
--- a/toolsrc/include/vcpkg/base/cstringview.h
+++ /dev/null
@@ -1,60 +0,0 @@
-#pragma once
-
-#include <cstring>
-#include <string>
-
-namespace vcpkg
-{
- struct CStringView
- {
- constexpr CStringView() noexcept : cstr(nullptr) { }
- constexpr CStringView(const char* cstr) : cstr(cstr) { }
- constexpr CStringView(const CStringView&) = default;
- CStringView(const std::string& str) : cstr(str.c_str()) { }
-
- constexpr const char* c_str() const { return cstr; }
-
- void to_string(std::string& str) const { str.append(cstr); }
-
- private:
- const char* cstr;
- };
-
- namespace details
- {
- inline bool strequal(const char* l, const char* r) { return strcmp(l, r) == 0; }
- }
-
- inline bool operator==(const CStringView& l, const CStringView& r)
- {
- return details::strequal(l.c_str(), r.c_str());
- }
-
- inline bool operator==(const char* l, const CStringView& r) { return details::strequal(l, r.c_str()); }
-
- inline bool operator==(const CStringView& r, const char* l) { return details::strequal(l, r.c_str()); }
-
- inline bool operator==(const std::string& l, const CStringView& r) { return l == r.c_str(); }
-
- inline bool operator==(const CStringView& r, const std::string& l) { return l == r.c_str(); }
-
- // notequals
- inline bool operator!=(const CStringView& l, const CStringView& r)
- {
- return !details::strequal(l.c_str(), r.c_str());
- }
-
- inline bool operator!=(const char* l, const CStringView& r) { return !details::strequal(l, r.c_str()); }
-
- inline bool operator!=(const CStringView& r, const char* l) { return !details::strequal(l, r.c_str()); }
-
- inline bool operator!=(const CStringView& r, const std::string& l) { return l != r.c_str(); }
-
- inline bool operator!=(const std::string& l, const CStringView& r) { return l != r.c_str(); }
-
- inline std::string operator+(std::string&& l, const CStringView& r) { return std::move(l) + r.c_str(); }
-
- inline const char* to_printf_arg(const CStringView string_view) { return string_view.c_str(); }
-
- static_assert(sizeof(CStringView) == sizeof(void*), "CStringView must be a simple wrapper around char*");
-}
diff --git a/toolsrc/include/vcpkg/base/delayed_init.h b/toolsrc/include/vcpkg/base/delayed_init.h
deleted file mode 100644
index a3257f54e..000000000
--- a/toolsrc/include/vcpkg/base/delayed_init.h
+++ /dev/null
@@ -1,29 +0,0 @@
-#pragma once
-
-#include <vcpkg/base/optional.h>
-
-#include <memory>
-#include <mutex>
-
-namespace vcpkg
-{
- // implements the equivalent of function static initialization for an object
- template<class T>
- struct DelayedInit
- {
- template<class F>
- const T& get(F&& f) const
- {
- std::call_once(underlying_->flag_, [&f, this]() { underlying_->storage_ = std::forward<F>(f)(); });
- return *underlying_->storage_.get();
- }
-
- private:
- struct Storage
- {
- std::once_flag flag_;
- Optional<T> storage_;
- };
- std::unique_ptr<Storage> underlying_ = std::make_unique<Storage>();
- };
-}
diff --git a/toolsrc/include/vcpkg/base/downloads.h b/toolsrc/include/vcpkg/base/downloads.h
deleted file mode 100644
index bf97c0650..000000000
--- a/toolsrc/include/vcpkg/base/downloads.h
+++ /dev/null
@@ -1,41 +0,0 @@
-#pragma once
-
-#include <vcpkg/base/files.h>
-#include <vcpkg/base/optional.h>
-#include <vcpkg/base/view.h>
-
-namespace vcpkg::Downloads
-{
- namespace details
- {
- struct SplitURIView
- {
- StringView scheme;
- Optional<StringView> authority;
- StringView path_query_fragment;
- };
-
- // e.g. {"https","//example.org", "/index.html"}
- Optional<SplitURIView> split_uri_view(StringView uri);
- }
-
- void verify_downloaded_file_hash(const Files::Filesystem& fs,
- const std::string& url,
- const fs::path& path,
- const std::string& sha512);
-
- // Returns url that was successfully downloaded from
- std::string download_file(Files::Filesystem& fs,
- View<std::string> urls,
- const fs::path& download_path,
- const std::string& sha512);
-
- void download_file(Files::Filesystem& fs,
- const std::string& url,
- const fs::path& download_path,
- const std::string& sha512);
-
- std::vector<int> download_files(Files::Filesystem& fs, View<std::pair<std::string, fs::path>> url_pairs);
- int put_file(const Files::Filesystem&, StringView url, const fs::path& file);
- std::vector<int> url_heads(View<std::string> urls);
-}
diff --git a/toolsrc/include/vcpkg/base/enums.h b/toolsrc/include/vcpkg/base/enums.h
deleted file mode 100644
index 1edd6dd8f..000000000
--- a/toolsrc/include/vcpkg/base/enums.h
+++ /dev/null
@@ -1,11 +0,0 @@
-#pragma once
-
-#include <vcpkg/base/cstringview.h>
-#include <vcpkg/base/lineinfo.h>
-
-namespace vcpkg::Enums
-{
- std::string nullvalue_to_string(const CStringView enum_name);
-
- [[noreturn]] void nullvalue_used(const LineInfo& line_info, const CStringView enum_name);
-}
diff --git a/toolsrc/include/vcpkg/base/expected.h b/toolsrc/include/vcpkg/base/expected.h
deleted file mode 100644
index f24366c4a..000000000
--- a/toolsrc/include/vcpkg/base/expected.h
+++ /dev/null
@@ -1,245 +0,0 @@
-#pragma once
-
-#include <vcpkg/base/checks.h>
-#include <vcpkg/base/lineinfo.h>
-#include <vcpkg/base/stringliteral.h>
-#include <vcpkg/base/system.print.h>
-
-#include <system_error>
-#include <type_traits>
-
-namespace vcpkg
-{
- template<class Err>
- struct ErrorHolder
- {
- ErrorHolder() : m_is_error(false), m_err{} { }
- template<class U>
- ErrorHolder(U&& err) : m_is_error(true), m_err(std::forward<U>(err))
- {
- }
-
- constexpr bool has_error() const { return m_is_error; }
-
- const Err& error() const { return m_err; }
- Err& error() { return m_err; }
-
- StringLiteral to_string() const { return "value was error"; }
-
- private:
- bool m_is_error;
- Err m_err;
- };
-
- template<>
- struct ErrorHolder<std::string>
- {
- ErrorHolder() : m_is_error(false) { }
- template<class U>
- ErrorHolder(U&& err) : m_is_error(true), m_err(std::forward<U>(err))
- {
- }
-
- bool has_error() const { return m_is_error; }
-
- const std::string& error() const { return m_err; }
- std::string& error() { return m_err; }
-
- const std::string& to_string() const { return m_err; }
-
- private:
- bool m_is_error;
- std::string m_err;
- };
-
- template<>
- struct ErrorHolder<std::error_code>
- {
- ErrorHolder() = default;
- ErrorHolder(const std::error_code& err) : m_err(err) { }
-
- bool has_error() const { return bool(m_err); }
-
- const std::error_code& error() const { return m_err; }
- std::error_code& error() { return m_err; }
-
- std::string to_string() const { return m_err.message(); }
-
- private:
- std::error_code m_err;
- };
-
- struct ExpectedLeftTag
- {
- };
- struct ExpectedRightTag
- {
- };
- constexpr ExpectedLeftTag expected_left_tag;
- constexpr ExpectedRightTag expected_right_tag;
-
- template<class T>
- struct ExpectedHolder
- {
- ExpectedHolder() = default;
- ExpectedHolder(const T& t) : t(t) { }
- ExpectedHolder(T&& t) : t(std::move(t)) { }
- using pointer = T*;
- using const_pointer = const T*;
- T* get() { return &t; }
- const T* get() const { return &t; }
- T t;
- };
- template<class T>
- struct ExpectedHolder<T&>
- {
- ExpectedHolder(T& t) : t(&t) { }
- ExpectedHolder() : t(nullptr) { }
- using pointer = T*;
- using const_pointer = T*;
- T* get() { return t; }
- T* get() const { return t; }
- T* t;
- };
-
- template<class T, class S>
- class ExpectedT
- {
- public:
- constexpr ExpectedT() = default;
-
- // Constructors are intentionally implicit
-
- ExpectedT(const S& s, ExpectedRightTag = {}) : m_s(s) { }
- template<class = std::enable_if<!std::is_reference<S>::value>>
- ExpectedT(S&& s, ExpectedRightTag = {}) : m_s(std::move(s))
- {
- }
-
- ExpectedT(const T& t, ExpectedLeftTag = {}) : m_t(t) { }
- template<class = std::enable_if<!std::is_reference<T>::value>>
- ExpectedT(T&& t, ExpectedLeftTag = {}) : m_t(std::move(t))
- {
- }
-
- ExpectedT(const ExpectedT&) = default;
- ExpectedT(ExpectedT&&) = default;
- ExpectedT& operator=(const ExpectedT&) = default;
- ExpectedT& operator=(ExpectedT&&) = default;
-
- explicit constexpr operator bool() const noexcept { return !m_s.has_error(); }
- constexpr bool has_value() const noexcept { return !m_s.has_error(); }
-
- T&& value_or_exit(const LineInfo& line_info) &&
- {
- exit_if_error(line_info);
- return std::move(*this->m_t.get());
- }
-
- const T& value_or_exit(const LineInfo& line_info) const&
- {
- exit_if_error(line_info);
- return *this->m_t.get();
- }
-
- const S& error() const& { return this->m_s.error(); }
-
- S&& error() && { return std::move(this->m_s.error()); }
-
- typename ExpectedHolder<T>::const_pointer get() const
- {
- if (!this->has_value())
- {
- return nullptr;
- }
- return this->m_t.get();
- }
-
- typename ExpectedHolder<T>::pointer get()
- {
- if (!this->has_value())
- {
- return nullptr;
- }
- return this->m_t.get();
- }
-
- template<class F>
- using map_t = decltype(std::declval<F&>()(*std::declval<typename ExpectedHolder<T>::const_pointer>()));
-
- template<class F, class U = map_t<F>>
- ExpectedT<U, S> map(F f) const&
- {
- if (has_value())
- {
- return {f(*m_t.get()), expected_left_tag};
- }
- else
- {
- return {error(), expected_right_tag};
- }
- }
-
- template<class F>
- using move_map_t =
- decltype(std::declval<F&>()(std::move(*std::declval<typename ExpectedHolder<T>::pointer>())));
-
- template<class F, class U = move_map_t<F>>
- ExpectedT<U, S> map(F f) &&
- {
- if (has_value())
- {
- return {f(std::move(*m_t.get())), expected_left_tag};
- }
- else
- {
- return {std::move(*this).error(), expected_right_tag};
- }
- }
-
- template<class F, class U = map_t<F>>
- U then(F f) const&
- {
- if (has_value())
- {
- return f(*m_t.get());
- }
- else
- {
- return U{error(), expected_right_tag};
- }
- }
-
- template<class F, class U = move_map_t<F>>
- U then(F f) &&
- {
- if (has_value())
- {
- return f(std::move(*m_t.get()));
- }
- else
- {
- return U{std::move(*this).error(), expected_right_tag};
- }
- }
-
- private:
- void exit_if_error(const LineInfo& line_info) const
- {
- if (m_s.has_error())
- {
- System::print2(System::Color::error, m_s.to_string(), "\n");
- Checks::exit_fail(line_info);
- }
- }
-
- ErrorHolder<S> m_s;
- ExpectedHolder<T> m_t;
- };
-
- template<class T>
- using Expected = ExpectedT<T, std::error_code>;
-
- template<class T>
- using ExpectedS = ExpectedT<T, std::string>;
-}
diff --git a/toolsrc/include/vcpkg/base/files.h b/toolsrc/include/vcpkg/base/files.h
deleted file mode 100644
index 5f2e96e91..000000000
--- a/toolsrc/include/vcpkg/base/files.h
+++ /dev/null
@@ -1,315 +0,0 @@
-#pragma once
-
-#include <vcpkg/base/expected.h>
-#include <vcpkg/base/ignore_errors.h>
-#include <vcpkg/base/pragmas.h>
-
-#include <string.h>
-
-#if !defined(VCPKG_USE_STD_FILESYSTEM)
-#error The build system must set VCPKG_USE_STD_FILESYSTEM.
-#endif // !defined(VCPKG_USE_STD_FILESYSTEM)
-
-#if VCPKG_USE_STD_FILESYSTEM
-#include <filesystem>
-#else
-#include <experimental/filesystem>
-#endif
-
-namespace fs
-{
-#if defined(_WIN32)
- struct IsSlash
- {
- bool operator()(const wchar_t c) const noexcept { return c == L'/' || c == L'\\'; }
- };
-#else
- struct IsSlash
- {
- bool operator()(const char c) const noexcept { return c == '/'; }
- };
-#endif
-
- constexpr IsSlash is_slash;
-
-#if VCPKG_USE_STD_FILESYSTEM
- namespace stdfs = std::filesystem;
-#else
- namespace stdfs = std::experimental::filesystem;
-#endif
-
- using stdfs::copy_options;
- using stdfs::directory_iterator;
- using stdfs::path;
- using stdfs::perms;
-
- path u8path(vcpkg::StringView s);
- inline path u8path(const char* first, const char* last) { return u8path(vcpkg::StringView{first, last}); }
- inline path u8path(std::initializer_list<char> il) { return u8path(vcpkg::StringView{il.begin(), il.end()}); }
- inline path u8path(const char* s) { return u8path(vcpkg::StringView{s, s + ::strlen(s)}); }
-
- inline path u8path(std::string::const_iterator first, std::string::const_iterator last)
- {
- auto firstp = &*first;
- return u8path(vcpkg::StringView{firstp, firstp + (last - first)});
- }
-
- std::string u8string(const path& p);
- std::string generic_u8string(const path& p);
-
- // equivalent to p.lexically_normal()
- path lexically_normal(const path& p);
-
-#if defined(_WIN32)
- enum class file_type
- {
- none = 0,
- not_found = -1,
- regular = 1,
- directory = 2,
- symlink = 3,
- block = 4,
- character = 5,
- fifo = 6,
- socket = 7,
- unknown = 8,
- // also stands for a junction
- directory_symlink = 42
- };
-
- struct file_status
- {
- explicit file_status(file_type type = file_type::none, perms permissions = perms::unknown) noexcept
- : m_type(type), m_permissions(permissions)
- {
- }
-
- file_type type() const noexcept { return m_type; }
- void type(file_type type) noexcept { m_type = type; }
-
- perms permissions() const noexcept { return m_permissions; }
- void permissions(perms perm) noexcept { m_permissions = perm; }
-
- private:
- file_type m_type;
- perms m_permissions;
- };
-
- struct SystemHandle
- {
- using type = intptr_t; // HANDLE
- type system_handle = -1;
-
- bool is_valid() const { return system_handle != -1; }
- };
-
-#else
-
- using stdfs::file_type;
- // to set up ADL correctly on `file_status` objects, we are defining
- // this in our own namespace
- struct file_status : private stdfs::file_status
- {
- using stdfs::file_status::file_status;
- using stdfs::file_status::permissions;
- using stdfs::file_status::type;
- };
-
- struct SystemHandle
- {
- using type = int; // file descriptor
- type system_handle = -1;
-
- bool is_valid() const { return system_handle != -1; }
- };
-
-#endif
-
- inline bool operator==(SystemHandle lhs, SystemHandle rhs) noexcept
- {
- return lhs.system_handle == rhs.system_handle;
- }
- inline bool operator!=(SystemHandle lhs, SystemHandle rhs) noexcept { return !(lhs == rhs); }
-
- inline bool is_symlink(file_status s) noexcept
- {
-#if defined(_WIN32)
- if (s.type() == file_type::directory_symlink) return true;
-#endif
- return s.type() == file_type::symlink;
- }
- inline bool is_regular_file(file_status s) { return s.type() == file_type::regular; }
- inline bool is_directory(file_status s) { return s.type() == file_type::directory; }
- inline bool exists(file_status s) { return s.type() != file_type::not_found && s.type() != file_type::none; }
-}
-
-/*
- if someone attempts to use unqualified `symlink_status` or `is_symlink`,
- they might get the ADL version, which is broken.
- Therefore, put `(symlink_)?status` as deleted in the global namespace, so
- that they get an error.
-
- We also want to poison the ADL on the other functions, because
- we don't want people calling these functions on paths
-*/
-void status(const fs::path& p) = delete;
-void status(const fs::path& p, std::error_code& ec) = delete;
-void symlink_status(const fs::path& p) = delete;
-void symlink_status(const fs::path& p, std::error_code& ec) = delete;
-void is_symlink(const fs::path& p) = delete;
-void is_symlink(const fs::path& p, std::error_code& ec) = delete;
-void is_regular_file(const fs::path& p) = delete;
-void is_regular_file(const fs::path& p, std::error_code& ec) = delete;
-void is_directory(const fs::path& p) = delete;
-void is_directory(const fs::path& p, std::error_code& ec) = delete;
-
-namespace vcpkg::Files
-{
- struct Filesystem
- {
- std::string read_contents(const fs::path& file_path, LineInfo linfo) const;
- virtual Expected<std::string> read_contents(const fs::path& file_path) const = 0;
- /// <summary>Read text lines from a file</summary>
- /// <remarks>Lines will have up to one trailing carriage-return character stripped (CRLF)</remarks>
- virtual Expected<std::vector<std::string>> read_lines(const fs::path& file_path) const = 0;
- virtual fs::path find_file_recursively_up(const fs::path& starting_dir, const fs::path& filename) const = 0;
- virtual std::vector<fs::path> get_files_recursive(const fs::path& dir) const = 0;
- virtual std::vector<fs::path> get_files_non_recursive(const fs::path& dir) const = 0;
- void write_lines(const fs::path& file_path, const std::vector<std::string>& lines, LineInfo linfo);
- virtual void write_lines(const fs::path& file_path,
- const std::vector<std::string>& lines,
- std::error_code& ec) = 0;
- void write_contents(const fs::path& path, const std::string& data, LineInfo linfo);
- virtual void write_contents(const fs::path& file_path, const std::string& data, std::error_code& ec) = 0;
- void write_contents_and_dirs(const fs::path& path, const std::string& data, LineInfo linfo);
- virtual void write_contents_and_dirs(const fs::path& file_path,
- const std::string& data,
- std::error_code& ec) = 0;
- void rename(const fs::path& oldpath, const fs::path& newpath, LineInfo linfo);
- virtual void rename(const fs::path& oldpath, const fs::path& newpath, std::error_code& ec) = 0;
- virtual void rename_or_copy(const fs::path& oldpath,
- const fs::path& newpath,
- StringLiteral temp_suffix,
- std::error_code& ec) = 0;
- bool remove(const fs::path& path, LineInfo linfo);
- bool remove(const fs::path& path, ignore_errors_t);
- virtual bool remove(const fs::path& path, std::error_code& ec) = 0;
-
- virtual void remove_all(const fs::path& path, std::error_code& ec, fs::path& failure_point) = 0;
- void remove_all(const fs::path& path, LineInfo li);
- void remove_all(const fs::path& path, ignore_errors_t);
- virtual void remove_all_inside(const fs::path& path, std::error_code& ec, fs::path& failure_point) = 0;
- void remove_all_inside(const fs::path& path, LineInfo li);
- void remove_all_inside(const fs::path& path, ignore_errors_t);
- bool exists(const fs::path& path, std::error_code& ec) const;
- bool exists(LineInfo li, const fs::path& path) const;
- bool exists(const fs::path& path, ignore_errors_t = ignore_errors) const;
- virtual bool is_directory(const fs::path& path) const = 0;
- virtual bool is_regular_file(const fs::path& path) const = 0;
- virtual bool is_empty(const fs::path& path) const = 0;
- virtual bool create_directory(const fs::path& path, std::error_code& ec) = 0;
- bool create_directory(const fs::path& path, ignore_errors_t);
- bool create_directory(const fs::path& path, LineInfo li);
- virtual bool create_directories(const fs::path& path, std::error_code& ec) = 0;
- bool create_directories(const fs::path& path, ignore_errors_t);
- bool create_directories(const fs::path& path, LineInfo);
- virtual void copy(const fs::path& oldpath, const fs::path& newpath, fs::copy_options opts) = 0;
- virtual bool copy_file(const fs::path& oldpath,
- const fs::path& newpath,
- fs::copy_options opts,
- std::error_code& ec) = 0;
- void copy_file(const fs::path& oldpath, const fs::path& newpath, fs::copy_options opts, LineInfo li);
- virtual void copy_symlink(const fs::path& oldpath, const fs::path& newpath, std::error_code& ec) = 0;
- virtual fs::file_status status(const fs::path& path, std::error_code& ec) const = 0;
- virtual fs::file_status symlink_status(const fs::path& path, std::error_code& ec) const = 0;
- fs::file_status status(LineInfo li, const fs::path& p) const noexcept;
- fs::file_status status(const fs::path& p, ignore_errors_t) const noexcept;
- fs::file_status symlink_status(LineInfo li, const fs::path& p) const noexcept;
- fs::file_status symlink_status(const fs::path& p, ignore_errors_t) const noexcept;
- virtual fs::path absolute(const fs::path& path, std::error_code& ec) const = 0;
- fs::path absolute(LineInfo li, const fs::path& path) const;
- virtual fs::path canonical(const fs::path& path, std::error_code& ec) const = 0;
- fs::path canonical(LineInfo li, const fs::path& path) const;
- fs::path canonical(const fs::path& path, ignore_errors_t) const;
- virtual fs::path current_path(std::error_code&) const = 0;
- fs::path current_path(LineInfo li) const;
- virtual void current_path(const fs::path& path, std::error_code&) = 0;
- void current_path(const fs::path& path, LineInfo li);
-
- // if the path does not exist, then (try_|)take_exclusive_file_lock attempts to create the file
- // (but not any path members above the file itself)
- // in other words, if `/a/b` is a directory, and you're attempting to lock `/a/b/c`,
- // then these lock functions create `/a/b/c` if it doesn't exist;
- // however, if `/a/b` doesn't exist, then the functions will fail.
-
- // waits forever for the file lock
- virtual fs::SystemHandle take_exclusive_file_lock(const fs::path& path, std::error_code&) = 0;
- // waits, at most, 1.5 seconds, for the file lock
- virtual fs::SystemHandle try_take_exclusive_file_lock(const fs::path& path, std::error_code&) = 0;
- virtual void unlock_file_lock(fs::SystemHandle handle, std::error_code&) = 0;
-
- virtual std::vector<fs::path> find_from_PATH(const std::string& name) const = 0;
- };
-
- Filesystem& get_real_filesystem();
-
- static constexpr const char* FILESYSTEM_INVALID_CHARACTERS = R"(\/:*?"<>|)";
-
- bool has_invalid_chars_for_filesystem(const std::string& s);
-
- void print_paths(const std::vector<fs::path>& paths);
-
- // Performs "lhs / rhs" according to the C++17 Filesystem Library Specification.
- // This function exists as a workaround for TS implementations.
- fs::path combine(const fs::path& lhs, const fs::path& rhs);
-
-#if defined(_WIN32)
- constexpr char preferred_separator = '\\';
-#else
- constexpr char preferred_separator = '/';
-#endif // _WIN32
-
-#if defined(_WIN32)
- fs::path win32_fix_path_case(const fs::path& source);
-#endif // _WIN32
-
- struct ExclusiveFileLock
- {
- enum class Wait
- {
- Yes,
- No,
- };
-
- ExclusiveFileLock() = default;
- ExclusiveFileLock(ExclusiveFileLock&&) = delete;
- ExclusiveFileLock& operator=(ExclusiveFileLock&&) = delete;
-
- ExclusiveFileLock(Wait wait, Filesystem& fs, const fs::path& path_, std::error_code& ec) : m_fs(&fs)
- {
- switch (wait)
- {
- case Wait::Yes: m_handle = m_fs->take_exclusive_file_lock(path_, ec); break;
- case Wait::No: m_handle = m_fs->try_take_exclusive_file_lock(path_, ec); break;
- }
- }
- ~ExclusiveFileLock() { clear(); }
-
- explicit operator bool() const { return m_handle.is_valid(); }
- bool has_lock() const { return m_handle.is_valid(); }
-
- void clear()
- {
- if (m_fs && m_handle.is_valid())
- {
- std::error_code ignore;
- m_fs->unlock_file_lock(std::exchange(m_handle, fs::SystemHandle{}), ignore);
- }
- }
-
- private:
- Filesystem* m_fs;
- fs::SystemHandle m_handle;
- };
-
-}
diff --git a/toolsrc/include/vcpkg/base/fwd/json.h b/toolsrc/include/vcpkg/base/fwd/json.h
deleted file mode 100644
index bb31a5f60..000000000
--- a/toolsrc/include/vcpkg/base/fwd/json.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#pragma once
-
-namespace vcpkg::Json
-{
- struct JsonStyle;
- enum class ValueKind : int;
- struct Value;
- struct Object;
- struct Array;
-}
diff --git a/toolsrc/include/vcpkg/base/fwd/lockguarded.h b/toolsrc/include/vcpkg/base/fwd/lockguarded.h
deleted file mode 100644
index e7e88b5a1..000000000
--- a/toolsrc/include/vcpkg/base/fwd/lockguarded.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#pragma once
-
-namespace vcpkg::Util
-{
- template<class T>
- struct LockGuardPtr;
-
- template<class T>
- struct LockGuarded;
-}
diff --git a/toolsrc/include/vcpkg/base/fwd/optional.h b/toolsrc/include/vcpkg/base/fwd/optional.h
deleted file mode 100644
index 2c3a7ea6c..000000000
--- a/toolsrc/include/vcpkg/base/fwd/optional.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#pragma once
-
-namespace vcpkg
-{
- template<class T>
- struct Optional;
-}
diff --git a/toolsrc/include/vcpkg/base/fwd/span.h b/toolsrc/include/vcpkg/base/fwd/span.h
deleted file mode 100644
index 9cd45250e..000000000
--- a/toolsrc/include/vcpkg/base/fwd/span.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#pragma once
-
-namespace vcpkg
-{
- template<class T>
- struct Span;
-
- template<class T>
- using View = Span<const T>;
-}
diff --git a/toolsrc/include/vcpkg/base/fwd/stringview.h b/toolsrc/include/vcpkg/base/fwd/stringview.h
deleted file mode 100644
index e297fd43b..000000000
--- a/toolsrc/include/vcpkg/base/fwd/stringview.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#pragma once
-
-namespace vcpkg
-{
- struct StringView;
-}
diff --git a/toolsrc/include/vcpkg/base/graphs.h b/toolsrc/include/vcpkg/base/graphs.h
deleted file mode 100644
index fd51d666b..000000000
--- a/toolsrc/include/vcpkg/base/graphs.h
+++ /dev/null
@@ -1,113 +0,0 @@
-#pragma once
-
-#include <vcpkg/base/checks.h>
-#include <vcpkg/base/lineinfo.h>
-#include <vcpkg/base/system.print.h>
-
-#include <string>
-#include <unordered_map>
-#include <vector>
-
-namespace vcpkg::Graphs
-{
- enum class ExplorationStatus
- {
- // We have not visited this vertex
- NOT_EXPLORED,
-
- // We have visited this vertex but haven't visited all vertices in its subtree
- PARTIALLY_EXPLORED,
-
- // We have visited this vertex and all vertices in its subtree
- FULLY_EXPLORED
- };
-
- template<class V, class U>
- struct AdjacencyProvider
- {
- virtual std::vector<V> adjacency_list(const U& vertex) const = 0;
- virtual std::string to_string(const V& vertex) const = 0;
- virtual U load_vertex_data(const V& vertex) const = 0;
- };
-
- struct Randomizer
- {
- virtual int random(int max_exclusive) = 0;
-
- protected:
- ~Randomizer() { }
- };
-
- namespace details
- {
- template<class Container>
- void shuffle(Container& c, Randomizer* r)
- {
- if (!r) return;
- for (auto i = c.size(); i > 1; --i)
- {
- std::size_t j = r->random(static_cast<int>(i));
- if (j != i - 1)
- {
- std::swap(c[i - 1], c[j]);
- }
- }
- }
-
- template<class V, class U>
- void topological_sort_internal(const V& vertex,
- const AdjacencyProvider<V, U>& f,
- std::unordered_map<V, ExplorationStatus>& exploration_status,
- std::vector<U>& sorted,
- Randomizer* randomizer)
- {
- ExplorationStatus& status = exploration_status[vertex];
- switch (status)
- {
- case ExplorationStatus::FULLY_EXPLORED: return;
- case ExplorationStatus::PARTIALLY_EXPLORED:
- {
- System::print2("Cycle detected within graph at ", f.to_string(vertex), ":\n");
- for (auto&& node : exploration_status)
- {
- if (node.second == ExplorationStatus::PARTIALLY_EXPLORED)
- {
- System::print2(" ", f.to_string(node.first), '\n');
- }
- }
- Checks::exit_fail(VCPKG_LINE_INFO);
- }
- case ExplorationStatus::NOT_EXPLORED:
- {
- status = ExplorationStatus::PARTIALLY_EXPLORED;
- U vertex_data = f.load_vertex_data(vertex);
- auto neighbours = f.adjacency_list(vertex_data);
- details::shuffle(neighbours, randomizer);
- for (const V& neighbour : neighbours)
- topological_sort_internal(neighbour, f, exploration_status, sorted, randomizer);
-
- sorted.push_back(std::move(vertex_data));
- status = ExplorationStatus::FULLY_EXPLORED;
- return;
- }
- default: Checks::unreachable(VCPKG_LINE_INFO);
- }
- }
- }
-
- template<class Range, class V, class U>
- std::vector<U> topological_sort(Range starting_vertices, const AdjacencyProvider<V, U>& f, Randomizer* randomizer)
- {
- std::vector<U> sorted;
- std::unordered_map<V, ExplorationStatus> exploration_status;
-
- details::shuffle(starting_vertices, randomizer);
-
- for (auto&& vertex : starting_vertices)
- {
- details::topological_sort_internal(vertex, f, exploration_status, sorted, randomizer);
- }
-
- return sorted;
- }
-}
diff --git a/toolsrc/include/vcpkg/base/hash.h b/toolsrc/include/vcpkg/base/hash.h
deleted file mode 100644
index 0747e6737..000000000
--- a/toolsrc/include/vcpkg/base/hash.h
+++ /dev/null
@@ -1,52 +0,0 @@
-#pragma once
-
-#include <vcpkg/base/files.h>
-
-#include <string>
-
-namespace vcpkg::Hash
-{
- enum class Algorithm
- {
- Sha1,
- Sha256,
- Sha512,
- };
-
- const char* to_string(Algorithm algo) noexcept;
- Optional<Algorithm> algorithm_from_string(StringView sv) noexcept;
-
- struct Hasher
- {
- virtual void add_bytes(const void* start, const void* end) noexcept = 0;
-
- // one may only call this once before calling `clear()` or the dtor
- virtual std::string get_hash() noexcept = 0;
- virtual void clear() noexcept = 0;
- virtual ~Hasher() = default;
- };
-
- std::unique_ptr<Hasher> get_hasher_for(Algorithm algo) noexcept;
-
- std::string get_bytes_hash(const void* first, const void* last, Algorithm algo) noexcept;
- std::string get_string_hash(StringView s, Algorithm algo) noexcept;
- std::string get_file_hash(const Files::Filesystem& fs,
- const fs::path& path,
- Algorithm algo,
- std::error_code& ec) noexcept;
- inline std::string get_file_hash(LineInfo li,
- const Files::Filesystem& fs,
- const fs::path& path,
- Algorithm algo) noexcept
- {
- std::error_code ec;
- const auto result = get_file_hash(fs, path, algo, ec);
- if (ec)
- {
- Checks::exit_with_message(
- li, "Failure to read file '%s' for hashing: %s", fs::u8string(path), ec.message());
- }
-
- return result;
- }
-}
diff --git a/toolsrc/include/vcpkg/base/ignore_errors.h b/toolsrc/include/vcpkg/base/ignore_errors.h
deleted file mode 100644
index ed8b38c56..000000000
--- a/toolsrc/include/vcpkg/base/ignore_errors.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#pragma once
-
-namespace vcpkg
-{
- struct ignore_errors_t
- {
- };
-
- constexpr ignore_errors_t ignore_errors;
-}
diff --git a/toolsrc/include/vcpkg/base/json.h b/toolsrc/include/vcpkg/base/json.h
deleted file mode 100644
index 5321308a3..000000000
--- a/toolsrc/include/vcpkg/base/json.h
+++ /dev/null
@@ -1,302 +0,0 @@
-#pragma once
-
-#include <vcpkg/base/fwd/json.h>
-
-#include <vcpkg/base/expected.h>
-#include <vcpkg/base/files.h>
-#include <vcpkg/base/parse.h>
-#include <vcpkg/base/stringview.h>
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include <memory>
-#include <string>
-#include <utility>
-#include <vector>
-
-namespace vcpkg::Json
-{
- struct JsonStyle
- {
- enum class Newline
- {
- Lf,
- CrLf
- } newline_kind = Newline::Lf;
-
- constexpr JsonStyle() noexcept = default;
-
- static JsonStyle with_tabs() noexcept { return JsonStyle{-1}; }
- static JsonStyle with_spaces(int indent) noexcept
- {
- vcpkg::Checks::check_exit(VCPKG_LINE_INFO, indent >= 0);
- return JsonStyle{indent};
- }
-
- void set_tabs() noexcept { this->indent = -1; }
- void set_spaces(int indent_) noexcept
- {
- vcpkg::Checks::check_exit(VCPKG_LINE_INFO, indent >= 0);
- this->indent = indent_;
- }
-
- bool use_tabs() const noexcept { return indent == -1; }
- bool use_spaces() const noexcept { return indent >= 0; }
-
- int spaces() const noexcept
- {
- vcpkg::Checks::check_exit(VCPKG_LINE_INFO, indent >= 0);
- return indent;
- }
-
- const char* newline() const noexcept
- {
- switch (this->newline_kind)
- {
- case Newline::Lf: return "\n";
- case Newline::CrLf: return "\r\n";
- default: Checks::unreachable(VCPKG_LINE_INFO);
- }
- }
-
- private:
- constexpr explicit JsonStyle(int indent) : indent(indent) { }
- // -1 for tab, >=0 gives # of spaces
- int indent = 2;
- };
-
- enum class ValueKind : int
- {
- Null,
- Boolean,
- Integer,
- Number,
- String,
- Array,
- Object
- };
-
- namespace impl
- {
- struct ValueImpl;
- }
-
- struct Value
- {
- Value() noexcept; // equivalent to Value::null()
- Value(Value&&) noexcept;
- Value(const Value&);
- Value& operator=(Value&&) noexcept;
- Value& operator=(const Value&);
- ~Value();
-
- ValueKind kind() const noexcept;
-
- bool is_null() const noexcept;
- bool is_boolean() const noexcept;
- bool is_integer() const noexcept;
- // either integer _or_ number
- bool is_number() const noexcept;
- bool is_string() const noexcept;
- bool is_array() const noexcept;
- bool is_object() const noexcept;
-
- // a.x() asserts when !a.is_x()
- bool boolean() const noexcept;
- int64_t integer() const noexcept;
- double number() const noexcept;
- StringView string() const noexcept;
-
- const Array& array() const& noexcept;
- Array& array() & noexcept;
- Array&& array() && noexcept;
-
- const Object& object() const& noexcept;
- Object& object() & noexcept;
- Object&& object() && noexcept;
-
- static Value null(std::nullptr_t) noexcept;
- static Value boolean(bool) noexcept;
- static Value integer(int64_t i) noexcept;
- static Value number(double d) noexcept;
- static Value string(std::string s) noexcept;
- static Value array(Array&&) noexcept;
- static Value array(const Array&) noexcept;
- static Value object(Object&&) noexcept;
- static Value object(const Object&) noexcept;
-
- friend bool operator==(const Value& lhs, const Value& rhs);
- friend bool operator!=(const Value& lhs, const Value& rhs) { return !(lhs == rhs); }
-
- private:
- friend struct impl::ValueImpl;
- std::unique_ptr<impl::ValueImpl> underlying_;
- };
-
- struct Array
- {
- private:
- using underlying_t = std::vector<Value>;
-
- public:
- Array() = default;
- Array(Array const&) = default;
- Array(Array&&) = default;
- Array& operator=(Array const&) = default;
- Array& operator=(Array&&) = default;
- ~Array() = default;
-
- using iterator = underlying_t::iterator;
- using const_iterator = underlying_t::const_iterator;
-
- Value& push_back(Value&& value);
- Object& push_back(Object&& value);
- Array& push_back(Array&& value);
- Value& insert_before(iterator it, Value&& value);
- Object& insert_before(iterator it, Object&& value);
- Array& insert_before(iterator it, Array&& value);
-
- std::size_t size() const noexcept { return this->underlying_.size(); }
-
- // asserts idx < size
- Value& operator[](std::size_t idx) noexcept
- {
- vcpkg::Checks::check_exit(VCPKG_LINE_INFO, idx < this->size());
- return this->underlying_[idx];
- }
- const Value& operator[](std::size_t idx) const noexcept
- {
- vcpkg::Checks::check_exit(VCPKG_LINE_INFO, idx < this->size());
- return this->underlying_[idx];
- }
-
- iterator begin() { return underlying_.begin(); }
- iterator end() { return underlying_.end(); }
- const_iterator begin() const { return cbegin(); }
- const_iterator end() const { return cend(); }
- const_iterator cbegin() const { return underlying_.cbegin(); }
- const_iterator cend() const { return underlying_.cend(); }
-
- friend bool operator==(const Array& lhs, const Array& rhs);
- friend bool operator!=(const Array& lhs, const Array& rhs) { return !(lhs == rhs); }
-
- private:
- underlying_t underlying_;
- };
-
- struct Object
- {
- private:
- using value_type = std::pair<std::string, Value>;
- using underlying_t = std::vector<value_type>;
-
- underlying_t::const_iterator internal_find_key(StringView key) const noexcept;
-
- public:
- // these are here for better diagnostics
- Object() = default;
- Object(Object const&) = default;
- Object(Object&&) = default;
- Object& operator=(Object const&) = default;
- Object& operator=(Object&&) = default;
- ~Object() = default;
-
- // asserts if the key is found
- Value& insert(std::string key, Value&& value);
- Value& insert(std::string key, const Value& value);
- Object& insert(std::string key, Object&& value);
- Object& insert(std::string key, const Object& value);
- Array& insert(std::string key, Array&& value);
- Array& insert(std::string key, const Array& value);
-
- // replaces the value if the key is found, otherwise inserts a new
- // value.
- Value& insert_or_replace(std::string key, Value&& value);
- Value& insert_or_replace(std::string key, const Value& value);
- Object& insert_or_replace(std::string key, Object&& value);
- Object& insert_or_replace(std::string key, const Object& value);
- Array& insert_or_replace(std::string key, Array&& value);
- Array& insert_or_replace(std::string key, const Array& value);
-
- // returns whether the key existed
- bool remove(StringView key) noexcept;
-
- // asserts on lookup failure
- Value& operator[](StringView key) noexcept
- {
- auto res = this->get(key);
- vcpkg::Checks::check_exit(VCPKG_LINE_INFO, res, "missing key: \"%s\"", key);
- return *res;
- }
- const Value& operator[](StringView key) const noexcept
- {
- auto res = this->get(key);
- vcpkg::Checks::check_exit(VCPKG_LINE_INFO, res, "missing key: \"%s\"", key);
- return *res;
- }
-
- Value* get(StringView key) noexcept;
- const Value* get(StringView key) const noexcept;
-
- bool contains(StringView key) const noexcept { return this->get(key); }
-
- bool is_empty() const noexcept { return size() == 0; }
- std::size_t size() const noexcept { return this->underlying_.size(); }
-
- // sorts keys alphabetically
- void sort_keys();
-
- struct const_iterator
- {
- using value_type = std::pair<StringView, const Value&>;
- using reference = value_type;
- using iterator_category = std::forward_iterator_tag;
-
- value_type operator*() const noexcept { return *underlying_; }
- const_iterator& operator++() noexcept
- {
- ++underlying_;
- return *this;
- }
- const_iterator operator++(int) noexcept
- {
- auto res = *this;
- ++underlying_;
- return res;
- }
-
- bool operator==(const_iterator other) const noexcept { return this->underlying_ == other.underlying_; }
- bool operator!=(const_iterator other) const noexcept { return !(this->underlying_ == other.underlying_); }
-
- private:
- friend struct Object;
- explicit const_iterator(const underlying_t::const_iterator& it) : underlying_(it) { }
- underlying_t::const_iterator underlying_;
- };
- using iterator = const_iterator;
-
- const_iterator begin() const noexcept { return this->cbegin(); }
- const_iterator end() const noexcept { return this->cend(); }
- const_iterator cbegin() const noexcept { return const_iterator{this->underlying_.begin()}; }
- const_iterator cend() const noexcept { return const_iterator{this->underlying_.end()}; }
-
- friend bool operator==(const Object& lhs, const Object& rhs);
- friend bool operator!=(const Object& lhs, const Object& rhs) { return !(lhs == rhs); }
-
- private:
- underlying_t underlying_;
- };
-
- ExpectedT<std::pair<Value, JsonStyle>, std::unique_ptr<Parse::IParseError>> parse_file(
- const Files::Filesystem&, const fs::path&, std::error_code& ec) noexcept;
- ExpectedT<std::pair<Value, JsonStyle>, std::unique_ptr<Parse::IParseError>> parse(
- StringView text, const fs::path& filepath) noexcept;
- ExpectedT<std::pair<Value, JsonStyle>, std::unique_ptr<Parse::IParseError>> parse(StringView text,
- StringView origin = {}) noexcept;
- std::pair<Value, JsonStyle> parse_file(vcpkg::LineInfo linfo, const Files::Filesystem&, const fs::path&) noexcept;
-
- std::string stringify(const Value&, JsonStyle style);
- std::string stringify(const Object&, JsonStyle style);
- std::string stringify(const Array&, JsonStyle style);
-}
diff --git a/toolsrc/include/vcpkg/base/jsonreader.h b/toolsrc/include/vcpkg/base/jsonreader.h
deleted file mode 100644
index 4aca02998..000000000
--- a/toolsrc/include/vcpkg/base/jsonreader.h
+++ /dev/null
@@ -1,367 +0,0 @@
-#pragma once
-
-#include <vcpkg/base/fwd/json.h>
-
-#include <vcpkg/base/json.h>
-#include <vcpkg/base/optional.h>
-#include <vcpkg/base/strings.h>
-#include <vcpkg/base/stringview.h>
-#include <vcpkg/base/view.h>
-
-namespace vcpkg::Json
-{
- struct Reader;
-
- template<class Type>
- struct IDeserializer
- {
- using type = Type;
- virtual StringView type_name() const = 0;
-
- private:
- friend struct Reader;
- Optional<Type> visit(Reader&, const Value&);
- Optional<Type> visit(Reader&, const Object&);
-
- public:
- virtual Optional<Type> visit_null(Reader&);
- virtual Optional<Type> visit_boolean(Reader&, bool);
- virtual Optional<Type> visit_integer(Reader& r, int64_t i);
- virtual Optional<Type> visit_number(Reader&, double);
- virtual Optional<Type> visit_string(Reader&, StringView);
- virtual Optional<Type> visit_array(Reader&, const Array&);
- virtual Optional<Type> visit_object(Reader&, const Object&);
- virtual View<StringView> valid_fields() const;
-
- virtual ~IDeserializer() = default;
-
- protected:
- IDeserializer() = default;
- IDeserializer(const IDeserializer&) = default;
- IDeserializer& operator=(const IDeserializer&) = default;
- IDeserializer(IDeserializer&&) = default;
- IDeserializer& operator=(IDeserializer&&) = default;
- };
-
- struct Reader
- {
- const std::vector<std::string>& errors() const { return m_errors; }
- std::vector<std::string>& errors() { return m_errors; }
-
- void add_missing_field_error(StringView type, StringView key, StringView key_type);
- void add_expected_type_error(StringView expected_type);
- void add_extra_field_error(StringView type, StringView fields, StringView suggestion = {});
- template<class... Args>
- void add_generic_error(StringView type, Args&&... args)
- {
- m_errors.push_back(Strings::concat(path(), " (", type, "): ", args...));
- }
-
- std::string path() const noexcept;
-
- private:
- template<class Type>
- friend struct IDeserializer;
-
- std::vector<std::string> m_errors;
- struct Path
- {
- constexpr Path() = default;
- constexpr Path(int64_t i) : index(i) { }
- constexpr Path(StringView f) : field(f) { }
-
- int64_t index = -1;
- StringView field;
- };
- std::vector<Path> m_path;
-
- public:
- // checks that an object doesn't contain any fields which both:
- // * don't start with a `$`
- // * are not in `valid_fields`
- // if known_fields.empty(), then it's treated as if all field names are valid
- void check_for_unexpected_fields(const Object& obj, View<StringView> valid_fields, StringView type_name);
-
- template<class Type>
- void required_object_field(
- StringView type, const Object& obj, StringView key, Type& place, IDeserializer<Type>& visitor)
- {
- if (auto value = obj.get(key))
- {
- visit_in_key(*value, key, place, visitor);
- }
- else
- {
- this->add_missing_field_error(type, key, visitor.type_name());
- }
- }
-
- // value should be the value at key of the currently visited object
- template<class Type>
- void visit_in_key(const Value& value, StringView key, Type& place, IDeserializer<Type>& visitor)
- {
- m_path.push_back(key);
- auto opt = visitor.visit(*this, value);
-
- if (auto p_opt = opt.get())
- {
- place = std::move(*p_opt);
- }
- else
- {
- add_expected_type_error(visitor.type_name());
- }
- m_path.pop_back();
- }
-
- // value should be the value at key of the currently visited object
- template<class Type>
- void visit_at_index(const Value& value, int64_t index, Type& place, IDeserializer<Type>& visitor)
- {
- m_path.push_back(index);
- auto opt = visitor.visit(*this, value);
-
- if (auto p_opt = opt.get())
- {
- place = std::move(*p_opt);
- }
- else
- {
- add_expected_type_error(visitor.type_name());
- }
- m_path.pop_back();
- }
-
- // returns whether key \in obj
- template<class Type>
- bool optional_object_field(const Object& obj, StringView key, Type& place, IDeserializer<Type>& visitor)
- {
- if (auto value = obj.get(key))
- {
- visit_in_key(*value, key, place, visitor);
- return true;
- }
- else
- {
- return false;
- }
- }
-
- template<class Type>
- Optional<Type> visit(const Value& value, IDeserializer<Type>& visitor)
- {
- return visitor.visit(*this, value);
- }
- template<class Type>
- Optional<Type> visit(const Object& value, IDeserializer<Type>& visitor)
- {
- return visitor.visit(*this, value);
- }
-
- template<class Type>
- Optional<std::vector<Type>> array_elements(const Array& arr, IDeserializer<Type>& visitor)
- {
- std::vector<Type> result;
- m_path.emplace_back();
- for (size_t i = 0; i < arr.size(); ++i)
- {
- m_path.back().index = static_cast<int64_t>(i);
- auto opt = visitor.visit(*this, arr[i]);
- if (auto p = opt.get())
- {
- result.push_back(std::move(*p));
- }
- else
- {
- this->add_expected_type_error(visitor.type_name());
- for (++i; i < arr.size(); ++i)
- {
- m_path.back().index = static_cast<int64_t>(i);
- auto opt2 = visitor.visit(*this, arr[i]);
- if (!opt2) this->add_expected_type_error(visitor.type_name());
- }
- }
- }
- m_path.pop_back();
- return std::move(result);
- }
- };
-
- VCPKG_MSVC_WARNING(push)
- VCPKG_MSVC_WARNING(disable : 4505)
-
- template<class Type>
- Optional<Type> IDeserializer<Type>::visit(Reader& r, const Value& value)
- {
- switch (value.kind())
- {
- case ValueKind::Null: return visit_null(r);
- case ValueKind::Boolean: return visit_boolean(r, value.boolean());
- case ValueKind::Integer: return visit_integer(r, value.integer());
- case ValueKind::Number: return visit_number(r, value.number());
- case ValueKind::String: return visit_string(r, value.string());
- case ValueKind::Array: return visit_array(r, value.array());
- case ValueKind::Object: return visit(r, value.object()); // Call `visit` to get unexpected fields checking
- default: vcpkg::Checks::unreachable(VCPKG_LINE_INFO);
- }
- }
-
- template<class Type>
- Optional<Type> IDeserializer<Type>::visit(Reader& r, const Object& obj)
- {
- r.check_for_unexpected_fields(obj, valid_fields(), type_name());
- return visit_object(r, obj);
- }
-
- template<class Type>
- View<StringView> IDeserializer<Type>::valid_fields() const
- {
- return {};
- }
-
- template<class Type>
- Optional<Type> IDeserializer<Type>::visit_null(Reader&)
- {
- return nullopt;
- }
- template<class Type>
- Optional<Type> IDeserializer<Type>::visit_boolean(Reader&, bool)
- {
- return nullopt;
- }
- template<class Type>
- Optional<Type> IDeserializer<Type>::visit_integer(Reader& r, int64_t i)
- {
- return this->visit_number(r, static_cast<double>(i));
- }
- template<class Type>
- Optional<Type> IDeserializer<Type>::visit_number(Reader&, double)
- {
- return nullopt;
- }
- template<class Type>
- Optional<Type> IDeserializer<Type>::visit_string(Reader&, StringView)
- {
- return nullopt;
- }
- template<class Type>
- Optional<Type> IDeserializer<Type>::visit_array(Reader&, const Array&)
- {
- return nullopt;
- }
- template<class Type>
- Optional<Type> IDeserializer<Type>::visit_object(Reader&, const Object&)
- {
- return nullopt;
- }
-
- VCPKG_MSVC_WARNING(pop)
-
- struct StringDeserializer final : IDeserializer<std::string>
- {
- virtual StringView type_name() const override { return type_name_; }
- virtual Optional<std::string> visit_string(Reader&, StringView sv) override { return sv.to_string(); }
-
- explicit StringDeserializer(StringLiteral type_name_) : type_name_(type_name_) { }
-
- private:
- StringLiteral type_name_;
- };
-
- struct PathDeserializer final : IDeserializer<fs::path>
- {
- virtual StringView type_name() const override { return "a path"; }
- virtual Optional<fs::path> visit_string(Reader&, StringView sv) override { return fs::u8path(sv); }
-
- static PathDeserializer instance;
- };
-
- struct NaturalNumberDeserializer final : IDeserializer<int>
- {
- virtual StringView type_name() const override { return "a nonnegative integer"; }
-
- virtual Optional<int> visit_integer(Reader&, int64_t value) override
- {
- if (value > std::numeric_limits<int>::max() || value < 0)
- {
- return nullopt;
- }
- return static_cast<int>(value);
- }
-
- static NaturalNumberDeserializer instance;
- };
-
- struct BooleanDeserializer final : IDeserializer<bool>
- {
- virtual StringView type_name() const override { return "a boolean"; }
-
- virtual Optional<bool> visit_boolean(Reader&, bool b) override { return b; }
-
- static BooleanDeserializer instance;
- };
-
- template<class Underlying>
- struct ArrayDeserializer final : IDeserializer<std::vector<typename Underlying::type>>
- {
- using type = std::vector<typename Underlying::type>;
-
- virtual StringView type_name() const override { return m_type_name; }
-
- ArrayDeserializer(StringLiteral type_name_, Underlying&& t = {})
- : m_type_name(type_name_), m_underlying_visitor(static_cast<Underlying&&>(t))
- {
- }
-
- virtual Optional<type> visit_array(Reader& r, const Array& arr) override
- {
- return r.array_elements(arr, m_underlying_visitor);
- }
-
- private:
- StringLiteral m_type_name;
- Underlying m_underlying_visitor;
- };
-
- struct ParagraphDeserializer final : IDeserializer<std::vector<std::string>>
- {
- virtual StringView type_name() const override { return "a string or array of strings"; }
-
- virtual Optional<std::vector<std::string>> visit_string(Reader&, StringView sv) override;
- virtual Optional<std::vector<std::string>> visit_array(Reader& r, const Array& arr) override;
-
- static ParagraphDeserializer instance;
- };
-
- struct IdentifierDeserializer final : Json::IDeserializer<std::string>
- {
- virtual StringView type_name() const override { return "an identifier"; }
-
- // [a-z0-9]+(-[a-z0-9]+)*, plus not any of {prn, aux, nul, con, lpt[1-9], com[1-9], core, default}
- static bool is_ident(StringView sv);
-
- virtual Optional<std::string> visit_string(Json::Reader&, StringView sv) override;
-
- static IdentifierDeserializer instance;
- };
-
- struct IdentifierArrayDeserializer final : Json::IDeserializer<std::vector<std::string>>
- {
- virtual StringView type_name() const override { return "an array of identifiers"; }
-
- virtual Optional<std::vector<std::string>> visit_array(Reader& r, const Array& arr) override;
-
- static IdentifierArrayDeserializer instance;
- };
-
- struct PackageNameDeserializer final : Json::IDeserializer<std::string>
- {
- virtual StringView type_name() const override { return "a package name"; }
-
- static bool is_package_name(StringView sv);
-
- virtual Optional<std::string> visit_string(Json::Reader&, StringView sv) override;
-
- static PackageNameDeserializer instance;
- };
-}
diff --git a/toolsrc/include/vcpkg/base/lazy.h b/toolsrc/include/vcpkg/base/lazy.h
deleted file mode 100644
index d0afdaeb2..000000000
--- a/toolsrc/include/vcpkg/base/lazy.h
+++ /dev/null
@@ -1,26 +0,0 @@
-#pragma once
-
-namespace vcpkg
-{
- template<typename T>
- class Lazy
- {
- public:
- Lazy() : value(T()), initialized(false) { }
-
- template<class F>
- T const& get_lazy(const F& f) const
- {
- if (!initialized)
- {
- value = f();
- initialized = true;
- }
- return value;
- }
-
- private:
- mutable T value;
- mutable bool initialized;
- };
-}
diff --git a/toolsrc/include/vcpkg/base/lineinfo.h b/toolsrc/include/vcpkg/base/lineinfo.h
deleted file mode 100644
index 68fca2e0e..000000000
--- a/toolsrc/include/vcpkg/base/lineinfo.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#pragma once
-
-namespace vcpkg
-{
- struct LineInfo
- {
- int line_number;
- const char* file_name;
- };
-}
-
-#define VCPKG_LINE_INFO \
- vcpkg::LineInfo { __LINE__, __FILE__ }
diff --git a/toolsrc/include/vcpkg/base/lockguarded.h b/toolsrc/include/vcpkg/base/lockguarded.h
deleted file mode 100644
index e49b0b5d9..000000000
--- a/toolsrc/include/vcpkg/base/lockguarded.h
+++ /dev/null
@@ -1,35 +0,0 @@
-#pragma once
-
-#include <vcpkg/base/fwd/lockguarded.h>
-
-#include <mutex>
-
-namespace vcpkg::Util
-{
- template<class T>
- struct LockGuarded
- {
- friend struct LockGuardPtr<T>;
-
- LockGuardPtr<T> lock() { return *this; }
-
- private:
- std::mutex m_mutex;
- T m_t;
- };
-
- template<class T>
- struct LockGuardPtr
- {
- T& operator*() { return m_ptr; }
- T* operator->() { return &m_ptr; }
-
- T* get() { return &m_ptr; }
-
- LockGuardPtr(LockGuarded<T>& sync) : m_lock(sync.m_mutex), m_ptr(sync.m_t) { }
-
- private:
- std::unique_lock<std::mutex> m_lock;
- T& m_ptr;
- };
-}
diff --git a/toolsrc/include/vcpkg/base/machinetype.h b/toolsrc/include/vcpkg/base/machinetype.h
deleted file mode 100644
index b85cdbb0b..000000000
--- a/toolsrc/include/vcpkg/base/machinetype.h
+++ /dev/null
@@ -1,37 +0,0 @@
-#pragma once
-
-#include <cstdint>
-
-namespace vcpkg
-{
- enum class MachineType : uint16_t
- {
- UNKNOWN = 0x0, // The contents of this field are assumed to be applicable to any machine type
- AM33 = 0x1d3, // Matsushita AM33
- AMD64 = 0x8664, // x64
- ARM = 0x1c0, // ARM little endian
- ARM64 = 0xaa64, // ARM64 little endian
- ARMNT = 0x1c4, // ARM Thumb-2 little endian
- EBC = 0xebc, // EFI byte code
- I386 = 0x14c, // Intel 386 or later processors and compatible processors
- IA64 = 0x200, // Intel Itanium processor family
- M32R = 0x9041, // Mitsubishi M32R little endian
- MIPS16 = 0x266, // MIPS16
- MIPSFPU = 0x366, // MIPS with FPU
- MIPSFPU16 = 0x466, // MIPS16 with FPU
- POWERPC = 0x1f0, // Power PC little endian
- POWERPCFP = 0x1f1, // Power PC with floating point support
- R4000 = 0x166, // MIPS little endian
- RISCV32 = 0x5032, // RISC-V 32-bit address space
- RISCV64 = 0x5064, // RISC-V 64-bit address space
- RISCV128 = 0x5128, // RISC-V 128-bit address space
- SH3 = 0x1a2, // Hitachi SH3
- SH3DSP = 0x1a3, // Hitachi SH3 DSP
- SH4 = 0x1a6, // Hitachi SH4
- SH5 = 0x1a8, // Hitachi SH5
- THUMB = 0x1c2, // Thumb
- WCEMIPSV2 = 0x169, // MIPS little-endian WCE v2
- };
-
- MachineType to_machine_type(const uint16_t value);
-}
diff --git a/toolsrc/include/vcpkg/base/optional.h b/toolsrc/include/vcpkg/base/optional.h
deleted file mode 100644
index d8c72ca6d..000000000
--- a/toolsrc/include/vcpkg/base/optional.h
+++ /dev/null
@@ -1,382 +0,0 @@
-#pragma once
-
-#include <vcpkg/base/fwd/optional.h>
-
-#include <vcpkg/base/basic_checks.h>
-#include <vcpkg/base/lineinfo.h>
-#include <vcpkg/base/pragmas.h>
-
-#include <type_traits>
-#include <utility>
-
-namespace vcpkg
-{
- struct NullOpt
- {
- explicit constexpr NullOpt(int) { }
- };
-
- const static constexpr NullOpt nullopt{0};
-
- template<class T>
- struct Optional;
-
- namespace details
- {
- template<class T, bool B = std::is_copy_constructible<T>::value>
- struct OptionalStorage
- {
- VCPKG_MSVC_WARNING(suppress : 26495)
- constexpr OptionalStorage() noexcept : m_is_present(false), m_inactive() { }
- constexpr OptionalStorage(const T& t) : m_is_present(true), m_t(t) { }
- constexpr OptionalStorage(T&& t) : m_is_present(true), m_t(std::move(t)) { }
- template<class U, class = std::enable_if_t<!std::is_reference<U>::value>>
- explicit OptionalStorage(Optional<U>&& t) : m_is_present(false), m_inactive()
- {
- if (auto p = t.get())
- {
- m_is_present = true;
- new (&m_t) T(std::move(*p));
- }
- }
- template<class U>
- explicit OptionalStorage(const Optional<U>& t) : m_is_present(false), m_inactive()
- {
- if (auto p = t.get())
- {
- m_is_present = true;
- new (&m_t) T(*p);
- }
- }
-
- ~OptionalStorage() noexcept
- {
- if (m_is_present) m_t.~T();
- }
-
- VCPKG_MSVC_WARNING(suppress : 26495)
- OptionalStorage(const OptionalStorage& o) : m_is_present(o.m_is_present), m_inactive()
- {
- if (m_is_present) new (&m_t) T(o.m_t);
- }
-
- VCPKG_MSVC_WARNING(suppress : 26495)
- OptionalStorage(OptionalStorage&& o) noexcept : m_is_present(o.m_is_present), m_inactive()
- {
- if (m_is_present)
- {
- new (&m_t) T(std::move(o.m_t));
- }
- }
-
- OptionalStorage& operator=(const OptionalStorage& o)
- {
- if (m_is_present && o.m_is_present)
- {
- m_t = o.m_t;
- }
- else if (!m_is_present && o.m_is_present)
- {
- m_is_present = true;
- new (&m_t) T(o.m_t);
- }
- else if (m_is_present && !o.m_is_present)
- {
- clear();
- }
- return *this;
- }
-
- OptionalStorage& operator=(OptionalStorage&& o) noexcept
- {
- if (m_is_present && o.m_is_present)
- {
- m_t = std::move(o.m_t);
- }
- else if (!m_is_present && o.m_is_present)
- {
- m_is_present = true;
- new (&m_t) T(std::move(o.m_t));
- }
- else if (m_is_present && !o.m_is_present)
- {
- clear();
- }
- return *this;
- }
-
- constexpr bool has_value() const { return m_is_present; }
-
- const T& value() const { return this->m_t; }
- T& value() { return this->m_t; }
-
- private:
- void clear()
- {
- m_is_present = false;
- m_t.~T();
- m_inactive = '\0';
- }
-
- bool m_is_present;
- union
- {
- char m_inactive;
- T m_t;
- };
- };
-
- template<class T>
- struct OptionalStorage<T, false>
- {
- VCPKG_MSVC_WARNING(suppress : 26495)
- constexpr OptionalStorage() noexcept : m_is_present(false), m_inactive() { }
- constexpr OptionalStorage(T&& t) : m_is_present(true), m_t(std::move(t)) { }
-
- ~OptionalStorage() noexcept
- {
- if (m_is_present) m_t.~T();
- }
-
- VCPKG_MSVC_WARNING(suppress : 26495)
- OptionalStorage(OptionalStorage&& o) noexcept : m_is_present(o.m_is_present), m_inactive()
- {
- if (m_is_present)
- {
- new (&m_t) T(std::move(o.m_t));
- }
- }
-
- OptionalStorage& operator=(OptionalStorage&& o) noexcept
- {
- if (m_is_present && o.m_is_present)
- {
- m_t = std::move(o.m_t);
- }
- else if (!m_is_present && o.m_is_present)
- {
- m_is_present = true;
- new (&m_t) T(std::move(o.m_t));
- }
- else if (m_is_present && !o.m_is_present)
- {
- clear();
- }
- return *this;
- }
-
- constexpr bool has_value() const { return m_is_present; }
-
- const T& value() const { return this->m_t; }
- T& value() { return this->m_t; }
-
- private:
- void clear()
- {
- m_is_present = false;
- m_t.~T();
- m_inactive = '\0';
- }
-
- bool m_is_present;
- union
- {
- char m_inactive;
- T m_t;
- };
- };
-
- template<class T, bool B>
- struct OptionalStorage<T&, B>
- {
- constexpr OptionalStorage() noexcept : m_t(nullptr) { }
- constexpr OptionalStorage(T& t) : m_t(&t) { }
- constexpr OptionalStorage(Optional<T>& t) : m_t(t.get()) { }
-
- constexpr bool has_value() const { return m_t != nullptr; }
-
- T& value() const { return *this->m_t; }
-
- private:
- T* m_t;
- };
-
- template<class T, bool B>
- struct OptionalStorage<const T&, B>
- {
- constexpr OptionalStorage() noexcept : m_t(nullptr) { }
- constexpr OptionalStorage(const T& t) : m_t(&t) { }
- constexpr OptionalStorage(const Optional<T>& t) : m_t(t.get()) { }
- constexpr OptionalStorage(const Optional<const T>& t) : m_t(t.get()) { }
- constexpr OptionalStorage(Optional<T>&& t) = delete;
- constexpr OptionalStorage(Optional<const T>&& t) = delete;
-
- constexpr bool has_value() const { return m_t != nullptr; }
-
- const T& value() const { return *this->m_t; }
-
- private:
- const T* m_t;
- };
- }
-
- template<class T>
- struct Optional
- {
- constexpr Optional() noexcept { }
-
- // Constructors are intentionally implicit
- constexpr Optional(NullOpt) { }
-
- template<class U, class = std::enable_if_t<!std::is_same<std::decay_t<U>, Optional>::value>>
- constexpr Optional(U&& t) : m_base(std::forward<U>(t))
- {
- }
-
- T&& value_or_exit(const LineInfo& line_info) &&
- {
- Checks::check_exit(line_info, this->m_base.has_value(), "Value was null");
- return std::move(this->m_base.value());
- }
-
- T& value_or_exit(const LineInfo& line_info) &
- {
- Checks::check_exit(line_info, this->m_base.has_value(), "Value was null");
- return this->m_base.value();
- }
-
- const T& value_or_exit(const LineInfo& line_info) const&
- {
- Checks::check_exit(line_info, this->m_base.has_value(), "Value was null");
- return this->m_base.value();
- }
-
- constexpr explicit operator bool() const { return this->m_base.has_value(); }
-
- constexpr bool has_value() const { return this->m_base.has_value(); }
-
- template<class U>
- T value_or(U&& default_value) const&
- {
- return this->m_base.has_value() ? this->m_base.value() : static_cast<T>(std::forward<U>(default_value));
- }
-
- T value_or(T&& default_value) const&
- {
- return this->m_base.has_value() ? this->m_base.value() : static_cast<T&&>(default_value);
- }
-
- template<class U>
- T value_or(U&& default_value) &&
- {
- return this->m_base.has_value() ? std::move(this->m_base.value())
- : static_cast<T>(std::forward<U>(default_value));
- }
- T value_or(T&& default_value) &&
- {
- return this->m_base.has_value() ? std::move(this->m_base.value()) : static_cast<T&&>(default_value);
- }
-
- typename std::add_pointer<const T>::type get() const
- {
- return this->m_base.has_value() ? &this->m_base.value() : nullptr;
- }
-
- typename std::add_pointer<T>::type get() { return this->m_base.has_value() ? &this->m_base.value() : nullptr; }
-
- template<class F>
- using map_t = decltype(std::declval<F&>()(std::declval<const T&>()));
-
- template<class F, class U = map_t<F>>
- Optional<U> map(F f) const&
- {
- if (has_value())
- {
- return f(this->m_base.value());
- }
- return nullopt;
- }
-
- template<class F, class U = map_t<F>>
- U then(F f) const&
- {
- if (has_value())
- {
- return f(this->m_base.value());
- }
- return nullopt;
- }
-
- template<class F>
- using move_map_t = decltype(std::declval<F&>()(std::declval<T&&>()));
-
- template<class F, class U = move_map_t<F>>
- Optional<U> map(F f) &&
- {
- if (has_value())
- {
- return f(std::move(this->m_base.value()));
- }
- return nullopt;
- }
-
- template<class F, class U = move_map_t<F>>
- U then(F f) &&
- {
- if (has_value())
- {
- return f(std::move(this->m_base.value()));
- }
- return nullopt;
- }
-
- friend bool operator==(const Optional& lhs, const Optional& rhs)
- {
- if (lhs.m_base.has_value())
- {
- if (rhs.m_base.has_value())
- {
- return lhs.m_base.value() == rhs.m_base.value();
- }
-
- return false;
- }
-
- return !rhs.m_base.has_value();
- }
-
- private:
- details::OptionalStorage<T> m_base;
- };
-
- template<class U>
- Optional<std::decay_t<U>> make_optional(U&& u)
- {
- return Optional<std::decay_t<U>>(std::forward<U>(u));
- }
-
- template<class T>
- bool operator==(const Optional<T>& o, const T& t)
- {
- if (auto p = o.get()) return *p == t;
- return false;
- }
- template<class T>
- bool operator==(const T& t, const Optional<T>& o)
- {
- if (auto p = o.get()) return t == *p;
- return false;
- }
- template<class T>
- bool operator!=(const Optional<T>& o, const T& t)
- {
- if (auto p = o.get()) return *p != t;
- return true;
- }
- template<class T>
- bool operator!=(const T& t, const Optional<T>& o)
- {
- if (auto p = o.get()) return t != *p;
- return true;
- }
-}
diff --git a/toolsrc/include/vcpkg/base/parse.h b/toolsrc/include/vcpkg/base/parse.h
deleted file mode 100644
index b3577e821..000000000
--- a/toolsrc/include/vcpkg/base/parse.h
+++ /dev/null
@@ -1,129 +0,0 @@
-#pragma once
-
-#include <vcpkg/base/cstringview.h>
-#include <vcpkg/base/optional.h>
-#include <vcpkg/base/stringview.h>
-#include <vcpkg/base/unicode.h>
-
-#include <vcpkg/textrowcol.h>
-
-#include <memory>
-#include <string>
-
-namespace vcpkg::Parse
-{
- struct IParseError
- {
- virtual ~IParseError() = default;
- virtual std::string format() const = 0;
- virtual const std::string& get_message() const = 0;
- };
-
- struct ParseError : IParseError
- {
- ParseError(std::string origin, int row, int column, int caret_col, std::string line, std::string message)
- : origin(std::move(origin))
- , row(row)
- , column(column)
- , caret_col(caret_col)
- , line(std::move(line))
- , message(std::move(message))
- {
- }
-
- const std::string origin;
- const int row;
- const int column;
- const int caret_col;
- const std::string line;
- const std::string message;
-
- virtual std::string format() const override;
- virtual const std::string& get_message() const override;
- };
-
- struct ParserBase
- {
- struct SourceLoc
- {
- Unicode::Utf8Decoder it;
- Unicode::Utf8Decoder start_of_line;
- int row;
- int column;
- };
-
- ParserBase(StringView text, StringView origin, TextRowCol init_rowcol = {});
-
- static constexpr bool is_whitespace(char32_t ch) { return ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n'; }
- static constexpr bool is_lower_alpha(char32_t ch) { return ch >= 'a' && ch <= 'z'; }
- static constexpr bool is_upper_alpha(char32_t ch) { return ch >= 'A' && ch <= 'Z'; }
- static constexpr bool is_ascii_digit(char32_t ch) { return ch >= '0' && ch <= '9'; }
- static constexpr bool is_lineend(char32_t ch) { return ch == '\r' || ch == '\n' || ch == Unicode::end_of_file; }
- static constexpr bool is_alphanum(char32_t ch)
- {
- return is_upper_alpha(ch) || is_lower_alpha(ch) || is_ascii_digit(ch);
- }
- static constexpr bool is_alphanumdash(char32_t ch) { return is_alphanum(ch) || ch == '-'; }
-
- StringView skip_whitespace() { return match_zero_or_more(is_whitespace); }
- StringView skip_tabs_spaces()
- {
- return match_zero_or_more([](char32_t ch) { return ch == ' ' || ch == '\t'; });
- }
- void skip_to_eof() { m_it = m_it.end(); }
- void skip_newline()
- {
- if (cur() == '\r') next();
- if (cur() == '\n') next();
- }
- void skip_line()
- {
- match_until(is_lineend);
- skip_newline();
- }
-
- template<class Pred>
- StringView match_zero_or_more(Pred p)
- {
- const char* start = m_it.pointer_to_current();
- auto ch = cur();
- while (ch != Unicode::end_of_file && p(ch))
- ch = next();
- return {start, m_it.pointer_to_current()};
- }
- template<class Pred>
- StringView match_until(Pred p)
- {
- const char* start = m_it.pointer_to_current();
- auto ch = cur();
- while (ch != Unicode::end_of_file && !p(ch))
- ch = next();
- return {start, m_it.pointer_to_current()};
- }
-
- StringView text() const { return m_text; }
- Unicode::Utf8Decoder it() const { return m_it; }
- char32_t cur() const { return m_it == m_it.end() ? Unicode::end_of_file : *m_it; }
- SourceLoc cur_loc() const { return {m_it, m_start_of_line, m_row, m_column}; }
- TextRowCol cur_rowcol() const { return {m_row, m_column}; }
- char32_t next();
- bool at_eof() const { return m_it == m_it.end(); }
-
- void add_error(std::string message) { add_error(std::move(message), cur_loc()); }
- void add_error(std::string message, const SourceLoc& loc);
-
- const Parse::IParseError* get_error() const { return m_err.get(); }
- std::unique_ptr<Parse::IParseError> extract_error() { return std::move(m_err); }
-
- private:
- Unicode::Utf8Decoder m_it;
- Unicode::Utf8Decoder m_start_of_line;
- int m_row;
- int m_column;
-
- StringView m_text;
- StringView m_origin;
-
- std::unique_ptr<IParseError> m_err;
- };
-}
diff --git a/toolsrc/include/vcpkg/base/pragmas.h b/toolsrc/include/vcpkg/base/pragmas.h
deleted file mode 100644
index 06efd5105..000000000
--- a/toolsrc/include/vcpkg/base/pragmas.h
+++ /dev/null
@@ -1,35 +0,0 @@
-#pragma once
-
-#if defined(_MSC_VER) && _MSC_VER < 1911
-// [[nodiscard]] is not recognized before VS 2017 version 15.3
-#pragma warning(disable : 5030)
-#endif
-
-#if defined(_MSC_VER) && _MSC_VER < 1910
-// https://docs.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-level-3-c4800?view=vs-2019
-#pragma warning(disable : 4800)
-#endif
-
-#if defined(__GNUC__) && __GNUC__ < 7
-// [[nodiscard]] is not recognized before GCC version 7
-#pragma GCC diagnostic ignored "-Wattributes"
-#endif
-
-#if defined(_MSC_VER)
-#include <sal.h>
-#endif
-
-#if defined(_MSC_VER)
-#define ASSUME(expr) __assume(expr)
-#else
-#define ASSUME(expr)
-#endif
-
-// the static_assert(true, "")s are to avoid the extra ';' warning
-#ifdef _MSC_VER
-#define VCPKG_MSVC_WARNING(...) __pragma(warning(__VA_ARGS__))
-#define GCC_DIAGNOSTIC(...)
-#else
-#define VCPKG_MSVC_WARNING(...)
-#define GCC_DIAGNOSTIC(...) _Pragma("diagnostic " #__VA_ARGS__)
-#endif
diff --git a/toolsrc/include/vcpkg/base/sortedvector.h b/toolsrc/include/vcpkg/base/sortedvector.h
deleted file mode 100644
index 33379676e..000000000
--- a/toolsrc/include/vcpkg/base/sortedvector.h
+++ /dev/null
@@ -1,52 +0,0 @@
-#pragma once
-
-#include <algorithm>
-#include <vector>
-
-// Add more forwarding functions to the m_data std::vector as needed.
-namespace vcpkg
-{
- template<class T>
- class SortedVector
- {
- public:
- using size_type = typename std::vector<T>::size_type;
- using iterator = typename std::vector<T>::const_iterator;
-
- SortedVector() : m_data() { }
-
- explicit SortedVector(std::vector<T> v) : m_data(std::move(v))
- {
- if (!std::is_sorted(m_data.begin(), m_data.end()))
- {
- std::sort(m_data.begin(), m_data.end());
- }
- }
-
- template<class Compare>
- SortedVector(std::vector<T> v, Compare comp) : m_data(std::move(v))
- {
- if (!std::is_sorted(m_data.cbegin(), m_data.cend(), comp))
- {
- std::sort(m_data.begin(), m_data.end(), comp);
- }
- }
-
- iterator begin() const { return this->m_data.cbegin(); }
-
- iterator end() const { return this->m_data.cend(); }
-
- iterator cbegin() const { return this->m_data.cbegin(); }
-
- iterator cend() const { return this->m_data.cend(); }
-
- bool empty() const { return this->m_data.empty(); }
-
- size_type size() const { return this->m_data.size(); }
-
- const T& operator[](int i) const { return this->m_data[i]; }
-
- private:
- std::vector<T> m_data;
- };
-}
diff --git a/toolsrc/include/vcpkg/base/span.h b/toolsrc/include/vcpkg/base/span.h
deleted file mode 100644
index 7748222cf..000000000
--- a/toolsrc/include/vcpkg/base/span.h
+++ /dev/null
@@ -1,55 +0,0 @@
-#pragma once
-
-#include <vcpkg/base/fwd/span.h>
-
-#include <array>
-#include <cstddef>
-#include <initializer_list>
-#include <type_traits>
-#include <vector>
-
-namespace vcpkg
-{
- template<class T>
- struct Span
- {
- public:
- static_assert(std::is_object<T>::value, "Span<non-object-type> is illegal");
-
- using value_type = std::decay_t<T>;
- using element_type = T;
- using pointer = std::add_pointer_t<T>;
- using reference = std::add_lvalue_reference_t<T>;
- using iterator = pointer;
-
- constexpr Span() noexcept : m_ptr(nullptr), m_count(0) { }
- constexpr Span(std::nullptr_t) noexcept : m_ptr(nullptr), m_count(0) { }
- constexpr Span(pointer ptr, size_t count) noexcept : m_ptr(ptr), m_count(count) { }
- constexpr Span(pointer ptr_begin, pointer ptr_end) noexcept : m_ptr(ptr_begin), m_count(ptr_end - ptr_begin) { }
-
- template<size_t N>
- constexpr Span(T (&arr)[N]) noexcept : m_ptr(arr), m_count(N)
- {
- }
-
- template<class Range,
- class = decltype(std::declval<Range>().data()),
- class = std::enable_if_t<!std::is_same<std::decay_t<Range>, Span>::value>>
- constexpr Span(Range&& v) noexcept : Span(v.data(), v.size())
- {
- static_assert(std::is_same<typename std::decay_t<Range>::value_type, value_type>::value,
- "Cannot convert incompatible ranges");
- }
-
- constexpr iterator begin() const { return m_ptr; }
- constexpr iterator end() const { return m_ptr + m_count; }
-
- constexpr reference operator[](size_t i) const { return m_ptr[i]; }
- constexpr pointer data() const { return m_ptr; }
- constexpr size_t size() const { return m_count; }
-
- private:
- pointer m_ptr;
- size_t m_count;
- };
-}
diff --git a/toolsrc/include/vcpkg/base/stringliteral.h b/toolsrc/include/vcpkg/base/stringliteral.h
deleted file mode 100644
index 43d171829..000000000
--- a/toolsrc/include/vcpkg/base/stringliteral.h
+++ /dev/null
@@ -1,18 +0,0 @@
-#pragma once
-
-#include <vcpkg/base/zstringview.h>
-
-#include <string>
-
-namespace vcpkg
-{
- struct StringLiteral : ZStringView
- {
- template<int N>
- constexpr StringLiteral(const char (&str)[N]) : ZStringView(str)
- {
- }
-
- operator std::string() const { return std::string(data(), size()); }
- };
-}
diff --git a/toolsrc/include/vcpkg/base/strings.h b/toolsrc/include/vcpkg/base/strings.h
deleted file mode 100644
index 16b39001b..000000000
--- a/toolsrc/include/vcpkg/base/strings.h
+++ /dev/null
@@ -1,306 +0,0 @@
-#pragma once
-
-#include <vcpkg/base/cstringview.h>
-#include <vcpkg/base/optional.h>
-#include <vcpkg/base/pragmas.h>
-#include <vcpkg/base/stringliteral.h>
-#include <vcpkg/base/stringview.h>
-#include <vcpkg/base/view.h>
-
-#include <errno.h>
-#include <inttypes.h>
-#include <limits.h>
-
-#include <vector>
-
-namespace vcpkg::Strings::details
-{
- template<class T>
- auto to_string(const T& t) -> decltype(t.to_string())
- {
- return t.to_string();
- }
-
- // first looks up to_string on `T` using ADL; then, if that isn't found,
- // uses the above definition which returns t.to_string()
- template<class T, class = std::enable_if_t<!std::is_arithmetic<T>::value>>
- auto to_printf_arg(const T& t) -> decltype(to_string(t))
- {
- return to_string(t);
- }
-
- inline const char* to_printf_arg(const std::string& s) { return s.c_str(); }
-
- inline const char* to_printf_arg(const char* s) { return s; }
-
- inline const wchar_t* to_printf_arg(const wchar_t* s) { return s; }
-
- template<class T, class = std::enable_if_t<std::is_arithmetic<T>::value>>
- T to_printf_arg(T s)
- {
- return s;
- }
-
- std::string format_internal(const char* fmtstr, ...);
-
- inline void append_internal(std::string& into, char c) { into += c; }
- template<class T, class = decltype(std::to_string(std::declval<T>()))>
- inline void append_internal(std::string& into, T x)
- {
- into += std::to_string(x);
- }
- inline void append_internal(std::string& into, const char* v) { into.append(v); }
- inline void append_internal(std::string& into, const std::string& s) { into.append(s); }
- inline void append_internal(std::string& into, StringView s) { into.append(s.begin(), s.end()); }
-
- template<class T, class = decltype(std::declval<const T&>().to_string(std::declval<std::string&>()))>
- void append_internal(std::string& into, const T& t)
- {
- t.to_string(into);
- }
-
- template<class T, class = void, class = decltype(to_string(std::declval<std::string&>(), std::declval<const T&>()))>
- void append_internal(std::string& into, const T& t)
- {
- to_string(into, t);
- }
-
- struct tolower_char
- {
- char operator()(char c) const { return (c < 'A' || c > 'Z') ? c : c - 'A' + 'a'; }
- };
-}
-
-namespace vcpkg::Strings
-{
- template<class Arg>
- std::string& append(std::string& into, const Arg& a)
- {
- details::append_internal(into, a);
- return into;
- }
- template<class Arg, class... Args>
- std::string& append(std::string& into, const Arg& a, const Args&... args)
- {
- append(into, a);
- return append(into, args...);
- }
-
- template<class... Args>
- [[nodiscard]] std::string concat(const Args&... args)
- {
- std::string ret;
- append(ret, args...);
- return ret;
- }
-
- template<class... Args>
- [[nodiscard]] std::string concat(std::string&& first, const Args&... args)
- {
- append(first, args...);
- return std::move(first);
- }
-
- template<class... Args, class = void>
- std::string concat_or_view(const Args&... args)
- {
- return Strings::concat(args...);
- }
-
- template<class T, class = std::enable_if_t<std::is_convertible<T, StringView>::value>>
- StringView concat_or_view(const T& v)
- {
- return v;
- }
-
- template<class... Args>
- std::string format(const char* fmtstr, const Args&... args)
- {
- using vcpkg::Strings::details::to_printf_arg;
- return details::format_internal(fmtstr, to_printf_arg(to_printf_arg(args))...);
- }
-
-#if defined(_WIN32)
- std::wstring to_utf16(StringView s);
-
- std::string to_utf8(const wchar_t* w);
- inline std::string to_utf8(const std::wstring& ws) { return to_utf8(ws.c_str()); }
-#endif
-
- std::string escape_string(std::string&& s, char char_to_escape, char escape_char);
-
- bool case_insensitive_ascii_contains(StringView s, StringView pattern);
-
- bool case_insensitive_ascii_equals(StringView left, StringView right);
-
- template<class It>
- void ascii_to_lowercase(It first, It last)
- {
- std::transform(first, last, first, details::tolower_char{});
- }
- std::string ascii_to_lowercase(std::string&& s);
-
- std::string ascii_to_uppercase(std::string&& s);
-
- bool case_insensitive_ascii_starts_with(StringView s, StringView pattern);
- bool ends_with(StringView s, StringView pattern);
- bool starts_with(StringView s, StringView pattern);
-
- template<class InputIterator, class Transformer>
- std::string join(const char* delimiter, InputIterator begin, InputIterator end, Transformer transformer)
- {
- if (begin == end)
- {
- return std::string();
- }
-
- std::string output;
- append(output, transformer(*begin));
- for (auto it = std::next(begin); it != end; ++it)
- {
- output.append(delimiter);
- append(output, transformer(*it));
- }
-
- return output;
- }
-
- template<class Container, class Transformer>
- std::string join(const char* delimiter, const Container& v, Transformer transformer)
- {
- const auto begin = std::begin(v);
- const auto end = std::end(v);
-
- return join(delimiter, begin, end, transformer);
- }
-
- template<class InputIterator>
- std::string join(const char* delimiter, InputIterator begin, InputIterator end)
- {
- using Element = decltype(*begin);
- return join(delimiter, begin, end, [](const Element& x) -> const Element& { return x; });
- }
-
- template<class Container>
- std::string join(const char* delimiter, const Container& v)
- {
- using Element = decltype(*std::begin(v));
- return join(delimiter, v, [](const Element& x) -> const Element& { return x; });
- }
-
- std::string replace_all(std::string&& s, StringView search, StringView rep);
-
- void inplace_replace_all(std::string& s, StringView search, StringView rep);
-
- void inplace_replace_all(std::string& s, char search, char rep) noexcept;
-
- std::string trim(std::string&& s);
-
- StringView trim(StringView sv);
-
- void trim_all_and_remove_whitespace_strings(std::vector<std::string>* strings);
-
- std::vector<std::string> split(StringView s, const char delimiter);
-
- std::vector<std::string> split_paths(StringView s);
-
- const char* find_first_of(StringView searched, StringView candidates);
-
- std::vector<StringView> find_all_enclosed(StringView input, StringView left_delim, StringView right_delim);
-
- StringView find_exactly_one_enclosed(StringView input, StringView left_tag, StringView right_tag);
-
- Optional<StringView> find_at_most_one_enclosed(StringView input, StringView left_tag, StringView right_tag);
-
- bool equals(StringView a, StringView b);
-
- template<class T>
- std::string serialize(const T& t)
- {
- std::string ret;
- serialize(t, ret);
- return ret;
- }
-
- // Equivalent to one of the `::strto[T]` functions. Returns `nullopt` if there is an error.
- template<class T>
- Optional<T> strto(CStringView sv);
-
- template<>
- inline Optional<double> strto<double>(CStringView sv)
- {
- char* endptr = nullptr;
- double res = strtod(sv.c_str(), &endptr);
- if (endptr == sv.c_str())
- {
- // no digits
- return nullopt;
- }
- // else, we may have HUGE_VAL but we expect the caller to deal with that
- return res;
- }
-
- template<>
- inline Optional<long> strto<long>(CStringView sv)
- {
- char* endptr = nullptr;
- long res = strtol(sv.c_str(), &endptr, 10);
- if (endptr == sv.c_str())
- {
- // no digits
- return nullopt;
- }
- if (errno == ERANGE)
- {
- // out of bounds
- return nullopt;
- }
-
- return res;
- }
-
- template<>
- inline Optional<long long> strto<long long>(CStringView sv)
- {
- char* endptr = nullptr;
- long long res = strtoll(sv.c_str(), &endptr, 10);
- if (endptr == sv.c_str())
- {
- // no digits
- return nullopt;
- }
- if (errno == ERANGE)
- {
- // out of bounds
- return nullopt;
- }
-
- return res;
- }
-
- template<>
- inline Optional<int> strto<int>(CStringView sv)
- {
- auto res = strto<long>(sv);
- if (auto r = res.get())
- {
- if (*r < INT_MIN || *r > INT_MAX)
- {
- return nullopt;
- }
- return static_cast<int>(*r);
- }
- return nullopt;
- }
-
- const char* search(StringView haystack, StringView needle);
-
- bool contains(StringView haystack, StringView needle);
-
- // base 32 encoding, following IETC RFC 4648
- std::string b32_encode(std::uint64_t x) noexcept;
-
- // Implements https://en.wikipedia.org/wiki/Levenshtein_distance with a "give-up" clause for large strings
- // Guarantees 0 for equal strings and nonzero for inequal strings.
- size_t byte_edit_distance(StringView a, StringView b);
-}
diff --git a/toolsrc/include/vcpkg/base/stringview.h b/toolsrc/include/vcpkg/base/stringview.h
deleted file mode 100644
index c6e0c6350..000000000
--- a/toolsrc/include/vcpkg/base/stringview.h
+++ /dev/null
@@ -1,55 +0,0 @@
-#pragma once
-
-#include <vcpkg/base/fwd/stringview.h>
-
-#include <stddef.h>
-
-#include <iterator>
-#include <limits>
-#include <string>
-
-namespace vcpkg
-{
- struct StringView
- {
- constexpr StringView() = default;
- StringView(const std::string& s) noexcept; // Implicit by design
-
- // NOTE: we do this instead of the delegating constructor since delegating ctors are a perf footgun
- template<size_t Sz>
- constexpr StringView(const char (&arr)[Sz]) noexcept : m_ptr(arr), m_size(Sz - 1)
- {
- }
-
- constexpr StringView(const char* ptr, size_t size) noexcept : m_ptr(ptr), m_size(size) { }
- constexpr StringView(const char* b, const char* e) noexcept : m_ptr(b), m_size(static_cast<size_t>(e - b)) { }
-
- constexpr const char* begin() const noexcept { return m_ptr; }
- constexpr const char* end() const noexcept { return m_ptr + m_size; }
-
- std::reverse_iterator<const char*> rbegin() const noexcept { return std::make_reverse_iterator(end()); }
- std::reverse_iterator<const char*> rend() const noexcept { return std::make_reverse_iterator(begin()); }
-
- constexpr const char* data() const noexcept { return m_ptr; }
- constexpr size_t size() const noexcept { return m_size; }
- constexpr bool empty() const noexcept { return m_size == 0; }
-
- std::string to_string() const;
- void to_string(std::string& out) const;
-
- StringView substr(size_t pos, size_t count = std::numeric_limits<size_t>::max()) const noexcept;
-
- constexpr char byte_at_index(size_t pos) const noexcept { return m_ptr[pos]; }
-
- private:
- const char* m_ptr = 0;
- size_t m_size = 0;
- };
-
- bool operator==(StringView lhs, StringView rhs) noexcept;
- bool operator!=(StringView lhs, StringView rhs) noexcept;
- bool operator<(StringView lhs, StringView rhs) noexcept;
- bool operator>(StringView lhs, StringView rhs) noexcept;
- bool operator<=(StringView lhs, StringView rhs) noexcept;
- bool operator>=(StringView lhs, StringView rhs) noexcept;
-}
diff --git a/toolsrc/include/vcpkg/base/system.debug.h b/toolsrc/include/vcpkg/base/system.debug.h
deleted file mode 100644
index 898052a01..000000000
--- a/toolsrc/include/vcpkg/base/system.debug.h
+++ /dev/null
@@ -1,45 +0,0 @@
-#pragma once
-
-#include <vcpkg/base/chrono.h>
-#include <vcpkg/base/lineinfo.h>
-#include <vcpkg/base/system.print.h>
-
-#include <atomic>
-
-namespace vcpkg::Debug
-{
- extern std::atomic<bool> g_debugging;
-
- template<class... Args>
- void print(const Args&... args)
- {
- if (g_debugging) System::print2("[DEBUG] ", args...);
- }
-
- template<class F, class R = std::result_of_t<F && ()>, class = std::enable_if_t<!std::is_void<R>::value>>
- R time(LineInfo line, F&& f)
- {
- if (g_debugging)
- {
- auto timer = Chrono::ElapsedTimer::create_started();
- auto&& result = f();
- System::print2("[DEBUG] ", line, " took ", timer, '\n');
- return static_cast<R&&>(result);
- }
- else
- return f();
- }
-
- template<class F, class R = std::result_of_t<F && ()>, class = std::enable_if_t<std::is_void<R>::value>>
- void time(LineInfo line, F&& f)
- {
- if (g_debugging)
- {
- auto timer = Chrono::ElapsedTimer::create_started();
- f();
- System::print2("[DEBUG] ", line, " took ", timer, '\n');
- }
- else
- f();
- }
-}
diff --git a/toolsrc/include/vcpkg/base/system.h b/toolsrc/include/vcpkg/base/system.h
deleted file mode 100644
index 992533eb5..000000000
--- a/toolsrc/include/vcpkg/base/system.h
+++ /dev/null
@@ -1,50 +0,0 @@
-#pragma once
-
-#include <vcpkg/base/files.h>
-#include <vcpkg/base/optional.h>
-#include <vcpkg/base/stringview.h>
-#include <vcpkg/base/zstringview.h>
-
-namespace vcpkg::System
-{
- Optional<std::string> get_environment_variable(ZStringView varname) noexcept;
- void set_environment_variable(ZStringView varname, Optional<ZStringView> value) noexcept;
-
- const ExpectedS<fs::path>& get_home_dir() noexcept;
-
- const ExpectedS<fs::path>& get_platform_cache_home() noexcept;
-
-#ifdef _WIN32
- const ExpectedS<fs::path>& get_appdata_local() noexcept;
-#endif
-
- Optional<std::string> get_registry_string(void* base_hkey, StringView subkey, StringView valuename);
-
- long get_process_id();
-
- enum class CPUArchitecture
- {
- X86,
- X64,
- ARM,
- ARM64,
- S390X,
- PPC64LE,
- };
-
- Optional<CPUArchitecture> to_cpu_architecture(StringView arch);
-
- ZStringView to_zstring_view(CPUArchitecture arch) noexcept;
-
- CPUArchitecture get_host_processor();
-
- std::vector<CPUArchitecture> get_supported_host_architectures();
-
- const Optional<fs::path>& get_program_files_32_bit();
-
- const Optional<fs::path>& get_program_files_platform_bitness();
-
- int get_num_logical_cores();
-
- Optional<CPUArchitecture> guess_visual_studio_prompt_target_architecture();
-}
diff --git a/toolsrc/include/vcpkg/base/system.print.h b/toolsrc/include/vcpkg/base/system.print.h
deleted file mode 100644
index abe685cf5..000000000
--- a/toolsrc/include/vcpkg/base/system.print.h
+++ /dev/null
@@ -1,67 +0,0 @@
-#pragma once
-
-#include <vcpkg/base/strings.h>
-#include <vcpkg/base/view.h>
-
-namespace vcpkg::System
-{
- enum class Color
- {
- success = 10,
- error = 12,
- warning = 14,
- };
-
- namespace details
- {
- void print(StringView message);
- void print(const Color c, StringView message);
- }
-
- template<class Arg1, class... Args>
- void printf(const char* message_template, const Arg1& message_arg1, const Args&... message_args)
- {
- return ::vcpkg::System::details::print(Strings::format(message_template, message_arg1, message_args...));
- }
-
- template<class Arg1, class... Args>
- void printf(const Color c, const char* message_template, const Arg1& message_arg1, const Args&... message_args)
- {
- return ::vcpkg::System::details::print(c, Strings::format(message_template, message_arg1, message_args...));
- }
-
- template<class... Args>
- void print2(const Color c, const Args&... args)
- {
- ::vcpkg::System::details::print(c, Strings::concat_or_view(args...));
- }
-
- template<class... Args>
- void print2(const Args&... args)
- {
- ::vcpkg::System::details::print(Strings::concat_or_view(args...));
- }
-
- class BufferedPrint
- {
- ::std::string stdout_buffer;
- static constexpr ::std::size_t buffer_size_target = 2048;
- static constexpr ::std::size_t expected_maximum_print = 256;
- static constexpr ::std::size_t alloc_size = buffer_size_target + expected_maximum_print;
-
- public:
- BufferedPrint() { stdout_buffer.reserve(alloc_size); }
- BufferedPrint(const BufferedPrint&) = delete;
- BufferedPrint& operator=(const BufferedPrint&) = delete;
- void append(::vcpkg::StringView nextView)
- {
- stdout_buffer.append(nextView.data(), nextView.size());
- if (stdout_buffer.size() > buffer_size_target)
- {
- ::vcpkg::System::details::print(stdout_buffer);
- stdout_buffer.clear();
- }
- }
- ~BufferedPrint() { ::vcpkg::System::details::print(stdout_buffer); }
- };
-}
diff --git a/toolsrc/include/vcpkg/base/system.process.h b/toolsrc/include/vcpkg/base/system.process.h
deleted file mode 100644
index 5b6f8cd55..000000000
--- a/toolsrc/include/vcpkg/base/system.process.h
+++ /dev/null
@@ -1,144 +0,0 @@
-#pragma once
-
-#include <vcpkg/base/files.h>
-#include <vcpkg/base/zstringview.h>
-
-#include <functional>
-#include <string>
-#include <unordered_map>
-#include <vector>
-
-namespace vcpkg::System
-{
- struct CMakeVariable
- {
- CMakeVariable(const StringView varname, const char* varvalue);
- CMakeVariable(const StringView varname, const std::string& varvalue);
- CMakeVariable(const StringView varname, const fs::path& path);
- CMakeVariable(std::string var);
-
- std::string s;
- };
-
- struct Command
- {
- Command() = default;
- explicit Command(const fs::path& p) { path_arg(p); }
- explicit Command(StringView s) { string_arg(s); }
- explicit Command(const std::string& s) { string_arg(s); }
- explicit Command(const char* s) { string_arg({s, ::strlen(s)}); }
-
- Command& path_arg(const fs::path& p) & { return string_arg(fs::u8string(p)); }
- Command& string_arg(StringView s) &;
- Command& raw_arg(StringView s) &
- {
- buf.push_back(' ');
- buf.append(s.data(), s.size());
- return *this;
- }
-
- Command&& path_arg(const fs::path& p) && { return std::move(path_arg(p)); }
- Command&& string_arg(StringView s) && { return std::move(string_arg(s)); };
- Command&& raw_arg(StringView s) && { return std::move(raw_arg(s)); }
-
- std::string&& extract() && { return std::move(buf); }
- StringView command_line() const { return buf; }
-
- void clear() { buf.clear(); }
- bool empty() const { return buf.empty(); }
-
- private:
- std::string buf;
- };
-
- struct CommandLess
- {
- bool operator()(const Command& lhs, const Command& rhs) const
- {
- return lhs.command_line() < rhs.command_line();
- }
- };
-
- Command make_basic_cmake_cmd(const fs::path& cmake_tool_path,
- const fs::path& cmake_script,
- const std::vector<CMakeVariable>& pass_variables);
-
- fs::path get_exe_path_of_current_process();
-
- struct ExitCodeAndOutput
- {
- int exit_code;
- std::string output;
- };
-
- struct Environment
- {
-#if defined(_WIN32)
- std::wstring m_env_data;
-#endif
- };
-
- const Environment& get_clean_environment();
- Environment get_modified_clean_environment(const std::unordered_map<std::string, std::string>& extra_env,
- const std::string& prepend_to_path = {});
-
- struct InWorkingDirectory
- {
- const fs::path& working_directory;
- };
-
- int cmd_execute(const Command& cmd_line, InWorkingDirectory wd, const Environment& env = {});
- inline int cmd_execute(const Command& cmd_line, const Environment& env = {})
- {
- return cmd_execute(cmd_line, InWorkingDirectory{fs::path()}, env);
- }
-
- int cmd_execute_clean(const Command& cmd_line, InWorkingDirectory wd);
- inline int cmd_execute_clean(const Command& cmd_line)
- {
- return cmd_execute_clean(cmd_line, InWorkingDirectory{fs::path()});
- }
-
-#if defined(_WIN32)
- Environment cmd_execute_modify_env(const Command& cmd_line, const Environment& env = {});
-
- void cmd_execute_background(const Command& cmd_line);
-#endif
-
- ExitCodeAndOutput cmd_execute_and_capture_output(const Command& cmd_line,
- InWorkingDirectory wd,
- const Environment& env = {});
- inline ExitCodeAndOutput cmd_execute_and_capture_output(const Command& cmd_line, const Environment& env = {})
- {
- return cmd_execute_and_capture_output(cmd_line, InWorkingDirectory{fs::path()}, env);
- }
-
- int cmd_execute_and_stream_lines(const Command& cmd_line,
- InWorkingDirectory wd,
- std::function<void(StringView)> per_line_cb,
- const Environment& env = {});
- inline int cmd_execute_and_stream_lines(const Command& cmd_line,
- std::function<void(StringView)> per_line_cb,
- const Environment& env = {})
- {
- return cmd_execute_and_stream_lines(cmd_line, InWorkingDirectory{fs::path()}, std::move(per_line_cb), env);
- }
-
- int cmd_execute_and_stream_data(const Command& cmd_line,
- InWorkingDirectory wd,
- std::function<void(StringView)> data_cb,
- const Environment& env = {});
- inline int cmd_execute_and_stream_data(const Command& cmd_line,
- std::function<void(StringView)> data_cb,
- const Environment& env = {})
- {
- return cmd_execute_and_stream_data(cmd_line, InWorkingDirectory{fs::path()}, std::move(data_cb), env);
- }
-
- void register_console_ctrl_handler();
-#if defined(_WIN32)
- void initialize_global_job_object();
- void enter_interactive_subprocess();
- void exit_interactive_subprocess();
-#endif
-}
diff --git a/toolsrc/include/vcpkg/base/system_headers.h b/toolsrc/include/vcpkg/base/system_headers.h
deleted file mode 100644
index 6667fd395..000000000
--- a/toolsrc/include/vcpkg/base/system_headers.h
+++ /dev/null
@@ -1,40 +0,0 @@
-#pragma once
-
-#if defined(_WIN32)
-
-#ifndef NOMINMAX
-#define NOMINMAX
-#endif
-
-#ifndef WIN32_LEAN_AND_MEAN
-#define WIN32_LEAN_AND_MEAN
-#endif
-
-#pragma warning(suppress : 4768)
-#include <windows.h>
-
-#pragma warning(suppress : 4768)
-#include <Shlobj.h>
-
-#else // ^^^^ Windows / Unix vvvv
-
-// 2020-05-19: workaround for a c standard library bug
-// ctermid is not behind an `extern "C"` barrier, so it's linked incorrectly.
-// This has been reported; remove it after 2023-05-19
-#if __APPLE__
-extern "C"
-{
-#endif
-
-#include <unistd.h>
-
-#if __APPLE__
-}
-#endif
-
-#endif
-
-#include <sys/types.h>
-// glibc defines major and minor in sys/types.h, and should not
-#undef major
-#undef minor
diff --git a/toolsrc/include/vcpkg/base/uint128.h b/toolsrc/include/vcpkg/base/uint128.h
deleted file mode 100644
index feac68bb7..000000000
--- a/toolsrc/include/vcpkg/base/uint128.h
+++ /dev/null
@@ -1,24 +0,0 @@
-#pragma once
-
-#include <stdint.h>
-
-namespace vcpkg
-{
- struct UInt128
- {
- UInt128() = default;
- UInt128(uint64_t value) : bottom(value), top(0) { }
-
- UInt128& operator<<=(int by) noexcept;
- UInt128& operator>>=(int by) noexcept;
- UInt128& operator+=(uint64_t lhs) noexcept;
-
- uint64_t bottom_64_bits() const noexcept { return bottom; }
- uint64_t top_64_bits() const noexcept { return top; }
-
- private:
- uint64_t bottom;
- uint64_t top;
- };
-
-}
diff --git a/toolsrc/include/vcpkg/base/unicode.h b/toolsrc/include/vcpkg/base/unicode.h
deleted file mode 100644
index c2143a235..000000000
--- a/toolsrc/include/vcpkg/base/unicode.h
+++ /dev/null
@@ -1,148 +0,0 @@
-#pragma once
-
-#include <stddef.h>
-
-namespace vcpkg::Unicode
-{
- enum class Utf8CodeUnitKind
- {
- Invalid = -1,
- Continue = 0,
- StartOne = 1,
- StartTwo = 2,
- StartThree = 3,
- StartFour = 4,
- };
-
- Utf8CodeUnitKind utf8_code_unit_kind(unsigned char code_unit) noexcept;
- int utf8_code_unit_count(Utf8CodeUnitKind kind) noexcept;
- int utf8_code_unit_count(char code_unit) noexcept;
-
- int utf8_encode_code_point(char (&array)[4], char32_t code_point) noexcept;
-
- template<class String>
- String& utf8_append_code_point(String& str, char32_t code_point)
- {
- char buf[4] = {};
- int count = ::vcpkg::Unicode::utf8_encode_code_point(buf, code_point);
- str.append(buf, buf + count);
- return str;
- }
-
- bool utf8_is_valid_string(const char* first, const char* last) noexcept;
-
- constexpr bool utf16_is_leading_surrogate_code_point(char32_t code_point)
- {
- return code_point >= 0xD800 && code_point < 0xDC00;
- }
- constexpr bool utf16_is_trailing_surrogate_code_point(char32_t code_point)
- {
- return code_point >= 0xDC00 && code_point < 0xE000;
- }
- constexpr bool utf16_is_surrogate_code_point(char32_t code_point)
- {
- return code_point >= 0xD800 && code_point < 0xE000;
- }
-
- char32_t utf16_surrogates_to_code_point(char32_t leading, char32_t trailing);
-
- constexpr static char32_t end_of_file = 0xFFFF'FFFF;
-
- enum class utf8_errc
- {
- NoError = 0,
- InvalidCodeUnit = 1,
- InvalidCodePoint = 2,
- PairedSurrogates = 3,
- UnexpectedContinue = 4,
- UnexpectedStart = 5,
- UnexpectedEof = 6,
- };
-
- struct utf8_category : std::error_category
- {
- const char* name() const noexcept override;
- std::string message(int condition) const override;
- };
-
- inline std::error_code make_error_code(utf8_errc err) noexcept
- {
- return std::error_code(static_cast<int>(err), utf8_category());
- }
-
- /*
- There are two ways to parse utf-8: we could allow unpaired surrogates (as in [wtf-8]) -- this is important
- for representing things like file paths on Windows. We could also require strict utf-8, as in the JSON
- specification. We need both, since when parsing JSON, we need to require strict utf-8; however, when
- outputting JSON, we need to be able to stringify unpaired surrogates (as '\uDxyz'). This dichotomy is an
- issue _because_ we need to be able to decode two different kinds of utf-8: utf-8 as read off of a disk
- (strict), and utf-8 as contained in a C++ string (non-strict).
-
- Since one is a strict superset of the other, we allow the non-strict utf-8 in this decoder; if a consumer
- wishes to make certain that the utf-8 is strictly conforming, it will have to do the check on it's own with
- `utf16_is_surrogate_code_point`.
-
- [wtf-8]: https://simonsapin.github.io/wtf-8/
- */
- struct Utf8Decoder
- {
- Utf8Decoder() noexcept;
- Utf8Decoder(const char* first, const char* last) noexcept;
-
- struct sentinel
- {
- };
-
- bool is_eof() const noexcept;
-
- void next(std::error_code& ec);
-
- Utf8Decoder& operator=(sentinel) noexcept;
-
- char const* pointer_to_current() const noexcept;
-
- char32_t operator*() const noexcept;
-
- Utf8Decoder& operator++() noexcept;
- Utf8Decoder operator++(int) noexcept
- {
- auto res = *this;
- ++*this;
- return res;
- }
-
- Utf8Decoder begin() const { return *this; }
-
- sentinel end() const { return sentinel(); }
-
- friend bool operator==(const Utf8Decoder& lhs, const Utf8Decoder& rhs) noexcept;
-
- using difference_type = std::ptrdiff_t;
- using value_type = char32_t;
- using pointer = void;
- using reference = char32_t;
- using iterator_category = std::forward_iterator_tag;
-
- private:
- char32_t current_;
- const char* next_;
- const char* last_;
- };
-
- inline bool operator!=(const Utf8Decoder& lhs, const Utf8Decoder& rhs) noexcept { return !(lhs == rhs); }
-
- inline bool operator==(const Utf8Decoder& d, Utf8Decoder::sentinel) { return d.is_eof(); }
- inline bool operator==(Utf8Decoder::sentinel s, const Utf8Decoder& d) { return d == s; }
- inline bool operator!=(const Utf8Decoder& d, Utf8Decoder::sentinel) { return !d.is_eof(); }
- inline bool operator!=(Utf8Decoder::sentinel s, const Utf8Decoder& d) { return d != s; }
-
-}
-
-namespace std
-{
- template<>
- struct is_error_code_enum<vcpkg::Unicode::utf8_errc> : std::true_type
- {
- };
-
-}
diff --git a/toolsrc/include/vcpkg/base/util.h b/toolsrc/include/vcpkg/base/util.h
deleted file mode 100644
index b5ad1d04f..000000000
--- a/toolsrc/include/vcpkg/base/util.h
+++ /dev/null
@@ -1,248 +0,0 @@
-#pragma once
-
-#include <vcpkg/base/optional.h>
-#include <vcpkg/base/view.h>
-
-#include <algorithm>
-#include <functional>
-#include <map>
-#include <type_traits>
-#include <unordered_map>
-#include <utility>
-#include <vector>
-
-namespace vcpkg::Util
-{
- template<class Container>
- using ElementT =
- std::remove_reference_t<decltype(*std::declval<typename std::remove_reference_t<Container>::iterator>())>;
-
- namespace Vectors
- {
- template<class Container, class T = ElementT<Container>>
- void append(std::vector<T>* augend, const Container& addend)
- {
- augend->insert(augend->end(), addend.begin(), addend.end());
- }
- template<class Vec, class Key>
- bool contains(const Vec& container, const Key& item)
- {
- return std::find(container.begin(), container.end(), item) != container.end();
- }
- template<class T>
- std::vector<T> concat(View<T> r1, View<T> r2)
- {
- std::vector<T> v;
- v.reserve(r1.size() + r2.size());
- v.insert(v.end(), r1.begin(), r1.end());
- v.insert(v.end(), r2.begin(), r2.end());
- return v;
- }
- }
-
- namespace Sets
- {
- template<class Container, class Key>
- bool contains(const Container& container, const Key& item)
- {
- return container.find(item) != container.end();
- }
- }
-
- namespace Maps
- {
- template<class K, class V1, class V2, class Func>
- void transform_values(const std::unordered_map<K, V1>& container, std::unordered_map<K, V2>& output, Func func)
- {
- std::for_each(container.cbegin(), container.cend(), [&](const std::pair<const K, V1>& p) {
- output[p.first] = func(p.second);
- });
- }
- }
-
- template<class Range, class Pred, class E = ElementT<Range>>
- std::vector<E> filter(const Range& xs, Pred&& f)
- {
- std::vector<E> ret;
-
- for (auto&& x : xs)
- {
- if (f(x)) ret.push_back(x);
- }
-
- return ret;
- }
-
- template<class Range, class Func>
- using FmapRefOut = decltype(std::declval<Func&>()(*std::declval<Range>().begin()));
-
- template<class Range, class Func>
- using FmapOut = std::decay_t<FmapRefOut<Range, Func>>;
-
- template<class Range, class Func, class Out = FmapOut<Range, Func>>
- std::vector<Out> fmap(Range&& xs, Func&& f)
- {
- std::vector<Out> ret;
- ret.reserve(xs.size());
-
- for (auto&& x : xs)
- ret.push_back(f(x));
-
- return ret;
- }
-
- template<class Range, class Proj, class Out = FmapRefOut<Range, Proj>>
- Optional<Out> common_projection(Range&& input, Proj&& proj)
- {
- const auto last = input.end();
- auto first = input.begin();
- if (first == last)
- {
- return nullopt;
- }
-
- Out prototype = proj(*first);
- while (++first != last)
- {
- if (prototype != proj(*first))
- {
- return nullopt;
- }
- }
-
- return prototype;
- }
-
- template<class Cont, class Func>
- using FmapFlattenOut = std::decay_t<decltype(*begin(std::declval<Func>()(*begin(std::declval<Cont>()))))>;
-
- template<class Cont, class Func, class Out = FmapFlattenOut<Cont, Func>>
- std::vector<Out> fmap_flatten(Cont&& xs, Func&& f)
- {
- std::vector<Out> ret;
-
- for (auto&& x : xs)
- for (auto&& y : f(x))
- ret.push_back(std::move(y));
-
- return ret;
- }
-
- template<class Container, class Pred>
- void erase_remove_if(Container& cont, Pred pred)
- {
- cont.erase(std::remove_if(cont.begin(), cont.end(), pred), cont.end());
- }
-
- template<class Container, class V>
- auto find(Container&& cont, V&& v)
- {
- using std::begin;
- using std::end;
- return std::find(begin(cont), end(cont), v);
- }
-
- template<class Container, class Pred>
- auto find_if(Container&& cont, Pred pred)
- {
- using std::begin;
- using std::end;
- return std::find_if(begin(cont), end(cont), pred);
- }
-
- template<class Container, class Pred>
- auto find_if_not(Container&& cont, Pred pred)
- {
- using std::begin;
- using std::end;
- return std::find_if_not(begin(cont), end(cont), pred);
- }
-
- template<class K, class V, class Container, class Func>
- void group_by(const Container& cont, std::map<K, std::vector<const V*>>* output, Func&& f)
- {
- for (const V& element : cont)
- {
- K key = f(element);
- (*output)[key].push_back(&element);
- }
- }
-
- template<class Range, class Comp = std::less<typename Range::value_type>>
- void sort(Range& cont, Comp comp = Comp())
- {
- using std::begin;
- using std::end;
- std::sort(begin(cont), end(cont), comp);
- }
-
- template<class Range, class Pred>
- bool any_of(Range&& rng, Pred pred)
- {
- return std::any_of(rng.begin(), rng.end(), std::move(pred));
- }
-
- template<class Range>
- Range&& sort_unique_erase(Range&& cont)
- {
- using std::begin;
- using std::end;
- std::sort(begin(cont), end(cont));
- cont.erase(std::unique(begin(cont), end(cont)), end(cont));
-
- return std::forward<Range>(cont);
- }
-
- template<class Range1, class Range2>
- bool all_equal(const Range1& r1, const Range2& r2)
- {
- using std::begin;
- using std::end;
- return std::equal(begin(r1), end(r1), begin(r2), end(r2));
- }
-
- template<class AssocContainer, class K = std::decay_t<decltype(begin(std::declval<AssocContainer>())->first)>>
- std::vector<K> extract_keys(AssocContainer&& input_map)
- {
- return fmap(input_map, [](auto&& p) { return p.first; });
- }
-
- struct MoveOnlyBase
- {
- MoveOnlyBase() = default;
- MoveOnlyBase(const MoveOnlyBase&) = delete;
- MoveOnlyBase(MoveOnlyBase&&) = default;
-
- MoveOnlyBase& operator=(const MoveOnlyBase&) = delete;
- MoveOnlyBase& operator=(MoveOnlyBase&&) = default;
-
- ~MoveOnlyBase() = default;
- };
-
- struct ResourceBase
- {
- ResourceBase() = default;
- ResourceBase(const ResourceBase&) = delete;
- ResourceBase(ResourceBase&&) = delete;
-
- ResourceBase& operator=(const ResourceBase&) = delete;
- ResourceBase& operator=(ResourceBase&&) = delete;
-
- ~ResourceBase() = default;
- };
-
- namespace Enum
- {
- template<class E>
- E to_enum(bool b)
- {
- return b ? E::YES : E::NO;
- }
-
- template<class E>
- bool to_bool(E e)
- {
- return e == E::YES;
- }
- }
-}
diff --git a/toolsrc/include/vcpkg/base/view.h b/toolsrc/include/vcpkg/base/view.h
deleted file mode 100644
index 12908c4a5..000000000
--- a/toolsrc/include/vcpkg/base/view.h
+++ /dev/null
@@ -1,3 +0,0 @@
-#pragma once
-
-#include <vcpkg/base/span.h>
diff --git a/toolsrc/include/vcpkg/base/xmlserializer.h b/toolsrc/include/vcpkg/base/xmlserializer.h
deleted file mode 100644
index 33b7c0811..000000000
--- a/toolsrc/include/vcpkg/base/xmlserializer.h
+++ /dev/null
@@ -1,31 +0,0 @@
-#pragma once
-
-#include <vcpkg/base/stringliteral.h>
-#include <vcpkg/base/stringview.h>
-
-#include <string>
-
-namespace vcpkg
-{
- struct XmlSerializer
- {
- XmlSerializer& emit_declaration();
- XmlSerializer& open_tag(StringLiteral sl);
- XmlSerializer& start_complex_open_tag(StringLiteral sl);
- XmlSerializer& text_attr(StringLiteral name, StringView content);
- XmlSerializer& finish_complex_open_tag();
- XmlSerializer& finish_self_closing_complex_tag();
- XmlSerializer& close_tag(StringLiteral sl);
- XmlSerializer& text(StringView sv);
- XmlSerializer& simple_tag(StringLiteral tag, StringView content);
- XmlSerializer& line_break();
-
- std::string buf;
-
- private:
- XmlSerializer& emit_pending_indent();
-
- int m_indent = 0;
- bool m_pending_indent = false;
- };
-}
diff --git a/toolsrc/include/vcpkg/base/zstringview.h b/toolsrc/include/vcpkg/base/zstringview.h
deleted file mode 100644
index ab2c23251..000000000
--- a/toolsrc/include/vcpkg/base/zstringview.h
+++ /dev/null
@@ -1,52 +0,0 @@
-#pragma once
-
-#include <vcpkg/base/stringview.h>
-
-#include <algorithm>
-#include <cstddef>
-#include <cstring>
-#include <string>
-
-namespace vcpkg
-{
- // A counted view of a null-terminated string
- struct ZStringView
- {
- using value_type = char;
-
- constexpr ZStringView() : m_size(0), m_cstr("") { }
-
- template<int N>
- constexpr ZStringView(const char (&str)[N])
- : m_size(N - 1) /* -1 here accounts for the null byte at the end*/, m_cstr(str)
- {
- }
-
- ZStringView(const std::string& s) : m_size(s.size()), m_cstr(s.c_str()) { }
- constexpr ZStringView(const char* str, size_t sz) : m_size(sz), m_cstr(str) { }
-
- constexpr const char* data() const { return m_cstr; }
- constexpr size_t size() const { return m_size; }
- constexpr char operator[](ptrdiff_t off) const { return m_cstr[off]; }
-
- constexpr const char* c_str() const { return m_cstr; }
-
- constexpr const char* begin() const { return m_cstr; }
- constexpr const char* end() const { return m_cstr + m_size; }
-
- std::string to_string() const { return std::string(m_cstr, m_size); }
- void to_string(std::string& out) const { out.append(m_cstr, m_size); }
-
- constexpr operator StringView() const { return StringView(m_cstr, m_size); }
-
- private:
- size_t m_size;
- const char* m_cstr;
- };
-
- inline bool operator==(ZStringView l, ZStringView r) { return std::equal(l.begin(), l.end(), r.begin(), r.end()); }
- inline bool operator!=(ZStringView l, ZStringView r) { return !std::equal(l.begin(), l.end(), r.begin(), r.end()); }
-
- inline bool operator==(const char* l, ZStringView r) { return strcmp(l, r.c_str()) == 0; }
- inline bool operator==(ZStringView l, const char* r) { return strcmp(l.c_str(), r) == 0; }
-}
diff --git a/toolsrc/include/vcpkg/binarycaching.h b/toolsrc/include/vcpkg/binarycaching.h
deleted file mode 100644
index 5a127cb5c..000000000
--- a/toolsrc/include/vcpkg/binarycaching.h
+++ /dev/null
@@ -1,62 +0,0 @@
-#pragma once
-
-#include <vcpkg/fwd/dependencies.h>
-#include <vcpkg/fwd/vcpkgpaths.h>
-
-#include <vcpkg/base/expected.h>
-#include <vcpkg/base/files.h>
-
-#include <vcpkg/packagespec.h>
-
-#include <unordered_map>
-
-namespace vcpkg
-{
- struct MergeBinaryProviders;
-
- enum class RestoreResult
- {
- missing,
- success,
- build_failed,
- };
-
- struct IBinaryProvider
- {
- virtual ~IBinaryProvider() = default;
-
- /// Attempts to restore the package referenced by `action` into the packages directory.
- virtual RestoreResult try_restore(const VcpkgPaths& paths, const Dependencies::InstallPlanAction& action) = 0;
-
- /// Called upon a successful build of `action`
- virtual void push_success(const VcpkgPaths& paths, const Dependencies::InstallPlanAction& action) = 0;
-
- /// <summary>Gives the BinaryProvider an opportunity to batch any downloading or server communication for
- /// executing `plan`.</summary>
- /// <remarks>Must only be called once for a given binary provider instance</remarks>
- /// <param name="actions">InOut vector of actions to be prefetched</param>
- virtual void prefetch(const VcpkgPaths& paths,
- std::vector<const Dependencies::InstallPlanAction*>& actions) = 0;
-
- /// <summary>Requests the result of <c>try_restore()</c> without actually downloading the package. Used by CI to
- /// determine missing packages.</summary>
- /// <param name="results_map">InOut map to track the restored packages. Should be initialized to
- /// <c>{&amp;action, RestoreResult::missing}</c> for all install actions</param>
- virtual void precheck(
- const VcpkgPaths& paths,
- std::unordered_map<const Dependencies::InstallPlanAction*, RestoreResult>& results_map) = 0;
- };
-
- std::unordered_map<const Dependencies::InstallPlanAction*, RestoreResult> binary_provider_precheck(
- const VcpkgPaths& paths, const Dependencies::ActionPlan& plan, IBinaryProvider& provider);
-
- IBinaryProvider& null_binary_provider();
-
- ExpectedS<std::unique_ptr<IBinaryProvider>> create_binary_provider_from_configs(View<std::string> args);
- ExpectedS<std::unique_ptr<IBinaryProvider>> create_binary_provider_from_configs_pure(const std::string& env_string,
- View<std::string> args);
-
- std::string generate_nuget_packages_config(const Dependencies::ActionPlan& action);
-
- void help_topic_binary_caching(const VcpkgPaths& paths);
-}
diff --git a/toolsrc/include/vcpkg/binarycaching.private.h b/toolsrc/include/vcpkg/binarycaching.private.h
deleted file mode 100644
index 2ac446792..000000000
--- a/toolsrc/include/vcpkg/binarycaching.private.h
+++ /dev/null
@@ -1,51 +0,0 @@
-#pragma once
-
-#include <vcpkg/fwd/packagespec.h>
-#include <vcpkg/fwd/vcpkgpaths.h>
-
-#include <vcpkg/base/strings.h>
-
-#include <vcpkg/dependencies.h>
-
-namespace vcpkg
-{
- std::string reformat_version(const std::string& version, const std::string& abi_tag);
-
- struct NugetReference
- {
- explicit NugetReference(const Dependencies::InstallPlanAction& action)
- : NugetReference(action.spec,
- action.source_control_file_location.value_or_exit(VCPKG_LINE_INFO)
- .source_control_file->core_paragraph->version,
- action.abi_info.value_or_exit(VCPKG_LINE_INFO).package_abi)
- {
- }
-
- NugetReference(const PackageSpec& spec, const std::string& raw_version, const std::string& abi_tag)
- : id(spec.dir()), version(reformat_version(raw_version, abi_tag))
- {
- }
-
- std::string id;
- std::string version;
-
- std::string nupkg_filename() const { return Strings::concat(id, '.', version, ".nupkg"); }
- };
-
- namespace details
- {
- struct NuGetRepoInfo
- {
- std::string repo;
- std::string branch;
- std::string commit;
- };
-
- NuGetRepoInfo get_nuget_repo_info_from_env();
- }
-
- std::string generate_nuspec(const VcpkgPaths& paths,
- const Dependencies::InstallPlanAction& action,
- const NugetReference& ref,
- details::NuGetRepoInfo rinfo = details::get_nuget_repo_info_from_env());
-}
diff --git a/toolsrc/include/vcpkg/binaryparagraph.h b/toolsrc/include/vcpkg/binaryparagraph.h
deleted file mode 100644
index f10c41af0..000000000
--- a/toolsrc/include/vcpkg/binaryparagraph.h
+++ /dev/null
@@ -1,55 +0,0 @@
-#pragma once
-
-#include <vcpkg/packagespec.h>
-#include <vcpkg/paragraphparser.h>
-#include <vcpkg/sourceparagraph.h>
-
-namespace vcpkg
-{
- /// <summary>
- /// Built package metadata
- /// </summary>
- struct BinaryParagraph
- {
- BinaryParagraph();
- explicit BinaryParagraph(Parse::Paragraph fields);
- BinaryParagraph(const SourceParagraph& spgh,
- Triplet triplet,
- const std::string& abi_tag,
- const std::vector<FeatureSpec>& deps);
- BinaryParagraph(const SourceParagraph& spgh,
- const FeatureParagraph& fpgh,
- Triplet triplet,
- const std::vector<FeatureSpec>& deps);
-
- std::string displayname() const;
-
- std::string fullstem() const;
-
- std::string dir() const;
-
- bool is_feature() const { return !feature.empty(); }
-
- PackageSpec spec;
- std::string version;
- int port_version = 0;
- std::vector<std::string> description;
- std::vector<std::string> maintainers;
- std::string feature;
- std::vector<std::string> default_features;
- std::vector<std::string> dependencies;
- std::string abi;
- Type type = {Type::UNKNOWN};
- };
-
- bool operator==(const BinaryParagraph&, const BinaryParagraph&);
- bool operator!=(const BinaryParagraph&, const BinaryParagraph&);
-
- struct BinaryControlFile
- {
- BinaryParagraph core_paragraph;
- std::vector<BinaryParagraph> features;
- };
-
- void serialize(const BinaryParagraph& pgh, std::string& out_str);
-}
diff --git a/toolsrc/include/vcpkg/build.h b/toolsrc/include/vcpkg/build.h
deleted file mode 100644
index ed2724435..000000000
--- a/toolsrc/include/vcpkg/build.h
+++ /dev/null
@@ -1,389 +0,0 @@
-#pragma once
-
-#include <vcpkg/fwd/cmakevars.h>
-#include <vcpkg/fwd/dependencies.h>
-#include <vcpkg/fwd/portfileprovider.h>
-
-#include <vcpkg/base/cstringview.h>
-#include <vcpkg/base/files.h>
-#include <vcpkg/base/optional.h>
-#include <vcpkg/base/system.process.h>
-
-#include <vcpkg/commands.integrate.h>
-#include <vcpkg/packagespec.h>
-#include <vcpkg/statusparagraphs.h>
-#include <vcpkg/triplet.h>
-#include <vcpkg/vcpkgcmdarguments.h>
-#include <vcpkg/vcpkgpaths.h>
-
-#include <array>
-#include <map>
-#include <set>
-#include <vector>
-
-namespace vcpkg
-{
- struct IBinaryProvider;
-}
-
-namespace vcpkg::System
-{
- struct Environment;
-}
-
-namespace vcpkg::Build
-{
- enum class BuildResult
- {
- NULLVALUE = 0,
- SUCCEEDED,
- BUILD_FAILED,
- POST_BUILD_CHECKS_FAILED,
- FILE_CONFLICTS,
- CASCADED_DUE_TO_MISSING_DEPENDENCIES,
- EXCLUDED,
- CACHE_MISSING,
- DOWNLOADED
- };
-
- struct IBuildLogsRecorder
- {
- virtual void record_build_result(const VcpkgPaths& paths,
- const PackageSpec& spec,
- BuildResult result) const = 0;
- };
-
- const IBuildLogsRecorder& null_build_logs_recorder() noexcept;
-
- namespace Command
- {
- int perform_ex(const VcpkgCmdArguments& args,
- const FullPackageSpec& full_spec,
- const SourceControlFileLocation& scfl,
- const PortFileProvider::PathsPortFileProvider& provider,
- IBinaryProvider& binaryprovider,
- const IBuildLogsRecorder& build_logs_recorder,
- const VcpkgPaths& paths);
- void perform_and_exit_ex(const VcpkgCmdArguments& args,
- const FullPackageSpec& full_spec,
- const SourceControlFileLocation& scfl,
- const PortFileProvider::PathsPortFileProvider& provider,
- IBinaryProvider& binaryprovider,
- const IBuildLogsRecorder& build_logs_recorder,
- const VcpkgPaths& paths);
-
- int perform(const VcpkgCmdArguments& args, const VcpkgPaths& paths, Triplet default_triplet);
- void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, Triplet default_triplet);
- }
-
- enum class UseHeadVersion
- {
- NO = 0,
- YES
- };
-
- enum class AllowDownloads
- {
- NO = 0,
- YES
- };
-
- enum class OnlyDownloads
- {
- NO = 0,
- YES
- };
-
- enum class CleanBuildtrees
- {
- NO = 0,
- YES
- };
-
- enum class CleanPackages
- {
- NO = 0,
- YES
- };
-
- enum class CleanDownloads
- {
- NO = 0,
- YES
- };
-
- enum class ConfigurationType
- {
- DEBUG,
- RELEASE,
- };
-
- enum class DownloadTool
- {
- BUILT_IN,
- ARIA2,
- };
- const std::string& to_string(DownloadTool tool);
- enum class PurgeDecompressFailure
- {
- NO = 0,
- YES
- };
-
- enum class Editable
- {
- NO = 0,
- YES
- };
-
- enum class BackcompatFeatures
- {
- ALLOW = 0,
- PROHIBIT
- };
-
- enum class BuildMissing
- {
- NO = 0,
- YES
- };
-
- struct BuildPackageOptions
- {
- BuildMissing build_missing;
- UseHeadVersion use_head_version;
- AllowDownloads allow_downloads;
- OnlyDownloads only_downloads;
- CleanBuildtrees clean_buildtrees;
- CleanPackages clean_packages;
- CleanDownloads clean_downloads;
- DownloadTool download_tool;
- PurgeDecompressFailure purge_decompress_failure;
- Editable editable;
- BackcompatFeatures backcompat_features;
- };
-
- static constexpr BuildPackageOptions default_build_package_options{
- Build::BuildMissing::YES,
- Build::UseHeadVersion::NO,
- Build::AllowDownloads::YES,
- Build::OnlyDownloads::NO,
- Build::CleanBuildtrees::YES,
- Build::CleanPackages::YES,
- Build::CleanDownloads::NO,
- Build::DownloadTool::BUILT_IN,
- Build::PurgeDecompressFailure::YES,
- Build::Editable::NO,
- Build::BackcompatFeatures::ALLOW,
- };
-
- static constexpr BuildPackageOptions backcompat_prohibiting_package_options{
- Build::BuildMissing::YES,
- Build::UseHeadVersion::NO,
- Build::AllowDownloads::YES,
- Build::OnlyDownloads::NO,
- Build::CleanBuildtrees::YES,
- Build::CleanPackages::YES,
- Build::CleanDownloads::NO,
- Build::DownloadTool::BUILT_IN,
- Build::PurgeDecompressFailure::YES,
- Build::Editable::NO,
- Build::BackcompatFeatures::PROHIBIT,
- };
-
- static constexpr std::array<BuildResult, 6> BUILD_RESULT_VALUES = {
- BuildResult::SUCCEEDED,
- BuildResult::BUILD_FAILED,
- BuildResult::POST_BUILD_CHECKS_FAILED,
- BuildResult::FILE_CONFLICTS,
- BuildResult::CASCADED_DUE_TO_MISSING_DEPENDENCIES,
- BuildResult::EXCLUDED};
-
- const std::string& to_string(const BuildResult build_result);
- std::string create_error_message(const BuildResult build_result, const PackageSpec& spec);
- std::string create_user_troubleshooting_message(const PackageSpec& spec);
-
- /// <summary>
- /// Settings from the triplet file which impact the build environment and post-build checks
- /// </summary>
- struct PreBuildInfo : Util::ResourceBase
- {
- PreBuildInfo(const VcpkgPaths& paths,
- Triplet triplet,
- const std::unordered_map<std::string, std::string>& cmakevars);
-
- Triplet triplet;
- bool load_vcvars_env = false;
- std::string target_architecture;
- std::string cmake_system_name;
- std::string cmake_system_version;
- Optional<std::string> platform_toolset;
- Optional<fs::path> visual_studio_path;
- Optional<std::string> external_toolchain_file;
- Optional<ConfigurationType> build_type;
- Optional<std::string> public_abi_override;
- std::vector<std::string> passthrough_env_vars;
- std::vector<std::string> passthrough_env_vars_tracked;
-
- fs::path toolchain_file() const;
- bool using_vcvars() const;
-
- private:
- const VcpkgPaths& m_paths;
- };
-
- System::Command make_build_env_cmd(const PreBuildInfo& pre_build_info,
- const Toolset& toolset,
- View<Toolset> all_toolsets);
-
- struct ExtendedBuildResult
- {
- ExtendedBuildResult(BuildResult code);
- ExtendedBuildResult(BuildResult code, std::vector<FeatureSpec>&& unmet_deps);
- ExtendedBuildResult(BuildResult code, std::unique_ptr<BinaryControlFile>&& bcf);
-
- BuildResult code;
- std::vector<FeatureSpec> unmet_dependencies;
- std::unique_ptr<BinaryControlFile> binary_control_file;
- };
-
- ExtendedBuildResult build_package(const VcpkgCmdArguments& args,
- const VcpkgPaths& paths,
- const Dependencies::InstallPlanAction& config,
- IBinaryProvider& binaries_provider,
- const IBuildLogsRecorder& build_logs_recorder,
- const StatusParagraphs& status_db);
-
- enum class BuildPolicy
- {
- EMPTY_PACKAGE,
- DLLS_WITHOUT_LIBS,
- DLLS_WITHOUT_EXPORTS,
- DLLS_IN_STATIC_LIBRARY,
- MISMATCHED_NUMBER_OF_BINARIES,
- ONLY_RELEASE_CRT,
- EMPTY_INCLUDE_FOLDER,
- ALLOW_OBSOLETE_MSVCRT,
- ALLOW_RESTRICTED_HEADERS,
- SKIP_DUMPBIN_CHECKS,
- SKIP_ARCHITECTURE_CHECK,
- // Must be last
- COUNT,
- };
-
- // could be constexpr, but we want to generate this and that's not constexpr in C++14
- extern const std::array<BuildPolicy, size_t(BuildPolicy::COUNT)> ALL_POLICIES;
-
- const std::string& to_string(BuildPolicy policy);
- CStringView to_cmake_variable(BuildPolicy policy);
-
- struct BuildPolicies
- {
- BuildPolicies() = default;
- BuildPolicies(std::map<BuildPolicy, bool>&& map) : m_policies(std::move(map)) { }
-
- bool is_enabled(BuildPolicy policy) const
- {
- const auto it = m_policies.find(policy);
- if (it != m_policies.cend()) return it->second;
- return false;
- }
-
- private:
- std::map<BuildPolicy, bool> m_policies;
- };
-
- enum class LinkageType : char
- {
- DYNAMIC,
- STATIC,
- };
-
- Optional<LinkageType> to_linkage_type(const std::string& str);
-
- struct BuildInfo
- {
- LinkageType crt_linkage = LinkageType::DYNAMIC;
- LinkageType library_linkage = LinkageType::DYNAMIC;
-
- Optional<std::string> version;
-
- BuildPolicies policies;
- };
-
- BuildInfo read_build_info(const Files::Filesystem& fs, const fs::path& filepath);
-
- struct AbiEntry
- {
- std::string key;
- std::string value;
-
- AbiEntry() = default;
- AbiEntry(const std::string& key, const std::string& value) : key(key), value(value) { }
-
- bool operator<(const AbiEntry& other) const
- {
- return key < other.key || (key == other.key && value < other.value);
- }
- };
-
- struct CompilerInfo
- {
- std::string id;
- std::string version;
- std::string hash;
- };
-
- struct AbiInfo
- {
- std::unique_ptr<PreBuildInfo> pre_build_info;
- Optional<const Toolset&> toolset;
- Optional<const std::string&> triplet_abi;
- std::string package_abi;
- Optional<fs::path> abi_tag_file;
- Optional<const CompilerInfo&> compiler_info;
- };
-
- void compute_all_abis(const VcpkgPaths& paths,
- Dependencies::ActionPlan& action_plan,
- const CMakeVars::CMakeVarProvider& var_provider,
- const StatusParagraphs& status_db);
-
- struct EnvCache
- {
- explicit EnvCache(bool compiler_tracking) : m_compiler_tracking(compiler_tracking) { }
-
- const System::Environment& get_action_env(const VcpkgPaths& paths, const AbiInfo& abi_info);
- const std::string& get_triplet_info(const VcpkgPaths& paths, const AbiInfo& abi_info);
- const CompilerInfo& get_compiler_info(const VcpkgPaths& paths, const AbiInfo& abi_info);
-
- private:
- struct TripletMapEntry
- {
- std::string hash;
- Cache<std::string, std::string> compiler_hashes;
- Cache<std::string, CompilerInfo> compiler_info;
- };
- Cache<fs::path, TripletMapEntry> m_triplet_cache;
- Cache<fs::path, std::string> m_toolchain_cache;
-
-#if defined(_WIN32)
- struct EnvMapEntry
- {
- std::unordered_map<std::string, std::string> env_map;
- Cache<System::Command, System::Environment, System::CommandLess> cmd_cache;
- };
-
- Cache<std::vector<std::string>, EnvMapEntry> envs;
-#endif
-
- bool m_compiler_tracking;
- };
-
- struct BuildCommand : Commands::TripletCommand
- {
- virtual void perform_and_exit(const VcpkgCmdArguments& args,
- const VcpkgPaths& paths,
- Triplet default_triplet) const override;
- };
-}
diff --git a/toolsrc/include/vcpkg/buildenvironment.h b/toolsrc/include/vcpkg/buildenvironment.h
deleted file mode 100644
index b7ffb164f..000000000
--- a/toolsrc/include/vcpkg/buildenvironment.h
+++ /dev/null
@@ -1,15 +0,0 @@
-#pragma once
-
-#include <vcpkg/fwd/vcpkgpaths.h>
-
-#include <vcpkg/base/system.process.h>
-
-#include <string>
-#include <vector>
-
-namespace vcpkg
-{
- System::Command make_cmake_cmd(const VcpkgPaths& paths,
- const fs::path& cmake_script,
- std::vector<System::CMakeVariable>&& pass_variables);
-}
diff --git a/toolsrc/include/vcpkg/cmakevars.h b/toolsrc/include/vcpkg/cmakevars.h
deleted file mode 100644
index 07c21bdfd..000000000
--- a/toolsrc/include/vcpkg/cmakevars.h
+++ /dev/null
@@ -1,38 +0,0 @@
-#pragma once
-
-#include <vcpkg/fwd/dependencies.h>
-#include <vcpkg/fwd/portfileprovider.h>
-#include <vcpkg/fwd/vcpkgpaths.h>
-
-#include <vcpkg/base/optional.h>
-
-#include <vcpkg/packagespec.h>
-
-namespace vcpkg::CMakeVars
-{
- struct CMakeVarProvider
- {
- virtual ~CMakeVarProvider() = default;
-
- virtual Optional<const std::unordered_map<std::string, std::string>&> get_generic_triplet_vars(
- Triplet triplet) const = 0;
-
- virtual Optional<const std::unordered_map<std::string, std::string>&> get_dep_info_vars(
- const PackageSpec& spec) const = 0;
-
- virtual Optional<const std::unordered_map<std::string, std::string>&> get_tag_vars(
- const PackageSpec& spec) const = 0;
-
- virtual void load_generic_triplet_vars(Triplet triplet) const = 0;
-
- virtual void load_dep_info_vars(Span<const PackageSpec> specs) const = 0;
-
- virtual void load_tag_vars(Span<const FullPackageSpec> specs,
- const PortFileProvider::PortFileProvider& port_provider) const = 0;
-
- void load_tag_vars(const vcpkg::Dependencies::ActionPlan& action_plan,
- const PortFileProvider::PortFileProvider& port_provider) const;
- };
-
- std::unique_ptr<CMakeVarProvider> make_triplet_cmake_var_provider(const vcpkg::VcpkgPaths& paths);
-}
diff --git a/toolsrc/include/vcpkg/commands.add-version.h b/toolsrc/include/vcpkg/commands.add-version.h
deleted file mode 100644
index 8b9e0336e..000000000
--- a/toolsrc/include/vcpkg/commands.add-version.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#pragma once
-
-#include <vcpkg/commands.interface.h>
-
-namespace vcpkg::Commands::AddVersion
-{
- void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths);
-
- struct AddVersionCommand : PathsCommand
- {
- void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) const override;
- };
-} \ No newline at end of file
diff --git a/toolsrc/include/vcpkg/commands.autocomplete.h b/toolsrc/include/vcpkg/commands.autocomplete.h
deleted file mode 100644
index 4f518d0f0..000000000
--- a/toolsrc/include/vcpkg/commands.autocomplete.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#pragma once
-
-#include <vcpkg/commands.interface.h>
-
-namespace vcpkg::Commands::Autocomplete
-{
- void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths);
-
- struct AutocompleteCommand : PathsCommand
- {
- virtual void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) const override;
- };
-}
diff --git a/toolsrc/include/vcpkg/commands.buildexternal.h b/toolsrc/include/vcpkg/commands.buildexternal.h
deleted file mode 100644
index b4e1aa669..000000000
--- a/toolsrc/include/vcpkg/commands.buildexternal.h
+++ /dev/null
@@ -1,15 +0,0 @@
-#pragma once
-
-#include <vcpkg/commands.interface.h>
-
-namespace vcpkg::Commands::BuildExternal
-{
- void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, Triplet default_triplet);
-
- struct BuildExternalCommand : TripletCommand
- {
- virtual void perform_and_exit(const VcpkgCmdArguments& args,
- const VcpkgPaths& paths,
- Triplet default_triplet) const override;
- };
-}
diff --git a/toolsrc/include/vcpkg/commands.cache.h b/toolsrc/include/vcpkg/commands.cache.h
deleted file mode 100644
index 5d18a3f99..000000000
--- a/toolsrc/include/vcpkg/commands.cache.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#pragma once
-
-#include <vcpkg/commands.interface.h>
-
-namespace vcpkg::Commands::Cache
-{
- void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths);
-
- struct CacheCommand : PathsCommand
- {
- virtual void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) const override;
- };
-}
diff --git a/toolsrc/include/vcpkg/commands.ci.h b/toolsrc/include/vcpkg/commands.ci.h
deleted file mode 100644
index 4657741c9..000000000
--- a/toolsrc/include/vcpkg/commands.ci.h
+++ /dev/null
@@ -1,16 +0,0 @@
-#pragma once
-
-#include <vcpkg/commands.interface.h>
-
-namespace vcpkg::Commands::CI
-{
- extern const CommandStructure COMMAND_STRUCTURE;
- void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, Triplet default_triplet);
-
- struct CICommand : TripletCommand
- {
- virtual void perform_and_exit(const VcpkgCmdArguments& args,
- const VcpkgPaths& paths,
- Triplet default_triplet) const override;
- };
-}
diff --git a/toolsrc/include/vcpkg/commands.ciclean.h b/toolsrc/include/vcpkg/commands.ciclean.h
deleted file mode 100644
index ed9e2f005..000000000
--- a/toolsrc/include/vcpkg/commands.ciclean.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#pragma once
-
-#include <vcpkg/commands.interface.h>
-
-namespace vcpkg::Commands::CIClean
-{
- void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths);
-
- struct CICleanCommand : PathsCommand
- {
- virtual void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) const override;
- };
-}
diff --git a/toolsrc/include/vcpkg/commands.civerifyversions.h b/toolsrc/include/vcpkg/commands.civerifyversions.h
deleted file mode 100644
index 17d8f5613..000000000
--- a/toolsrc/include/vcpkg/commands.civerifyversions.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#pragma once
-
-#include <vcpkg/commands.interface.h>
-
-namespace vcpkg::Commands::CIVerifyVersions
-{
- void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths);
-
- struct CIVerifyVersionsCommand : PathsCommand
- {
- void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) const override;
- };
-} \ No newline at end of file
diff --git a/toolsrc/include/vcpkg/commands.contact.h b/toolsrc/include/vcpkg/commands.contact.h
deleted file mode 100644
index f0af41c14..000000000
--- a/toolsrc/include/vcpkg/commands.contact.h
+++ /dev/null
@@ -1,15 +0,0 @@
-#pragma once
-
-#include <vcpkg/commands.interface.h>
-
-namespace vcpkg::Commands::Contact
-{
- extern const CommandStructure COMMAND_STRUCTURE;
- const std::string& email();
- void perform_and_exit(const VcpkgCmdArguments& args, Files::Filesystem& fs);
-
- struct ContactCommand : BasicCommand
- {
- virtual void perform_and_exit(const VcpkgCmdArguments& args, Files::Filesystem& fs) const override;
- };
-}
diff --git a/toolsrc/include/vcpkg/commands.create.h b/toolsrc/include/vcpkg/commands.create.h
deleted file mode 100644
index a8eb99b27..000000000
--- a/toolsrc/include/vcpkg/commands.create.h
+++ /dev/null
@@ -1,15 +0,0 @@
-#pragma once
-
-#include <vcpkg/commands.interface.h>
-
-namespace vcpkg::Commands::Create
-{
- extern const CommandStructure COMMAND_STRUCTURE;
- int perform(const VcpkgCmdArguments& args, const VcpkgPaths& paths);
- void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths);
-
- struct CreateCommand : PathsCommand
- {
- virtual void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) const override;
- };
-}
diff --git a/toolsrc/include/vcpkg/commands.dependinfo.h b/toolsrc/include/vcpkg/commands.dependinfo.h
deleted file mode 100644
index 81301b6d9..000000000
--- a/toolsrc/include/vcpkg/commands.dependinfo.h
+++ /dev/null
@@ -1,16 +0,0 @@
-#pragma once
-
-#include <vcpkg/commands.interface.h>
-
-namespace vcpkg::Commands::DependInfo
-{
- extern const CommandStructure COMMAND_STRUCTURE;
- void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, Triplet default_triplet);
-
- struct DependInfoCommand : TripletCommand
- {
- virtual void perform_and_exit(const VcpkgCmdArguments& args,
- const VcpkgPaths& paths,
- Triplet default_triplet) const override;
- };
-}
diff --git a/toolsrc/include/vcpkg/commands.edit.h b/toolsrc/include/vcpkg/commands.edit.h
deleted file mode 100644
index 9a37d2ee3..000000000
--- a/toolsrc/include/vcpkg/commands.edit.h
+++ /dev/null
@@ -1,14 +0,0 @@
-#pragma once
-
-#include <vcpkg/commands.interface.h>
-
-namespace vcpkg::Commands::Edit
-{
- extern const CommandStructure COMMAND_STRUCTURE;
- void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths);
-
- struct EditCommand : PathsCommand
- {
- virtual void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) const override;
- };
-}
diff --git a/toolsrc/include/vcpkg/commands.env.h b/toolsrc/include/vcpkg/commands.env.h
deleted file mode 100644
index 5ba58d081..000000000
--- a/toolsrc/include/vcpkg/commands.env.h
+++ /dev/null
@@ -1,16 +0,0 @@
-#pragma once
-
-#include <vcpkg/commands.interface.h>
-
-namespace vcpkg::Commands::Env
-{
- extern const CommandStructure COMMAND_STRUCTURE;
- void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, Triplet default_triplet);
-
- struct EnvCommand : TripletCommand
- {
- virtual void perform_and_exit(const VcpkgCmdArguments& args,
- const VcpkgPaths& paths,
- Triplet default_triplet) const override;
- };
-}
diff --git a/toolsrc/include/vcpkg/commands.fetch.h b/toolsrc/include/vcpkg/commands.fetch.h
deleted file mode 100644
index c41965903..000000000
--- a/toolsrc/include/vcpkg/commands.fetch.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#pragma once
-
-#include <vcpkg/commands.interface.h>
-
-namespace vcpkg::Commands::Fetch
-{
- void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths);
-
- struct FetchCommand : PathsCommand
- {
- virtual void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) const override;
- };
-}
diff --git a/toolsrc/include/vcpkg/commands.format-manifest.h b/toolsrc/include/vcpkg/commands.format-manifest.h
deleted file mode 100644
index 1317bbc70..000000000
--- a/toolsrc/include/vcpkg/commands.format-manifest.h
+++ /dev/null
@@ -1,14 +0,0 @@
-#pragma once
-
-#include <vcpkg/commands.interface.h>
-
-namespace vcpkg::Commands::FormatManifest
-{
- extern const CommandStructure COMMAND_STRUCTURE;
- void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths);
-
- struct FormatManifestCommand : PathsCommand
- {
- virtual void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) const override;
- };
-}
diff --git a/toolsrc/include/vcpkg/commands.h b/toolsrc/include/vcpkg/commands.h
deleted file mode 100644
index dfabb809f..000000000
--- a/toolsrc/include/vcpkg/commands.h
+++ /dev/null
@@ -1,32 +0,0 @@
-#pragma once
-
-#include <vcpkg/commands.interface.h>
-
-namespace vcpkg::Commands
-{
- template<class T>
- struct PackageNameAndFunction
- {
- std::string name;
- T function;
- };
-
- Span<const PackageNameAndFunction<const BasicCommand*>> get_available_basic_commands();
- Span<const PackageNameAndFunction<const PathsCommand*>> get_available_paths_commands();
- Span<const PackageNameAndFunction<const TripletCommand*>> get_available_triplet_commands();
-
- template<typename T>
- T find(StringView command_name, Span<const PackageNameAndFunction<T>> available_commands)
- {
- for (const PackageNameAndFunction<T>& cmd : available_commands)
- {
- if (cmd.name == command_name)
- {
- return cmd.function;
- }
- }
-
- // not found
- return nullptr;
- }
-}
diff --git a/toolsrc/include/vcpkg/commands.hash.h b/toolsrc/include/vcpkg/commands.hash.h
deleted file mode 100644
index aa9b11c05..000000000
--- a/toolsrc/include/vcpkg/commands.hash.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#pragma once
-
-#include <vcpkg/commands.interface.h>
-
-namespace vcpkg::Commands::Hash
-{
- void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths);
-
- struct HashCommand : PathsCommand
- {
- virtual void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) const override;
- };
-}
diff --git a/toolsrc/include/vcpkg/commands.info.h b/toolsrc/include/vcpkg/commands.info.h
deleted file mode 100644
index 556d1eb01..000000000
--- a/toolsrc/include/vcpkg/commands.info.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#pragma once
-
-#include <vcpkg/commands.interface.h>
-
-namespace vcpkg::Commands::Info
-{
- extern const CommandStructure COMMAND_STRUCTURE;
-
- struct InfoCommand : PathsCommand
- {
- virtual void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) const override;
- };
-}
diff --git a/toolsrc/include/vcpkg/commands.integrate.h b/toolsrc/include/vcpkg/commands.integrate.h
deleted file mode 100644
index 162f49a3c..000000000
--- a/toolsrc/include/vcpkg/commands.integrate.h
+++ /dev/null
@@ -1,17 +0,0 @@
-#pragma once
-
-#include <vcpkg/commands.interface.h>
-
-namespace vcpkg::Commands::Integrate
-{
- extern const CommandStructure COMMAND_STRUCTURE;
-
- void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths);
- void append_helpstring(HelpTableFormatter& table);
- std::string get_helpstring();
-
- struct IntegrateCommand : PathsCommand
- {
- virtual void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) const override;
- };
-}
diff --git a/toolsrc/include/vcpkg/commands.interface.h b/toolsrc/include/vcpkg/commands.interface.h
deleted file mode 100644
index c8bc14ca9..000000000
--- a/toolsrc/include/vcpkg/commands.interface.h
+++ /dev/null
@@ -1,37 +0,0 @@
-#pragma once
-
-#include <vcpkg/fwd/vcpkgcmdarguments.h>
-#include <vcpkg/fwd/vcpkgpaths.h>
-
-#include <vcpkg/base/files.h>
-
-#include <vcpkg/triplet.h>
-
-namespace vcpkg::Commands
-{
- enum class DryRun : bool
- {
- No,
- Yes,
- };
-
- struct BasicCommand
- {
- virtual void perform_and_exit(const VcpkgCmdArguments& args, Files::Filesystem& fs) const = 0;
- virtual ~BasicCommand() = default;
- };
-
- struct PathsCommand
- {
- virtual void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) const = 0;
- virtual ~PathsCommand() = default;
- };
-
- struct TripletCommand
- {
- virtual void perform_and_exit(const VcpkgCmdArguments& args,
- const VcpkgPaths& paths,
- Triplet default_triplet) const = 0;
- virtual ~TripletCommand() = default;
- };
-}
diff --git a/toolsrc/include/vcpkg/commands.list.h b/toolsrc/include/vcpkg/commands.list.h
deleted file mode 100644
index 77a5f41bd..000000000
--- a/toolsrc/include/vcpkg/commands.list.h
+++ /dev/null
@@ -1,14 +0,0 @@
-#pragma once
-
-#include <vcpkg/commands.interface.h>
-
-namespace vcpkg::Commands::List
-{
- extern const CommandStructure COMMAND_STRUCTURE;
- void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths);
-
- struct ListCommand : PathsCommand
- {
- virtual void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) const override;
- };
-}
diff --git a/toolsrc/include/vcpkg/commands.owns.h b/toolsrc/include/vcpkg/commands.owns.h
deleted file mode 100644
index 39037649d..000000000
--- a/toolsrc/include/vcpkg/commands.owns.h
+++ /dev/null
@@ -1,15 +0,0 @@
-#pragma once
-
-#include <vcpkg/commands.interface.h>
-#include <vcpkg/vcpkgcmdarguments.h>
-
-namespace vcpkg::Commands::Owns
-{
- extern const CommandStructure COMMAND_STRUCTURE;
- void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths);
-
- struct OwnsCommand : PathsCommand
- {
- virtual void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) const override;
- };
-}
diff --git a/toolsrc/include/vcpkg/commands.porthistory.h b/toolsrc/include/vcpkg/commands.porthistory.h
deleted file mode 100644
index 3ca532532..000000000
--- a/toolsrc/include/vcpkg/commands.porthistory.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#pragma once
-
-#include <vcpkg/commands.interface.h>
-
-namespace vcpkg::Commands::PortHistory
-{
- void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths);
-
- struct PortHistoryCommand : PathsCommand
- {
- virtual void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) const override;
- };
-}
diff --git a/toolsrc/include/vcpkg/commands.portsdiff.h b/toolsrc/include/vcpkg/commands.portsdiff.h
deleted file mode 100644
index 8cd1b094c..000000000
--- a/toolsrc/include/vcpkg/commands.portsdiff.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#pragma once
-
-#include <vcpkg/commands.interface.h>
-
-namespace vcpkg::Commands::PortsDiff
-{
- void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths);
-
- struct PortsDiffCommand : PathsCommand
- {
- virtual void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) const override;
- };
-}
diff --git a/toolsrc/include/vcpkg/commands.search.h b/toolsrc/include/vcpkg/commands.search.h
deleted file mode 100644
index 530a3ac28..000000000
--- a/toolsrc/include/vcpkg/commands.search.h
+++ /dev/null
@@ -1,15 +0,0 @@
-#pragma once
-
-#include <vcpkg/commands.interface.h>
-#include <vcpkg/vcpkgcmdarguments.h>
-
-namespace vcpkg::Commands::Search
-{
- extern const CommandStructure COMMAND_STRUCTURE;
- void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths);
-
- struct SearchCommand : PathsCommand
- {
- virtual void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) const override;
- };
-}
diff --git a/toolsrc/include/vcpkg/commands.setinstalled.h b/toolsrc/include/vcpkg/commands.setinstalled.h
deleted file mode 100644
index c5723669b..000000000
--- a/toolsrc/include/vcpkg/commands.setinstalled.h
+++ /dev/null
@@ -1,26 +0,0 @@
-#pragma once
-
-#include <vcpkg/cmakevars.h>
-#include <vcpkg/commands.interface.h>
-#include <vcpkg/portfileprovider.h>
-
-namespace vcpkg::Commands::SetInstalled
-{
- extern const CommandStructure COMMAND_STRUCTURE;
- void perform_and_exit_ex(const VcpkgCmdArguments& args,
- const VcpkgPaths& paths,
- const PortFileProvider::PathsPortFileProvider& provider,
- IBinaryProvider& binary_provider,
- const CMakeVars::CMakeVarProvider& cmake_vars,
- Dependencies::ActionPlan action_plan,
- DryRun dry_run,
- const Optional<fs::path>& pkgsconfig_path);
- void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, Triplet default_triplet);
-
- struct SetInstalledCommand : TripletCommand
- {
- virtual void perform_and_exit(const VcpkgCmdArguments& args,
- const VcpkgPaths& paths,
- Triplet default_triplet) const override;
- };
-}
diff --git a/toolsrc/include/vcpkg/commands.upgrade.h b/toolsrc/include/vcpkg/commands.upgrade.h
deleted file mode 100644
index 340a70c97..000000000
--- a/toolsrc/include/vcpkg/commands.upgrade.h
+++ /dev/null
@@ -1,16 +0,0 @@
-#pragma once
-
-#include <vcpkg/commands.interface.h>
-
-namespace vcpkg::Commands::Upgrade
-{
- extern const CommandStructure COMMAND_STRUCTURE;
- void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, Triplet default_triplet);
-
- struct UpgradeCommand : TripletCommand
- {
- virtual void perform_and_exit(const VcpkgCmdArguments& args,
- const VcpkgPaths& paths,
- Triplet default_triplet) const override;
- };
-}
diff --git a/toolsrc/include/vcpkg/commands.upload-metrics.h b/toolsrc/include/vcpkg/commands.upload-metrics.h
deleted file mode 100644
index 4cfb66092..000000000
--- a/toolsrc/include/vcpkg/commands.upload-metrics.h
+++ /dev/null
@@ -1,12 +0,0 @@
-#pragma once
-
-#include <vcpkg/commands.interface.h>
-
-namespace vcpkg::Commands::UploadMetrics
-{
- extern const CommandStructure COMMAND_STRUCTURE;
- struct UploadMetricsCommand : BasicCommand
- {
- virtual void perform_and_exit(const VcpkgCmdArguments& args, Files::Filesystem& fs) const override;
- };
-}
diff --git a/toolsrc/include/vcpkg/commands.version.h b/toolsrc/include/vcpkg/commands.version.h
deleted file mode 100644
index 6deb5167d..000000000
--- a/toolsrc/include/vcpkg/commands.version.h
+++ /dev/null
@@ -1,15 +0,0 @@
-#pragma once
-
-#include <vcpkg/commands.interface.h>
-
-namespace vcpkg::Commands::Version
-{
- const char* base_version() noexcept;
- const char* version() noexcept;
- void perform_and_exit(const VcpkgCmdArguments& args, Files::Filesystem& fs);
-
- struct VersionCommand : BasicCommand
- {
- virtual void perform_and_exit(const VcpkgCmdArguments& args, Files::Filesystem& fs) const override;
- };
-}
diff --git a/toolsrc/include/vcpkg/commands.xvsinstances.h b/toolsrc/include/vcpkg/commands.xvsinstances.h
deleted file mode 100644
index fc7a39b98..000000000
--- a/toolsrc/include/vcpkg/commands.xvsinstances.h
+++ /dev/null
@@ -1,14 +0,0 @@
-#pragma once
-
-#include <vcpkg/commands.interface.h>
-
-namespace vcpkg::Commands::X_VSInstances
-{
- extern const CommandStructure COMMAND_STRUCTURE;
- void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths);
-
- struct VSInstancesCommand : PathsCommand
- {
- virtual void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) const override;
- };
-}
diff --git a/toolsrc/include/vcpkg/configuration.h b/toolsrc/include/vcpkg/configuration.h
deleted file mode 100644
index 6d6a9b1f4..000000000
--- a/toolsrc/include/vcpkg/configuration.h
+++ /dev/null
@@ -1,25 +0,0 @@
-#pragma once
-
-#include <vcpkg/fwd/configuration.h>
-#include <vcpkg/fwd/vcpkgcmdarguments.h>
-
-#include <vcpkg/base/files.h>
-#include <vcpkg/base/json.h>
-
-#include <vcpkg/registries.h>
-
-namespace vcpkg
-{
- struct Configuration
- {
- // This member is set up via two different configuration options,
- // `registries` and `default_registry`. The fall back logic is
- // taken care of in RegistrySet.
- RegistrySet registry_set;
-
- void validate_feature_flags(const FeatureFlagSettings& flags);
- };
-
- std::unique_ptr<Json::IDeserializer<Configuration>> make_configuration_deserializer(
- const fs::path& config_directory);
-}
diff --git a/toolsrc/include/vcpkg/dependencies.h b/toolsrc/include/vcpkg/dependencies.h
deleted file mode 100644
index 1b1a7748b..000000000
--- a/toolsrc/include/vcpkg/dependencies.h
+++ /dev/null
@@ -1,188 +0,0 @@
-#pragma once
-
-#include <vcpkg/fwd/cmakevars.h>
-#include <vcpkg/fwd/portfileprovider.h>
-
-#include <vcpkg/base/optional.h>
-#include <vcpkg/base/util.h>
-
-#include <vcpkg/build.h>
-#include <vcpkg/packagespec.h>
-
-#include <functional>
-#include <map>
-#include <vector>
-
-namespace vcpkg::Graphs
-{
- struct Randomizer;
-}
-
-namespace vcpkg
-{
- struct StatusParagraphs;
-}
-
-namespace vcpkg::Dependencies
-{
- enum class RequestType
- {
- UNKNOWN,
- USER_REQUESTED,
- AUTO_SELECTED
- };
-
- std::string to_output_string(RequestType request_type,
- const CStringView s,
- const Build::BuildPackageOptions& options);
- std::string to_output_string(RequestType request_type, const CStringView s);
-
- enum class InstallPlanType
- {
- UNKNOWN,
- BUILD_AND_INSTALL,
- ALREADY_INSTALLED,
- EXCLUDED
- };
-
- struct InstallPlanAction : Util::MoveOnlyBase
- {
- static bool compare_by_name(const InstallPlanAction* left, const InstallPlanAction* right);
-
- InstallPlanAction() noexcept;
-
- InstallPlanAction(InstalledPackageView&& spghs, const RequestType& request_type);
-
- InstallPlanAction(const PackageSpec& spec,
- const SourceControlFileLocation& scfl,
- const RequestType& request_type,
- std::map<std::string, std::vector<FeatureSpec>>&& dependencies);
-
- std::string displayname() const;
- const std::string& public_abi() const;
- bool has_package_abi() const;
- Optional<const std::string&> package_abi() const;
- const Build::PreBuildInfo& pre_build_info(LineInfo linfo) const;
-
- PackageSpec spec;
-
- Optional<const SourceControlFileLocation&> source_control_file_location;
- Optional<InstalledPackageView> installed_package;
-
- InstallPlanType plan_type;
- RequestType request_type;
- Build::BuildPackageOptions build_options;
-
- std::map<std::string, std::vector<FeatureSpec>> feature_dependencies;
- std::vector<PackageSpec> package_dependencies;
- std::vector<std::string> feature_list;
-
- Optional<Build::AbiInfo> abi_info;
- };
-
- enum class RemovePlanType
- {
- UNKNOWN,
- NOT_INSTALLED,
- REMOVE
- };
-
- struct RemovePlanAction : Util::MoveOnlyBase
- {
- static bool compare_by_name(const RemovePlanAction* left, const RemovePlanAction* right);
-
- RemovePlanAction() noexcept;
- RemovePlanAction(const PackageSpec& spec, const RemovePlanType& plan_type, const RequestType& request_type);
-
- PackageSpec spec;
- RemovePlanType plan_type;
- RequestType request_type;
- };
-
- struct ActionPlan
- {
- bool empty() const { return remove_actions.empty() && already_installed.empty() && install_actions.empty(); }
- size_t size() const { return remove_actions.size() + already_installed.size() + install_actions.size(); }
-
- std::vector<RemovePlanAction> remove_actions;
- std::vector<InstallPlanAction> already_installed;
- std::vector<InstallPlanAction> install_actions;
- };
-
- enum class ExportPlanType
- {
- UNKNOWN,
- NOT_BUILT,
- ALREADY_BUILT
- };
-
- struct ExportPlanAction : Util::MoveOnlyBase
- {
- static bool compare_by_name(const ExportPlanAction* left, const ExportPlanAction* right);
-
- ExportPlanAction() noexcept;
- ExportPlanAction(const PackageSpec& spec,
- InstalledPackageView&& installed_package,
- const RequestType& request_type);
-
- ExportPlanAction(const PackageSpec& spec, const RequestType& request_type);
-
- PackageSpec spec;
- ExportPlanType plan_type;
- RequestType request_type;
-
- Optional<const BinaryParagraph&> core_paragraph() const;
- std::vector<PackageSpec> dependencies() const;
-
- private:
- Optional<InstalledPackageView> m_installed_package;
- };
-
- struct ClusterGraph;
-
- struct CreateInstallPlanOptions
- {
- Graphs::Randomizer* randomizer = nullptr;
- };
-
- std::vector<RemovePlanAction> create_remove_plan(const std::vector<PackageSpec>& specs,
- const StatusParagraphs& status_db);
-
- std::vector<ExportPlanAction> create_export_plan(const std::vector<PackageSpec>& specs,
- const StatusParagraphs& status_db);
-
- /// <summary>Figure out which actions are required to install features specifications in `specs`.</summary>
- /// <param name="provider">Contains the ports of the current environment.</param>
- /// <param name="specs">Feature specifications to resolve dependencies for.</param>
- /// <param name="status_db">Status of installed packages in the current environment.</param>
- ActionPlan create_feature_install_plan(const PortFileProvider::PortFileProvider& provider,
- const CMakeVars::CMakeVarProvider& var_provider,
- const std::vector<FullPackageSpec>& specs,
- const StatusParagraphs& status_db,
- const CreateInstallPlanOptions& options = {});
-
- ActionPlan create_upgrade_plan(const PortFileProvider::PortFileProvider& provider,
- const CMakeVars::CMakeVarProvider& var_provider,
- const std::vector<PackageSpec>& specs,
- const StatusParagraphs& status_db,
- const CreateInstallPlanOptions& options = {});
-
- // `features` should have "default" instead of missing "core". This is only exposed for testing purposes.
- std::vector<FullPackageSpec> resolve_deps_as_top_level(const SourceControlFile& scf,
- Triplet triplet,
- std::vector<std::string> features,
- CMakeVars::CMakeVarProvider& var_provider);
-
- /// <param name="provider">Contains the ports of the current environment.</param>
- /// <param name="specs">Feature specifications to resolve dependencies for.</param>
- /// <param name="status_db">Status of installed packages in the current environment.</param>
- ExpectedS<ActionPlan> create_versioned_install_plan(const PortFileProvider::IVersionedPortfileProvider& vprovider,
- const PortFileProvider::IBaselineProvider& bprovider,
- const PortFileProvider::IOverlayProvider& oprovider,
- const CMakeVars::CMakeVarProvider& var_provider,
- const std::vector<Dependency>& deps,
- const std::vector<DependencyOverride>& overrides,
- const PackageSpec& toplevel);
-
- void print_plan(const ActionPlan& action_plan, const bool is_recursive = true, const fs::path& vcpkg_root_dir = {});
-}
diff --git a/toolsrc/include/vcpkg/export.chocolatey.h b/toolsrc/include/vcpkg/export.chocolatey.h
deleted file mode 100644
index 26238cf43..000000000
--- a/toolsrc/include/vcpkg/export.chocolatey.h
+++ /dev/null
@@ -1,20 +0,0 @@
-#pragma once
-
-#include <vcpkg/fwd/vcpkgpaths.h>
-
-#include <vcpkg/dependencies.h>
-
-#include <vector>
-
-namespace vcpkg::Export::Chocolatey
-{
- struct Options
- {
- Optional<std::string> maybe_maintainer;
- Optional<std::string> maybe_version_suffix;
- };
-
- void do_export(const std::vector<Dependencies::ExportPlanAction>& export_plan,
- const VcpkgPaths& paths,
- const Options& chocolatey_options);
-}
diff --git a/toolsrc/include/vcpkg/export.h b/toolsrc/include/vcpkg/export.h
deleted file mode 100644
index 0dd5b1aac..000000000
--- a/toolsrc/include/vcpkg/export.h
+++ /dev/null
@@ -1,19 +0,0 @@
-#pragma once
-
-#include <vcpkg/commands.interface.h>
-
-namespace vcpkg::Export
-{
- extern const CommandStructure COMMAND_STRUCTURE;
-
- void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, Triplet default_triplet);
-
- void export_integration_files(const fs::path& raw_exported_dir_path, const VcpkgPaths& paths);
-
- struct ExportCommand : Commands::TripletCommand
- {
- virtual void perform_and_exit(const VcpkgCmdArguments& args,
- const VcpkgPaths& paths,
- Triplet default_triplet) const override;
- };
-}
diff --git a/toolsrc/include/vcpkg/export.ifw.h b/toolsrc/include/vcpkg/export.ifw.h
deleted file mode 100644
index 0fe07227c..000000000
--- a/toolsrc/include/vcpkg/export.ifw.h
+++ /dev/null
@@ -1,25 +0,0 @@
-#pragma once
-
-#include <vcpkg/fwd/vcpkgpaths.h>
-
-#include <vcpkg/dependencies.h>
-
-#include <string>
-#include <vector>
-
-namespace vcpkg::Export::IFW
-{
- struct Options
- {
- Optional<std::string> maybe_repository_url;
- Optional<std::string> maybe_packages_dir_path;
- Optional<std::string> maybe_repository_dir_path;
- Optional<std::string> maybe_config_file_path;
- Optional<std::string> maybe_installer_file_path;
- };
-
- void do_export(const std::vector<Dependencies::ExportPlanAction>& export_plan,
- const std::string& export_id,
- const Options& ifw_options,
- const VcpkgPaths& paths);
-}
diff --git a/toolsrc/include/vcpkg/export.prefab.h b/toolsrc/include/vcpkg/export.prefab.h
deleted file mode 100644
index 2038949be..000000000
--- a/toolsrc/include/vcpkg/export.prefab.h
+++ /dev/null
@@ -1,79 +0,0 @@
-#pragma once
-
-#include <vcpkg/fwd/vcpkgpaths.h>
-
-#include <vcpkg/base/system.h>
-
-#include <vcpkg/dependencies.h>
-
-#include <vector>
-
-namespace vcpkg::Export::Prefab
-{
- constexpr int kFragmentSize = 3;
-
- struct Options
- {
- Optional<std::string> maybe_group_id;
- Optional<std::string> maybe_artifact_id;
- Optional<std::string> maybe_version;
- Optional<std::string> maybe_min_sdk;
- Optional<std::string> maybe_target_sdk;
- bool enable_maven = false;
- bool enable_debug = false;
- };
- struct NdkVersion
- {
- NdkVersion(int _major, int _minor, int _patch) : m_major{_major}, m_minor{_minor}, m_patch{_patch} { }
- int major() { return this->m_major; }
- int minor() { return this->m_minor; }
- int patch() { return this->m_patch; }
- std::string to_string();
- void to_string(std::string& out);
-
- private:
- int m_major;
- int m_minor;
- int m_patch;
- };
-
- struct ABIMetadata
- {
- std::string abi;
- int api;
- int ndk;
- std::string stl;
- std::string to_string();
- };
-
- struct PlatformModuleMetadata
- {
- std::vector<std::string> export_libraries;
- std::string library_name;
- std::string to_json();
- };
-
- struct ModuleMetadata
- {
- std::vector<std::string> export_libraries;
- std::string library_name;
- PlatformModuleMetadata android;
- std::string to_json();
- };
-
- struct PackageMetadata
- {
- std::string name;
- int schema;
- std::vector<std::string> dependencies;
- std::string version;
- std::string to_json();
- };
-
- void do_export(const std::vector<Dependencies::ExportPlanAction>& export_plan,
- const VcpkgPaths& paths,
- const Options& prefab_options,
- const Triplet& triplet);
- Optional<std::string> find_ndk_version(const std::string& content);
- Optional<NdkVersion> to_version(const std::string& version);
-}
diff --git a/toolsrc/include/vcpkg/fwd/build.h b/toolsrc/include/vcpkg/fwd/build.h
deleted file mode 100644
index c7f74513f..000000000
--- a/toolsrc/include/vcpkg/fwd/build.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#pragma once
-
-namespace vcpkg::Build
-{
- struct BuildInfo;
- struct PreBuildInfo;
-}
diff --git a/toolsrc/include/vcpkg/fwd/cmakevars.h b/toolsrc/include/vcpkg/fwd/cmakevars.h
deleted file mode 100644
index e1dade368..000000000
--- a/toolsrc/include/vcpkg/fwd/cmakevars.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#pragma once
-
-namespace vcpkg::CMakeVars
-{
- struct CMakeVarProvider;
-}
diff --git a/toolsrc/include/vcpkg/fwd/configuration.h b/toolsrc/include/vcpkg/fwd/configuration.h
deleted file mode 100644
index 5fa9cee34..000000000
--- a/toolsrc/include/vcpkg/fwd/configuration.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#pragma once
-
-namespace vcpkg
-{
- struct Configuration;
-}
diff --git a/toolsrc/include/vcpkg/fwd/dependencies.h b/toolsrc/include/vcpkg/fwd/dependencies.h
deleted file mode 100644
index 08e824b4c..000000000
--- a/toolsrc/include/vcpkg/fwd/dependencies.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#pragma once
-
-namespace vcpkg::Dependencies
-{
- struct InstallPlanAction;
- struct ActionPlan;
-}
diff --git a/toolsrc/include/vcpkg/fwd/packagespec.h b/toolsrc/include/vcpkg/fwd/packagespec.h
deleted file mode 100644
index 2f5719e1b..000000000
--- a/toolsrc/include/vcpkg/fwd/packagespec.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#pragma once
-
-namespace vcpkg
-{
- struct PackageSpec;
-}
diff --git a/toolsrc/include/vcpkg/fwd/portfileprovider.h b/toolsrc/include/vcpkg/fwd/portfileprovider.h
deleted file mode 100644
index a75cfc137..000000000
--- a/toolsrc/include/vcpkg/fwd/portfileprovider.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#pragma once
-
-namespace vcpkg::PortFileProvider
-{
- struct PortFileProvider;
- struct PathsPortFileProvider;
- struct IVersionedPortfileProvider;
- struct IBaselineProvider;
- struct IOverlayProvider;
-}
diff --git a/toolsrc/include/vcpkg/fwd/registries.h b/toolsrc/include/vcpkg/fwd/registries.h
deleted file mode 100644
index 73783cc6b..000000000
--- a/toolsrc/include/vcpkg/fwd/registries.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#pragma once
-
-namespace vcpkg
-{
- struct RegistryEntry;
- struct RegistryImplementation;
- struct Registry;
- struct RegistrySet;
-}
diff --git a/toolsrc/include/vcpkg/fwd/vcpkgcmdarguments.h b/toolsrc/include/vcpkg/fwd/vcpkgcmdarguments.h
deleted file mode 100644
index 152627128..000000000
--- a/toolsrc/include/vcpkg/fwd/vcpkgcmdarguments.h
+++ /dev/null
@@ -1,14 +0,0 @@
-#pragma once
-
-namespace vcpkg
-{
- struct ParsedArguments;
- struct CommandSwitch;
- struct CommandSetting;
- struct CommandMultiSetting;
- struct CommandOptionsStructure;
- struct CommandStructure;
- struct HelpTableFormatter;
- struct VcpkgCmdArguments;
- struct FeatureFlagSettings;
-}
diff --git a/toolsrc/include/vcpkg/fwd/vcpkgpaths.h b/toolsrc/include/vcpkg/fwd/vcpkgpaths.h
deleted file mode 100644
index 79655bf4a..000000000
--- a/toolsrc/include/vcpkg/fwd/vcpkgpaths.h
+++ /dev/null
@@ -1,8 +0,0 @@
-#pragma once
-
-namespace vcpkg
-{
- struct ToolsetArchOption;
- struct Toolset;
- struct VcpkgPaths;
-}
diff --git a/toolsrc/include/vcpkg/globalstate.h b/toolsrc/include/vcpkg/globalstate.h
deleted file mode 100644
index 44c34f25c..000000000
--- a/toolsrc/include/vcpkg/globalstate.h
+++ /dev/null
@@ -1,21 +0,0 @@
-#pragma once
-
-#include <vcpkg/base/fwd/lockguarded.h>
-
-#include <vcpkg/base/chrono.h>
-
-#include <atomic>
-#include <string>
-
-namespace vcpkg
-{
- struct GlobalState
- {
- static Util::LockGuarded<Chrono::ElapsedTimer> timer;
- static Util::LockGuarded<std::string> g_surveydate;
-
- static std::atomic<int> g_init_console_cp;
- static std::atomic<int> g_init_console_output_cp;
- static std::atomic<bool> g_init_console_initialized;
- };
-}
diff --git a/toolsrc/include/vcpkg/help.h b/toolsrc/include/vcpkg/help.h
deleted file mode 100644
index 3e1ef381e..000000000
--- a/toolsrc/include/vcpkg/help.h
+++ /dev/null
@@ -1,19 +0,0 @@
-#pragma once
-
-#include <vcpkg/commands.interface.h>
-
-#include <string>
-
-namespace vcpkg::Help
-{
- extern const CommandStructure COMMAND_STRUCTURE;
-
- void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths);
-
- void help_topic_valid_triplet(const VcpkgPaths& paths);
-
- struct HelpCommand : Commands::PathsCommand
- {
- virtual void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) const override;
- };
-}
diff --git a/toolsrc/include/vcpkg/input.h b/toolsrc/include/vcpkg/input.h
deleted file mode 100644
index 917b5af10..000000000
--- a/toolsrc/include/vcpkg/input.h
+++ /dev/null
@@ -1,15 +0,0 @@
-#pragma once
-
-#include <vcpkg/packagespec.h>
-
-namespace vcpkg::Input
-{
- PackageSpec check_and_get_package_spec(std::string&& spec_string,
- Triplet default_triplet,
- CStringView example_text);
- FullPackageSpec check_and_get_full_package_spec(std::string&& spec_string,
- Triplet default_triplet,
- CStringView example_text);
-
- void check_triplet(Triplet t, const VcpkgPaths& paths);
-}
diff --git a/toolsrc/include/vcpkg/install.h b/toolsrc/include/vcpkg/install.h
deleted file mode 100644
index 8187735c5..000000000
--- a/toolsrc/include/vcpkg/install.h
+++ /dev/null
@@ -1,116 +0,0 @@
-#pragma once
-
-#include <vcpkg/base/chrono.h>
-
-#include <vcpkg/binaryparagraph.h>
-#include <vcpkg/build.h>
-#include <vcpkg/dependencies.h>
-#include <vcpkg/vcpkgcmdarguments.h>
-#include <vcpkg/vcpkgpaths.h>
-
-#include <vector>
-
-namespace vcpkg::Install
-{
- enum class KeepGoing
- {
- NO = 0,
- YES
- };
-
- inline KeepGoing to_keep_going(const bool value) { return value ? KeepGoing::YES : KeepGoing::NO; }
-
- struct SpecSummary
- {
- SpecSummary(const PackageSpec& spec, const Dependencies::InstallPlanAction* action);
-
- const BinaryParagraph* get_binary_paragraph() const;
-
- PackageSpec spec;
- Build::ExtendedBuildResult build_result;
- vcpkg::Chrono::ElapsedTime timing;
-
- const Dependencies::InstallPlanAction* action;
- };
-
- struct InstallSummary
- {
- std::vector<SpecSummary> results;
- std::string total_elapsed_time;
-
- void print() const;
- std::string xunit_results() const;
- };
-
- struct InstallDir
- {
- static InstallDir from_destination_root(const fs::path& destination_root,
- const std::string& destination_subdirectory,
- const fs::path& listfile);
-
- private:
- fs::path m_destination;
- std::string m_destination_subdirectory;
- fs::path m_listfile;
-
- public:
- const fs::path& destination() const;
- const std::string& destination_subdirectory() const;
- const fs::path& listfile() const;
- };
-
- Build::ExtendedBuildResult perform_install_plan_action(const VcpkgCmdArguments& args,
- const VcpkgPaths& paths,
- Dependencies::InstallPlanAction& action,
- StatusParagraphs& status_db,
- const CMakeVars::CMakeVarProvider& var_provider);
-
- enum class InstallResult
- {
- FILE_CONFLICTS,
- SUCCESS,
- };
-
- std::vector<std::string> get_all_port_names(const VcpkgPaths& paths);
-
- void install_package_and_write_listfile(const VcpkgPaths& paths, const PackageSpec& spec, const InstallDir& dirs);
-
- void install_files_and_write_listfile(Files::Filesystem& fs,
- const fs::path& source_dir,
- const std::vector<fs::path>& files,
- const InstallDir& destination_dir);
-
- InstallResult install_package(const VcpkgPaths& paths,
- const BinaryControlFile& binary_paragraph,
- StatusParagraphs* status_db);
-
- InstallSummary perform(const VcpkgCmdArguments& args,
- Dependencies::ActionPlan& action_plan,
- const KeepGoing keep_going,
- const VcpkgPaths& paths,
- StatusParagraphs& status_db,
- IBinaryProvider& binaryprovider,
- const Build::IBuildLogsRecorder& build_logs_recorder,
- const CMakeVars::CMakeVarProvider& var_provider);
-
- struct CMakeUsageInfo
- {
- std::string message;
- bool usage_file = false;
- Optional<bool> header_only;
- std::map<std::string, std::vector<std::string>> cmake_targets_map;
- };
-
- CMakeUsageInfo get_cmake_usage(const BinaryParagraph& bpgh, const VcpkgPaths& paths);
-
- extern const CommandStructure COMMAND_STRUCTURE;
-
- void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, Triplet default_triplet);
-
- struct InstallCommand : Commands::TripletCommand
- {
- virtual void perform_and_exit(const VcpkgCmdArguments& args,
- const VcpkgPaths& paths,
- Triplet default_triplet) const override;
- };
-}
diff --git a/toolsrc/include/vcpkg/metrics.h b/toolsrc/include/vcpkg/metrics.h
deleted file mode 100644
index b1a5e6104..000000000
--- a/toolsrc/include/vcpkg/metrics.h
+++ /dev/null
@@ -1,33 +0,0 @@
-#pragma once
-
-#include <vcpkg/base/files.h>
-#include <vcpkg/base/lockguarded.h>
-#include <vcpkg/base/util.h>
-
-#include <string>
-
-namespace vcpkg::Metrics
-{
- struct Metrics : Util::ResourceBase
- {
- void set_send_metrics(bool should_send_metrics);
- void set_print_metrics(bool should_print_metrics);
- void set_disabled(bool disabled);
- void set_user_information(const std::string& user_id, const std::string& first_use_time);
- static void init_user_information(std::string& user_id, std::string& first_use_time);
-
- void track_metric(const std::string& name, double value);
- void track_buildtime(const std::string& name, double value);
- void track_property(const std::string& name, const std::string& value);
- void track_feature(const std::string& feature, bool value);
-
- bool metrics_enabled();
-
- void upload(const std::string& payload);
- void flush(Files::Filesystem& fs);
- };
-
- extern Util::LockGuarded<Metrics> g_metrics;
-
- std::string get_MAC_user();
-}
diff --git a/toolsrc/include/vcpkg/packagespec.h b/toolsrc/include/vcpkg/packagespec.h
deleted file mode 100644
index 43be57e68..000000000
--- a/toolsrc/include/vcpkg/packagespec.h
+++ /dev/null
@@ -1,226 +0,0 @@
-#pragma once
-
-#include <vcpkg/base/expected.h>
-#include <vcpkg/base/json.h>
-#include <vcpkg/base/optional.h>
-
-#include <vcpkg/platform-expression.h>
-#include <vcpkg/triplet.h>
-#include <vcpkg/versions.h>
-
-namespace vcpkg::Parse
-{
- struct ParserBase;
-}
-
-namespace vcpkg
-{
- ///
- /// <summary>
- /// Full specification of a package. Contains all information to reference
- /// a specific package.
- /// </summary>
- ///
- struct PackageSpec
- {
- PackageSpec() = default;
- PackageSpec(std::string name, Triplet triplet) : m_name(std::move(name)), m_triplet(triplet) { }
-
- static std::vector<PackageSpec> to_package_specs(const std::vector<std::string>& ports, Triplet triplet);
-
- const std::string& name() const;
-
- Triplet triplet() const;
-
- std::string dir() const;
-
- std::string to_string() const;
- void to_string(std::string& s) const;
-
- bool operator<(const PackageSpec& other) const
- {
- if (name() < other.name()) return true;
- if (name() > other.name()) return false;
- return triplet() < other.triplet();
- }
-
- private:
- std::string m_name;
- Triplet m_triplet;
- };
-
- bool operator==(const PackageSpec& left, const PackageSpec& right);
- inline bool operator!=(const PackageSpec& left, const PackageSpec& right) { return !(left == right); }
-
- ///
- /// <summary>
- /// Full specification of a feature. Contains all information to reference
- /// a single feature in a specific package.
- /// </summary>
- ///
- struct FeatureSpec
- {
- FeatureSpec(const PackageSpec& spec, const std::string& feature) : m_spec(spec), m_feature(feature) { }
-
- const std::string& name() const { return m_spec.name(); }
- const std::string& feature() const { return m_feature; }
- Triplet triplet() const { return m_spec.triplet(); }
-
- const PackageSpec& spec() const { return m_spec; }
-
- std::string to_string() const;
- void to_string(std::string& out) const;
-
- bool operator<(const FeatureSpec& other) const
- {
- if (name() < other.name()) return true;
- if (name() > other.name()) return false;
- if (feature() < other.feature()) return true;
- if (feature() > other.feature()) return false;
- return triplet() < other.triplet();
- }
-
- bool operator==(const FeatureSpec& other) const
- {
- return triplet() == other.triplet() && name() == other.name() && feature() == other.feature();
- }
-
- bool operator!=(const FeatureSpec& other) const { return !(*this == other); }
-
- private:
- PackageSpec m_spec;
- std::string m_feature;
- };
-
- ///
- /// <summary>
- /// Full specification of a package. Contains all information to reference
- /// a collection of features in a single package.
- /// </summary>
- ///
- struct FullPackageSpec
- {
- PackageSpec package_spec;
- std::vector<std::string> features;
-
- FullPackageSpec() = default;
- explicit FullPackageSpec(PackageSpec spec, std::vector<std::string> features = {})
- : package_spec(std::move(spec)), features(std::move(features))
- {
- }
-
- std::vector<FeatureSpec> to_feature_specs(const std::vector<std::string>& default_features,
- const std::vector<std::string>& all_features) const;
-
- static ExpectedS<FullPackageSpec> from_string(const std::string& spec_as_string, Triplet default_triplet);
-
- bool operator==(const FullPackageSpec& o) const
- {
- return package_spec == o.package_spec && features == o.features;
- }
- bool operator!=(const FullPackageSpec& o) const { return !(*this == o); }
- };
-
- ///
- /// <summary>
- /// Contains all information to reference a collection of features in a single package by their names.
- /// </summary>
- ///
- struct Features
- {
- std::string name;
- std::vector<std::string> features;
-
- static ExpectedS<Features> from_string(const std::string& input);
- };
-
- struct DependencyConstraint
- {
- Versions::Constraint::Type type = Versions::Constraint::Type::None;
- std::string value;
- int port_version = 0;
-
- friend bool operator==(const DependencyConstraint& lhs, const DependencyConstraint& rhs);
- friend bool operator!=(const DependencyConstraint& lhs, const DependencyConstraint& rhs)
- {
- return !(lhs == rhs);
- }
- };
-
- struct Dependency
- {
- std::string name;
- std::vector<std::string> features;
- PlatformExpression::Expr platform;
- DependencyConstraint constraint;
-
- Json::Object extra_info;
-
- friend bool operator==(const Dependency& lhs, const Dependency& rhs);
- friend bool operator!=(const Dependency& lhs, const Dependency& rhs) { return !(lhs == rhs); }
- };
-
- struct DependencyOverride
- {
- std::string name;
- std::string version;
- int port_version = 0;
- Versions::Scheme version_scheme = Versions::Scheme::String;
-
- Json::Object extra_info;
-
- friend bool operator==(const DependencyOverride& lhs, const DependencyOverride& rhs);
- friend bool operator!=(const DependencyOverride& lhs, const DependencyOverride& rhs) { return !(lhs == rhs); }
- };
-
- struct ParsedQualifiedSpecifier
- {
- std::string name;
- Optional<std::vector<std::string>> features;
- Optional<std::string> triplet;
- Optional<PlatformExpression::Expr> platform;
- };
-
- Optional<std::string> parse_feature_name(Parse::ParserBase& parser);
- Optional<std::string> parse_package_name(Parse::ParserBase& parser);
- ExpectedS<ParsedQualifiedSpecifier> parse_qualified_specifier(StringView input);
- Optional<ParsedQualifiedSpecifier> parse_qualified_specifier(Parse::ParserBase& parser);
-}
-
-namespace std
-{
- template<>
- struct hash<vcpkg::PackageSpec>
- {
- size_t operator()(const vcpkg::PackageSpec& value) const
- {
- size_t hash = 17;
- hash = hash * 31 + std::hash<std::string>()(value.name());
- hash = hash * 31 + std::hash<vcpkg::Triplet>()(value.triplet());
- return hash;
- }
- };
-
- template<>
- struct equal_to<vcpkg::PackageSpec>
- {
- bool operator()(const vcpkg::PackageSpec& left, const vcpkg::PackageSpec& right) const { return left == right; }
- };
-
- template<>
- struct hash<vcpkg::FeatureSpec>
- {
- size_t operator()(const vcpkg::FeatureSpec& value) const
- {
- size_t hash = std::hash<vcpkg::PackageSpec>()(value.spec());
- hash = hash * 31 + std::hash<std::string>()(value.feature());
- return hash;
- }
- };
-
- template<>
- struct equal_to<vcpkg::FeatureSpec>
- {
- bool operator()(const vcpkg::FeatureSpec& left, const vcpkg::FeatureSpec& right) const { return left == right; }
- };
-}
diff --git a/toolsrc/include/vcpkg/paragraphparser.h b/toolsrc/include/vcpkg/paragraphparser.h
deleted file mode 100644
index 22060f32f..000000000
--- a/toolsrc/include/vcpkg/paragraphparser.h
+++ /dev/null
@@ -1,68 +0,0 @@
-#pragma once
-
-#include <vcpkg/base/expected.h>
-
-#include <vcpkg/packagespec.h>
-#include <vcpkg/textrowcol.h>
-
-#include <map>
-#include <memory>
-#include <string>
-#include <unordered_map>
-#include <vector>
-
-namespace vcpkg::Parse
-{
- struct ParseControlErrorInfo
- {
- std::string name;
- std::map<std::string, std::vector<std::string>> missing_fields;
- std::map<std::string, std::vector<std::string>> extra_fields;
- std::map<std::string, std::string> expected_types;
- std::map<std::string, std::vector<std::string>> mutually_exclusive_fields;
- std::vector<std::string> other_errors;
- std::string error;
-
- bool has_error() const
- {
- return !missing_fields.empty() || !extra_fields.empty() || !expected_types.empty() ||
- !other_errors.empty() || !error.empty();
- }
- };
-
- template<class P>
- using ParseExpected = vcpkg::ExpectedT<std::unique_ptr<P>, std::unique_ptr<ParseControlErrorInfo>>;
-
- using Paragraph = std::unordered_map<std::string, std::pair<std::string, TextRowCol>>;
-
- struct ParagraphParser
- {
- ParagraphParser(Paragraph&& fields) : fields(std::move(fields)) { }
-
- std::string required_field(const std::string& fieldname);
- void required_field(const std::string& fieldname, std::string& out);
- void required_field(const std::string& fieldname, std::pair<std::string&, TextRowCol&> out);
-
- std::string optional_field(const std::string& fieldname);
- void optional_field(const std::string& fieldname, std::pair<std::string&, TextRowCol&> out);
-
- void add_type_error(const std::string& fieldname, const char* type) { expected_types[fieldname] = type; }
-
- std::unique_ptr<ParseControlErrorInfo> error_info(const std::string& name) const;
-
- private:
- Paragraph&& fields;
- std::vector<std::string> missing_fields;
- std::map<std::string, std::string> expected_types;
- };
-
- ExpectedS<std::vector<std::string>> parse_default_features_list(const std::string& str,
- StringView origin = "<unknown>",
- TextRowCol textrowcol = {});
- ExpectedS<std::vector<ParsedQualifiedSpecifier>> parse_qualified_specifier_list(const std::string& str,
- StringView origin = "<unknown>",
- TextRowCol textrowcol = {});
- ExpectedS<std::vector<Dependency>> parse_dependencies_list(const std::string& str,
- StringView origin = "<unknown>",
- TextRowCol textrowcol = {});
-}
diff --git a/toolsrc/include/vcpkg/paragraphs.h b/toolsrc/include/vcpkg/paragraphs.h
deleted file mode 100644
index b376eef81..000000000
--- a/toolsrc/include/vcpkg/paragraphs.h
+++ /dev/null
@@ -1,60 +0,0 @@
-#pragma once
-
-#include <vcpkg/fwd/vcpkgpaths.h>
-
-#include <vcpkg/base/expected.h>
-
-#include <vcpkg/binaryparagraph.h>
-
-namespace vckpg::Parse
-{
- struct ParseControlErrorInfo;
-}
-
-namespace vcpkg::Paragraphs
-{
- using Paragraph = Parse::Paragraph;
-
- ExpectedS<Paragraph> parse_single_paragraph(const std::string& str, const std::string& origin);
- ExpectedS<Paragraph> get_single_paragraph(const Files::Filesystem& fs, const fs::path& control_path);
-
- ExpectedS<std::vector<Paragraph>> get_paragraphs(const Files::Filesystem& fs, const fs::path& control_path);
- ExpectedS<std::vector<Paragraph>> get_paragraphs_text(const std::string& text, const std::string& origin);
-
- ExpectedS<std::vector<Paragraph>> parse_paragraphs(const std::string& str, const std::string& origin);
-
- bool is_port_directory(const Files::Filesystem& fs, const fs::path& path);
-
- Parse::ParseExpected<SourceControlFile> try_load_port(const Files::Filesystem& fs, const fs::path& path);
- Parse::ParseExpected<SourceControlFile> try_load_port_text(const std::string& text,
- const std::string& origin,
- bool is_manifest);
-
- ExpectedS<BinaryControlFile> try_load_cached_package(const VcpkgPaths& paths, const PackageSpec& spec);
-
- struct LoadResults
- {
- std::vector<SourceControlFileLocation> paragraphs;
- std::vector<std::unique_ptr<Parse::ParseControlErrorInfo>> errors;
- };
-
- // this allows one to pass this around as an overload set to stuff like `Util::fmap`,
- // as opposed to making it a function
- constexpr struct
- {
- const std::string& operator()(const SourceControlFileLocation* loc) const
- {
- return (*this)(*loc->source_control_file);
- }
- const std::string& operator()(const SourceControlFileLocation& loc) const
- {
- return (*this)(*loc.source_control_file);
- }
- const std::string& operator()(const SourceControlFile& scf) const { return scf.core_paragraph->name; }
- } get_name_of_control_file;
-
- LoadResults try_load_all_registry_ports(const VcpkgPaths& paths);
-
- std::vector<SourceControlFileLocation> load_all_registry_ports(const VcpkgPaths& paths);
- std::vector<SourceControlFileLocation> load_overlay_ports(const Files::Filesystem& fs, const fs::path& dir);
-}
diff --git a/toolsrc/include/vcpkg/platform-expression.h b/toolsrc/include/vcpkg/platform-expression.h
deleted file mode 100644
index 5de13b7a2..000000000
--- a/toolsrc/include/vcpkg/platform-expression.h
+++ /dev/null
@@ -1,82 +0,0 @@
-#pragma once
-
-#include <vcpkg/base/expected.h>
-#include <vcpkg/base/stringview.h>
-
-#include <string>
-#include <unordered_map>
-
-namespace vcpkg::PlatformExpression
-{
- // map of cmake variables and their values.
- using Context = std::unordered_map<std::string, std::string>;
-
- namespace detail
- {
- struct ExprImpl;
- }
- struct Expr
- {
- static Expr Identifier(StringView id);
- static Expr Not(Expr&& e);
- static Expr And(std::vector<Expr>&& exprs);
- static Expr Or(std::vector<Expr>&& exprs);
-
- // The empty expression is always true
- static Expr Empty() { return Expr(); }
-
- // since ExprImpl is not yet defined, we need to define the ctor and dtor in the C++ file
- Expr();
- Expr(const Expr&);
- Expr(Expr&&);
- Expr& operator=(const Expr& e);
- Expr& operator=(Expr&&);
-
- explicit Expr(std::unique_ptr<detail::ExprImpl>&& e);
- ~Expr();
-
- bool evaluate(const Context& context) const;
- bool is_empty() const { return !static_cast<bool>(underlying_); }
-
- // returns:
- // - 0 for empty
- // - 1 for identifiers
- // - 1 + complexity(inner) for !
- // - 1 + sum(complexity(inner)) for & and |
- int complexity() const;
-
- // these two are friends so that they're only findable via ADL
-
- // this does a structural equality, so, for example:
- // !structurally_equal((x & y) & z, x & y & z)
- // !structurally_equal((x & y) | z, (x | z) & (y | z))
- // even though these expressions are equivalent
- friend bool structurally_equal(const Expr& lhs, const Expr& rhs);
-
- // returns 0 if and only if structurally_equal(lhs, rhs)
- // Orders via the following:
- // - If complexity(a) < complexity(b) => a < b
- // - Otherwise, if to_string(a).size() < to_string(b).size() => a < b
- // - Otherwise, if to_string(a) < to_string(b) => a < b
- // - else, they must be structurally equal
- friend int compare(const Expr& lhs, const Expr& rhs);
-
- friend std::string to_string(const Expr& expr);
-
- private:
- std::unique_ptr<detail::ExprImpl> underlying_;
- };
-
- // Note: for backwards compatibility, in CONTROL files,
- // multiple binary operators are allowed to be next to one another; i.e.
- // (windows & arm) = (windows && arm) = (windows &&& arm), etc.
- enum class MultipleBinaryOperators
- {
- Deny,
- Allow,
- };
-
- // platform expression parses a platform expression; the EBNF of such is defined in
- // /docs/maintainers/manifest-files.md#supports
- ExpectedS<Expr> parse_platform_expression(StringView expression, MultipleBinaryOperators multiple_binary_operators);
-}
diff --git a/toolsrc/include/vcpkg/portfileprovider.h b/toolsrc/include/vcpkg/portfileprovider.h
deleted file mode 100644
index 979004f94..000000000
--- a/toolsrc/include/vcpkg/portfileprovider.h
+++ /dev/null
@@ -1,70 +0,0 @@
-#pragma once
-
-#include <vcpkg/fwd/vcpkgpaths.h>
-
-#include <vcpkg/base/expected.h>
-#include <vcpkg/base/util.h>
-
-#include <vcpkg/registries.h>
-#include <vcpkg/sourceparagraph.h>
-#include <vcpkg/versions.h>
-
-namespace vcpkg::PortFileProvider
-{
- struct PortFileProvider
- {
- virtual ~PortFileProvider() = default;
- virtual ExpectedS<const SourceControlFileLocation&> get_control_file(const std::string& src_name) const = 0;
- virtual std::vector<const SourceControlFileLocation*> load_all_control_files() const = 0;
- };
-
- struct MapPortFileProvider : Util::ResourceBase, PortFileProvider
- {
- explicit MapPortFileProvider(const std::unordered_map<std::string, SourceControlFileLocation>& map);
- ExpectedS<const SourceControlFileLocation&> get_control_file(const std::string& src_name) const override;
- std::vector<const SourceControlFileLocation*> load_all_control_files() const override;
-
- private:
- const std::unordered_map<std::string, SourceControlFileLocation>& ports;
- };
-
- struct IVersionedPortfileProvider
- {
- virtual View<VersionT> get_port_versions(StringView port_name) const = 0;
- virtual ~IVersionedPortfileProvider() = default;
-
- virtual ExpectedS<const SourceControlFileLocation&> get_control_file(
- const Versions::VersionSpec& version_spec) const = 0;
- virtual void load_all_control_files(std::map<std::string, const SourceControlFileLocation*>& out) const = 0;
- };
-
- struct IBaselineProvider
- {
- virtual Optional<VersionT> get_baseline_version(StringView port_name) const = 0;
- virtual ~IBaselineProvider() = default;
- };
-
- struct IOverlayProvider
- {
- virtual ~IOverlayProvider() = default;
- virtual Optional<const SourceControlFileLocation&> get_control_file(StringView port_name) const = 0;
- virtual void load_all_control_files(std::map<std::string, const SourceControlFileLocation*>& out) const = 0;
- };
-
- struct PathsPortFileProvider : Util::ResourceBase, PortFileProvider
- {
- explicit PathsPortFileProvider(const vcpkg::VcpkgPaths& paths, const std::vector<std::string>& overlay_ports);
- ExpectedS<const SourceControlFileLocation&> get_control_file(const std::string& src_name) const override;
- std::vector<const SourceControlFileLocation*> load_all_control_files() const override;
-
- private:
- std::unique_ptr<IBaselineProvider> m_baseline;
- std::unique_ptr<IVersionedPortfileProvider> m_versioned;
- std::unique_ptr<IOverlayProvider> m_overlay;
- };
-
- std::unique_ptr<IBaselineProvider> make_baseline_provider(const vcpkg::VcpkgPaths& paths);
- std::unique_ptr<IVersionedPortfileProvider> make_versioned_portfile_provider(const vcpkg::VcpkgPaths& paths);
- std::unique_ptr<IOverlayProvider> make_overlay_provider(const vcpkg::VcpkgPaths& paths,
- View<std::string> overlay_ports);
-}
diff --git a/toolsrc/include/vcpkg/postbuildlint.buildtype.h b/toolsrc/include/vcpkg/postbuildlint.buildtype.h
deleted file mode 100644
index 4d6da1494..000000000
--- a/toolsrc/include/vcpkg/postbuildlint.buildtype.h
+++ /dev/null
@@ -1,65 +0,0 @@
-#pragma once
-
-#include <vcpkg/base/cstringview.h>
-
-#include <vcpkg/build.h>
-
-#include <array>
-#include <regex>
-
-namespace vcpkg::PostBuildLint
-{
- struct BuildType
- {
- enum class BackingEnum
- {
- DEBUG_STATIC = 1,
- DEBUG_DYNAMIC,
- RELEASE_STATIC,
- RELEASE_DYNAMIC
- };
-
- static BuildType value_of(const Build::ConfigurationType& config, const Build::LinkageType& linkage);
-
- BuildType() = delete;
-
- constexpr BuildType(const BackingEnum backing_enum,
- const Build::ConfigurationType config,
- const Build::LinkageType linkage)
- : backing_enum(backing_enum), m_config(config), m_linkage(linkage)
- {
- }
-
- constexpr operator BackingEnum() const { return backing_enum; }
-
- const Build::ConfigurationType& config() const;
- const Build::LinkageType& linkage() const;
- const std::regex& crt_regex() const;
- const std::string& to_string() const;
-
- private:
- BackingEnum backing_enum;
- Build::ConfigurationType m_config;
- Build::LinkageType m_linkage;
- };
-
- namespace BuildTypeC
- {
- using Build::LinkageType;
- using BE = BuildType::BackingEnum;
-
- static constexpr CStringView ENUM_NAME = "vcpkg::PostBuildLint::BuildType";
-
- static constexpr BuildType DEBUG_STATIC = {
- BE::DEBUG_STATIC, Build::ConfigurationType::DEBUG, LinkageType::STATIC};
- static constexpr BuildType DEBUG_DYNAMIC = {
- BE::DEBUG_DYNAMIC, Build::ConfigurationType::DEBUG, LinkageType::DYNAMIC};
- static constexpr BuildType RELEASE_STATIC = {
- BE::RELEASE_STATIC, Build::ConfigurationType::RELEASE, LinkageType::STATIC};
- static constexpr BuildType RELEASE_DYNAMIC = {
- BE::RELEASE_DYNAMIC, Build::ConfigurationType::RELEASE, LinkageType::DYNAMIC};
-
- static constexpr std::array<BuildType, 4> VALUES = {
- DEBUG_STATIC, DEBUG_DYNAMIC, RELEASE_STATIC, RELEASE_DYNAMIC};
- }
-}
diff --git a/toolsrc/include/vcpkg/postbuildlint.h b/toolsrc/include/vcpkg/postbuildlint.h
deleted file mode 100644
index deaf3a2ae..000000000
--- a/toolsrc/include/vcpkg/postbuildlint.h
+++ /dev/null
@@ -1,20 +0,0 @@
-#pragma once
-
-#include <vcpkg/fwd/build.h>
-#include <vcpkg/fwd/vcpkgpaths.h>
-
-#include <vcpkg/base/files.h>
-
-namespace vcpkg
-{
- struct PackageSpec;
-}
-
-namespace vcpkg::PostBuildLint
-{
- size_t perform_all_checks(const PackageSpec& spec,
- const VcpkgPaths& paths,
- const Build::PreBuildInfo& pre_build_info,
- const Build::BuildInfo& build_info,
- const fs::path& port_dir);
-}
diff --git a/toolsrc/include/vcpkg/registries.h b/toolsrc/include/vcpkg/registries.h
deleted file mode 100644
index 9c07f1a60..000000000
--- a/toolsrc/include/vcpkg/registries.h
+++ /dev/null
@@ -1,111 +0,0 @@
-#pragma once
-
-#include <vcpkg/fwd/configuration.h>
-#include <vcpkg/fwd/registries.h>
-#include <vcpkg/fwd/vcpkgpaths.h>
-
-#include <vcpkg/base/files.h>
-#include <vcpkg/base/jsonreader.h>
-#include <vcpkg/base/stringview.h>
-#include <vcpkg/base/view.h>
-
-#include <vcpkg/versiondeserializers.h>
-#include <vcpkg/versiont.h>
-
-#include <map>
-#include <memory>
-#include <string>
-#include <system_error>
-#include <vector>
-
-namespace vcpkg
-{
- struct RegistryEntry
- {
- virtual View<VersionT> get_port_versions() const = 0;
-
- virtual ExpectedS<fs::path> get_path_to_version(const VcpkgPaths& paths, const VersionT& version) const = 0;
-
- virtual ~RegistryEntry() = default;
- };
-
- struct RegistryImplementation
- {
- // returns nullptr if the port doesn't exist
- virtual std::unique_ptr<RegistryEntry> get_port_entry(const VcpkgPaths& paths, StringView port_name) const = 0;
-
- // appends the names of the ports to the out parameter
- // may result in duplicated port names; make sure to Util::sort_unique_erase at the end
- virtual void get_all_port_names(std::vector<std::string>& port_names, const VcpkgPaths& paths) const = 0;
-
- virtual Optional<VersionT> get_baseline_version(const VcpkgPaths& paths, StringView port_name) const = 0;
-
- virtual ~RegistryImplementation() = default;
- };
-
- struct Registry
- {
- // requires: static_cast<bool>(implementation)
- Registry(std::vector<std::string>&& packages, std::unique_ptr<RegistryImplementation>&& implementation);
-
- Registry(std::vector<std::string>&&, std::nullptr_t) = delete;
-
- // always ordered lexicographically
- View<std::string> packages() const { return packages_; }
- const RegistryImplementation& implementation() const { return *implementation_; }
-
- friend RegistrySet; // for experimental_set_builtin_registry_baseline
-
- private:
- std::vector<std::string> packages_;
- std::unique_ptr<RegistryImplementation> implementation_;
- };
-
- // this type implements the registry fall back logic from the registries RFC:
- // A port name maps to one of the non-default registries if that registry declares
- // that it is the registry for that port name, else it maps to the default registry
- // if that registry exists; else, there is no registry for a port.
- // The way one sets this up is via the `"registries"` and `"default_registry"`
- // configuration fields.
- struct RegistrySet
- {
- RegistrySet();
-
- // finds the correct registry for the port name
- // Returns the null pointer if there is no registry set up for that name
- const RegistryImplementation* registry_for_port(StringView port_name) const;
- Optional<VersionT> baseline_for_port(const VcpkgPaths& paths, StringView port_name) const;
-
- View<Registry> registries() const { return registries_; }
-
- const RegistryImplementation* default_registry() const { return default_registry_.get(); }
-
- // TODO: figure out how to get this to return an error (or maybe it should be a warning?)
- void add_registry(Registry&& r);
- void set_default_registry(std::unique_ptr<RegistryImplementation>&& r);
- void set_default_registry(std::nullptr_t r);
-
- // this exists in order to allow versioning and registries to be developed and tested separately
- void experimental_set_builtin_registry_baseline(StringView baseline) const;
-
- // returns whether the registry set has any modifications to the default
- // (i.e., whether `default_registry` was set, or `registries` had any entries)
- // for checking against the registry feature flag.
- bool has_modifications() const;
-
- private:
- std::unique_ptr<RegistryImplementation> default_registry_;
- std::vector<Registry> registries_;
- };
-
- std::unique_ptr<Json::IDeserializer<std::unique_ptr<RegistryImplementation>>>
- get_registry_implementation_deserializer(const fs::path& configuration_directory);
-
- std::unique_ptr<Json::IDeserializer<std::vector<Registry>>> get_registry_array_deserializer(
- const fs::path& configuration_directory);
-
- ExpectedS<std::vector<std::pair<SchemedVersion, std::string>>> get_builtin_versions(const VcpkgPaths& paths,
- StringView port_name);
-
- ExpectedS<std::map<std::string, VersionT, std::less<>>> get_builtin_baseline(const VcpkgPaths& paths);
-}
diff --git a/toolsrc/include/vcpkg/remove.h b/toolsrc/include/vcpkg/remove.h
deleted file mode 100644
index faba3e368..000000000
--- a/toolsrc/include/vcpkg/remove.h
+++ /dev/null
@@ -1,34 +0,0 @@
-#pragma once
-
-#include <vcpkg/fwd/dependencies.h>
-#include <vcpkg/fwd/vcpkgcmdarguments.h>
-#include <vcpkg/fwd/vcpkgpaths.h>
-
-#include <vcpkg/commands.interface.h>
-
-namespace vcpkg::Remove
-{
- enum class Purge
- {
- NO = 0,
- YES
- };
-
- inline Purge to_purge(const bool value) { return value ? Purge::YES : Purge::NO; }
-
- void perform_remove_plan_action(const VcpkgPaths& paths,
- const Dependencies::RemovePlanAction& action,
- const Purge purge,
- StatusParagraphs* status_db);
-
- extern const CommandStructure COMMAND_STRUCTURE;
-
- void remove_package(const VcpkgPaths& paths, const PackageSpec& spec, StatusParagraphs* status_db);
-
- struct RemoveCommand : Commands::TripletCommand
- {
- virtual void perform_and_exit(const VcpkgCmdArguments& args,
- const VcpkgPaths& paths,
- Triplet default_triplet) const override;
- };
-}
diff --git a/toolsrc/include/vcpkg/sourceparagraph.h b/toolsrc/include/vcpkg/sourceparagraph.h
deleted file mode 100644
index 52ce53980..000000000
--- a/toolsrc/include/vcpkg/sourceparagraph.h
+++ /dev/null
@@ -1,156 +0,0 @@
-#pragma once
-
-#include <vcpkg/base/fwd/json.h>
-
-#include <vcpkg/fwd/vcpkgcmdarguments.h>
-
-#include <vcpkg/base/expected.h>
-#include <vcpkg/base/span.h>
-#include <vcpkg/base/system.h>
-#include <vcpkg/base/system.print.h>
-
-#include <vcpkg/packagespec.h>
-#include <vcpkg/paragraphparser.h>
-#include <vcpkg/platform-expression.h>
-#include <vcpkg/versiondeserializers.h>
-#include <vcpkg/versions.h>
-
-namespace vcpkg
-{
- std::vector<FullPackageSpec> filter_dependencies(const std::vector<Dependency>& deps,
- Triplet t,
- const std::unordered_map<std::string, std::string>& cmake_vars);
-
- struct Type
- {
- enum
- {
- UNKNOWN,
- PORT,
- ALIAS,
- } type;
-
- static std::string to_string(const Type&);
- static Type from_string(const std::string&);
- };
-
- bool operator==(const Type&, const Type&);
- bool operator!=(const Type&, const Type&);
-
- /// <summary>
- /// Port metadata of additional feature in a package (part of CONTROL file)
- /// </summary>
- struct FeatureParagraph
- {
- std::string name;
- std::vector<std::string> description;
- std::vector<Dependency> dependencies;
-
- Json::Object extra_info;
-
- friend bool operator==(const FeatureParagraph& lhs, const FeatureParagraph& rhs);
- friend bool operator!=(const FeatureParagraph& lhs, const FeatureParagraph& rhs) { return !(lhs == rhs); }
- };
-
- /// <summary>
- /// Port metadata of the core feature of a package (part of CONTROL file)
- /// </summary>
- struct SourceParagraph
- {
- std::string name;
- Versions::Scheme version_scheme = Versions::Scheme::String;
- std::string version;
- int port_version = 0;
- std::vector<std::string> description;
- std::vector<std::string> maintainers;
- std::string homepage;
- std::string documentation;
- std::vector<Dependency> dependencies;
- std::vector<DependencyOverride> overrides;
- std::vector<std::string> default_features;
- std::string license; // SPDX license expression
- Optional<std::string> builtin_baseline;
-
- Type type;
- PlatformExpression::Expr supports_expression;
-
- Json::Object extra_info;
-
- VersionT to_versiont() const { return VersionT{version, port_version}; }
-
- friend bool operator==(const SourceParagraph& lhs, const SourceParagraph& rhs);
- friend bool operator!=(const SourceParagraph& lhs, const SourceParagraph& rhs) { return !(lhs == rhs); }
- };
-
- /// <summary>
- /// Full metadata of a package: core and other features.
- /// </summary>
- struct SourceControlFile
- {
- SourceControlFile clone() const;
-
- static Parse::ParseExpected<SourceControlFile> parse_manifest_object(const std::string& origin,
- const Json::Object& object);
-
- static Parse::ParseExpected<SourceControlFile> parse_manifest_file(const fs::path& path_to_manifest,
- const Json::Object& object);
-
- static Parse::ParseExpected<SourceControlFile> parse_control_file(
- const std::string& origin, std::vector<Parse::Paragraph>&& control_paragraphs);
-
- // Always non-null in non-error cases
- std::unique_ptr<SourceParagraph> core_paragraph;
- std::vector<std::unique_ptr<FeatureParagraph>> feature_paragraphs;
-
- Optional<const FeatureParagraph&> find_feature(const std::string& featurename) const;
- Optional<const std::vector<Dependency>&> find_dependencies_for_feature(const std::string& featurename) const;
-
- Optional<std::string> check_against_feature_flags(const fs::path& origin,
- const FeatureFlagSettings& flags) const;
-
- VersionT to_versiont() const { return core_paragraph->to_versiont(); }
- SchemedVersion to_schemed_version() const
- {
- return SchemedVersion{core_paragraph->version_scheme, core_paragraph->to_versiont()};
- }
-
- friend bool operator==(const SourceControlFile& lhs, const SourceControlFile& rhs);
- friend bool operator!=(const SourceControlFile& lhs, const SourceControlFile& rhs) { return !(lhs == rhs); }
- };
-
- Json::Object serialize_manifest(const SourceControlFile& scf);
- Json::Object serialize_debug_manifest(const SourceControlFile& scf);
-
- /// <summary>
- /// Full metadata of a package: core and other features,
- /// as well as the port directory the SourceControlFile was loaded from
- /// </summary>
- struct SourceControlFileLocation
- {
- SourceControlFileLocation(std::unique_ptr<SourceControlFile>&& scf, fs::path&& source)
- : source_control_file(std::move(scf)), source_location(std::move(source))
- {
- }
-
- SourceControlFileLocation(std::unique_ptr<SourceControlFile>&& scf, const fs::path& source)
- : source_control_file(std::move(scf)), source_location(source)
- {
- }
-
- SourceControlFileLocation clone() const
- {
- return {std::make_unique<SourceControlFile>(source_control_file->clone()), source_location};
- }
-
- VersionT to_versiont() const { return source_control_file->to_versiont(); }
-
- std::unique_ptr<SourceControlFile> source_control_file;
- fs::path source_location;
- };
-
- void print_error_message(Span<const std::unique_ptr<Parse::ParseControlErrorInfo>> error_info_list);
- inline void print_error_message(const std::unique_ptr<Parse::ParseControlErrorInfo>& error_info_list)
- {
- return print_error_message({&error_info_list, 1});
- }
-}
diff --git a/toolsrc/include/vcpkg/statusparagraph.h b/toolsrc/include/vcpkg/statusparagraph.h
deleted file mode 100644
index 1cfa7a17c..000000000
--- a/toolsrc/include/vcpkg/statusparagraph.h
+++ /dev/null
@@ -1,68 +0,0 @@
-#pragma once
-
-#include <vcpkg/fwd/vcpkgpaths.h>
-
-#include <vcpkg/binaryparagraph.h>
-
-#include <map>
-
-namespace vcpkg
-{
- enum class InstallState
- {
- ERROR_STATE,
- NOT_INSTALLED,
- HALF_INSTALLED,
- INSTALLED,
- };
-
- enum class Want
- {
- ERROR_STATE,
- UNKNOWN,
- INSTALL,
- HOLD,
- DEINSTALL,
- PURGE
- };
-
- /// <summary>
- /// Installed package metadata
- /// </summary>
- struct StatusParagraph
- {
- StatusParagraph() noexcept;
- explicit StatusParagraph(Parse::Paragraph&& fields);
-
- bool is_installed() const { return want == Want::INSTALL && state == InstallState::INSTALLED; }
-
- BinaryParagraph package;
- Want want;
- InstallState state;
- };
-
- void serialize(const StatusParagraph& pgh, std::string& out_str);
-
- std::string to_string(InstallState f);
-
- std::string to_string(Want f);
-
- struct InstalledPackageView
- {
- InstalledPackageView() noexcept : core(nullptr) { }
-
- InstalledPackageView(const StatusParagraph* c, std::vector<const StatusParagraph*>&& fs)
- : core(c), features(std::move(fs))
- {
- }
-
- const PackageSpec& spec() const { return core->package.spec; }
- std::vector<PackageSpec> dependencies() const;
- std::map<std::string, std::vector<FeatureSpec>> feature_dependencies() const;
-
- const StatusParagraph* core;
- std::vector<const StatusParagraph*> features;
- };
-
- Json::Value serialize_ipv(const InstalledPackageView& ipv, const VcpkgPaths& paths);
-}
diff --git a/toolsrc/include/vcpkg/statusparagraphs.h b/toolsrc/include/vcpkg/statusparagraphs.h
deleted file mode 100644
index 8fd85b4e0..000000000
--- a/toolsrc/include/vcpkg/statusparagraphs.h
+++ /dev/null
@@ -1,82 +0,0 @@
-#pragma once
-#include <vcpkg/statusparagraph.h>
-
-#include <iterator>
-#include <memory>
-
-namespace vcpkg
-{
- /// <summary>Status paragraphs</summary>
- ///
- /// Collection of <see cref="vcpkg::StatusParagraph"/>, e.g. contains the information
- /// about whether a package is installed or not.
- ///
- struct StatusParagraphs
- {
- StatusParagraphs();
- explicit StatusParagraphs(std::vector<std::unique_ptr<StatusParagraph>>&& ps);
-
- using container = std::vector<std::unique_ptr<StatusParagraph>>;
- using iterator = container::reverse_iterator;
- using const_iterator = container::const_reverse_iterator;
-
- /// <summary>Find the StatusParagraph for given spec.</summary>
- /// <param name="spec">Package specification to find the status paragraph for</param>
- /// <returns>Iterator for found spec</returns>
- const_iterator find(const PackageSpec& spec) const { return find(spec.name(), spec.triplet()); }
-
- /// <summary>Find the StatusParagraph for given feature spec.</summary>
- /// <param name="spec">Feature specification to find the status paragraph for</param>
- /// <returns>Iterator for found spec</returns>
- const_iterator find(const FeatureSpec& spec) const { return find(spec.name(), spec.triplet(), spec.feature()); }
-
- /// <summary>Find a StatusParagraph by name, triplet and feature.</summary>
- /// <param name="name">Package name</param>
- /// <param name="triplet">Triplet</param>
- /// <param name="feature">Feature name</param>
- /// <returns>Iterator for found spec</returns>
- iterator find(const std::string& name, Triplet triplet, const std::string& feature = {});
- const_iterator find(const std::string& name, Triplet triplet, const std::string& feature = {}) const;
-
- std::vector<std::unique_ptr<StatusParagraph>*> find_all(const std::string& name, Triplet triplet);
-
- Optional<InstalledPackageView> get_installed_package_view(const PackageSpec& spec) const;
-
- /// <summary>Find the StatusParagraph for given spec if installed</summary>
- /// <param name="spec">Package specification to find the status for</param>
- /// <returns>Iterator for found spec</returns>
- const_iterator find_installed(const PackageSpec& spec) const;
-
- /// <summary>Find the StatusParagraph for given feature spec if installed</summary>
- /// <param name="spec">Feature specification to find the status for</param>
- /// <returns>Iterator for found spec</returns>
- const_iterator find_installed(const FeatureSpec& spec) const;
-
- /// <summary>Find the StatusParagraph for given spec and return its install status</summary>
- /// <param name="spec">Package specification to check if installed</param>
- /// <returns>`true` if installed, `false` if not or not found.</returns>
- bool is_installed(const PackageSpec& spec) const;
-
- /// <summary>Find the StatusParagraph for given feature spec and return its install status</summary>
- /// <param name="spec">Feature specification to check if installed</param>
- /// <returns>`true` if installed, `false` if not or not found.</returns>
- bool is_installed(const FeatureSpec& spec) const;
-
- iterator insert(std::unique_ptr<StatusParagraph>);
-
- friend void serialize(const StatusParagraphs& pgh, std::string& out_str);
-
- iterator end() { return paragraphs.rend(); }
-
- const_iterator end() const { return paragraphs.rend(); }
-
- iterator begin() { return paragraphs.rbegin(); }
-
- const_iterator begin() const { return paragraphs.rbegin(); }
-
- private:
- std::vector<std::unique_ptr<StatusParagraph>> paragraphs;
- };
-
- void serialize(const StatusParagraphs& pgh, std::string& out_str);
-}
diff --git a/toolsrc/include/vcpkg/textrowcol.h b/toolsrc/include/vcpkg/textrowcol.h
deleted file mode 100644
index b8269f697..000000000
--- a/toolsrc/include/vcpkg/textrowcol.h
+++ /dev/null
@@ -1,17 +0,0 @@
-#pragma once
-
-namespace vcpkg::Parse
-{
- struct TextRowCol
- {
- constexpr TextRowCol() noexcept = default;
- constexpr TextRowCol(int row, int column) noexcept : row(row), column(column) { }
- /// '0' indicates uninitialized; '1' is the first row.
- int row = 0;
- /// '0' indicates uninitialized; '1' is the first column.
- int column = 0;
-
- constexpr int row_or(int def) const noexcept { return row ? row : def; }
- constexpr int column_or(int def) const noexcept { return column ? column : def; }
- };
-}
diff --git a/toolsrc/include/vcpkg/tools.h b/toolsrc/include/vcpkg/tools.h
deleted file mode 100644
index 8f0398a5c..000000000
--- a/toolsrc/include/vcpkg/tools.h
+++ /dev/null
@@ -1,37 +0,0 @@
-#pragma once
-
-#include <vcpkg/fwd/vcpkgpaths.h>
-
-#include <vcpkg/base/files.h>
-
-#include <string>
-#include <utility>
-
-namespace vcpkg
-{
- namespace Tools
- {
- static const std::string SEVEN_ZIP = "7zip";
- static const std::string SEVEN_ZIP_ALT = "7z";
- static const std::string MAVEN = "mvn";
- static const std::string CMAKE = "cmake";
- static const std::string GIT = "git";
- static const std::string MONO = "mono";
- static const std::string NINJA = "ninja";
- static const std::string POWERSHELL_CORE = "powershell-core";
- static const std::string NUGET = "nuget";
- static const std::string IFW_INSTALLER_BASE = "ifw_installerbase";
- static const std::string IFW_BINARYCREATOR = "ifw_binarycreator";
- static const std::string IFW_REPOGEN = "ifw_repogen";
- }
-
- struct ToolCache
- {
- virtual ~ToolCache() { }
-
- virtual const fs::path& get_tool_path(const VcpkgPaths& paths, const std::string& tool) const = 0;
- virtual const std::string& get_tool_version(const VcpkgPaths& paths, const std::string& tool) const = 0;
- };
-
- std::unique_ptr<ToolCache> get_tool_cache();
-}
diff --git a/toolsrc/include/vcpkg/triplet.h b/toolsrc/include/vcpkg/triplet.h
deleted file mode 100644
index 40f6d6f23..000000000
--- a/toolsrc/include/vcpkg/triplet.h
+++ /dev/null
@@ -1,50 +0,0 @@
-#pragma once
-
-#include <vcpkg/fwd/vcpkgcmdarguments.h>
-
-#include <vcpkg/base/optional.h>
-#include <vcpkg/base/system.h>
-
-#include <string>
-
-namespace vcpkg
-{
- struct TripletInstance;
-
- struct Triplet
- {
- public:
- constexpr Triplet() noexcept : m_instance(&DEFAULT_INSTANCE) { }
-
- static Triplet from_canonical_name(std::string&& triplet_as_string);
-
- const std::string& canonical_name() const;
- const std::string& to_string() const;
- void to_string(std::string& out) const;
- size_t hash_code() const;
- Optional<System::CPUArchitecture> guess_architecture() const noexcept;
-
- bool operator==(Triplet other) const { return this->m_instance == other.m_instance; }
- bool operator<(Triplet other) const { return canonical_name() < other.canonical_name(); }
-
- private:
- static const TripletInstance DEFAULT_INSTANCE;
-
- constexpr Triplet(const TripletInstance* ptr) : m_instance(ptr) { }
-
- const TripletInstance* m_instance;
- };
-
- inline bool operator!=(Triplet left, Triplet right) { return !(left == right); }
-
- Triplet default_triplet(const VcpkgCmdArguments& args);
-}
-
-namespace std
-{
- template<>
- struct hash<vcpkg::Triplet>
- {
- size_t operator()(vcpkg::Triplet t) const { return t.hash_code(); }
- };
-}
diff --git a/toolsrc/include/vcpkg/update.h b/toolsrc/include/vcpkg/update.h
deleted file mode 100644
index 063e16997..000000000
--- a/toolsrc/include/vcpkg/update.h
+++ /dev/null
@@ -1,35 +0,0 @@
-#pragma once
-
-#include <vcpkg/fwd/portfileprovider.h>
-#include <vcpkg/fwd/vcpkgcmdarguments.h>
-#include <vcpkg/fwd/vcpkgpaths.h>
-
-#include <vcpkg/commands.interface.h>
-#include <vcpkg/packagespec.h>
-#include <vcpkg/versiont.h>
-
-namespace vcpkg
-{
- struct StatusParagraphs;
-}
-
-namespace vcpkg::Update
-{
- struct OutdatedPackage
- {
- static bool compare_by_name(const OutdatedPackage& left, const OutdatedPackage& right);
-
- PackageSpec spec;
- VersionDiff version_diff;
- };
-
- std::vector<OutdatedPackage> find_outdated_packages(const PortFileProvider::PortFileProvider& provider,
- const StatusParagraphs& status_db);
-
- void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths);
-
- struct UpdateCommand : Commands::PathsCommand
- {
- virtual void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) const override;
- };
-}
diff --git a/toolsrc/include/vcpkg/userconfig.h b/toolsrc/include/vcpkg/userconfig.h
deleted file mode 100644
index 74f8c876a..000000000
--- a/toolsrc/include/vcpkg/userconfig.h
+++ /dev/null
@@ -1,23 +0,0 @@
-#pragma once
-
-#include <vcpkg/base/files.h>
-
-#include <string>
-
-namespace vcpkg
-{
- struct UserConfig
- {
- std::string user_id;
- std::string user_time;
- std::string user_mac;
-
- std::string last_completed_survey;
-
- static UserConfig try_read_data(const Files::Filesystem& fs);
-
- void try_write_data(Files::Filesystem& fs) const;
- };
-
- fs::path get_user_dir();
-}
diff --git a/toolsrc/include/vcpkg/vcpkgcmdarguments.h b/toolsrc/include/vcpkg/vcpkgcmdarguments.h
deleted file mode 100644
index 14208e926..000000000
--- a/toolsrc/include/vcpkg/vcpkgcmdarguments.h
+++ /dev/null
@@ -1,236 +0,0 @@
-#pragma once
-
-#include <vcpkg/fwd/vcpkgcmdarguments.h>
-#include <vcpkg/fwd/vcpkgpaths.h>
-
-#include <vcpkg/base/files.h>
-#include <vcpkg/base/optional.h>
-#include <vcpkg/base/span.h>
-#include <vcpkg/base/stringliteral.h>
-
-#include <memory>
-#include <unordered_map>
-#include <unordered_set>
-#include <vector>
-
-namespace vcpkg
-{
- struct ParsedArguments
- {
- std::unordered_set<std::string> switches;
- std::unordered_map<std::string, std::string> settings;
- std::unordered_map<std::string, std::vector<std::string>> multisettings;
- };
-
- struct CommandSwitch
- {
- constexpr CommandSwitch(const StringLiteral& name, const StringLiteral& short_help_text)
- : name(name), short_help_text(short_help_text)
- {
- }
-
- StringLiteral name;
- StringLiteral short_help_text;
- };
-
- struct CommandSetting
- {
- constexpr CommandSetting(const StringLiteral& name, const StringLiteral& short_help_text)
- : name(name), short_help_text(short_help_text)
- {
- }
-
- StringLiteral name;
- StringLiteral short_help_text;
- };
-
- struct CommandMultiSetting
- {
- constexpr CommandMultiSetting(const StringLiteral& name, const StringLiteral& short_help_text)
- : name(name), short_help_text(short_help_text)
- {
- }
-
- StringLiteral name;
- StringLiteral short_help_text;
- };
-
- struct CommandOptionsStructure
- {
- Span<const CommandSwitch> switches;
- Span<const CommandSetting> settings;
- Span<const CommandMultiSetting> multisettings;
- };
-
- struct CommandStructure
- {
- std::string example_text;
-
- size_t minimum_arity;
- size_t maximum_arity;
-
- CommandOptionsStructure options;
-
- std::vector<std::string> (*valid_arguments)(const VcpkgPaths& paths);
- };
-
- void print_usage();
- void print_usage(const CommandStructure& command_structure);
-
-#if defined(_WIN32)
- using CommandLineCharType = wchar_t;
-#else
- using CommandLineCharType = char;
-#endif
-
- std::string create_example_string(const std::string& command_and_arguments);
-
- std::string format_environment_variable(StringLiteral lit);
-
- struct HelpTableFormatter
- {
- void format(StringView col1, StringView col2);
- void example(StringView example_text);
- void header(StringView name);
- void blank();
- void text(StringView text, int indent = 0);
-
- std::string m_str;
- };
-
- struct FeatureFlagSettings
- {
- bool registries;
- bool compiler_tracking;
- bool binary_caching;
- bool versions;
- };
-
- struct VcpkgCmdArguments
- {
- static VcpkgCmdArguments create_from_command_line(const Files::Filesystem& fs,
- const int argc,
- const CommandLineCharType* const* const argv);
- static VcpkgCmdArguments create_from_arg_sequence(const std::string* arg_begin, const std::string* arg_end);
-
- static void append_common_options(HelpTableFormatter& target);
-
- constexpr static StringLiteral VCPKG_ROOT_DIR_ENV = "VCPKG_ROOT";
- constexpr static StringLiteral VCPKG_ROOT_DIR_ARG = "vcpkg-root";
- std::unique_ptr<std::string> vcpkg_root_dir;
- constexpr static StringLiteral MANIFEST_ROOT_DIR_ARG = "x-manifest-root";
- std::unique_ptr<std::string> manifest_root_dir;
-
- constexpr static StringLiteral BUILDTREES_ROOT_DIR_ARG = "x-buildtrees-root";
- std::unique_ptr<std::string> buildtrees_root_dir;
- constexpr static StringLiteral DOWNLOADS_ROOT_DIR_ENV = "VCPKG_DOWNLOADS";
- constexpr static StringLiteral DOWNLOADS_ROOT_DIR_ARG = "downloads-root";
- std::unique_ptr<std::string> downloads_root_dir;
- constexpr static StringLiteral INSTALL_ROOT_DIR_ARG = "x-install-root";
- std::unique_ptr<std::string> install_root_dir;
- constexpr static StringLiteral PACKAGES_ROOT_DIR_ARG = "x-packages-root";
- std::unique_ptr<std::string> packages_root_dir;
- constexpr static StringLiteral SCRIPTS_ROOT_DIR_ARG = "x-scripts-root";
- std::unique_ptr<std::string> scripts_root_dir;
- constexpr static StringLiteral BUILTIN_PORTS_ROOT_DIR_ARG = "x-builtin-ports-root";
- std::unique_ptr<std::string> builtin_ports_root_dir;
- constexpr static StringLiteral BUILTIN_REGISTRY_VERSIONS_DIR_ARG = "x-builtin-registry-versions-dir";
- std::unique_ptr<std::string> builtin_registry_versions_dir;
-
- constexpr static StringLiteral DEFAULT_VISUAL_STUDIO_PATH_ENV = "VCPKG_VISUAL_STUDIO_PATH";
- std::unique_ptr<std::string> default_visual_studio_path;
-
- constexpr static StringLiteral TRIPLET_ENV = "VCPKG_DEFAULT_TRIPLET";
- constexpr static StringLiteral TRIPLET_ARG = "triplet";
- std::unique_ptr<std::string> triplet;
- constexpr static StringLiteral OVERLAY_PORTS_ENV = "VCPKG_OVERLAY_PORTS";
- constexpr static StringLiteral OVERLAY_PORTS_ARG = "overlay-ports";
- std::vector<std::string> overlay_ports;
- constexpr static StringLiteral OVERLAY_TRIPLETS_ENV = "VCPKG_OVERLAY_TRIPLETS";
- constexpr static StringLiteral OVERLAY_TRIPLETS_ARG = "overlay-triplets";
- std::vector<std::string> overlay_triplets;
-
- constexpr static StringLiteral BINARY_SOURCES_ARG = "binarysource";
- std::vector<std::string> binary_sources;
-
- constexpr static StringLiteral CMAKE_SCRIPT_ARG = "x-cmake-args";
- std::vector<std::string> cmake_args;
-
- constexpr static StringLiteral DEBUG_SWITCH = "debug";
- Optional<bool> debug = nullopt;
- constexpr static StringLiteral SEND_METRICS_SWITCH = "sendmetrics";
- Optional<bool> send_metrics = nullopt;
- // fully disable metrics -- both printing and sending
- constexpr static StringLiteral DISABLE_METRICS_ENV = "VCPKG_DISABLE_METRICS";
- constexpr static StringLiteral DISABLE_METRICS_SWITCH = "disable-metrics";
- Optional<bool> disable_metrics = nullopt;
- constexpr static StringLiteral PRINT_METRICS_SWITCH = "printmetrics";
- Optional<bool> print_metrics = nullopt;
-
- constexpr static StringLiteral WAIT_FOR_LOCK_SWITCH = "x-wait-for-lock";
- Optional<bool> wait_for_lock = nullopt;
-
- constexpr static StringLiteral IGNORE_LOCK_FAILURES_SWITCH = "x-ignore-lock-failures";
- constexpr static StringLiteral IGNORE_LOCK_FAILURES_ENV = "X_VCPKG_IGNORE_LOCK_FAILURES";
- Optional<bool> ignore_lock_failures = nullopt;
-
- constexpr static StringLiteral JSON_SWITCH = "x-json";
- Optional<bool> json = nullopt;
-
- // feature flags
- constexpr static StringLiteral FEATURE_FLAGS_ENV = "VCPKG_FEATURE_FLAGS";
- constexpr static StringLiteral FEATURE_FLAGS_ARG = "feature-flags";
-
- constexpr static StringLiteral FEATURE_PACKAGES_SWITCH = "featurepackages";
- Optional<bool> feature_packages = nullopt;
- constexpr static StringLiteral BINARY_CACHING_FEATURE = "binarycaching";
- constexpr static StringLiteral BINARY_CACHING_SWITCH = "binarycaching";
- Optional<bool> binary_caching = nullopt;
- constexpr static StringLiteral COMPILER_TRACKING_FEATURE = "compilertracking";
- Optional<bool> compiler_tracking = nullopt;
- constexpr static StringLiteral MANIFEST_MODE_FEATURE = "manifests";
- Optional<bool> manifest_mode = nullopt;
- constexpr static StringLiteral REGISTRIES_FEATURE = "registries";
- Optional<bool> registries_feature = nullopt;
- constexpr static StringLiteral VERSIONS_FEATURE = "versions";
- Optional<bool> versions_feature = nullopt;
-
- constexpr static StringLiteral RECURSIVE_DATA_ENV = "VCPKG_X_RECURSIVE_DATA";
-
- bool binary_caching_enabled() const { return binary_caching.value_or(true); }
- bool compiler_tracking_enabled() const { return compiler_tracking.value_or(true); }
- bool registries_enabled() const { return registries_feature.value_or(false); }
- bool versions_enabled() const { return versions_feature.value_or(false); }
- FeatureFlagSettings feature_flag_settings() const
- {
- FeatureFlagSettings f;
- f.binary_caching = binary_caching_enabled();
- f.compiler_tracking = compiler_tracking_enabled();
- f.registries = registries_enabled();
- f.versions = versions_enabled();
- return f;
- }
-
- bool output_json() const { return json.value_or(false); }
-
- std::string command;
- std::vector<std::string> command_arguments;
-
- ParsedArguments parse_arguments(const CommandStructure& command_structure) const;
-
- void imbue_from_environment();
-
- // Applies recursive settings from the environment or sets a global environment variable
- // to be consumed by subprocesses; may only be called once per process.
- static void imbue_or_apply_process_recursion(VcpkgCmdArguments& args);
-
- void check_feature_flag_consistency() const;
-
- void debug_print_feature_flags() const;
- void track_feature_flag_metrics() const;
-
- private:
- std::unordered_set<std::string> command_switches;
- std::unordered_map<std::string, std::vector<std::string>> command_options;
- };
-}
diff --git a/toolsrc/include/vcpkg/vcpkglib.h b/toolsrc/include/vcpkg/vcpkglib.h
deleted file mode 100644
index bb1d61c73..000000000
--- a/toolsrc/include/vcpkg/vcpkglib.h
+++ /dev/null
@@ -1,26 +0,0 @@
-#pragma once
-
-#include <vcpkg/fwd/vcpkgpaths.h>
-
-#include <vcpkg/base/sortedvector.h>
-
-#include <vcpkg/statusparagraphs.h>
-
-namespace vcpkg
-{
- StatusParagraphs database_load_check(const VcpkgPaths& paths);
-
- void write_update(const VcpkgPaths& paths, const StatusParagraph& p);
-
- struct StatusParagraphAndAssociatedFiles
- {
- StatusParagraph pgh;
- SortedVector<std::string> files;
- };
-
- std::vector<InstalledPackageView> get_installed_ports(const StatusParagraphs& status_db);
- std::vector<StatusParagraphAndAssociatedFiles> get_installed_files(const VcpkgPaths& paths,
- const StatusParagraphs& status_db);
-
- std::string shorten_text(const std::string& desc, const size_t length);
-} // namespace vcpkg
diff --git a/toolsrc/include/vcpkg/vcpkgpaths.h b/toolsrc/include/vcpkg/vcpkgpaths.h
deleted file mode 100644
index 643baf57e..000000000
--- a/toolsrc/include/vcpkg/vcpkgpaths.h
+++ /dev/null
@@ -1,178 +0,0 @@
-#pragma once
-
-#include <vcpkg/base/fwd/json.h>
-
-#include <vcpkg/fwd/configuration.h>
-#include <vcpkg/fwd/registries.h>
-#include <vcpkg/fwd/vcpkgcmdarguments.h>
-#include <vcpkg/fwd/vcpkgpaths.h>
-
-#include <vcpkg/base/cache.h>
-#include <vcpkg/base/files.h>
-#include <vcpkg/base/lazy.h>
-#include <vcpkg/base/optional.h>
-#include <vcpkg/base/system.h>
-#include <vcpkg/base/util.h>
-
-namespace vcpkg
-{
- struct ToolsetArchOption
- {
- CStringView name;
- System::CPUArchitecture host_arch;
- System::CPUArchitecture target_arch;
- };
-
- struct Toolset
- {
- fs::path visual_studio_root_path;
- fs::path dumpbin;
- fs::path vcvarsall;
- std::vector<std::string> vcvarsall_options;
- CStringView version;
- std::vector<ToolsetArchOption> supported_architectures;
- };
-
- namespace Build
- {
- struct PreBuildInfo;
- struct AbiInfo;
- struct CompilerInfo;
- }
-
- namespace System
- {
- struct Environment;
- }
-
- namespace details
- {
- struct VcpkgPathsImpl;
- }
-
- struct BinaryParagraph;
- struct PackageSpec;
- struct Triplet;
-
- struct VcpkgPaths : Util::MoveOnlyBase
- {
- struct TripletFile
- {
- std::string name;
- fs::path location;
-
- TripletFile(const std::string& name, const fs::path& location) : name(name), location(location) { }
- };
-
- VcpkgPaths(Files::Filesystem& filesystem, const VcpkgCmdArguments& args);
- ~VcpkgPaths();
-
- fs::path package_dir(const PackageSpec& spec) const;
- fs::path build_dir(const PackageSpec& spec) const;
- fs::path build_dir(const std::string& package_name) const;
- fs::path build_info_file_path(const PackageSpec& spec) const;
- fs::path listfile_path(const BinaryParagraph& pgh) const;
-
- bool is_valid_triplet(Triplet t) const;
- const std::vector<std::string> get_available_triplets_names() const;
- const std::vector<TripletFile>& get_available_triplets() const;
- const std::map<std::string, std::string>& get_cmake_script_hashes() const;
- const fs::path get_triplet_file_path(Triplet triplet) const;
-
- fs::path original_cwd;
- fs::path root;
- fs::path manifest_root_dir;
- fs::path config_root_dir;
- fs::path buildtrees;
- fs::path downloads;
- fs::path packages;
- fs::path installed;
- fs::path triplets;
- fs::path community_triplets;
- fs::path scripts;
- fs::path prefab;
- fs::path builtin_ports;
- fs::path builtin_registry_versions;
-
- fs::path tools;
- fs::path buildsystems;
- fs::path buildsystems_msbuild_targets;
- fs::path buildsystems_msbuild_props;
-
- fs::path vcpkg_dir;
- fs::path vcpkg_dir_status_file;
- fs::path vcpkg_dir_info;
- fs::path vcpkg_dir_updates;
-
- fs::path baselines_dot_git_dir;
- fs::path baselines_work_tree;
- fs::path baselines_output;
-
- fs::path versions_dot_git_dir;
- fs::path versions_work_tree;
- fs::path versions_output;
-
- fs::path ports_cmake;
-
- const fs::path& get_tool_exe(const std::string& tool) const;
- const std::string& get_tool_version(const std::string& tool) const;
-
- // Git manipulation in the vcpkg directory
- ExpectedS<std::string> get_current_git_sha() const;
- std::string get_current_git_sha_message() const;
- ExpectedS<fs::path> git_checkout_baseline(StringView commit_sha) const;
- ExpectedS<fs::path> git_checkout_port(StringView port_name,
- StringView git_tree,
- const fs::path& dot_git_dir) const;
- ExpectedS<std::string> git_show(const std::string& treeish, const fs::path& dot_git_dir) const;
-
- ExpectedS<std::map<std::string, std::string, std::less<>>> git_get_local_port_treeish_map() const;
-
- // Git manipulation for remote registries
- // runs `git fetch {uri} {treeish}`, and returns the hash of FETCH_HEAD.
- // If `treeish` is empty, then just runs `git fetch {uri}`
- ExpectedS<std::string> git_fetch_from_remote_registry(StringView uri, StringView treeish = {}) const;
- ExpectedS<std::string> git_show_from_remote_registry(StringView hash,
- const fs::path& relative_path_to_file) const;
- ExpectedS<std::string> git_find_object_id_for_remote_registry_path(StringView hash,
- const fs::path& relative_path_to_file) const;
- ExpectedS<fs::path> git_checkout_object_from_remote_registry(StringView tree) const;
-
- Optional<const Json::Object&> get_manifest() const;
- Optional<const fs::path&> get_manifest_path() const;
- const Configuration& get_configuration() const;
-
- /// <summary>Retrieve a toolset matching a VS version</summary>
- /// <remarks>
- /// Valid version strings are "v120", "v140", "v141", and "". Empty string gets the latest.
- /// </remarks>
- const Toolset& get_toolset(const Build::PreBuildInfo& prebuildinfo) const;
-
- View<Toolset> get_all_toolsets() const;
-
- Files::Filesystem& get_filesystem() const;
-
- const System::Environment& get_action_env(const Build::AbiInfo& abi_info) const;
- const std::string& get_triplet_info(const Build::AbiInfo& abi_info) const;
- const Build::CompilerInfo& get_compiler_info(const Build::AbiInfo& abi_info) const;
- bool manifest_mode_enabled() const { return get_manifest().has_value(); }
-
- const FeatureFlagSettings& get_feature_flags() const;
- void track_feature_flag_metrics() const;
-
- // the directory of the builtin ports
- // this should be used only for helper commands, not core commands like `install`.
- fs::path builtin_ports_directory() const { return this->builtin_ports; }
-
- private:
- std::unique_ptr<details::VcpkgPathsImpl> m_pimpl;
-
- static void git_checkout_subpath(const VcpkgPaths& paths,
- StringView commit_sha,
- const fs::path& subpath,
- const fs::path& local_repo,
- const fs::path& destination,
- const fs::path& dot_git_dir,
- const fs::path& work_tree);
- };
-}
diff --git a/toolsrc/include/vcpkg/versiondeserializers.h b/toolsrc/include/vcpkg/versiondeserializers.h
deleted file mode 100644
index ae368f6c5..000000000
--- a/toolsrc/include/vcpkg/versiondeserializers.h
+++ /dev/null
@@ -1,41 +0,0 @@
-#pragma once
-
-#include <vcpkg/base/fwd/stringview.h>
-
-#include <vcpkg/base/jsonreader.h>
-#include <vcpkg/base/stringliteral.h>
-
-#include <vcpkg/versions.h>
-#include <vcpkg/versiont.h>
-
-namespace vcpkg
-{
- Json::IDeserializer<VersionT>& get_versiont_deserializer_instance();
- Json::IDeserializer<VersionT>& get_versiontag_deserializer_instance();
- std::unique_ptr<Json::IDeserializer<std::string>> make_version_deserializer(StringLiteral type_name);
-
- struct SchemedVersion
- {
- SchemedVersion() = default;
- SchemedVersion(Versions::Scheme scheme_, VersionT versiont_) : scheme(scheme_), versiont(std::move(versiont_))
- {
- }
-
- Versions::Scheme scheme = Versions::Scheme::String;
- VersionT versiont;
- };
-
- Optional<SchemedVersion> visit_optional_schemed_deserializer(StringView parent_type,
- Json::Reader& r,
- const Json::Object& obj);
- SchemedVersion visit_required_schemed_deserializer(StringView parent_type,
- Json::Reader& r,
- const Json::Object& obj);
- View<StringView> schemed_deserializer_fields();
-
- void serialize_schemed_version(Json::Object& out_obj,
- Versions::Scheme scheme,
- const std::string& version,
- int port_version,
- bool always_emit_port_version = false);
-}
diff --git a/toolsrc/include/vcpkg/versions.h b/toolsrc/include/vcpkg/versions.h
deleted file mode 100644
index b26c90dfb..000000000
--- a/toolsrc/include/vcpkg/versions.h
+++ /dev/null
@@ -1,87 +0,0 @@
-#pragma once
-
-#include <vcpkg/versiont.h>
-
-namespace vcpkg::Versions
-{
- using Version = VersionT;
-
- enum class VerComp
- {
- unk,
- lt,
- eq,
- gt,
- };
-
- enum class Scheme
- {
- Relaxed,
- Semver,
- Date,
- String
- };
-
- struct VersionSpec
- {
- std::string port_name;
- VersionT version;
-
- VersionSpec(const std::string& port_name, const VersionT& version);
-
- VersionSpec(const std::string& port_name, const std::string& version_string, int port_version);
-
- friend bool operator==(const VersionSpec& lhs, const VersionSpec& rhs);
- friend bool operator!=(const VersionSpec& lhs, const VersionSpec& rhs);
- };
-
- struct VersionSpecHasher
- {
- std::size_t operator()(const VersionSpec& key) const;
- };
-
- struct RelaxedVersion
- {
- std::string original_string;
- std::vector<uint64_t> version;
-
- static ExpectedS<RelaxedVersion> from_string(const std::string& str);
- };
-
- struct SemanticVersion
- {
- std::string original_string;
- std::string version_string;
- std::string prerelease_string;
-
- std::vector<uint64_t> version;
- std::vector<std::string> identifiers;
-
- static ExpectedS<SemanticVersion> from_string(const std::string& str);
- };
-
- struct DateVersion
- {
- std::string original_string;
- std::string version_string;
- std::string identifiers_string;
-
- std::vector<uint64_t> identifiers;
-
- static ExpectedS<DateVersion> from_string(const std::string& str);
- };
-
- VerComp compare(const std::string& a, const std::string& b, Scheme scheme);
- VerComp compare(const RelaxedVersion& a, const RelaxedVersion& b);
- VerComp compare(const SemanticVersion& a, const SemanticVersion& b);
- VerComp compare(const DateVersion& a, const DateVersion& b);
-
- struct Constraint
- {
- enum class Type
- {
- None,
- Minimum
- };
- };
-}
diff --git a/toolsrc/include/vcpkg/versiont.h b/toolsrc/include/vcpkg/versiont.h
deleted file mode 100644
index 910183b9d..000000000
--- a/toolsrc/include/vcpkg/versiont.h
+++ /dev/null
@@ -1,44 +0,0 @@
-#pragma once
-
-#include <string>
-
-namespace vcpkg
-{
- struct VersionT
- {
- VersionT() noexcept;
- VersionT(std::string&& value, int port_version);
- VersionT(const std::string& value, int port_version);
-
- std::string to_string() const;
- void to_string(std::string& out) const;
-
- friend bool operator==(const VersionT& left, const VersionT& right);
- friend bool operator!=(const VersionT& left, const VersionT& right);
-
- friend struct VersionTMapLess;
-
- const std::string text() const { return m_text; }
- int port_version() const { return m_port_version; }
-
- private:
- std::string m_text;
- int m_port_version = 0;
- };
-
- struct VersionDiff
- {
- VersionT left;
- VersionT right;
-
- VersionDiff() noexcept;
- VersionDiff(const VersionT& left, const VersionT& right);
-
- std::string to_string() const;
- };
-
- struct VersionTMapLess
- {
- bool operator()(const VersionT& left, const VersionT& right) const;
- };
-}
diff --git a/toolsrc/include/vcpkg/visualstudio.h b/toolsrc/include/vcpkg/visualstudio.h
deleted file mode 100644
index da6652b3e..000000000
--- a/toolsrc/include/vcpkg/visualstudio.h
+++ /dev/null
@@ -1,14 +0,0 @@
-#pragma once
-
-#if defined(_WIN32)
-
-#include <vcpkg/vcpkgpaths.h>
-
-namespace vcpkg::VisualStudio
-{
- std::vector<std::string> get_visual_studio_instances(const VcpkgPaths& paths);
-
- std::vector<Toolset> find_toolset_instances_preferred_first(const VcpkgPaths& paths);
-}
-
-#endif
diff --git a/toolsrc/src/pch.cpp b/toolsrc/src/pch.cpp
deleted file mode 100644
index ebc3d8904..000000000
--- a/toolsrc/src/pch.cpp
+++ /dev/null
@@ -1,2 +0,0 @@
-// This file intentionally left blank. It exists to be a target for pch compilation,
-// but `#include "pch.h"` is already injected by the compiler. \ No newline at end of file
diff --git a/toolsrc/src/tls12-download.c b/toolsrc/src/tls12-download.c
deleted file mode 100644
index 16edc5448..000000000
--- a/toolsrc/src/tls12-download.c
+++ /dev/null
@@ -1,311 +0,0 @@
-#include <Windows.h>
-#include <process.h>
-#include <winhttp.h>
-/*
- * This program must be as small as possible, because it is committed in binary form to the
- * vcpkg github repo to enable downloading the main vcpkg program on Windows 7, where TLS 1.2 is
- * unavailable to PowerShell.
- * To that end it avoids using C runtime functions (beyond the vcruntime ones the compiler
- * injects itself).
- * (In testing as of 2021-01-07, this version that doesn't link with the CRT is ~8kb, whereas a
- * hello world program that does link with the CRT is ~300kb)
- */
-
-static void __declspec(noreturn) win32_abort()
-{
- /*
- * Note that TerminateProcess does not return when called from the terminated process, see
- * https://github.com/MicrosoftDocs/sdk-api/pull/626
- */
- TerminateProcess(GetCurrentProcess(), 3);
-}
-
-static size_t wide_length(const wchar_t* str)
-{
- size_t answer = 0;
- while (*str)
- {
- ++answer;
- ++str;
- }
- return answer;
-}
-
-static void write_message(const HANDLE std_out, const wchar_t* msg)
-{
- size_t wchars_to_write = wide_length(msg);
- if (wchars_to_write == 0)
- {
- return;
- }
-
- if (wchars_to_write > 65535)
- {
- win32_abort();
- }
-
- if (WriteConsoleW(std_out, msg, wchars_to_write, 0, 0))
- {
- return;
- }
-
- // this happens if output has been redirected
- int narrow_chars = WideCharToMultiByte(CP_ACP, 0, msg, (int)wchars_to_write, 0, 0, 0, 0);
- if (narrow_chars == 0)
- {
- win32_abort();
- }
-
- char* narrow_buffer = HeapAlloc(GetProcessHeap(), 0, (size_t)narrow_chars);
- if (WideCharToMultiByte(CP_ACP, 0, msg, (int)wchars_to_write, narrow_buffer, narrow_chars, 0, 0) == 0)
- {
- win32_abort();
- }
-
- while (narrow_chars != 0)
- {
- DWORD chars_written;
- if (!WriteFile(std_out, narrow_buffer, (DWORD)narrow_chars, &chars_written, 0))
- {
- win32_abort();
- }
-
- narrow_chars -= (int)chars_written;
- }
-
- if (!HeapFree(GetProcessHeap(), 0, narrow_buffer))
- {
- win32_abort();
- }
-}
-
-static void write_number(const HANDLE std_out, DWORD number)
-{
- wchar_t buffer[11]; // 4294967295\0
- wchar_t* first_digit = buffer + 11;
- *--first_digit = L'\0';
- if (number == 0)
- {
- *--first_digit = L'0';
- }
- else
- {
- do
- {
- *--first_digit = L'0' + number % 10;
- number /= 10;
- } while (number != 0);
- }
-
- write_message(std_out, first_digit);
-}
-
-static void write_hex(const HANDLE std_out, DWORD number)
-{
- wchar_t buffer[] = L"0x00000000";
- wchar_t* first_digit = buffer + (sizeof(buffer) / sizeof(wchar_t)) - 1;
- while (number != 0)
- {
- *--first_digit = L"0123456789ABCDEF"[number % 16];
- number /= 16;
- }
-
- write_message(std_out, buffer);
-}
-
-static void __declspec(noreturn) abort_api_failure(const HANDLE std_out, const wchar_t* api_name)
-{
- DWORD last_error = GetLastError();
- write_message(std_out, L"While calling Windows API function ");
- write_message(std_out, api_name);
- write_message(std_out, L" got error ");
- write_hex(std_out, last_error);
- write_message(std_out, L":\r\n");
- wchar_t* message;
- if (FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_ALLOCATE_BUFFER,
- GetModuleHandleW(L"winhttp.dll"),
- last_error,
- 0,
- (LPWSTR)&message,
- 0,
- 0))
- {
- write_message(std_out, message);
- // intentionally leaks the message buffer
- }
- else
- {
- last_error = GetLastError();
- write_message(std_out, L"(unknown error, FormatMessageW failed with ");
- write_hex(std_out, last_error);
- write_message(std_out, L")");
- }
-
- write_message(std_out, L"\r\n");
- FlushFileBuffers(std_out);
- win32_abort();
-}
-
-#ifndef NDEBUG
-int main()
-#else // ^^^ debug // !debug vvv
-int __stdcall entry()
-#endif // ^^^ !debug
-{
-#ifdef NDEBUG
- __security_init_cookie();
-#endif // ^^^ release
-
- const HANDLE std_out = GetStdHandle(STD_OUTPUT_HANDLE);
- if (std_out == INVALID_HANDLE_VALUE)
- {
- win32_abort();
- }
-
- int argc;
- wchar_t** argv = CommandLineToArgvW(GetCommandLineW(), &argc); // intentionally leaks argv
- if (argv == 0)
- {
- win32_abort();
- }
-
- if (argc != 4)
- {
- write_message(std_out, L"Usage: tls12-download.exe DOMAIN RELATIVE-PATH OUT-FILE\r\n");
- return 1;
- }
-
- const wchar_t* const domain = argv[1];
- const wchar_t* const relative_path = argv[2];
- const wchar_t* const out_file_path = argv[3];
- write_message(std_out, L"Downloading https://");
- write_message(std_out, domain);
- write_message(std_out, relative_path);
- write_message(std_out, L" -> ");
- write_message(std_out, out_file_path);
-
- wchar_t https_proxy_env[32767];
- DWORD access_type;
- const wchar_t* proxy_setting;
- const wchar_t* proxy_bypass_setting;
- if (GetEnvironmentVariableW(L"HTTPS_PROXY", https_proxy_env, sizeof(https_proxy_env) / sizeof(wchar_t)))
- {
- access_type = WINHTTP_ACCESS_TYPE_NAMED_PROXY;
- proxy_setting = https_proxy_env;
- proxy_bypass_setting = L"<local>";
- write_message(std_out, L" (using proxy: ");
- write_message(std_out, proxy_setting);
- write_message(std_out, L")");
- }
- else if (GetLastError() == ERROR_ENVVAR_NOT_FOUND)
- {
- access_type = WINHTTP_ACCESS_TYPE_NO_PROXY;
- proxy_setting = WINHTTP_NO_PROXY_NAME;
- proxy_bypass_setting = WINHTTP_NO_PROXY_BYPASS;
- }
- else
- {
- abort_api_failure(std_out, L"GetEnvironmentVariableW");
- }
-
- write_message(std_out, L"\r\n");
-
- const HANDLE out_file = CreateFileW(out_file_path, FILE_WRITE_DATA, 0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
- if (out_file == INVALID_HANDLE_VALUE)
- {
- abort_api_failure(std_out, L"CreateFileW");
- }
-
- BOOL results = FALSE;
- const HINTERNET session = WinHttpOpen(L"tls12-download/1.0", access_type, proxy_setting, proxy_bypass_setting, 0);
- if (!session)
- {
- abort_api_failure(std_out, L"WinHttpOpen");
- }
-
- unsigned long secure_protocols = WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_2;
- if (!WinHttpSetOption(session, WINHTTP_OPTION_SECURE_PROTOCOLS, &secure_protocols, sizeof(DWORD)))
- {
- abort_api_failure(std_out, L"WinHttpSetOption");
- }
-
- const HINTERNET connect = WinHttpConnect(session, domain, INTERNET_DEFAULT_HTTPS_PORT, 0);
- if (!connect)
- {
- abort_api_failure(std_out, L"WinHttpConnect");
- }
-
- const HINTERNET request = WinHttpOpenRequest(
- connect, L"GET", relative_path, 0, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_SECURE);
- if (!request)
- {
- abort_api_failure(std_out, L"WinHttpOpenRequest");
- }
-
- if (!WinHttpSendRequest(request, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0))
- {
- abort_api_failure(std_out, L"WinHttpSendRequest");
- }
-
- if (!WinHttpReceiveResponse(request, 0))
- {
- abort_api_failure(std_out, L"WinHttpReceiveResponse");
- }
-
- DWORD http_code = 0;
- DWORD query_headers_buffer_size = sizeof(http_code);
- if (!WinHttpQueryHeaders(request,
- WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER,
- WINHTTP_HEADER_NAME_BY_INDEX,
- &http_code,
- &query_headers_buffer_size,
- WINHTTP_NO_HEADER_INDEX))
- {
- abort_api_failure(std_out, L"WinHttpQueryHeaders");
- }
-
- if (http_code != 200)
- {
- write_message(std_out, L"Download failed, server returned HTTP status: ");
- write_number(std_out, http_code);
- write_message(std_out, L"\r\n");
- FlushFileBuffers(std_out);
- TerminateProcess(GetCurrentProcess(), 2);
- }
-
- char buffer[32768];
- for (;;)
- {
- DWORD received_bytes;
- if (!WinHttpReadData(request, buffer, sizeof(buffer), &received_bytes))
- {
- abort_api_failure(std_out, L"WinHttpReadData");
- }
-
- if (received_bytes == 0)
- {
- break; // end of response
- }
-
- do
- {
- DWORD written_bytes;
- if (!WriteFile(out_file, buffer, received_bytes, &written_bytes, 0))
- {
- abort_api_failure(std_out, L"WriteFile");
- }
-
- received_bytes -= written_bytes;
- } while (received_bytes != 0);
- }
-
- WinHttpCloseHandle(request);
- WinHttpCloseHandle(connect);
- WinHttpCloseHandle(session);
- CloseHandle(out_file);
-
- write_message(std_out, L"Done.\r\n");
- FlushFileBuffers(std_out);
- TerminateProcess(GetCurrentProcess(), 0);
- return 0;
-}
diff --git a/toolsrc/src/vcpkg-fuzz/main.cpp b/toolsrc/src/vcpkg-fuzz/main.cpp
deleted file mode 100644
index bbbf71708..000000000
--- a/toolsrc/src/vcpkg-fuzz/main.cpp
+++ /dev/null
@@ -1,194 +0,0 @@
-#include <vcpkg/base/checks.h>
-#include <vcpkg/base/json.h>
-#include <vcpkg/base/stringview.h>
-#include <vcpkg/base/system.print.h>
-#include <vcpkg/base/unicode.h>
-
-#include <vcpkg/platform-expression.h>
-
-#include <string.h>
-
-#include <iostream>
-#include <sstream>
-#include <utility>
-
-using namespace vcpkg;
-
-namespace
-{
- enum class FuzzKind
- {
- None,
- Utf8Decoder,
- JsonParser,
- PlatformExpr,
- };
-
- struct FuzzArgs
- {
- FuzzArgs(int argc, char** argv)
- {
- if (argc <= 1)
- {
- print_help_and_exit();
- }
-
- char** it = argv + 1; // skip the name of the program
- char** last = argv + argc;
-
- for (; it != last; ++it)
- {
- auto arg = StringView(*it, strlen(*it));
- if (arg == "/?")
- {
- print_help_and_exit();
- }
-
- auto pr = split_arg(arg);
- auto key = pr.first;
- auto value = pr.second;
- if (key == "h" || key == "help")
- {
- print_help_and_exit();
- }
-
- if (key == "kind")
- {
- if (value == "json")
- {
- kind = FuzzKind::JsonParser;
- }
- else if (value == "utf-8")
- {
- kind = FuzzKind::Utf8Decoder;
- }
- else if (value == "platform-expr")
- {
- kind = FuzzKind::PlatformExpr;
- }
- else
- {
- System::print2(System::Color::error, "Invalid kind: ", value, "\n");
- System::print2(System::Color::error, " Expected one of: utf-8, json, platform-expr\n\n");
- print_help_and_exit(true);
- }
- }
- else
- {
- System::print2("Unknown option: ", key, "\n\n");
- print_help_and_exit(true);
- }
- }
- }
-
- // returns {arg, ""} when there isn't an `=`
- // skips preceding `-`s
- std::pair<StringView, StringView> split_arg(StringView arg)
- {
- auto first = std::find_if(arg.begin(), arg.end(), [](char c) { return c != '-'; });
- auto division = std::find(first, arg.end(), '=');
- if (division == arg.end())
- {
- return {StringView(first, arg.end()), StringView(arg.end(), arg.end())};
- }
- else
- {
- return {StringView(first, division), StringView(division + 1, arg.end())};
- }
- }
-
- [[noreturn]] void print_help_and_exit(bool invalid = false)
- {
- constexpr auto help =
- R"(
-Usage: vcpkg-fuzz <options>
-
-Accepts input on stdin.
-
-Options:
- --kind=... One of {utf-8, json}
-)";
-
- auto color = invalid ? System::Color::error : System::Color::success;
-
- System::print2(color, help);
- if (invalid)
- {
- Checks::exit_fail(VCPKG_LINE_INFO);
- }
- else
- {
- Checks::exit_success(VCPKG_LINE_INFO);
- }
- }
-
- FuzzKind kind;
- };
-
- std::string read_all_of_stdin()
- {
- std::stringstream ss;
- ss << std::cin.rdbuf();
- return std::move(ss).str();
- }
-
- [[noreturn]] void fuzz_json_and_exit(StringView text)
- {
- auto res = Json::parse(text);
- if (!res)
- {
- Checks::exit_with_message(VCPKG_LINE_INFO, res.error()->format());
- }
-
- Checks::exit_success(VCPKG_LINE_INFO);
- }
-
- [[noreturn]] void fuzz_utf8_and_exit(StringView text)
- {
- auto res = Unicode::Utf8Decoder(text.begin(), text.end());
- for (auto ch : res)
- {
- (void)ch;
- }
-
- Checks::exit_success(VCPKG_LINE_INFO);
- }
-
- [[noreturn]] void fuzz_platform_expr_and_exit(StringView text)
- {
- auto res1 =
- PlatformExpression::parse_platform_expression(text, PlatformExpression::MultipleBinaryOperators::Deny);
- auto res2 =
- PlatformExpression::parse_platform_expression(text, PlatformExpression::MultipleBinaryOperators::Allow);
-
- if (!res1)
- {
- Checks::exit_with_message(VCPKG_LINE_INFO, res1.error());
- }
- if (!res2)
- {
- Checks::exit_with_message(VCPKG_LINE_INFO, res2.error());
- }
-
- Checks::exit_success(VCPKG_LINE_INFO);
- }
-}
-
-int main(int argc, char** argv)
-{
- auto args = FuzzArgs(argc, argv);
-
- if (args.kind == FuzzKind::None)
- {
- args.print_help_and_exit(true);
- }
-
- auto text = read_all_of_stdin();
- switch (args.kind)
- {
- case FuzzKind::JsonParser: fuzz_json_and_exit(text);
- case FuzzKind::Utf8Decoder: fuzz_utf8_and_exit(text);
- case FuzzKind::PlatformExpr: fuzz_platform_expr_and_exit(text);
- default: Checks::unreachable(VCPKG_LINE_INFO);
- }
-}
diff --git a/toolsrc/src/vcpkg-test/arguments.cpp b/toolsrc/src/vcpkg-test/arguments.cpp
deleted file mode 100644
index 7a7c70151..000000000
--- a/toolsrc/src/vcpkg-test/arguments.cpp
+++ /dev/null
@@ -1,135 +0,0 @@
-#include <catch2/catch.hpp>
-
-#include <vcpkg/vcpkgcmdarguments.h>
-
-#include <vector>
-
-using vcpkg::CommandSetting;
-using vcpkg::CommandStructure;
-using vcpkg::CommandSwitch;
-using vcpkg::VcpkgCmdArguments;
-
-TEST_CASE ("VcpkgCmdArguments from lowercase argument sequence", "[arguments]")
-{
- std::vector<std::string> t = {"--vcpkg-root",
- "C:\\vcpkg",
- "--x-scripts-root=C:\\scripts",
- "--x-builtin-ports-root=C:\\ports",
- "--x-builtin-registry-versions-dir=C:\\versions",
- "--debug",
- "--sendmetrics",
- "--printmetrics",
- "--overlay-ports=C:\\ports1",
- "--overlay-ports=C:\\ports2",
- "--overlay-triplets=C:\\tripletsA",
- "--overlay-triplets=C:\\tripletsB"};
- auto v = VcpkgCmdArguments::create_from_arg_sequence(t.data(), t.data() + t.size());
-
- REQUIRE(*v.vcpkg_root_dir == "C:\\vcpkg");
- REQUIRE(*v.scripts_root_dir == "C:\\scripts");
- REQUIRE(*v.builtin_ports_root_dir == "C:\\ports");
- REQUIRE(*v.builtin_registry_versions_dir == "C:\\versions");
- REQUIRE(v.debug);
- REQUIRE(*v.debug.get());
- REQUIRE(v.send_metrics);
- REQUIRE(*v.send_metrics.get());
- REQUIRE(v.print_metrics);
- REQUIRE(*v.print_metrics.get());
-
- REQUIRE(v.overlay_ports.size() == 2);
- REQUIRE(v.overlay_ports.at(0) == "C:\\ports1");
- REQUIRE(v.overlay_ports.at(1) == "C:\\ports2");
-
- REQUIRE(v.overlay_triplets.size() == 2);
- REQUIRE(v.overlay_triplets.at(0) == "C:\\tripletsA");
- REQUIRE(v.overlay_triplets.at(1) == "C:\\tripletsB");
-}
-
-TEST_CASE ("VcpkgCmdArguments from uppercase argument sequence", "[arguments]")
-{
- std::vector<std::string> t = {"--VCPKG-ROOT",
- "C:\\vcpkg",
- "--X-SCRIPTS-ROOT=C:\\scripts",
- "--X-BUILTIN-PORTS-ROOT=C:\\ports",
- "--X-BUILTIN-REGISTRY-VERSIONS-DIR=C:\\versions",
- "--DEBUG",
- "--SENDMETRICS",
- "--PRINTMETRICS",
- "--OVERLAY-PORTS=C:\\ports1",
- "--OVERLAY-PORTS=C:\\ports2",
- "--OVERLAY-TRIPLETS=C:\\tripletsA",
- "--OVERLAY-TRIPLETS=C:\\tripletsB"};
- auto v = VcpkgCmdArguments::create_from_arg_sequence(t.data(), t.data() + t.size());
-
- REQUIRE(*v.vcpkg_root_dir == "C:\\vcpkg");
- REQUIRE(*v.scripts_root_dir == "C:\\scripts");
- REQUIRE(*v.builtin_ports_root_dir == "C:\\ports");
- REQUIRE(*v.builtin_registry_versions_dir == "C:\\versions");
- REQUIRE(v.debug);
- REQUIRE(*v.debug.get());
- REQUIRE(v.send_metrics);
- REQUIRE(*v.send_metrics.get());
- REQUIRE(v.print_metrics);
- REQUIRE(*v.print_metrics.get());
-
- REQUIRE(v.overlay_ports.size() == 2);
- REQUIRE(v.overlay_ports.at(0) == "C:\\ports1");
- REQUIRE(v.overlay_ports.at(1) == "C:\\ports2");
-
- REQUIRE(v.overlay_triplets.size() == 2);
- REQUIRE(v.overlay_triplets.at(0) == "C:\\tripletsA");
- REQUIRE(v.overlay_triplets.at(1) == "C:\\tripletsB");
-}
-
-TEST_CASE ("VcpkgCmdArguments from argument sequence with valued options", "[arguments]")
-{
- SECTION ("case 1")
- {
- std::array<CommandSetting, 1> settings = {{{"a", ""}}};
- CommandStructure cmdstruct = {"", 0, SIZE_MAX, {{}, settings}, nullptr};
-
- std::vector<std::string> t = {"--a=b", "command", "argument"};
- auto v = VcpkgCmdArguments::create_from_arg_sequence(t.data(), t.data() + t.size());
- auto opts = v.parse_arguments(cmdstruct);
-
- REQUIRE(opts.settings["a"] == "b");
- REQUIRE(v.command_arguments.size() == 1);
- REQUIRE(v.command_arguments[0] == "argument");
- REQUIRE(v.command == "command");
- }
-
- SECTION ("case 2")
- {
- std::array<CommandSwitch, 2> switches = {{{"a", ""}, {"c", ""}}};
- std::array<CommandSetting, 2> settings = {{{"b", ""}, {"d", ""}}};
- CommandStructure cmdstruct = {"", 0, SIZE_MAX, {switches, settings}, nullptr};
-
- std::vector<std::string> t = {"--a", "--b=c"};
- auto v = VcpkgCmdArguments::create_from_arg_sequence(t.data(), t.data() + t.size());
- auto opts = v.parse_arguments(cmdstruct);
-
- REQUIRE(opts.settings["b"] == "c");
- REQUIRE(opts.settings.find("d") == opts.settings.end());
- REQUIRE(opts.switches.find("a") != opts.switches.end());
- REQUIRE(opts.settings.find("c") == opts.settings.end());
- REQUIRE(v.command_arguments.size() == 0);
- }
-}
-
-TEST_CASE ("vcpkg_root parse with arg separator", "[arguments]")
-{
- std::vector<std::string> t = {"--vcpkg-root", "C:\\vcpkg"};
- auto v = VcpkgCmdArguments::create_from_arg_sequence(t.data(), t.data() + t.size());
- auto& vcpkg_root_dir = v.vcpkg_root_dir;
- REQUIRE(vcpkg_root_dir);
- REQUIRE(*vcpkg_root_dir == "C:\\vcpkg");
-}
-
-TEST_CASE ("vcpkg_root parse with equal separator", "[arguments]")
-{
- std::vector<std::string> t = {"--vcpkg-root=C:\\vcpkg"};
- auto v = VcpkgCmdArguments::create_from_arg_sequence(t.data(), t.data() + t.size());
- auto& vcpkg_root_dir = v.vcpkg_root_dir;
- REQUIRE(vcpkg_root_dir);
- REQUIRE(*vcpkg_root_dir == "C:\\vcpkg");
-}
diff --git a/toolsrc/src/vcpkg-test/binarycaching.cpp b/toolsrc/src/vcpkg-test/binarycaching.cpp
deleted file mode 100644
index 8a1a28d23..000000000
--- a/toolsrc/src/vcpkg-test/binarycaching.cpp
+++ /dev/null
@@ -1,290 +0,0 @@
-#include <catch2/catch.hpp>
-
-#include <vcpkg/base/files.h>
-#include <vcpkg/base/xmlserializer.h>
-
-#include <vcpkg/binarycaching.h>
-#include <vcpkg/binarycaching.private.h>
-#include <vcpkg/dependencies.h>
-#include <vcpkg/paragraphs.h>
-#include <vcpkg/sourceparagraph.h>
-#include <vcpkg/vcpkgcmdarguments.h>
-
-#include <string>
-
-#include <vcpkg-test/util.h>
-
-using namespace vcpkg;
-
-#define REQUIRE_EQUAL_TEXT(lhs, rhs) \
- { \
- auto lhs_lines = Strings::split((lhs), '\n'); \
- auto rhs_lines = Strings::split((rhs), '\n'); \
- for (size_t i = 0; i < lhs_lines.size() && i < rhs_lines.size(); ++i) \
- { \
- INFO("on line: " << i); \
- REQUIRE(lhs_lines[i] == rhs_lines[i]); \
- } \
- REQUIRE(lhs_lines.size() == rhs_lines.size()); \
- }
-
-TEST_CASE ("reformat_version semver-ish", "[reformat_version]")
-{
- REQUIRE(reformat_version("0.0.0", "abitag") == "0.0.0-vcpkgabitag");
- REQUIRE(reformat_version("1.0.1", "abitag") == "1.0.1-vcpkgabitag");
- REQUIRE(reformat_version("1.01.000", "abitag") == "1.1.0-vcpkgabitag");
- REQUIRE(reformat_version("1.2", "abitag") == "1.2.0-vcpkgabitag");
- REQUIRE(reformat_version("v52", "abitag") == "52.0.0-vcpkgabitag");
- REQUIRE(reformat_version("v09.01.02", "abitag") == "9.1.2-vcpkgabitag");
- REQUIRE(reformat_version("1.1.1q", "abitag") == "1.1.1-vcpkgabitag");
- REQUIRE(reformat_version("1", "abitag") == "1.0.0-vcpkgabitag");
-}
-
-TEST_CASE ("reformat_version date", "[reformat_version]")
-{
- REQUIRE(reformat_version("2020-06-26", "abitag") == "2020.6.26-vcpkgabitag");
- REQUIRE(reformat_version("20-06-26", "abitag") == "0.0.0-vcpkgabitag");
- REQUIRE(reformat_version("2020-06-26-release", "abitag") == "2020.6.26-vcpkgabitag");
- REQUIRE(reformat_version("2020-06-26000", "abitag") == "2020.6.26-vcpkgabitag");
-}
-
-TEST_CASE ("reformat_version generic", "[reformat_version]")
-{
- REQUIRE(reformat_version("apr", "abitag") == "0.0.0-vcpkgabitag");
- REQUIRE(reformat_version("", "abitag") == "0.0.0-vcpkgabitag");
-}
-
-TEST_CASE ("generate_nuspec", "[generate_nuspec]")
-{
- auto& fsWrapper = Files::get_real_filesystem();
- VcpkgCmdArguments args = VcpkgCmdArguments::create_from_arg_sequence(nullptr, nullptr);
- args.imbue_from_environment();
- args.packages_root_dir = std::make_unique<std::string>("/");
- auto pkgPath = fsWrapper.absolute(VCPKG_LINE_INFO, fs::u8path("/zlib2_x64-windows")) / fs::u8path("**");
- pkgPath.make_preferred();
- const auto pkgPathStr = fs::u8string(pkgPath);
- VcpkgPaths paths(fsWrapper, args);
-
- auto pghs = Paragraphs::parse_paragraphs(R"(
-Source: zlib2
-Version: 1.5
-Build-Depends: zlib
-Description: a spiffy compression library wrapper
-
-Feature: a
-Description: a feature
-
-Feature: b
-Description: enable bzip capabilities
-Build-Depends: bzip
-)",
- "<testdata>");
- REQUIRE(pghs.has_value());
- auto maybe_scf = SourceControlFile::parse_control_file(fs::u8string(fs::path()), std::move(*pghs.get()));
- REQUIRE(maybe_scf.has_value());
- SourceControlFileLocation scfl{std::move(*maybe_scf.get()), fs::path()};
-
- Dependencies::InstallPlanAction ipa(PackageSpec{"zlib2", Test::X64_WINDOWS},
- scfl,
- Dependencies::RequestType::USER_REQUESTED,
- {{"a", {}}, {"b", {}}});
-
- ipa.abi_info = Build::AbiInfo{};
- ipa.abi_info.get()->package_abi = "packageabi";
- std::string tripletabi("tripletabi");
- ipa.abi_info.get()->triplet_abi = tripletabi;
- Build::CompilerInfo compiler_info;
- compiler_info.hash = "compilerhash";
- compiler_info.id = "compilerid";
- compiler_info.version = "compilerversion";
- ipa.abi_info.get()->compiler_info = compiler_info;
-
- NugetReference ref(ipa);
-
- REQUIRE(ref.nupkg_filename() == "zlib2_x64-windows.1.5.0-vcpkgpackageabi.nupkg");
-
- {
- auto nuspec = generate_nuspec(paths, ipa, ref, {});
- std::string expected = R"(<package>
- <metadata>
- <id>zlib2_x64-windows</id>
- <version>1.5.0-vcpkgpackageabi</version>
- <authors>vcpkg</authors>
- <description>NOT FOR DIRECT USE. Automatically generated cache package.
-
-a spiffy compression library wrapper
-
-Version: 1.5
-Triplet: x64-windows
-CXX Compiler id: compilerid
-CXX Compiler version: compilerversion
-Triplet/Compiler hash: tripletabi
-Features: a, b
-Dependencies:
-</description>
- <packageTypes><packageType name="vcpkg"/></packageTypes>
- </metadata>
- <files><file src=")" + pkgPathStr +
- R"(" target=""/></files>
-</package>
-)";
- REQUIRE_EQUAL_TEXT(nuspec, expected);
- }
-
- {
- auto nuspec = generate_nuspec(paths, ipa, ref, {"urlvalue"});
- std::string expected = R"(<package>
- <metadata>
- <id>zlib2_x64-windows</id>
- <version>1.5.0-vcpkgpackageabi</version>
- <authors>vcpkg</authors>
- <description>NOT FOR DIRECT USE. Automatically generated cache package.
-
-a spiffy compression library wrapper
-
-Version: 1.5
-Triplet: x64-windows
-CXX Compiler id: compilerid
-CXX Compiler version: compilerversion
-Triplet/Compiler hash: tripletabi
-Features: a, b
-Dependencies:
-</description>
- <packageTypes><packageType name="vcpkg"/></packageTypes>
- <repository type="git" url="urlvalue"/>
- </metadata>
- <files><file src=")" + pkgPathStr +
- R"(" target=""/></files>
-</package>
-)";
- REQUIRE_EQUAL_TEXT(nuspec, expected);
- }
- {
- auto nuspec = generate_nuspec(paths, ipa, ref, {"urlvalue", "branchvalue", "commitvalue"});
- std::string expected = R"(<package>
- <metadata>
- <id>zlib2_x64-windows</id>
- <version>1.5.0-vcpkgpackageabi</version>
- <authors>vcpkg</authors>
- <description>NOT FOR DIRECT USE. Automatically generated cache package.
-
-a spiffy compression library wrapper
-
-Version: 1.5
-Triplet: x64-windows
-CXX Compiler id: compilerid
-CXX Compiler version: compilerversion
-Triplet/Compiler hash: tripletabi
-Features: a, b
-Dependencies:
-</description>
- <packageTypes><packageType name="vcpkg"/></packageTypes>
- <repository type="git" url="urlvalue" branch="branchvalue" commit="commitvalue"/>
- </metadata>
- <files><file src=")" + pkgPathStr +
- R"(" target=""/></files>
-</package>
-)";
- REQUIRE_EQUAL_TEXT(nuspec, expected);
- }
-}
-
-TEST_CASE ("XmlSerializer", "[XmlSerializer]")
-{
- XmlSerializer xml;
- xml.open_tag("a");
- xml.open_tag("b");
- xml.simple_tag("c", "d");
- xml.close_tag("b");
- xml.text("escaping: & < > \" '");
-
- REQUIRE(xml.buf == R"(<a><b><c>d</c></b>escaping: &amp; &lt; &gt; &quot; &apos;)");
-
- xml = XmlSerializer();
- xml.emit_declaration();
- xml.start_complex_open_tag("a")
- .text_attr("b", "<")
- .text_attr("c", " ")
- .finish_self_closing_complex_tag()
- .line_break();
- xml.simple_tag("d", "e");
- REQUIRE(xml.buf == R"(<?xml version="1.0" encoding="utf-8"?><a b="&lt;" c=" "/>)"
- "\n<d>e</d>");
-
- xml = XmlSerializer();
- xml.start_complex_open_tag("a").finish_complex_open_tag();
- REQUIRE(xml.buf == R"(<a>)");
-
- xml = XmlSerializer();
- xml.line_break();
- xml.open_tag("a").line_break().line_break();
- xml.close_tag("a").line_break().line_break();
- REQUIRE(xml.buf == "\n<a>\n\n</a>\n\n");
-
- xml = XmlSerializer();
- xml.start_complex_open_tag("a")
- .text_attr("b", "<")
- .line_break()
- .text_attr("c", " ")
- .finish_complex_open_tag()
- .line_break();
- xml.simple_tag("d", "e").line_break();
- REQUIRE(xml.buf == "<a b=\"&lt;\"\n c=\" \">\n <d>e</d>\n");
-}
-
-TEST_CASE ("generate_nuget_packages_config", "[generate_nuget_packages_config]")
-{
- Dependencies::ActionPlan plan;
- auto packageconfig = generate_nuget_packages_config(plan);
- REQUIRE(packageconfig == R"(<?xml version="1.0" encoding="utf-8"?>
-<packages>
-</packages>
-)");
-
- auto pghs = Paragraphs::parse_paragraphs(R"(
-Source: zlib
-Version: 1.5
-Description: a spiffy compression library wrapper
-)",
- "<testdata>");
- REQUIRE(pghs.has_value());
- auto maybe_scf = SourceControlFile::parse_control_file(fs::u8string(fs::path()), std::move(*pghs.get()));
- REQUIRE(maybe_scf.has_value());
- SourceControlFileLocation scfl{std::move(*maybe_scf.get()), fs::path()};
- plan.install_actions.push_back(Dependencies::InstallPlanAction());
- plan.install_actions[0].spec = PackageSpec("zlib", Test::X64_ANDROID);
- plan.install_actions[0].source_control_file_location = scfl;
- plan.install_actions[0].abi_info = Build::AbiInfo{};
- plan.install_actions[0].abi_info.get()->package_abi = "packageabi";
-
- packageconfig = generate_nuget_packages_config(plan);
- REQUIRE(packageconfig == R"(<?xml version="1.0" encoding="utf-8"?>
-<packages>
- <package id="zlib_x64-android" version="1.5.0-vcpkgpackageabi"/>
-</packages>
-)");
-
- auto pghs2 = Paragraphs::parse_paragraphs(R"(
-Source: zlib2
-Version: 1.52
-Description: a spiffy compression library wrapper
-)",
- "<testdata>");
- REQUIRE(pghs2.has_value());
- auto maybe_scf2 = SourceControlFile::parse_control_file(fs::u8string(fs::path()), std::move(*pghs2.get()));
- REQUIRE(maybe_scf2.has_value());
- SourceControlFileLocation scfl2{std::move(*maybe_scf2.get()), fs::path()};
- plan.install_actions.push_back(Dependencies::InstallPlanAction());
- plan.install_actions[1].spec = PackageSpec("zlib2", Test::X64_ANDROID);
- plan.install_actions[1].source_control_file_location = scfl2;
- plan.install_actions[1].abi_info = Build::AbiInfo{};
- plan.install_actions[1].abi_info.get()->package_abi = "packageabi2";
-
- packageconfig = generate_nuget_packages_config(plan);
- REQUIRE(packageconfig == R"(<?xml version="1.0" encoding="utf-8"?>
-<packages>
- <package id="zlib_x64-android" version="1.5.0-vcpkgpackageabi"/>
- <package id="zlib2_x64-android" version="1.52.0-vcpkgpackageabi2"/>
-</packages>
-)");
-}
diff --git a/toolsrc/src/vcpkg-test/binaryconfigparser.cpp b/toolsrc/src/vcpkg-test/binaryconfigparser.cpp
deleted file mode 100644
index 1c46790bf..000000000
--- a/toolsrc/src/vcpkg-test/binaryconfigparser.cpp
+++ /dev/null
@@ -1,336 +0,0 @@
-#include <catch2/catch.hpp>
-
-#include <vcpkg/binarycaching.h>
-
-using namespace vcpkg;
-
-#if defined(_WIN32)
-#define ABSOLUTE_PATH "C:\\foo"
-#else
-#define ABSOLUTE_PATH "/foo"
-#endif
-
-TEST_CASE ("BinaryConfigParser empty", "[binaryconfigparser]")
-{
- auto parsed = create_binary_provider_from_configs_pure("", {});
- REQUIRE(parsed.has_value());
-}
-
-TEST_CASE ("BinaryConfigParser unacceptable provider", "[binaryconfigparser]")
-{
- auto parsed = create_binary_provider_from_configs_pure("unacceptable", {});
- REQUIRE(!parsed.has_value());
-}
-
-TEST_CASE ("BinaryConfigParser files provider", "[binaryconfigparser]")
-{
- {
- auto parsed = create_binary_provider_from_configs_pure("files", {});
- REQUIRE(!parsed.has_value());
- }
- {
- auto parsed = create_binary_provider_from_configs_pure("files,relative-path", {});
- REQUIRE(!parsed.has_value());
- }
- {
- auto parsed = create_binary_provider_from_configs_pure("files,C:foo", {});
- REQUIRE(!parsed.has_value());
- }
- {
- auto parsed = create_binary_provider_from_configs_pure("files," ABSOLUTE_PATH, {});
- REQUIRE(parsed.has_value());
- }
- {
- auto parsed = create_binary_provider_from_configs_pure("files," ABSOLUTE_PATH ",nonsense", {});
- REQUIRE(!parsed.has_value());
- }
- {
- auto parsed = create_binary_provider_from_configs_pure("files," ABSOLUTE_PATH ",read", {});
- REQUIRE(parsed.has_value());
- }
- {
- auto parsed = create_binary_provider_from_configs_pure("files," ABSOLUTE_PATH ",write", {});
- REQUIRE(parsed.has_value());
- }
- {
- auto parsed = create_binary_provider_from_configs_pure("files," ABSOLUTE_PATH ",readwrite", {});
- REQUIRE(parsed.has_value());
- }
- {
- auto parsed = create_binary_provider_from_configs_pure("files," ABSOLUTE_PATH ",readwrite,extra", {});
- REQUIRE(!parsed.has_value());
- }
- {
- auto parsed = create_binary_provider_from_configs_pure("files,,upload", {});
- REQUIRE(!parsed.has_value());
- }
-}
-
-TEST_CASE ("BinaryConfigParser nuget source provider", "[binaryconfigparser]")
-{
- {
- auto parsed = create_binary_provider_from_configs_pure("nuget", {});
- REQUIRE(!parsed.has_value());
- }
- {
- auto parsed = create_binary_provider_from_configs_pure("nuget,relative-path", {});
- REQUIRE(parsed.has_value());
- }
- {
- auto parsed = create_binary_provider_from_configs_pure("nuget,http://example.org/", {});
- REQUIRE(parsed.has_value());
- }
- {
- auto parsed = create_binary_provider_from_configs_pure("nuget," ABSOLUTE_PATH, {});
- REQUIRE(parsed.has_value());
- }
- {
- auto parsed = create_binary_provider_from_configs_pure("nuget," ABSOLUTE_PATH ",nonsense", {});
- REQUIRE(!parsed.has_value());
- }
- {
- auto parsed = create_binary_provider_from_configs_pure("nuget," ABSOLUTE_PATH ",readwrite", {});
- REQUIRE(parsed.has_value());
- }
- {
- auto parsed = create_binary_provider_from_configs_pure("nuget," ABSOLUTE_PATH ",readwrite,extra", {});
- REQUIRE(!parsed.has_value());
- }
- {
- auto parsed = create_binary_provider_from_configs_pure("nuget,,readwrite", {});
- REQUIRE(!parsed.has_value());
- }
-}
-
-TEST_CASE ("BinaryConfigParser nuget config provider", "[binaryconfigparser]")
-{
- {
- auto parsed = create_binary_provider_from_configs_pure("nugetconfig", {});
- REQUIRE(!parsed.has_value());
- }
- {
- auto parsed = create_binary_provider_from_configs_pure("nugetconfig,relative-path", {});
- REQUIRE(!parsed.has_value());
- }
- {
- auto parsed = create_binary_provider_from_configs_pure("nugetconfig,http://example.org/", {});
- REQUIRE(!parsed.has_value());
- }
- {
- auto parsed = create_binary_provider_from_configs_pure("nugetconfig," ABSOLUTE_PATH, {});
- REQUIRE(parsed.has_value());
- }
- {
- auto parsed = create_binary_provider_from_configs_pure("nugetconfig," ABSOLUTE_PATH ",nonsense", {});
- REQUIRE(!parsed.has_value());
- }
- {
- auto parsed = create_binary_provider_from_configs_pure("nugetconfig," ABSOLUTE_PATH ",read", {});
- REQUIRE(parsed.has_value());
- }
- {
- auto parsed = create_binary_provider_from_configs_pure("nugetconfig," ABSOLUTE_PATH ",write", {});
- REQUIRE(parsed.has_value());
- }
- {
- auto parsed = create_binary_provider_from_configs_pure("nugetconfig," ABSOLUTE_PATH ",readwrite", {});
- REQUIRE(parsed.has_value());
- }
- {
- auto parsed = create_binary_provider_from_configs_pure("nugetconfig," ABSOLUTE_PATH ",readwrite,extra", {});
- REQUIRE(!parsed.has_value());
- }
- {
- auto parsed = create_binary_provider_from_configs_pure("nugetconfig,,readwrite", {});
- REQUIRE(!parsed.has_value());
- }
-}
-
-TEST_CASE ("BinaryConfigParser default provider", "[binaryconfigparser]")
-{
- {
- auto parsed = create_binary_provider_from_configs_pure("default", {});
- REQUIRE(parsed.has_value());
- }
- {
- auto parsed = create_binary_provider_from_configs_pure("default,nonsense", {});
- REQUIRE(!parsed.has_value());
- }
- {
- auto parsed = create_binary_provider_from_configs_pure("default,read", {});
- REQUIRE(parsed.has_value());
- }
- {
- auto parsed = create_binary_provider_from_configs_pure("default,readwrite", {});
- REQUIRE(parsed.has_value());
- }
- {
- auto parsed = create_binary_provider_from_configs_pure("default,write", {});
- REQUIRE(parsed.has_value());
- }
- {
- auto parsed = create_binary_provider_from_configs_pure("default,read,extra", {});
- REQUIRE(!parsed.has_value());
- }
-}
-
-TEST_CASE ("BinaryConfigParser clear provider", "[binaryconfigparser]")
-{
- {
- auto parsed = create_binary_provider_from_configs_pure("clear", {});
- REQUIRE(parsed.has_value());
- }
- {
- auto parsed = create_binary_provider_from_configs_pure("clear,upload", {});
- REQUIRE(!parsed.has_value());
- }
-}
-
-TEST_CASE ("BinaryConfigParser interactive provider", "[binaryconfigparser]")
-{
- {
- auto parsed = create_binary_provider_from_configs_pure("interactive", {});
- REQUIRE(parsed.has_value());
- }
- {
- auto parsed = create_binary_provider_from_configs_pure("interactive,read", {});
- REQUIRE(!parsed.has_value());
- }
-}
-
-TEST_CASE ("BinaryConfigParser multiple providers", "[binaryconfigparser]")
-{
- {
- auto parsed = create_binary_provider_from_configs_pure("clear;default", {});
- REQUIRE(parsed.has_value());
- }
- {
- auto parsed = create_binary_provider_from_configs_pure("clear;default,read", {});
- REQUIRE(parsed.has_value());
- }
- {
- auto parsed = create_binary_provider_from_configs_pure("clear;default,write", {});
- REQUIRE(parsed.has_value());
- }
- {
- auto parsed = create_binary_provider_from_configs_pure("clear;default,readwrite", {});
- REQUIRE(parsed.has_value());
- }
- {
- auto parsed = create_binary_provider_from_configs_pure("clear;default,readwrite;clear;clear", {});
- REQUIRE(parsed.has_value());
- }
- {
- auto parsed = create_binary_provider_from_configs_pure("clear;files,relative;default", {});
- REQUIRE(!parsed.has_value());
- }
- {
- auto parsed = create_binary_provider_from_configs_pure(";;;clear;;;;", {});
- REQUIRE(parsed.has_value());
- }
- {
- auto parsed = create_binary_provider_from_configs_pure(";;;,;;;;", {});
- REQUIRE(!parsed.has_value());
- }
-}
-
-TEST_CASE ("BinaryConfigParser escaping", "[binaryconfigparser]")
-{
- {
- auto parsed = create_binary_provider_from_configs_pure(";;;;;;;`", {});
- REQUIRE(!parsed.has_value());
- }
- {
- auto parsed = create_binary_provider_from_configs_pure(";;;;;;;`defaul`t", {});
- REQUIRE(parsed.has_value());
- }
- {
- auto parsed = create_binary_provider_from_configs_pure("files," ABSOLUTE_PATH "`", {});
- REQUIRE(!parsed.has_value());
- }
- {
- auto parsed = create_binary_provider_from_configs_pure("files," ABSOLUTE_PATH "`,", {});
- REQUIRE(parsed.has_value());
- }
- {
- auto parsed = create_binary_provider_from_configs_pure("files," ABSOLUTE_PATH "``", {});
- REQUIRE(parsed.has_value());
- }
- {
- auto parsed = create_binary_provider_from_configs_pure("files," ABSOLUTE_PATH "```", {});
- REQUIRE(!parsed.has_value());
- }
- {
- auto parsed = create_binary_provider_from_configs_pure("files," ABSOLUTE_PATH "````", {});
- REQUIRE(parsed.has_value());
- }
- {
- auto parsed = create_binary_provider_from_configs_pure("files," ABSOLUTE_PATH ",", {});
- REQUIRE(!parsed.has_value());
- }
-}
-
-TEST_CASE ("BinaryConfigParser args", "[binaryconfigparser]")
-{
- {
- auto parsed =
- create_binary_provider_from_configs_pure("files," ABSOLUTE_PATH, std::vector<std::string>{"clear"});
- REQUIRE(parsed.has_value());
- }
- {
- auto parsed =
- create_binary_provider_from_configs_pure("files," ABSOLUTE_PATH, std::vector<std::string>{"clear;default"});
- REQUIRE(parsed.has_value());
- }
- {
- auto parsed = create_binary_provider_from_configs_pure("files," ABSOLUTE_PATH,
- std::vector<std::string>{"clear;default,"});
- REQUIRE(!parsed.has_value());
- }
- {
- auto parsed = create_binary_provider_from_configs_pure("files," ABSOLUTE_PATH,
- std::vector<std::string>{"clear", "clear;default,"});
- REQUIRE(!parsed.has_value());
- }
- {
- auto parsed = create_binary_provider_from_configs_pure("files," ABSOLUTE_PATH,
- std::vector<std::string>{"clear", "clear"});
- REQUIRE(parsed.has_value());
- }
-}
-
-TEST_CASE ("BinaryConfigParser azblob provider", "[binaryconfigparser]")
-{
- {
- auto parsed = create_binary_provider_from_configs_pure("x-azblob,https://azure/container,sas", {});
- REQUIRE(parsed.has_value());
- }
- {
- auto parsed = create_binary_provider_from_configs_pure("x-azblob,https://azure/container,?sas", {});
- REQUIRE(!parsed.has_value());
- }
- {
- auto parsed = create_binary_provider_from_configs_pure("x-azblob,,sas", {});
- REQUIRE(!parsed.has_value());
- }
- {
- auto parsed = create_binary_provider_from_configs_pure("x-azblob,https://azure/container", {});
- REQUIRE(!parsed.has_value());
- }
- {
- auto parsed = create_binary_provider_from_configs_pure("x-azblob,https://azure/container,sas,invalid", {});
- REQUIRE(!parsed.has_value());
- }
- {
- auto parsed = create_binary_provider_from_configs_pure("x-azblob,https://azure/container,sas,read", {});
- REQUIRE(parsed.has_value());
- }
- {
- auto parsed = create_binary_provider_from_configs_pure("x-azblob,https://azure/container,sas,write", {});
- REQUIRE(parsed.has_value());
- }
- {
- auto parsed = create_binary_provider_from_configs_pure("x-azblob,https://azure/container,sas,readwrite", {});
- REQUIRE(parsed.has_value());
- }
-}
diff --git a/toolsrc/src/vcpkg-test/catch.cpp b/toolsrc/src/vcpkg-test/catch.cpp
deleted file mode 100644
index fb62c5d06..000000000
--- a/toolsrc/src/vcpkg-test/catch.cpp
+++ /dev/null
@@ -1,12 +0,0 @@
-#define CATCH_CONFIG_RUNNER
-#include <catch2/catch.hpp>
-
-#include <vcpkg/base/system.debug.h>
-#include <vcpkg/base/system.h>
-
-int main(int argc, char** argv)
-{
- if (vcpkg::System::get_environment_variable("VCPKG_DEBUG").value_or("") == "1") vcpkg::Debug::g_debugging = true;
-
- return Catch::Session().run(argc, argv);
-}
diff --git a/toolsrc/src/vcpkg-test/chrono.cpp b/toolsrc/src/vcpkg-test/chrono.cpp
deleted file mode 100644
index fb8a0dee9..000000000
--- a/toolsrc/src/vcpkg-test/chrono.cpp
+++ /dev/null
@@ -1,34 +0,0 @@
-#include <catch2/catch.hpp>
-
-#include <vcpkg/base/chrono.h>
-
-namespace Chrono = vcpkg::Chrono;
-
-TEST_CASE ("parse time", "[chrono]")
-{
- auto timestring = "1990-02-03T04:05:06.0Z";
- auto maybe_time = Chrono::CTime::parse(timestring);
-
- REQUIRE(maybe_time.has_value());
- REQUIRE(maybe_time.get()->to_string() == timestring);
-}
-
-TEST_CASE ("parse blank time", "[chrono]")
-{
- auto maybe_time = Chrono::CTime::parse("");
-
- REQUIRE_FALSE(maybe_time.has_value());
-}
-
-TEST_CASE ("difference of times", "[chrono]")
-{
- auto maybe_time1 = Chrono::CTime::parse("1990-02-03T04:05:06.0Z");
- auto maybe_time2 = Chrono::CTime::parse("1990-02-10T04:05:06.0Z");
-
- REQUIRE(maybe_time1.has_value());
- REQUIRE(maybe_time2.has_value());
-
- auto delta = maybe_time2.get()->to_time_point() - maybe_time1.get()->to_time_point();
-
- REQUIRE(std::chrono::duration_cast<std::chrono::hours>(delta).count() == 24 * 7);
-}
diff --git a/toolsrc/src/vcpkg-test/commands.cpp b/toolsrc/src/vcpkg-test/commands.cpp
deleted file mode 100644
index 1a582beb3..000000000
--- a/toolsrc/src/vcpkg-test/commands.cpp
+++ /dev/null
@@ -1,83 +0,0 @@
-#include <catch2/catch.hpp>
-
-#include <vcpkg/commands.contact.h>
-#include <vcpkg/commands.h>
-#include <vcpkg/commands.upload-metrics.h>
-#include <vcpkg/commands.version.h>
-
-#include <stddef.h>
-
-using namespace vcpkg;
-
-namespace
-{
- template<class CommandListT, size_t ExpectedCount>
- void check_all_commands(const CommandListT& actual_commands, const char* const (&expected_commands)[ExpectedCount])
- {
- CHECK(actual_commands.size() == ExpectedCount); // makes sure this test is updated if we add a command
- for (const char* expected_command : expected_commands)
- {
- CHECK(Commands::find(StringView{expected_command, strlen(expected_command)}, actual_commands) != nullptr);
- }
-
- CHECK(Commands::find("x-never-will-exist", actual_commands) == nullptr);
- }
-} // unnamed namespace
-
-// clang-format tries to wrap the following lists inappropriately
-
-// clang-format off
-TEST_CASE ("get_available_basic_commands works", "[commands]")
-{
- check_all_commands(Commands::get_available_basic_commands(), {
- "contact",
- "version",
-#if defined(_WIN32)
- "x-upload-metrics",
-#endif // defined(_WIN32)
- });
-}
-
-TEST_CASE ("get_available_paths_commands works", "[commands]")
-{
- check_all_commands(Commands::get_available_paths_commands(), {
- "/?",
- "help",
- "search",
- "list",
- "integrate",
- "owns",
- "update",
- "edit",
- "create",
- "cache",
- "portsdiff",
- "autocomplete",
- "hash",
- "fetch",
- "format-manifest",
- "x-ci-clean",
- "x-history",
- "x-package-info",
- "x-vsinstances",
- "x-ci-verify-versions",
- "x-add-version",
- });
-}
-
-TEST_CASE ("get_available_commands_type_a works", "[commands]")
-{
- check_all_commands(Commands::get_available_triplet_commands(), {
- "install",
- "x-set-installed",
- "ci",
- "remove",
- "upgrade",
- "build",
- "env",
- "build-external",
- "export",
- "depend-info",
- });
-}
-// clang-format on
diff --git a/toolsrc/src/vcpkg-test/dependencies.cpp b/toolsrc/src/vcpkg-test/dependencies.cpp
deleted file mode 100644
index c6241ebe0..000000000
--- a/toolsrc/src/vcpkg-test/dependencies.cpp
+++ /dev/null
@@ -1,1713 +0,0 @@
-#include <catch2/catch.hpp>
-
-#include <vcpkg/base/graphs.h>
-
-#include <vcpkg/dependencies.h>
-#include <vcpkg/portfileprovider.h>
-#include <vcpkg/sourceparagraph.h>
-#include <vcpkg/triplet.h>
-
-#include <memory>
-#include <unordered_map>
-#include <vector>
-
-#include <vcpkg-test/mockcmakevarprovider.h>
-#include <vcpkg-test/util.h>
-
-using namespace vcpkg;
-
-using Test::make_control_file;
-using Test::make_status_feature_pgh;
-using Test::make_status_pgh;
-using Test::MockCMakeVarProvider;
-using Test::PackageSpecMap;
-
-struct MockBaselineProvider : PortFileProvider::IBaselineProvider
-{
- mutable std::map<std::string, Versions::Version, std::less<>> v;
-
- Optional<Versions::Version> get_baseline_version(StringView name) const override
- {
- auto it = v.find(name);
- if (it == v.end()) return nullopt;
- return it->second;
- }
-};
-
-struct MockVersionedPortfileProvider : PortFileProvider::IVersionedPortfileProvider
-{
- mutable std::map<std::string, std::map<Versions::Version, SourceControlFileLocation, VersionTMapLess>> v;
-
- ExpectedS<const SourceControlFileLocation&> get_control_file(
- const vcpkg::Versions::VersionSpec& versionspec) const override
- {
- return get_control_file(versionspec.port_name, versionspec.version);
- }
-
- ExpectedS<const SourceControlFileLocation&> get_control_file(const std::string& name,
- const vcpkg::Versions::Version& version) const
- {
- auto it = v.find(name);
- if (it == v.end()) return std::string("Unknown port name");
- auto it2 = it->second.find(version);
- if (it2 == it->second.end()) return std::string("Unknown port version");
- return it2->second;
- }
-
- virtual View<vcpkg::VersionT> get_port_versions(StringView) const override { Checks::unreachable(VCPKG_LINE_INFO); }
-
- SourceControlFileLocation& emplace(std::string&& name,
- Versions::Version&& version,
- Versions::Scheme scheme = Versions::Scheme::String)
- {
- auto it = v.find(name);
- if (it == v.end())
- it = v.emplace(name, std::map<Versions::Version, SourceControlFileLocation, VersionTMapLess>{}).first;
-
- auto it2 = it->second.find(version);
- if (it2 == it->second.end())
- {
- auto scf = std::make_unique<SourceControlFile>();
- auto core = std::make_unique<SourceParagraph>();
- core->name = name;
- core->version = version.text();
- core->port_version = version.port_version();
- core->version_scheme = scheme;
- scf->core_paragraph = std::move(core);
- it2 = it->second.emplace(version, SourceControlFileLocation{std::move(scf), fs::u8path(name)}).first;
- }
- return it2->second;
- }
-
- virtual void load_all_control_files(std::map<std::string, const SourceControlFileLocation*>&) const override
- {
- Checks::unreachable(VCPKG_LINE_INFO);
- }
-};
-
-using Versions::Constraint;
-using Versions::Scheme;
-
-template<class T>
-T unwrap(ExpectedS<T> e)
-{
- if (!e.has_value())
- {
- INFO(e.error());
- REQUIRE(false);
- }
- return std::move(*e.get());
-}
-
-static void check_name_and_version(const Dependencies::InstallPlanAction& ipa,
- StringLiteral name,
- Versions::Version v,
- std::initializer_list<StringLiteral> features = {})
-{
- CHECK(ipa.spec.name() == name);
- CHECK(ipa.source_control_file_location.has_value());
- CHECK(ipa.feature_list.size() == features.size() + 1);
- {
- INFO("ipa.feature_list = [" << Strings::join(", ", ipa.feature_list) << "]");
- for (auto&& f : features)
- {
- INFO("f = \"" << f.c_str() << "\"");
- CHECK(Util::find(ipa.feature_list, f) != ipa.feature_list.end());
- }
- CHECK(Util::find(ipa.feature_list, "core") != ipa.feature_list.end());
- }
- if (auto scfl = ipa.source_control_file_location.get())
- {
- CHECK(scfl->source_control_file->core_paragraph->version == v.text());
- CHECK(scfl->source_control_file->core_paragraph->port_version == v.port_version());
- }
-}
-
-static void check_semver_version(const ExpectedS<Versions::SemanticVersion>& maybe_version,
- const std::string& version_string,
- const std::string& prerelease_string,
- uint64_t major,
- uint64_t minor,
- uint64_t patch,
- const std::vector<std::string>& identifiers)
-{
- auto actual_version = unwrap(maybe_version);
- CHECK(actual_version.version_string == version_string);
- CHECK(actual_version.prerelease_string == prerelease_string);
- REQUIRE(actual_version.version.size() == 3);
- CHECK(actual_version.version[0] == major);
- CHECK(actual_version.version[1] == minor);
- CHECK(actual_version.version[2] == patch);
- CHECK(actual_version.identifiers == identifiers);
-}
-
-static void check_relaxed_version(const ExpectedS<Versions::RelaxedVersion>& maybe_version,
- const std::vector<uint64_t>& version)
-{
- auto actual_version = unwrap(maybe_version);
- CHECK(actual_version.version == version);
-}
-
-static void check_date_version(const ExpectedS<Versions::DateVersion>& maybe_version,
- const std::string& version_string,
- const std::string& identifiers_string,
- const std::vector<uint64_t>& identifiers)
-{
- auto actual_version = unwrap(maybe_version);
- CHECK(actual_version.version_string == version_string);
- CHECK(actual_version.identifiers_string == identifiers_string);
- CHECK(actual_version.identifiers == identifiers);
-}
-
-static const PackageSpec& toplevel_spec()
-{
- static const PackageSpec ret("toplevel-spec", Test::X86_WINDOWS);
- return ret;
-}
-
-struct MockOverlayProvider : PortFileProvider::IOverlayProvider, Util::ResourceBase
-{
- virtual Optional<const SourceControlFileLocation&> get_control_file(StringView name) const override
- {
- auto it = mappings.find(name);
- if (it != mappings.end())
- return it->second;
- else
- return nullopt;
- }
-
- SourceControlFileLocation& emplace(const std::string& name,
- Versions::Version&& version,
- Versions::Scheme scheme = Versions::Scheme::String)
- {
- auto it = mappings.find(name);
- if (it == mappings.end())
- {
- auto scf = std::make_unique<SourceControlFile>();
- auto core = std::make_unique<SourceParagraph>();
- core->name = name;
- core->version = version.text();
- core->port_version = version.port_version();
- core->version_scheme = scheme;
- scf->core_paragraph = std::move(core);
- it = mappings.emplace(name, SourceControlFileLocation{std::move(scf), fs::u8path(name)}).first;
- }
- return it->second;
- }
-
- virtual void load_all_control_files(std::map<std::string, const SourceControlFileLocation*>&) const override
- {
- Checks::unreachable(VCPKG_LINE_INFO);
- }
-
-private:
- std::map<std::string, SourceControlFileLocation, std::less<>> mappings;
-};
-
-static const MockOverlayProvider s_empty_mock_overlay;
-
-static ExpectedS<Dependencies::ActionPlan> create_versioned_install_plan(
- const PortFileProvider::IVersionedPortfileProvider& provider,
- const PortFileProvider::IBaselineProvider& bprovider,
- const CMakeVars::CMakeVarProvider& var_provider,
- const std::vector<Dependency>& deps,
- const std::vector<DependencyOverride>& overrides,
- const PackageSpec& toplevel)
-{
- return Dependencies::create_versioned_install_plan(
- provider, bprovider, s_empty_mock_overlay, var_provider, deps, overrides, toplevel);
-}
-
-TEST_CASE ("basic version install single", "[versionplan]")
-{
- MockBaselineProvider bp;
- bp.v["a"] = {"1", 0};
-
- MockVersionedPortfileProvider vp;
- vp.emplace("a", {"1", 0});
-
- MockCMakeVarProvider var_provider;
-
- auto install_plan = unwrap(create_versioned_install_plan(vp, bp, var_provider, {{"a"}}, {}, toplevel_spec()));
-
- REQUIRE(install_plan.size() == 1);
- REQUIRE(install_plan.install_actions.at(0).spec.name() == "a");
-}
-
-TEST_CASE ("basic version install detect cycle", "[versionplan]")
-{
- MockBaselineProvider bp;
- bp.v["a"] = {"1", 0};
- bp.v["b"] = {"1", 0};
-
- MockVersionedPortfileProvider vp;
- vp.emplace("a", {"1", 0}).source_control_file->core_paragraph->dependencies = {
- Dependency{"b", {}, {}, DependencyConstraint{}},
- };
- vp.emplace("b", {"1", 0}).source_control_file->core_paragraph->dependencies = {
- Dependency{"a", {}, {}, DependencyConstraint{}},
- };
-
- MockCMakeVarProvider var_provider;
-
- auto install_plan = create_versioned_install_plan(vp, bp, var_provider, {{"a"}}, {}, toplevel_spec());
-
- REQUIRE(!install_plan.has_value());
-}
-
-TEST_CASE ("basic version install scheme", "[versionplan]")
-{
- MockBaselineProvider bp;
- bp.v["a"] = {"1", 0};
- bp.v["b"] = {"1", 0};
-
- MockVersionedPortfileProvider vp;
- vp.emplace("a", {"1", 0}).source_control_file->core_paragraph->dependencies = {
- Dependency{"b", {}, {}, DependencyConstraint{}},
- };
- vp.emplace("b", {"1", 0});
-
- MockCMakeVarProvider var_provider;
-
- auto install_plan = unwrap(create_versioned_install_plan(vp, bp, var_provider, {{"a"}}, {}, toplevel_spec()));
-
- CHECK(install_plan.size() == 2);
-
- StringLiteral names[] = {"b", "a"};
- for (size_t i = 0; i < install_plan.install_actions.size() && i < 2; ++i)
- {
- CHECK(install_plan.install_actions[i].spec.name() == names[i]);
- }
-}
-
-TEST_CASE ("basic version install scheme diamond", "[versionplan]")
-{
- MockBaselineProvider bp;
- bp.v["a"] = {"1", 0};
- bp.v["b"] = {"1", 0};
- bp.v["c"] = {"1", 0};
- bp.v["d"] = {"1", 0};
-
- MockVersionedPortfileProvider vp;
- vp.emplace("a", {"1", 0}).source_control_file->core_paragraph->dependencies = {
- Dependency{"b", {}, {}, DependencyConstraint{}},
- Dependency{"c", {}, {}, DependencyConstraint{}},
- };
- vp.emplace("b", {"1", 0}).source_control_file->core_paragraph->dependencies = {
- Dependency{"c", {}, {}, DependencyConstraint{}},
- Dependency{"d", {}, {}, DependencyConstraint{}},
- };
- vp.emplace("c", {"1", 0}).source_control_file->core_paragraph->dependencies = {
- Dependency{"d", {}, {}, DependencyConstraint{}},
- };
- vp.emplace("d", {"1", 0});
-
- MockCMakeVarProvider var_provider;
-
- auto install_plan = unwrap(create_versioned_install_plan(vp, bp, var_provider, {{"a"}}, {}, toplevel_spec()));
-
- CHECK(install_plan.size() == 4);
-
- StringLiteral names[] = {"d", "c", "b", "a"};
- for (size_t i = 0; i < install_plan.install_actions.size() && i < 4; ++i)
- {
- CHECK(install_plan.install_actions[i].spec.name() == names[i]);
- }
-}
-
-TEST_CASE ("basic version install scheme baseline missing", "[versionplan]")
-{
- MockBaselineProvider bp;
-
- MockVersionedPortfileProvider vp;
- vp.emplace("a", {"1", 0});
-
- MockCMakeVarProvider var_provider;
-
- auto install_plan = create_versioned_install_plan(vp, bp, var_provider, {{"a"}}, {}, toplevel_spec());
-
- REQUIRE(!install_plan.has_value());
-}
-
-TEST_CASE ("basic version install scheme baseline missing success", "[versionplan]")
-{
- MockBaselineProvider bp;
-
- MockVersionedPortfileProvider vp;
- vp.emplace("a", {"1", 0});
- vp.emplace("a", {"2", 0});
- vp.emplace("a", {"3", 0});
-
- MockCMakeVarProvider var_provider;
-
- auto install_plan =
- unwrap(create_versioned_install_plan(vp,
- bp,
- var_provider,
- {
- Dependency{"a", {}, {}, {Constraint::Type::Minimum, "2"}},
- },
- {},
- toplevel_spec()));
-
- REQUIRE(install_plan.size() == 1);
- check_name_and_version(install_plan.install_actions[0], "a", {"2", 0});
-}
-
-TEST_CASE ("basic version install scheme baseline", "[versionplan]")
-{
- MockBaselineProvider bp;
- bp.v["a"] = {"2", 0};
-
- MockVersionedPortfileProvider vp;
- vp.emplace("a", {"1", 0});
- vp.emplace("a", {"2", 0});
- vp.emplace("a", {"3", 0});
-
- MockCMakeVarProvider var_provider;
-
- auto install_plan = unwrap(create_versioned_install_plan(vp, bp, var_provider, {{"a"}}, {}, toplevel_spec()));
-
- REQUIRE(install_plan.size() == 1);
- check_name_and_version(install_plan.install_actions[0], "a", {"2", 0});
-}
-
-TEST_CASE ("version string baseline agree", "[versionplan]")
-{
- MockBaselineProvider bp;
- bp.v["a"] = {"2", 0};
-
- MockVersionedPortfileProvider vp;
- vp.emplace("a", {"1", 0});
- vp.emplace("a", {"2", 0});
- vp.emplace("a", {"3", 0});
-
- MockCMakeVarProvider var_provider;
-
- auto install_plan = create_versioned_install_plan(
- vp, bp, var_provider, {Dependency{"a", {}, {}, {Constraint::Type::Minimum, "2"}}}, {}, toplevel_spec());
-
- REQUIRE(install_plan.has_value());
-}
-
-TEST_CASE ("version install scheme baseline conflict", "[versionplan]")
-{
- MockBaselineProvider bp;
- bp.v["a"] = {"2", 0};
-
- MockVersionedPortfileProvider vp;
- vp.emplace("a", {"1", 0});
- vp.emplace("a", {"2", 0});
- vp.emplace("a", {"3", 0});
-
- MockCMakeVarProvider var_provider;
-
- auto install_plan = create_versioned_install_plan(vp,
- bp,
- var_provider,
- {
- Dependency{"a", {}, {}, {Constraint::Type::Minimum, "3"}},
- },
- {},
- toplevel_spec());
-
- REQUIRE(!install_plan.has_value());
-}
-
-TEST_CASE ("version install string port version", "[versionplan]")
-{
- MockBaselineProvider bp;
- bp.v["a"] = {"2", 0};
-
- MockVersionedPortfileProvider vp;
- vp.emplace("a", {"2", 0});
- vp.emplace("a", {"2", 1});
- vp.emplace("a", {"2", 2});
-
- MockCMakeVarProvider var_provider;
-
- auto install_plan =
- unwrap(create_versioned_install_plan(vp,
- bp,
- var_provider,
- {
- Dependency{"a", {}, {}, {Constraint::Type::Minimum, "2", 1}},
- },
- {},
- toplevel_spec()));
-
- REQUIRE(install_plan.size() == 1);
- check_name_and_version(install_plan.install_actions[0], "a", {"2", 1});
-}
-
-TEST_CASE ("version install string port version 2", "[versionplan]")
-{
- MockBaselineProvider bp;
- bp.v["a"] = {"2", 1};
-
- MockVersionedPortfileProvider vp;
- vp.emplace("a", {"2", 0});
- vp.emplace("a", {"2", 1});
- vp.emplace("a", {"2", 2});
-
- MockCMakeVarProvider var_provider;
-
- auto install_plan =
- unwrap(create_versioned_install_plan(vp,
- bp,
- var_provider,
- {
- Dependency{"a", {}, {}, {Constraint::Type::Minimum, "2", 0}},
- },
- {},
- toplevel_spec()));
-
- REQUIRE(install_plan.size() == 1);
- check_name_and_version(install_plan.install_actions[0], "a", {"2", 1});
-}
-
-TEST_CASE ("version install transitive string", "[versionplan]")
-{
- MockBaselineProvider bp;
- bp.v["a"] = {"2", 0};
-
- MockVersionedPortfileProvider vp;
- vp.emplace("a", {"2", 0}).source_control_file->core_paragraph->dependencies = {
- Dependency{"b", {}, {}, DependencyConstraint{Constraint::Type::Minimum, "1"}},
- };
- vp.emplace("a", {"2", 1}).source_control_file->core_paragraph->dependencies = {
- Dependency{"b", {}, {}, DependencyConstraint{Constraint::Type::Minimum, "2"}},
- };
- vp.emplace("b", {"1", 0});
- vp.emplace("b", {"2", 0});
-
- MockCMakeVarProvider var_provider;
-
- auto install_plan =
- unwrap(create_versioned_install_plan(vp,
- bp,
- var_provider,
- {
- Dependency{"a", {}, {}, {Constraint::Type::Minimum, "2", 1}},
- },
- {},
- toplevel_spec()));
-
- REQUIRE(install_plan.size() == 2);
- check_name_and_version(install_plan.install_actions[0], "b", {"2", 0});
- check_name_and_version(install_plan.install_actions[1], "a", {"2", 1});
-}
-
-TEST_CASE ("version install simple relaxed", "[versionplan]")
-{
- MockBaselineProvider bp;
- bp.v["a"] = {"2", 0};
-
- MockVersionedPortfileProvider vp;
- vp.emplace("a", {"2", 0}, Scheme::Relaxed);
- vp.emplace("a", {"3", 0}, Scheme::Relaxed);
-
- MockCMakeVarProvider var_provider;
-
- auto install_plan =
- unwrap(create_versioned_install_plan(vp,
- bp,
- var_provider,
- {
- Dependency{"a", {}, {}, {Constraint::Type::Minimum, "3", 0}},
- },
- {},
- toplevel_spec()));
-
- REQUIRE(install_plan.size() == 1);
- check_name_and_version(install_plan.install_actions[0], "a", {"3", 0});
-}
-
-TEST_CASE ("version install transitive relaxed", "[versionplan]")
-{
- MockBaselineProvider bp;
- bp.v["a"] = {"2", 0};
- bp.v["b"] = {"2", 0};
-
- MockVersionedPortfileProvider vp;
- vp.emplace("a", {"2", 0}, Scheme::Relaxed);
- vp.emplace("a", {"3", 0}, Scheme::Relaxed).source_control_file->core_paragraph->dependencies = {
- Dependency{"b", {}, {}, DependencyConstraint{Constraint::Type::Minimum, "3"}},
- };
- vp.emplace("b", {"2", 0}, Scheme::Relaxed);
- vp.emplace("b", {"3", 0}, Scheme::Relaxed);
-
- MockCMakeVarProvider var_provider;
-
- auto install_plan =
- unwrap(create_versioned_install_plan(vp,
- bp,
- var_provider,
- {
- Dependency{"a", {}, {}, {Constraint::Type::Minimum, "3", 0}},
- },
- {},
- toplevel_spec()));
-
- REQUIRE(install_plan.size() == 2);
- check_name_and_version(install_plan.install_actions[0], "b", {"3", 0});
- check_name_and_version(install_plan.install_actions[1], "a", {"3", 0});
-}
-
-TEST_CASE ("version install diamond relaxed", "[versionplan]")
-{
- MockBaselineProvider bp;
- bp.v["a"] = {"2", 0};
- bp.v["b"] = {"3", 0};
-
- MockVersionedPortfileProvider vp;
- vp.emplace("a", {"2", 0}, Scheme::Relaxed);
- vp.emplace("a", {"3", 0}, Scheme::Relaxed).source_control_file->core_paragraph->dependencies = {
- Dependency{"b", {}, {}, DependencyConstraint{Constraint::Type::Minimum, "2", 1}},
- Dependency{"c", {}, {}, DependencyConstraint{Constraint::Type::Minimum, "5", 1}},
- };
- vp.emplace("b", {"2", 1}, Scheme::Relaxed);
- vp.emplace("b", {"3", 0}, Scheme::Relaxed).source_control_file->core_paragraph->dependencies = {
- Dependency{"c", {}, {}, DependencyConstraint{Constraint::Type::Minimum, "9", 2}},
- };
- vp.emplace("c", {"5", 1}, Scheme::Relaxed);
- vp.emplace("c", {"9", 2}, Scheme::Relaxed);
-
- MockCMakeVarProvider var_provider;
-
- auto install_plan =
- unwrap(create_versioned_install_plan(vp,
- bp,
- var_provider,
- {
- Dependency{"a", {}, {}, {Constraint::Type::Minimum, "3", 0}},
- Dependency{"b", {}, {}, {Constraint::Type::Minimum, "2", 1}},
- },
- {},
- toplevel_spec()));
-
- REQUIRE(install_plan.size() == 3);
- check_name_and_version(install_plan.install_actions[0], "c", {"9", 2});
- check_name_and_version(install_plan.install_actions[1], "b", {"3", 0});
- check_name_and_version(install_plan.install_actions[2], "a", {"3", 0});
-}
-
-TEST_CASE ("version parse semver", "[versionplan]")
-{
- auto version_basic = Versions::SemanticVersion::from_string("1.2.3");
- check_semver_version(version_basic, "1.2.3", "", 1, 2, 3, {});
-
- auto version_simple_tag = Versions::SemanticVersion::from_string("1.0.0-alpha");
- check_semver_version(version_simple_tag, "1.0.0", "alpha", 1, 0, 0, {"alpha"});
-
- auto version_alphanumeric_tag = Versions::SemanticVersion::from_string("1.0.0-0alpha0");
- check_semver_version(version_alphanumeric_tag, "1.0.0", "0alpha0", 1, 0, 0, {"0alpha0"});
-
- auto version_complex_tag = Versions::SemanticVersion::from_string("1.0.0-alpha.1.0.0");
- check_semver_version(version_complex_tag, "1.0.0", "alpha.1.0.0", 1, 0, 0, {"alpha", "1", "0", "0"});
-
- auto version_complexer_tag = Versions::SemanticVersion::from_string("1.0.0-alpha.1.x.y.z.0-alpha.0-beta.l-a-s-t");
- check_semver_version(version_complexer_tag,
- "1.0.0",
- "alpha.1.x.y.z.0-alpha.0-beta.l-a-s-t",
- 1,
- 0,
- 0,
- {"alpha", "1", "x", "y", "z", "0-alpha", "0-beta", "l-a-s-t"});
-
- auto version_ridiculous_tag = Versions::SemanticVersion::from_string("1.0.0----------------------------------");
- check_semver_version(version_ridiculous_tag,
- "1.0.0",
- "---------------------------------",
- 1,
- 0,
- 0,
- {"---------------------------------"});
-
- auto version_build_tag = Versions::SemanticVersion::from_string("1.0.0+build");
- check_semver_version(version_build_tag, "1.0.0", "", 1, 0, 0, {});
-
- auto version_prerelease_build_tag = Versions::SemanticVersion::from_string("1.0.0-alpha+build");
- check_semver_version(version_prerelease_build_tag, "1.0.0", "alpha", 1, 0, 0, {"alpha"});
-
- auto version_invalid_incomplete = Versions::SemanticVersion::from_string("1.0-alpha");
- CHECK(!version_invalid_incomplete.has_value());
-
- auto version_invalid_leading_zeroes = Versions::SemanticVersion::from_string("1.02.03-alpha+build");
- CHECK(!version_invalid_leading_zeroes.has_value());
-
- auto version_invalid_leading_zeroes_in_tag = Versions::SemanticVersion::from_string("1.0.0-01");
- CHECK(!version_invalid_leading_zeroes_in_tag.has_value());
-
- auto version_invalid_characters = Versions::SemanticVersion::from_string("1.0.0-alpha#2");
- CHECK(!version_invalid_characters.has_value());
-}
-
-TEST_CASE ("version parse relaxed", "[versionplan]")
-{
- auto version_basic = Versions::RelaxedVersion::from_string("1.2.3");
- check_relaxed_version(version_basic, {1, 2, 3});
-
- auto version_short = Versions::RelaxedVersion::from_string("1");
- check_relaxed_version(version_short, {1});
-
- auto version_long =
- Versions::RelaxedVersion::from_string("1.20.300.4000.50000.6000000.70000000.80000000.18446744073709551610");
- check_relaxed_version(version_long, {1, 20, 300, 4000, 50000, 6000000, 70000000, 80000000, 18446744073709551610u});
-
- auto version_invalid_characters = Versions::RelaxedVersion::from_string("1.a.0");
- CHECK(!version_invalid_characters.has_value());
-
- auto version_invalid_identifiers_2 = Versions::RelaxedVersion::from_string("1.1a.2");
- CHECK(!version_invalid_identifiers_2.has_value());
-
- auto version_invalid_leading_zeroes = Versions::RelaxedVersion::from_string("01.002.003");
- CHECK(!version_invalid_leading_zeroes.has_value());
-}
-
-TEST_CASE ("version parse date", "[versionplan]")
-{
- auto version_basic = Versions::DateVersion::from_string("2020-12-25");
- check_date_version(version_basic, "2020-12-25", "", {});
-
- auto version_identifiers = Versions::DateVersion::from_string("2020-12-25.1.2.3");
- check_date_version(version_identifiers, "2020-12-25", "1.2.3", {1, 2, 3});
-
- auto version_invalid_date = Versions::DateVersion::from_string("2020-1-1");
- CHECK(!version_invalid_date.has_value());
-
- auto version_invalid_identifiers = Versions::DateVersion::from_string("2020-01-01.alpha");
- CHECK(!version_invalid_identifiers.has_value());
-
- auto version_invalid_identifiers_2 = Versions::DateVersion::from_string("2020-01-01.2a");
- CHECK(!version_invalid_identifiers_2.has_value());
-
- auto version_invalid_leading_zeroes = Versions::DateVersion::from_string("2020-01-01.01");
- CHECK(!version_invalid_leading_zeroes.has_value());
-}
-
-TEST_CASE ("version sort semver", "[versionplan]")
-{
- std::vector<Versions::SemanticVersion> versions{unwrap(Versions::SemanticVersion::from_string("1.0.0")),
- unwrap(Versions::SemanticVersion::from_string("0.0.0")),
- unwrap(Versions::SemanticVersion::from_string("1.1.0")),
- unwrap(Versions::SemanticVersion::from_string("2.0.0")),
- unwrap(Versions::SemanticVersion::from_string("1.1.1")),
- unwrap(Versions::SemanticVersion::from_string("1.0.1")),
- unwrap(Versions::SemanticVersion::from_string("1.0.0-alpha.1")),
- unwrap(Versions::SemanticVersion::from_string("1.0.0-beta")),
- unwrap(Versions::SemanticVersion::from_string("1.0.0-alpha")),
- unwrap(Versions::SemanticVersion::from_string("1.0.0-alpha.beta")),
- unwrap(Versions::SemanticVersion::from_string("1.0.0-rc")),
- unwrap(Versions::SemanticVersion::from_string("1.0.0-beta.2")),
- unwrap(Versions::SemanticVersion::from_string("1.0.0-beta.20")),
- unwrap(Versions::SemanticVersion::from_string("1.0.0-beta.3")),
- unwrap(Versions::SemanticVersion::from_string("1.0.0-1")),
- unwrap(Versions::SemanticVersion::from_string("1.0.0-0alpha"))};
-
- std::sort(std::begin(versions), std::end(versions), [](const auto& lhs, const auto& rhs) -> bool {
- return Versions::compare(lhs, rhs) == Versions::VerComp::lt;
- });
-
- CHECK(versions[0].original_string == "0.0.0");
- CHECK(versions[1].original_string == "1.0.0-1");
- CHECK(versions[2].original_string == "1.0.0-0alpha");
- CHECK(versions[3].original_string == "1.0.0-alpha");
- CHECK(versions[4].original_string == "1.0.0-alpha.1");
- CHECK(versions[5].original_string == "1.0.0-alpha.beta");
- CHECK(versions[6].original_string == "1.0.0-beta");
- CHECK(versions[7].original_string == "1.0.0-beta.2");
- CHECK(versions[8].original_string == "1.0.0-beta.3");
- CHECK(versions[9].original_string == "1.0.0-beta.20");
- CHECK(versions[10].original_string == "1.0.0-rc");
- CHECK(versions[11].original_string == "1.0.0");
- CHECK(versions[12].original_string == "1.0.1");
- CHECK(versions[13].original_string == "1.1.0");
- CHECK(versions[14].original_string == "1.1.1");
- CHECK(versions[15].original_string == "2.0.0");
-}
-
-TEST_CASE ("version sort relaxed", "[versionplan]")
-{
- std::vector<Versions::RelaxedVersion> versions{unwrap(Versions::RelaxedVersion::from_string("1.0.0")),
- unwrap(Versions::RelaxedVersion::from_string("1.0")),
- unwrap(Versions::RelaxedVersion::from_string("1")),
- unwrap(Versions::RelaxedVersion::from_string("2")),
- unwrap(Versions::RelaxedVersion::from_string("1.1")),
- unwrap(Versions::RelaxedVersion::from_string("1.10.1")),
- unwrap(Versions::RelaxedVersion::from_string("1.0.1")),
- unwrap(Versions::RelaxedVersion::from_string("1.0.0.1")),
- unwrap(Versions::RelaxedVersion::from_string("1.0.0.2"))};
-
- std::sort(std::begin(versions), std::end(versions), [](const auto& lhs, const auto& rhs) -> bool {
- return Versions::compare(lhs, rhs) == Versions::VerComp::lt;
- });
-
- CHECK(versions[0].original_string == "1");
- CHECK(versions[1].original_string == "1.0");
- CHECK(versions[2].original_string == "1.0.0");
- CHECK(versions[3].original_string == "1.0.0.1");
- CHECK(versions[4].original_string == "1.0.0.2");
- CHECK(versions[5].original_string == "1.0.1");
- CHECK(versions[6].original_string == "1.1");
- CHECK(versions[7].original_string == "1.10.1");
- CHECK(versions[8].original_string == "2");
-}
-
-TEST_CASE ("version sort date", "[versionplan]")
-{
- std::vector<Versions::DateVersion> versions{unwrap(Versions::DateVersion::from_string("2021-01-01.2")),
- unwrap(Versions::DateVersion::from_string("2021-01-01.1")),
- unwrap(Versions::DateVersion::from_string("2021-01-01.1.1")),
- unwrap(Versions::DateVersion::from_string("2021-01-01.1.0")),
- unwrap(Versions::DateVersion::from_string("2021-01-01")),
- unwrap(Versions::DateVersion::from_string("2021-01-01")),
- unwrap(Versions::DateVersion::from_string("2020-12-25")),
- unwrap(Versions::DateVersion::from_string("2020-12-31")),
- unwrap(Versions::DateVersion::from_string("2021-01-01.10"))};
-
- std::sort(std::begin(versions), std::end(versions), [](const auto& lhs, const auto& rhs) -> bool {
- return Versions::compare(lhs, rhs) == Versions::VerComp::lt;
- });
-
- CHECK(versions[0].original_string == "2020-12-25");
- CHECK(versions[1].original_string == "2020-12-31");
- CHECK(versions[2].original_string == "2021-01-01");
- CHECK(versions[3].original_string == "2021-01-01");
- CHECK(versions[4].original_string == "2021-01-01.1");
- CHECK(versions[5].original_string == "2021-01-01.1.0");
- CHECK(versions[6].original_string == "2021-01-01.1.1");
- CHECK(versions[7].original_string == "2021-01-01.2");
- CHECK(versions[8].original_string == "2021-01-01.10");
-}
-
-TEST_CASE ("version install simple semver", "[versionplan]")
-{
- MockBaselineProvider bp;
- bp.v["a"] = {"2.0.0", 0};
-
- MockVersionedPortfileProvider vp;
- vp.emplace("a", {"2.0.0", 0}, Scheme::Semver);
- vp.emplace("a", {"3.0.0", 0}, Scheme::Semver);
-
- MockCMakeVarProvider var_provider;
-
- auto install_plan =
- unwrap(create_versioned_install_plan(vp,
- bp,
- var_provider,
- {
- Dependency{"a", {}, {}, {Constraint::Type::Minimum, "3.0.0", 0}},
- },
- {},
- toplevel_spec()));
-
- REQUIRE(install_plan.size() == 1);
- check_name_and_version(install_plan.install_actions[0], "a", {"3.0.0", 0});
-}
-
-TEST_CASE ("version install transitive semver", "[versionplan]")
-{
- MockBaselineProvider bp;
- bp.v["a"] = {"2.0.0", 0};
- bp.v["b"] = {"2.0.0", 0};
-
- MockVersionedPortfileProvider vp;
- vp.emplace("a", {"2.0.0", 0}, Scheme::Semver);
- vp.emplace("a", {"3.0.0", 0}, Scheme::Semver).source_control_file->core_paragraph->dependencies = {
- Dependency{"b", {}, {}, DependencyConstraint{Constraint::Type::Minimum, "3.0.0"}},
- };
- vp.emplace("b", {"2.0.0", 0}, Scheme::Semver);
- vp.emplace("b", {"3.0.0", 0}, Scheme::Semver);
-
- MockCMakeVarProvider var_provider;
-
- auto install_plan =
- unwrap(create_versioned_install_plan(vp,
- bp,
- var_provider,
- {
- Dependency{"a", {}, {}, {Constraint::Type::Minimum, "3.0.0", 0}},
- },
- {},
- toplevel_spec()));
-
- REQUIRE(install_plan.size() == 2);
- check_name_and_version(install_plan.install_actions[0], "b", {"3.0.0", 0});
- check_name_and_version(install_plan.install_actions[1], "a", {"3.0.0", 0});
-}
-
-TEST_CASE ("version install diamond semver", "[versionplan]")
-{
- MockBaselineProvider bp;
- bp.v["a"] = {"2.0.0", 0};
- bp.v["b"] = {"3.0.0", 0};
-
- MockVersionedPortfileProvider vp;
- vp.emplace("a", {"2.0.0", 0}, Scheme::Semver);
- vp.emplace("a", {"3.0.0", 0}, Scheme::Semver).source_control_file->core_paragraph->dependencies = {
- Dependency{"b", {}, {}, DependencyConstraint{Constraint::Type::Minimum, "2.0.0", 1}},
- Dependency{"c", {}, {}, DependencyConstraint{Constraint::Type::Minimum, "5.0.0", 1}},
- };
- vp.emplace("b", {"2.0.0", 1}, Scheme::Semver);
- vp.emplace("b", {"3.0.0", 0}, Scheme::Semver).source_control_file->core_paragraph->dependencies = {
- Dependency{"c", {}, {}, DependencyConstraint{Constraint::Type::Minimum, "9.0.0", 2}},
- };
- vp.emplace("c", {"5.0.0", 1}, Scheme::Semver);
- vp.emplace("c", {"9.0.0", 2}, Scheme::Semver);
-
- MockCMakeVarProvider var_provider;
-
- auto install_plan =
- unwrap(create_versioned_install_plan(vp,
- bp,
- var_provider,
- {
- Dependency{"a", {}, {}, {Constraint::Type::Minimum, "3.0.0", 0}},
- Dependency{"b", {}, {}, {Constraint::Type::Minimum, "2.0.0", 1}},
- },
- {},
- toplevel_spec()));
-
- REQUIRE(install_plan.size() == 3);
- check_name_and_version(install_plan.install_actions[0], "c", {"9.0.0", 2});
- check_name_and_version(install_plan.install_actions[1], "b", {"3.0.0", 0});
- check_name_and_version(install_plan.install_actions[2], "a", {"3.0.0", 0});
-}
-
-TEST_CASE ("version install simple date", "[versionplan]")
-{
- MockBaselineProvider bp;
- bp.v["a"] = {"2020-02-01", 0};
-
- MockVersionedPortfileProvider vp;
- vp.emplace("a", {"2020-02-01", 0}, Scheme::Date);
- vp.emplace("a", {"2020-03-01", 0}, Scheme::Date);
-
- MockCMakeVarProvider var_provider;
-
- auto install_plan =
- unwrap(create_versioned_install_plan(vp,
- bp,
- var_provider,
- {
- Dependency{"a", {}, {}, {Constraint::Type::Minimum, "2020-03-01", 0}},
- },
- {},
- toplevel_spec()));
-
- REQUIRE(install_plan.size() == 1);
- check_name_and_version(install_plan.install_actions[0], "a", {"2020-03-01", 0});
-}
-
-TEST_CASE ("version install transitive date", "[versionplan]")
-{
- MockBaselineProvider bp;
- bp.v["a"] = {"2020-01-01.2", 0};
- bp.v["b"] = {"2020-01-01.3", 0};
-
- MockVersionedPortfileProvider vp;
- vp.emplace("a", {"2020-01-01.2", 0}, Scheme::Date);
- vp.emplace("a", {"2020-01-01.3", 0}, Scheme::Date).source_control_file->core_paragraph->dependencies = {
- Dependency{"b", {}, {}, DependencyConstraint{Constraint::Type::Minimum, "2020-01-01.3"}},
- };
- vp.emplace("b", {"2020-01-01.2", 0}, Scheme::Date);
- vp.emplace("b", {"2020-01-01.3", 0}, Scheme::Date);
-
- MockCMakeVarProvider var_provider;
-
- auto install_plan = unwrap(
- create_versioned_install_plan(vp,
- bp,
- var_provider,
- {
- Dependency{"a", {}, {}, {Constraint::Type::Minimum, "2020-01-01.3", 0}},
- },
- {},
- toplevel_spec()));
-
- REQUIRE(install_plan.size() == 2);
- check_name_and_version(install_plan.install_actions[0], "b", {"2020-01-01.3", 0});
- check_name_and_version(install_plan.install_actions[1], "a", {"2020-01-01.3", 0});
-}
-
-TEST_CASE ("version install diamond date", "[versionplan]")
-{
- MockBaselineProvider bp;
- bp.v["a"] = {"2020-01-02", 0};
- bp.v["b"] = {"2020-01-03", 0};
-
- MockVersionedPortfileProvider vp;
- vp.emplace("a", {"2020-01-02", 0}, Scheme::Date);
- vp.emplace("a", {"2020-01-03", 0}, Scheme::Date).source_control_file->core_paragraph->dependencies = {
- Dependency{"b", {}, {}, DependencyConstraint{Constraint::Type::Minimum, "2020-01-02", 1}},
- Dependency{"c", {}, {}, DependencyConstraint{Constraint::Type::Minimum, "2020-01-05", 1}},
- };
- vp.emplace("b", {"2020-01-02", 1}, Scheme::Date);
- vp.emplace("b", {"2020-01-03", 0}, Scheme::Date).source_control_file->core_paragraph->dependencies = {
- Dependency{"c", {}, {}, DependencyConstraint{Constraint::Type::Minimum, "2020-01-09", 2}},
- };
- vp.emplace("c", {"2020-01-05", 1}, Scheme::Date);
- vp.emplace("c", {"2020-01-09", 2}, Scheme::Date);
-
- MockCMakeVarProvider var_provider;
-
- auto install_plan =
- unwrap(create_versioned_install_plan(vp,
- bp,
- var_provider,
- {
- Dependency{"a", {}, {}, {Constraint::Type::Minimum, "2020-01-03", 0}},
- Dependency{"b", {}, {}, {Constraint::Type::Minimum, "2020-01-02", 1}},
- },
- {},
- toplevel_spec()));
-
- REQUIRE(install_plan.size() == 3);
- check_name_and_version(install_plan.install_actions[0], "c", {"2020-01-09", 2});
- check_name_and_version(install_plan.install_actions[1], "b", {"2020-01-03", 0});
- check_name_and_version(install_plan.install_actions[2], "a", {"2020-01-03", 0});
-}
-
-TEST_CASE ("version install scheme failure", "[versionplan]")
-{
- MockVersionedPortfileProvider vp;
- vp.emplace("a", {"1.0.0", 0}, Scheme::Semver);
- vp.emplace("a", {"1.0.1", 0}, Scheme::Relaxed);
- vp.emplace("a", {"1.0.2", 0}, Scheme::Semver);
-
- MockCMakeVarProvider var_provider;
-
- SECTION ("lower baseline")
- {
- MockBaselineProvider bp;
- bp.v["a"] = {"1.0.0", 0};
-
- auto install_plan =
- create_versioned_install_plan(vp,
- bp,
- var_provider,
- {Dependency{"a", {}, {}, {Constraint::Type::Minimum, "1.0.1", 0}}},
- {},
- toplevel_spec());
-
- REQUIRE(!install_plan.error().empty());
- CHECK(install_plan.error() == "Version conflict on a@1.0.1: baseline required 1.0.0");
- }
- SECTION ("higher baseline")
- {
- MockBaselineProvider bp;
- bp.v["a"] = {"1.0.2", 0};
-
- auto install_plan =
- create_versioned_install_plan(vp,
- bp,
- var_provider,
- {Dependency{"a", {}, {}, {Constraint::Type::Minimum, "1.0.1", 0}}},
- {},
- toplevel_spec());
-
- REQUIRE(!install_plan.error().empty());
- CHECK(install_plan.error() == "Version conflict on a@1.0.1: baseline required 1.0.2");
- }
-}
-
-TEST_CASE ("version install scheme change in port version", "[versionplan]")
-{
- MockVersionedPortfileProvider vp;
- vp.emplace("a", {"2", 0}).source_control_file->core_paragraph->dependencies = {
- Dependency{"b", {}, {}, DependencyConstraint{Constraint::Type::Minimum, "1"}},
- };
- vp.emplace("a", {"2", 1}).source_control_file->core_paragraph->dependencies = {
- Dependency{"b", {}, {}, DependencyConstraint{Constraint::Type::Minimum, "1", 1}},
- };
- vp.emplace("b", {"1", 0}, Scheme::String);
- vp.emplace("b", {"1", 1}, Scheme::Relaxed);
-
- MockCMakeVarProvider var_provider;
-
- SECTION ("lower baseline")
- {
- MockBaselineProvider bp;
- bp.v["a"] = {"2", 0};
-
- auto install_plan =
- unwrap(create_versioned_install_plan(vp,
- bp,
- var_provider,
- {
- Dependency{"a", {}, {}, {Constraint::Type::Minimum, "2", 1}},
- },
- {},
- toplevel_spec()));
-
- REQUIRE(install_plan.size() == 2);
- check_name_and_version(install_plan.install_actions[0], "b", {"1", 1});
- check_name_and_version(install_plan.install_actions[1], "a", {"2", 1});
- }
- SECTION ("higher baseline")
- {
- MockBaselineProvider bp;
- bp.v["a"] = {"2", 1};
-
- auto install_plan =
- unwrap(create_versioned_install_plan(vp,
- bp,
- var_provider,
- {
- Dependency{"a", {}, {}, {Constraint::Type::Minimum, "2", 0}},
- },
- {},
- toplevel_spec()));
-
- REQUIRE(install_plan.size() == 2);
- check_name_and_version(install_plan.install_actions[0], "b", {"1", 1});
- check_name_and_version(install_plan.install_actions[1], "a", {"2", 1});
- }
-}
-
-TEST_CASE ("version install simple feature", "[versionplan]")
-{
- MockVersionedPortfileProvider vp;
- auto a_x = std::make_unique<FeatureParagraph>();
- a_x->name = "x";
- vp.emplace("a", {"1", 0}, Scheme::Relaxed).source_control_file->feature_paragraphs.push_back(std::move(a_x));
-
- MockCMakeVarProvider var_provider;
-
- SECTION ("with baseline")
- {
- MockBaselineProvider bp;
- bp.v["a"] = {"1", 0};
-
- auto install_plan = unwrap(create_versioned_install_plan(vp,
- bp,
- var_provider,
- {
- Dependency{"a", {"x"}},
- },
- {},
- toplevel_spec()));
-
- REQUIRE(install_plan.size() == 1);
- check_name_and_version(install_plan.install_actions[0], "a", {"1", 0}, {"x"});
- }
-
- SECTION ("without baseline")
- {
- MockBaselineProvider bp;
-
- auto install_plan =
- unwrap(create_versioned_install_plan(vp,
- bp,
- var_provider,
- {
- Dependency{"a", {"x"}, {}, {Constraint::Type::Minimum, "1", 0}},
- },
- {},
- toplevel_spec()));
-
- REQUIRE(install_plan.size() == 1);
- check_name_and_version(install_plan.install_actions[0], "a", {"1", 0}, {"x"});
- }
-}
-
-static std::unique_ptr<FeatureParagraph> make_fpgh(std::string name)
-{
- auto f = std::make_unique<FeatureParagraph>();
- f->name = std::move(name);
- return f;
-}
-
-TEST_CASE ("version install transitive features", "[versionplan]")
-{
- MockVersionedPortfileProvider vp;
-
- auto a_x = make_fpgh("x");
- a_x->dependencies.push_back(Dependency{"b", {"y"}});
- vp.emplace("a", {"1", 0}, Scheme::Relaxed).source_control_file->feature_paragraphs.push_back(std::move(a_x));
-
- auto b_y = make_fpgh("y");
- vp.emplace("b", {"1", 0}, Scheme::Relaxed).source_control_file->feature_paragraphs.push_back(std::move(b_y));
-
- MockCMakeVarProvider var_provider;
-
- MockBaselineProvider bp;
- bp.v["a"] = {"1", 0};
- bp.v["b"] = {"1", 0};
-
- auto install_plan = unwrap(create_versioned_install_plan(vp,
- bp,
- var_provider,
- {
- Dependency{"a", {"x"}},
- },
- {},
- toplevel_spec()));
-
- REQUIRE(install_plan.size() == 2);
- check_name_and_version(install_plan.install_actions[0], "b", {"1", 0}, {"y"});
- check_name_and_version(install_plan.install_actions[1], "a", {"1", 0}, {"x"});
-}
-
-TEST_CASE ("version install transitive feature versioned", "[versionplan]")
-{
- MockVersionedPortfileProvider vp;
-
- auto a_x = make_fpgh("x");
- a_x->dependencies.push_back(Dependency{"b", {"y"}, {}, {Constraint::Type::Minimum, "2", 0}});
- vp.emplace("a", {"1", 0}, Scheme::Relaxed).source_control_file->feature_paragraphs.push_back(std::move(a_x));
-
- {
- auto b_y = make_fpgh("y");
- vp.emplace("b", {"1", 0}, Scheme::Relaxed).source_control_file->feature_paragraphs.push_back(std::move(b_y));
- }
- {
- auto b_y = make_fpgh("y");
- b_y->dependencies.push_back(Dependency{"c"});
- vp.emplace("b", {"2", 0}, Scheme::Relaxed).source_control_file->feature_paragraphs.push_back(std::move(b_y));
- }
-
- vp.emplace("c", {"1", 0}, Scheme::Relaxed);
-
- MockCMakeVarProvider var_provider;
-
- MockBaselineProvider bp;
- bp.v["a"] = {"1", 0};
- bp.v["c"] = {"1", 0};
-
- auto install_plan = unwrap(create_versioned_install_plan(vp,
- bp,
- var_provider,
- {
- Dependency{"a", {"x"}},
- },
- {},
- toplevel_spec()));
-
- REQUIRE(install_plan.size() == 3);
- check_name_and_version(install_plan.install_actions[0], "c", {"1", 0});
- check_name_and_version(install_plan.install_actions[1], "b", {"2", 0}, {"y"});
- check_name_and_version(install_plan.install_actions[2], "a", {"1", 0}, {"x"});
-}
-
-TEST_CASE ("version install constraint-reduction", "[versionplan]")
-{
- MockCMakeVarProvider var_provider;
-
- SECTION ("higher baseline")
- {
- MockVersionedPortfileProvider vp;
-
- vp.emplace("b", {"1", 0}, Scheme::Relaxed).source_control_file->core_paragraph->dependencies = {
- Dependency{"c", {}, {}, {Constraint::Type::Minimum, "2"}},
- };
- vp.emplace("b", {"2", 0}, Scheme::Relaxed).source_control_file->core_paragraph->dependencies = {
- Dependency{"c", {}, {}, {Constraint::Type::Minimum, "1"}},
- };
-
- vp.emplace("c", {"1", 0}, Scheme::Relaxed);
- // c@2 is used to detect if certain constraints were evaluated
- vp.emplace("c", {"2", 0}, Scheme::Relaxed);
-
- MockBaselineProvider bp;
- bp.v["b"] = {"2", 0};
- bp.v["c"] = {"1", 0};
-
- auto install_plan =
- unwrap(create_versioned_install_plan(vp,
- bp,
- var_provider,
- {
- Dependency{"b", {}, {}, {Constraint::Type::Minimum, "1"}},
- },
- {},
- toplevel_spec()));
-
- REQUIRE(install_plan.size() == 2);
- check_name_and_version(install_plan.install_actions[0], "c", {"1", 0});
- check_name_and_version(install_plan.install_actions[1], "b", {"2", 0});
- }
-
- SECTION ("higher toplevel")
- {
- MockVersionedPortfileProvider vp;
-
- vp.emplace("b", {"1", 0}, Scheme::Relaxed).source_control_file->core_paragraph->dependencies = {
- Dependency{"c", {}, {}, {Constraint::Type::Minimum, "2"}},
- };
- vp.emplace("b", {"2", 0}, Scheme::Relaxed).source_control_file->core_paragraph->dependencies = {
- Dependency{"c", {}, {}, {Constraint::Type::Minimum, "1"}},
- };
-
- vp.emplace("c", {"1", 0}, Scheme::Relaxed);
- // c@2 is used to detect if certain constraints were evaluated
- vp.emplace("c", {"2", 0}, Scheme::Relaxed);
-
- MockBaselineProvider bp;
- bp.v["b"] = {"1", 0};
- bp.v["c"] = {"1", 0};
-
- auto install_plan =
- unwrap(create_versioned_install_plan(vp,
- bp,
- var_provider,
- {
- Dependency{"b", {}, {}, {Constraint::Type::Minimum, "2"}},
- },
- {},
- toplevel_spec()));
-
- REQUIRE(install_plan.size() == 2);
- check_name_and_version(install_plan.install_actions[0], "c", {"1", 0});
- check_name_and_version(install_plan.install_actions[1], "b", {"2", 0});
- }
-}
-
-TEST_CASE ("version install overrides", "[versionplan]")
-{
- MockCMakeVarProvider var_provider;
-
- MockVersionedPortfileProvider vp;
-
- vp.emplace("b", {"1", 0}, Scheme::Relaxed);
- vp.emplace("b", {"2", 0}, Scheme::Relaxed);
- vp.emplace("c", {"1", 0}, Scheme::String);
- vp.emplace("c", {"2", 0}, Scheme::String);
-
- MockBaselineProvider bp;
- bp.v["b"] = {"2", 0};
- bp.v["c"] = {"2", 0};
-
- SECTION ("string")
- {
- auto install_plan =
- unwrap(create_versioned_install_plan(vp,
- bp,
- var_provider,
- {Dependency{"c"}},
- {DependencyOverride{"b", "1"}, DependencyOverride{"c", "1"}},
- toplevel_spec()));
-
- REQUIRE(install_plan.size() == 1);
- check_name_and_version(install_plan.install_actions[0], "c", {"1", 0});
- }
-
- SECTION ("relaxed")
- {
- auto install_plan =
- unwrap(create_versioned_install_plan(vp,
- bp,
- var_provider,
- {Dependency{"b"}},
- {DependencyOverride{"b", "1"}, DependencyOverride{"c", "1"}},
- toplevel_spec()));
-
- REQUIRE(install_plan.size() == 1);
- check_name_and_version(install_plan.install_actions[0], "b", {"1", 0});
- }
-}
-
-TEST_CASE ("version install transitive overrides", "[versionplan]")
-{
- MockCMakeVarProvider var_provider;
-
- MockVersionedPortfileProvider vp;
-
- vp.emplace("b", {"1", 0}, Scheme::Relaxed)
- .source_control_file->core_paragraph->dependencies.push_back(
- {"c", {}, {}, {Constraint::Type::Minimum, "2", 1}});
- vp.emplace("b", {"2", 0}, Scheme::Relaxed);
- vp.emplace("c", {"1", 0}, Scheme::String);
- vp.emplace("c", {"2", 1}, Scheme::String);
-
- MockBaselineProvider bp;
- bp.v["b"] = {"2", 0};
- bp.v["c"] = {"2", 1};
-
- auto install_plan =
- unwrap(create_versioned_install_plan(vp,
- bp,
- var_provider,
- {Dependency{"b"}},
- {DependencyOverride{"b", "1"}, DependencyOverride{"c", "1"}},
- toplevel_spec()));
-
- REQUIRE(install_plan.size() == 2);
- check_name_and_version(install_plan.install_actions[0], "c", {"1", 0});
- check_name_and_version(install_plan.install_actions[1], "b", {"1", 0});
-}
-
-TEST_CASE ("version install default features", "[versionplan]")
-{
- MockVersionedPortfileProvider vp;
-
- auto a_x = make_fpgh("x");
- auto& a_scf = vp.emplace("a", {"1", 0}, Scheme::Relaxed).source_control_file;
- a_scf->core_paragraph->default_features.push_back("x");
- a_scf->feature_paragraphs.push_back(std::move(a_x));
-
- MockCMakeVarProvider var_provider;
-
- MockBaselineProvider bp;
- bp.v["a"] = {"1", 0};
-
- auto install_plan =
- unwrap(create_versioned_install_plan(vp, bp, var_provider, {Dependency{"a"}}, {}, toplevel_spec()));
-
- REQUIRE(install_plan.size() == 1);
- check_name_and_version(install_plan.install_actions[0], "a", {"1", 0}, {"x"});
-}
-
-TEST_CASE ("version dont install default features", "[versionplan]")
-{
- MockVersionedPortfileProvider vp;
-
- auto a_x = make_fpgh("x");
- auto& a_scf = vp.emplace("a", {"1", 0}, Scheme::Relaxed).source_control_file;
- a_scf->core_paragraph->default_features.push_back("x");
- a_scf->feature_paragraphs.push_back(std::move(a_x));
-
- MockCMakeVarProvider var_provider;
-
- MockBaselineProvider bp;
- bp.v["a"] = {"1", 0};
-
- auto install_plan =
- unwrap(create_versioned_install_plan(vp, bp, var_provider, {Dependency{"a", {"core"}}}, {}, toplevel_spec()));
-
- REQUIRE(install_plan.size() == 1);
- check_name_and_version(install_plan.install_actions[0], "a", {"1", 0});
-}
-
-TEST_CASE ("version install transitive default features", "[versionplan]")
-{
- MockVersionedPortfileProvider vp;
-
- auto a_x = make_fpgh("x");
- auto& a_scf = vp.emplace("a", {"1", 0}, Scheme::Relaxed).source_control_file;
- a_scf->core_paragraph->default_features.push_back("x");
- a_scf->feature_paragraphs.push_back(std::move(a_x));
-
- auto& b_scf = vp.emplace("b", {"1", 0}, Scheme::Relaxed).source_control_file;
- b_scf->core_paragraph->dependencies.push_back({"a", {"core"}});
-
- MockCMakeVarProvider var_provider;
-
- MockBaselineProvider bp;
- bp.v["a"] = {"1", 0};
- bp.v["b"] = {"1", 0};
-
- auto install_plan =
- unwrap(create_versioned_install_plan(vp, bp, var_provider, {Dependency{"b"}}, {}, toplevel_spec()));
-
- REQUIRE(install_plan.size() == 2);
- check_name_and_version(install_plan.install_actions[0], "a", {"1", 0}, {"x"});
- check_name_and_version(install_plan.install_actions[1], "b", {"1", 0});
-}
-
-static PlatformExpression::Expr parse_platform(StringView l)
-{
- return unwrap(PlatformExpression::parse_platform_expression(l, PlatformExpression::MultipleBinaryOperators::Deny));
-}
-
-TEST_CASE ("version install qualified dependencies", "[versionplan]")
-{
- MockVersionedPortfileProvider vp;
-
- vp.emplace("b", {"1", 0}, Scheme::Relaxed);
- vp.emplace("c", {"1", 0}, Scheme::Relaxed);
-
- MockBaselineProvider bp;
- bp.v["b"] = {"1", 0};
- bp.v["c"] = {"1", 0};
-
- SECTION ("windows")
- {
- MockCMakeVarProvider var_provider;
- var_provider.dep_info_vars[toplevel_spec()] = {{"VCPKG_CMAKE_SYSTEM_NAME", "Windows"}};
-
- auto install_plan = unwrap(
- create_versioned_install_plan(vp,
- bp,
- var_provider,
- {{"b", {}, parse_platform("!linux")}, {"c", {}, parse_platform("linux")}},
- {},
- toplevel_spec()));
-
- REQUIRE(install_plan.size() == 1);
- check_name_and_version(install_plan.install_actions[0], "b", {"1", 0});
- }
-
- SECTION ("linux")
- {
- MockCMakeVarProvider var_provider;
- var_provider.dep_info_vars[toplevel_spec()] = {{"VCPKG_CMAKE_SYSTEM_NAME", "Linux"}};
-
- auto install_plan = unwrap(
- create_versioned_install_plan(vp,
- bp,
- var_provider,
- {{"b", {}, parse_platform("!linux")}, {"c", {}, parse_platform("linux")}},
- {},
- toplevel_spec()));
-
- REQUIRE(install_plan.size() == 1);
- check_name_and_version(install_plan.install_actions[0], "c", {"1", 0});
- }
-}
-
-TEST_CASE ("version install qualified default suppression", "[versionplan]")
-{
- MockVersionedPortfileProvider vp;
-
- auto& a_scf = vp.emplace("a", {"1", 0}, Scheme::Relaxed).source_control_file;
- a_scf->core_paragraph->default_features.push_back("x");
- a_scf->feature_paragraphs.push_back(make_fpgh("x"));
-
- vp.emplace("b", {"1", 0}, Scheme::Relaxed)
- .source_control_file->core_paragraph->dependencies.push_back({"a", {"core"}});
-
- MockCMakeVarProvider var_provider;
-
- MockBaselineProvider bp;
- bp.v["a"] = {"1", 0};
- bp.v["b"] = {"1", 0};
-
- auto install_plan = unwrap(
- create_versioned_install_plan(vp,
- bp,
- var_provider,
- {{"b", {}, parse_platform("!linux")}, {"a", {"core"}, parse_platform("linux")}},
- {},
- toplevel_spec()));
-
- REQUIRE(install_plan.size() == 2);
- check_name_and_version(install_plan.install_actions[0], "a", {"1", 0}, {"x"});
- check_name_and_version(install_plan.install_actions[1], "b", {"1", 0});
-}
-
-TEST_CASE ("version install qualified transitive", "[versionplan]")
-{
- MockVersionedPortfileProvider vp;
-
- vp.emplace("a", {"1", 0}, Scheme::Relaxed);
- vp.emplace("c", {"1", 0}, Scheme::Relaxed);
-
- auto& b_scf = vp.emplace("b", {"1", 0}, Scheme::Relaxed).source_control_file;
- b_scf->core_paragraph->dependencies.push_back({"a", {}, parse_platform("!linux")});
- b_scf->core_paragraph->dependencies.push_back({"c", {}, parse_platform("linux")});
-
- MockCMakeVarProvider var_provider;
-
- MockBaselineProvider bp;
- bp.v["a"] = {"1", 0};
- bp.v["b"] = {"1", 0};
- bp.v["c"] = {"1", 0};
-
- auto install_plan = unwrap(create_versioned_install_plan(vp, bp, var_provider, {{"b"}}, {}, toplevel_spec()));
-
- REQUIRE(install_plan.size() == 2);
- check_name_and_version(install_plan.install_actions[0], "a", {"1", 0});
- check_name_and_version(install_plan.install_actions[1], "b", {"1", 0});
-}
-
-TEST_CASE ("version install different vars", "[versionplan]")
-{
- MockVersionedPortfileProvider vp;
-
- auto& b_scf = vp.emplace("b", {"1", 0}, Scheme::Relaxed).source_control_file;
- b_scf->core_paragraph->dependencies.push_back({"a", {}, parse_platform("!linux")});
-
- auto& a_scf = vp.emplace("a", {"1", 0}, Scheme::Relaxed).source_control_file;
- a_scf->core_paragraph->dependencies.push_back({"c", {}, parse_platform("linux")});
-
- vp.emplace("c", {"1", 0}, Scheme::Relaxed);
-
- MockCMakeVarProvider var_provider;
- var_provider.dep_info_vars[PackageSpec{"a", Test::X86_WINDOWS}] = {{"VCPKG_CMAKE_SYSTEM_NAME", "Linux"}};
-
- MockBaselineProvider bp;
- bp.v["a"] = {"1", 0};
- bp.v["b"] = {"1", 0};
- bp.v["c"] = {"1", 0};
-
- auto install_plan = unwrap(create_versioned_install_plan(vp, bp, var_provider, {{"b"}}, {}, toplevel_spec()));
-
- REQUIRE(install_plan.size() == 3);
- check_name_and_version(install_plan.install_actions[0], "c", {"1", 0});
- check_name_and_version(install_plan.install_actions[1], "a", {"1", 0});
- check_name_and_version(install_plan.install_actions[2], "b", {"1", 0});
-}
-
-TEST_CASE ("version install qualified features", "[versionplan]")
-{
- MockVersionedPortfileProvider vp;
-
- auto& b_scf = vp.emplace("b", {"1", 0}, Scheme::Relaxed).source_control_file;
- b_scf->core_paragraph->default_features.push_back("x");
- b_scf->feature_paragraphs.push_back(make_fpgh("x"));
- b_scf->feature_paragraphs.back()->dependencies.push_back({"a", {}, parse_platform("!linux")});
-
- auto& a_scf = vp.emplace("a", {"1", 0}, Scheme::Relaxed).source_control_file;
- a_scf->core_paragraph->default_features.push_back("y");
- a_scf->feature_paragraphs.push_back(make_fpgh("y"));
- a_scf->feature_paragraphs.back()->dependencies.push_back({"c", {}, parse_platform("linux")});
-
- auto& c_scf = vp.emplace("c", {"1", 0}, Scheme::Relaxed).source_control_file;
- c_scf->core_paragraph->default_features.push_back("z");
- c_scf->feature_paragraphs.push_back(make_fpgh("z"));
- c_scf->feature_paragraphs.back()->dependencies.push_back({"d", {}, parse_platform("linux")});
-
- vp.emplace("d", {"1", 0}, Scheme::Relaxed);
-
- MockCMakeVarProvider var_provider;
- var_provider.dep_info_vars[PackageSpec{"a", Test::X86_WINDOWS}] = {{"VCPKG_CMAKE_SYSTEM_NAME", "Linux"}};
-
- MockBaselineProvider bp;
- bp.v["a"] = {"1", 0};
- bp.v["b"] = {"1", 0};
- bp.v["c"] = {"1", 0};
- bp.v["d"] = {"1", 0};
-
- auto install_plan = unwrap(create_versioned_install_plan(vp, bp, var_provider, {{"b"}}, {}, toplevel_spec()));
-
- REQUIRE(install_plan.size() == 3);
- check_name_and_version(install_plan.install_actions[0], "c", {"1", 0}, {"z"});
- check_name_and_version(install_plan.install_actions[1], "a", {"1", 0}, {"y"});
- check_name_and_version(install_plan.install_actions[2], "b", {"1", 0}, {"x"});
-}
-
-TEST_CASE ("version install self features", "[versionplan]")
-{
- MockBaselineProvider bp;
- bp.v["a"] = {"1", 0};
-
- MockVersionedPortfileProvider vp;
- auto& a_scf = vp.emplace("a", {"1", 0}).source_control_file;
- a_scf->feature_paragraphs.push_back(make_fpgh("x"));
- a_scf->feature_paragraphs.back()->dependencies.push_back({"a", {"core", "y"}});
- a_scf->feature_paragraphs.push_back(make_fpgh("y"));
- a_scf->feature_paragraphs.push_back(make_fpgh("z"));
-
- MockCMakeVarProvider var_provider;
-
- auto install_plan =
- unwrap(create_versioned_install_plan(vp, bp, var_provider, {{"a", {"x"}}}, {}, toplevel_spec()));
-
- REQUIRE(install_plan.size() == 1);
- check_name_and_version(install_plan.install_actions[0], "a", {"1", 0}, {"x", "y"});
-}
-
-TEST_CASE ("version overlay ports", "[versionplan]")
-{
- MockBaselineProvider bp;
- bp.v["a"] = {"1", 0};
- bp.v["b"] = {"1", 0};
- bp.v["c"] = {"1", 0};
-
- MockVersionedPortfileProvider vp;
- vp.emplace("a", {"1", 0});
- vp.emplace("a", {"1", 1});
- vp.emplace("a", {"2", 0});
- vp.emplace("b", {"1", 0}).source_control_file->core_paragraph->dependencies.emplace_back(Dependency{"a"});
- vp.emplace("c", {"1", 0})
- .source_control_file->core_paragraph->dependencies.emplace_back(
- Dependency{"a", {}, {}, {Constraint::Type::Minimum, "1", 1}});
-
- MockCMakeVarProvider var_provider;
-
- MockOverlayProvider oprovider;
- oprovider.emplace("a", {"overlay", 0});
-
- SECTION ("no baseline")
- {
- const MockBaselineProvider empty_bp;
-
- auto install_plan = unwrap(Dependencies::create_versioned_install_plan(
- vp, empty_bp, oprovider, var_provider, {{"a"}}, {}, toplevel_spec()));
-
- REQUIRE(install_plan.size() == 1);
- check_name_and_version(install_plan.install_actions[0], "a", {"overlay", 0});
- }
-
- SECTION ("transitive")
- {
- auto install_plan = unwrap(
- Dependencies::create_versioned_install_plan(vp, bp, oprovider, var_provider, {{"b"}}, {}, toplevel_spec()));
-
- REQUIRE(install_plan.size() == 2);
- check_name_and_version(install_plan.install_actions[0], "a", {"overlay", 0});
- check_name_and_version(install_plan.install_actions[1], "b", {"1", 0});
- }
-
- SECTION ("transitive constraint")
- {
- auto install_plan = unwrap(
- Dependencies::create_versioned_install_plan(vp, bp, oprovider, var_provider, {{"c"}}, {}, toplevel_spec()));
-
- REQUIRE(install_plan.size() == 2);
- check_name_and_version(install_plan.install_actions[0], "a", {"overlay", 0});
- check_name_and_version(install_plan.install_actions[1], "c", {"1", 0});
- }
-
- SECTION ("none")
- {
- auto install_plan = unwrap(
- Dependencies::create_versioned_install_plan(vp, bp, oprovider, var_provider, {{"a"}}, {}, toplevel_spec()));
-
- REQUIRE(install_plan.size() == 1);
- check_name_and_version(install_plan.install_actions[0], "a", {"overlay", 0});
- }
- SECTION ("constraint")
- {
- auto install_plan = unwrap(Dependencies::create_versioned_install_plan(
- vp,
- bp,
- oprovider,
- var_provider,
- {
- Dependency{"a", {}, {}, {Constraint::Type::Minimum, "1", 1}},
- },
- {},
- toplevel_spec()));
-
- REQUIRE(install_plan.size() == 1);
- check_name_and_version(install_plan.install_actions[0], "a", {"overlay", 0});
- }
- SECTION ("constraint+override")
- {
- auto install_plan = unwrap(Dependencies::create_versioned_install_plan(
- vp,
- bp,
- oprovider,
- var_provider,
- {
- Dependency{"a", {}, {}, {Constraint::Type::Minimum, "1", 1}},
- },
- {
- DependencyOverride{"a", {"2", 0}},
- },
- toplevel_spec()));
-
- REQUIRE(install_plan.size() == 1);
- check_name_and_version(install_plan.install_actions[0], "a", {"overlay", 0});
- }
- SECTION ("override")
- {
- auto install_plan = unwrap(Dependencies::create_versioned_install_plan(vp,
- bp,
- oprovider,
- var_provider,
- {
- Dependency{"a"},
- },
- {
- DependencyOverride{"a", {"2", 0}},
- },
- toplevel_spec()));
-
- REQUIRE(install_plan.size() == 1);
- check_name_and_version(install_plan.install_actions[0], "a", {"overlay", 0});
- }
-}
diff --git a/toolsrc/src/vcpkg-test/downloads.cpp b/toolsrc/src/vcpkg-test/downloads.cpp
deleted file mode 100644
index b182e46d6..000000000
--- a/toolsrc/src/vcpkg-test/downloads.cpp
+++ /dev/null
@@ -1,59 +0,0 @@
-#include <catch2/catch.hpp>
-
-#include <vcpkg/base/downloads.h>
-
-using namespace vcpkg;
-
-TEST_CASE ("Downloads::details::split_uri_view", "[downloads]")
-{
- {
- auto x = Downloads::details::split_uri_view("https://github.com/Microsoft/vcpkg");
- REQUIRE(x.has_value());
- REQUIRE(x.get()->scheme == "https");
- REQUIRE(x.get()->authority.value_or("") == "//github.com");
- REQUIRE(x.get()->path_query_fragment == "/Microsoft/vcpkg");
- }
- {
- auto x = Downloads::details::split_uri_view("");
- REQUIRE(!x.has_value());
- }
- {
- auto x = Downloads::details::split_uri_view("hello");
- REQUIRE(!x.has_value());
- }
- {
- auto x = Downloads::details::split_uri_view("file:");
- REQUIRE(x.has_value());
- REQUIRE(x.get()->scheme == "file");
- REQUIRE(!x.get()->authority.has_value());
- REQUIRE(x.get()->path_query_fragment == "");
- }
- {
- auto x = Downloads::details::split_uri_view("file:path");
- REQUIRE(x.has_value());
- REQUIRE(x.get()->scheme == "file");
- REQUIRE(!x.get()->authority.has_value());
- REQUIRE(x.get()->path_query_fragment == "path");
- }
- {
- auto x = Downloads::details::split_uri_view("file:/path");
- REQUIRE(x.has_value());
- REQUIRE(x.get()->scheme == "file");
- REQUIRE(!x.get()->authority.has_value());
- REQUIRE(x.get()->path_query_fragment == "/path");
- }
- {
- auto x = Downloads::details::split_uri_view("file://user:pw@host");
- REQUIRE(x.has_value());
- REQUIRE(x.get()->scheme == "file");
- REQUIRE(x.get()->authority.value_or({}) == "//user:pw@host");
- REQUIRE(x.get()->path_query_fragment == "");
- }
- {
- auto x = Downloads::details::split_uri_view("ftp://host:port/");
- REQUIRE(x.has_value());
- REQUIRE(x.get()->scheme == "ftp");
- REQUIRE(x.get()->authority.value_or({}) == "//host:port");
- REQUIRE(x.get()->path_query_fragment == "/");
- }
-}
diff --git a/toolsrc/src/vcpkg-test/files.cpp b/toolsrc/src/vcpkg-test/files.cpp
deleted file mode 100644
index ffa72d0fb..000000000
--- a/toolsrc/src/vcpkg-test/files.cpp
+++ /dev/null
@@ -1,406 +0,0 @@
-#include <catch2/catch.hpp>
-
-#include <vcpkg/base/files.h>
-#include <vcpkg/base/strings.h>
-
-#include <iostream>
-#include <random>
-#include <vector>
-
-#include <vcpkg-test/util.h>
-
-using vcpkg::Test::AllowSymlinks;
-using vcpkg::Test::base_temporary_directory;
-using vcpkg::Test::can_create_symlinks;
-
-#define CHECK_EC_ON_FILE(file, ec) \
- do \
- { \
- if (ec) \
- { \
- FAIL(file << ": " << ec.message()); \
- } \
- } while (0)
-
-namespace
-{
- using uid_t = std::uniform_int_distribution<std::uint64_t>;
- using urbg_t = std::mt19937_64;
-
- urbg_t get_urbg(std::uint64_t index)
- {
- // smallest prime > 2**63 - 1
- return urbg_t{index + 9223372036854775837ULL};
- }
-
- std::string get_random_filename(urbg_t& urbg) { return vcpkg::Strings::b32_encode(uid_t{}(urbg)); }
-
- struct MaxDepth
- {
- std::uint64_t i;
- explicit MaxDepth(std::uint64_t i) : i(i) { }
- operator uint64_t() const { return i; }
- };
-
- struct Width
- {
- std::uint64_t i;
- explicit Width(std::uint64_t i) : i(i) { }
- operator uint64_t() const { return i; }
- };
-
- struct CurrentDepth
- {
- std::uint64_t i;
- explicit CurrentDepth(std::uint64_t i) : i(i) { }
- operator uint64_t() const { return i; }
- CurrentDepth incremented() const { return CurrentDepth{i + 1}; }
- };
-
- void create_directory_tree(urbg_t& urbg,
- vcpkg::Files::Filesystem& fs,
- const fs::path& base,
- MaxDepth max_depth,
- AllowSymlinks allow_symlinks = AllowSymlinks::Yes,
- Width width = Width{5},
- CurrentDepth current_depth = CurrentDepth{0})
- {
- // we want ~70% of our "files" to be directories, and then a third
- // each of the remaining ~30% to be regular files, directory symlinks,
- // and regular symlinks
- constexpr std::uint64_t directory_min_tag = 0;
- constexpr std::uint64_t directory_max_tag = 6;
- constexpr std::uint64_t regular_file_tag = 7;
- constexpr std::uint64_t regular_symlink_tag = 8;
- constexpr std::uint64_t directory_symlink_tag = 9;
-
- allow_symlinks = AllowSymlinks{allow_symlinks && can_create_symlinks()};
-
- // if we're at the max depth, we only want to build non-directories
- std::uint64_t file_type;
- if (current_depth >= max_depth)
- {
- file_type = uid_t{regular_file_tag, directory_symlink_tag}(urbg);
- }
- else if (current_depth < 2)
- {
- file_type = directory_min_tag;
- }
- else
- {
- file_type = uid_t{directory_min_tag, regular_symlink_tag}(urbg);
- }
-
- if (!allow_symlinks && file_type > regular_file_tag)
- {
- file_type = regular_file_tag;
- }
-
- std::error_code ec;
- if (file_type <= directory_max_tag)
- {
- fs.create_directory(base, ec);
- if (ec)
- {
- CHECK_EC_ON_FILE(base, ec);
- }
-
- for (std::uint64_t i = 0; i < width; ++i)
- {
- create_directory_tree(urbg,
- fs,
- base / get_random_filename(urbg),
- max_depth,
- allow_symlinks,
- width,
- current_depth.incremented());
- }
- }
- else if (file_type == regular_file_tag)
- {
- // regular file
- fs.write_contents(base, "", ec);
- }
- else if (file_type == regular_symlink_tag)
- {
- // regular symlink
- auto base_link = base;
- base_link.replace_filename(fs::u8string(base.filename()) + "-orig");
- fs.write_contents(base_link, "", ec);
- CHECK_EC_ON_FILE(base_link, ec);
- vcpkg::Test::create_symlink(base_link, base, ec);
- }
- else // file_type == directory_symlink_tag
- {
- // directory symlink
- auto parent = base;
- parent.remove_filename();
- vcpkg::Test::create_directory_symlink(parent, base, ec);
- }
-
- CHECK_EC_ON_FILE(base, ec);
- REQUIRE(fs::exists(fs.symlink_status(base, ec)));
- CHECK_EC_ON_FILE(base, ec);
- }
-
- vcpkg::Files::Filesystem& setup()
- {
- auto& fs = vcpkg::Files::get_real_filesystem();
-
- std::error_code ec;
- fs.create_directory(base_temporary_directory(), ec);
- CHECK_EC_ON_FILE(base_temporary_directory(), ec);
-
- return fs;
- }
-}
-
-TEST_CASE ("fs::combine works correctly", "[filesystem][files]")
-{
- using namespace fs;
- using namespace vcpkg::Files;
- CHECK(combine(u8path("/a/b"), u8path("c/d")) == u8path("/a/b/c/d"));
- CHECK(combine(u8path("a/b"), u8path("c/d")) == u8path("a/b/c/d"));
- CHECK(combine(u8path("/a/b"), u8path("/c/d")) == u8path("/c/d"));
-
-#if defined(_WIN32)
- CHECK(combine(u8path("C:/a/b"), u8path("c/d")) == u8path("C:/a/b/c/d"));
- CHECK(combine(u8path("C:a/b"), u8path("c/d")) == u8path("C:a/b/c/d"));
- CHECK(combine(u8path("C:a/b"), u8path("/c/d")) == u8path("C:/c/d"));
- CHECK(combine(u8path("C:/a/b"), u8path("/c/d")) == u8path("C:/c/d"));
- CHECK(combine(u8path("C:/a/b"), u8path("D:/c/d")) == u8path("D:/c/d"));
- CHECK(combine(u8path("C:/a/b"), u8path("D:c/d")) == u8path("D:c/d"));
- CHECK(combine(u8path("C:/a/b"), u8path("C:c/d")) == u8path("C:/a/b/c/d"));
-#endif
-}
-
-TEST_CASE ("remove all", "[files]")
-{
- auto urbg = get_urbg(0);
-
- auto& fs = setup();
-
- fs::path temp_dir = base_temporary_directory() / get_random_filename(urbg);
- INFO("temp dir is: " << temp_dir);
-
- create_directory_tree(urbg, fs, temp_dir, MaxDepth{5});
-
- std::error_code ec;
- fs::path fp;
- fs.remove_all(temp_dir, ec, fp);
- CHECK_EC_ON_FILE(fp, ec);
-
- REQUIRE_FALSE(fs.exists(temp_dir, ec));
- CHECK_EC_ON_FILE(temp_dir, ec);
-}
-
-TEST_CASE ("lexically_normal", "[files]")
-{
- const auto lexically_normal = [](const char* s) { return fs::lexically_normal(fs::u8path(s)); };
- const auto native = [](const char* s) { return std::move(fs::u8path(s).make_preferred()); };
- CHECK(fs::lexically_normal(fs::path()).native() == fs::path().native());
-
- // these test cases are taken from the MS STL tests
- CHECK(lexically_normal("cat/./dog/..").native() == native("cat/").native());
- CHECK(lexically_normal("cat/.///dog/../").native() == native("cat/").native());
-
- CHECK(lexically_normal("cat/./dog/..").native() == native("cat/").native());
- CHECK(lexically_normal("cat/.///dog/../").native() == native("cat/").native());
-
- CHECK(lexically_normal(".").native() == native(".").native());
- CHECK(lexically_normal("./").native() == native(".").native());
- CHECK(lexically_normal("./.").native() == native(".").native());
- CHECK(lexically_normal("././").native() == native(".").native());
-
- CHECK(lexically_normal("../../..").native() == native("../../..").native());
- CHECK(lexically_normal("../../../").native() == native("../../..").native());
-
- CHECK(lexically_normal("../../../a/b/c").native() == native("../../../a/b/c").native());
-
- CHECK(lexically_normal("/../../..").native() == native("/").native());
- CHECK(lexically_normal("/../../../").native() == native("/").native());
-
- CHECK(lexically_normal("/../../../a/b/c").native() == native("/a/b/c").native());
-
- CHECK(lexically_normal("a/..").native() == native(".").native());
- CHECK(lexically_normal("a/../").native() == native(".").native());
-
-#if defined(_WIN32)
- CHECK(lexically_normal(R"(X:)").native() == LR"(X:)");
-
- CHECK(lexically_normal(R"(X:DriveRelative)").native() == LR"(X:DriveRelative)");
-
- CHECK(lexically_normal(R"(X:\)").native() == LR"(X:\)");
- CHECK(lexically_normal(R"(X:/)").native() == LR"(X:\)");
- CHECK(lexically_normal(R"(X:\\\)").native() == LR"(X:\)");
- CHECK(lexically_normal(R"(X:///)").native() == LR"(X:\)");
-
- CHECK(lexically_normal(R"(X:\DosAbsolute)").native() == LR"(X:\DosAbsolute)");
- CHECK(lexically_normal(R"(X:/DosAbsolute)").native() == LR"(X:\DosAbsolute)");
- CHECK(lexically_normal(R"(X:\\\DosAbsolute)").native() == LR"(X:\DosAbsolute)");
- CHECK(lexically_normal(R"(X:///DosAbsolute)").native() == LR"(X:\DosAbsolute)");
-
- CHECK(lexically_normal(R"(\RootRelative)").native() == LR"(\RootRelative)");
- CHECK(lexically_normal(R"(/RootRelative)").native() == LR"(\RootRelative)");
- CHECK(lexically_normal(R"(\\\RootRelative)").native() == LR"(\RootRelative)");
- CHECK(lexically_normal(R"(///RootRelative)").native() == LR"(\RootRelative)");
-
- CHECK(lexically_normal(R"(\\server\share)").native() == LR"(\\server\share)");
- CHECK(lexically_normal(R"(//server/share)").native() == LR"(\\server\share)");
- CHECK(lexically_normal(R"(\\server\\\share)").native() == LR"(\\server\share)");
- CHECK(lexically_normal(R"(//server///share)").native() == LR"(\\server\share)");
-
- CHECK(lexically_normal(R"(\\?\device)").native() == LR"(\\?\device)");
- CHECK(lexically_normal(R"(//?/device)").native() == LR"(\\?\device)");
-
- CHECK(lexically_normal(R"(\??\device)").native() == LR"(\??\device)");
- CHECK(lexically_normal(R"(/??/device)").native() == LR"(\??\device)");
-
- CHECK(lexically_normal(R"(\\.\device)").native() == LR"(\\.\device)");
- CHECK(lexically_normal(R"(//./device)").native() == LR"(\\.\device)");
-
- CHECK(lexically_normal(R"(\\?\UNC\server\share)").native() == LR"(\\?\UNC\server\share)");
- CHECK(lexically_normal(R"(//?/UNC/server/share)").native() == LR"(\\?\UNC\server\share)");
-
- CHECK(lexically_normal(R"(C:\a/b\\c\/d/\e//f)").native() == LR"(C:\a\b\c\d\e\f)");
-
- CHECK(lexically_normal(R"(C:\meow\)").native() == LR"(C:\meow\)");
- CHECK(lexically_normal(R"(C:\meow/)").native() == LR"(C:\meow\)");
- CHECK(lexically_normal(R"(C:\meow\\)").native() == LR"(C:\meow\)");
- CHECK(lexically_normal(R"(C:\meow\/)").native() == LR"(C:\meow\)");
- CHECK(lexically_normal(R"(C:\meow/\)").native() == LR"(C:\meow\)");
- CHECK(lexically_normal(R"(C:\meow//)").native() == LR"(C:\meow\)");
-
- CHECK(lexically_normal(R"(C:\a\.\b\.\.\c\.\.\.)").native() == LR"(C:\a\b\c\)");
- CHECK(lexically_normal(R"(C:\a\.\b\.\.\c\.\.\.\)").native() == LR"(C:\a\b\c\)");
-
- CHECK(lexically_normal(R"(C:\a\b\c\d\e\..\f\..\..\..\g\h)").native() == LR"(C:\a\b\g\h)");
-
- CHECK(lexically_normal(R"(C:\a\b\c\d\e\..\f\..\..\..\g\h\..)").native() == LR"(C:\a\b\g\)");
- CHECK(lexically_normal(R"(C:\a\b\c\d\e\..\f\..\..\..\g\h\..\)").native() == LR"(C:\a\b\g\)");
- CHECK(lexically_normal(
- R"(/\server/\share/\a/\b/\c/\./\./\d/\../\../\../\../\../\../\../\other/x/y/z/.././..\meow.txt)")
- .native() == LR"(\\server\other\x\meow.txt)");
-#endif
-}
-
-#if defined(_WIN32)
-TEST_CASE ("win32_fix_path_case", "[files]")
-{
- using vcpkg::Files::win32_fix_path_case;
-
- // This test assumes that the Windows directory is C:\Windows
-
- CHECK(win32_fix_path_case(L"") == L"");
-
- CHECK(win32_fix_path_case(L"C:") == L"C:");
- CHECK(win32_fix_path_case(L"c:") == L"C:");
- CHECK(win32_fix_path_case(L"C:/") == L"C:\\");
- CHECK(win32_fix_path_case(L"C:\\") == L"C:\\");
- CHECK(win32_fix_path_case(L"c:\\") == L"C:\\");
- CHECK(win32_fix_path_case(L"C:\\WiNdOws") == L"C:\\Windows");
- CHECK(win32_fix_path_case(L"c:\\WiNdOws\\") == L"C:\\Windows\\");
- CHECK(win32_fix_path_case(L"C://///////WiNdOws") == L"C:\\Windows");
- CHECK(win32_fix_path_case(L"c:\\/\\/WiNdOws\\/") == L"C:\\Windows\\");
-
- auto& fs = vcpkg::Files::get_real_filesystem();
- auto original_cwd = fs.current_path(VCPKG_LINE_INFO);
- fs.current_path(L"C:\\", VCPKG_LINE_INFO);
- CHECK(win32_fix_path_case(L"\\") == L"\\");
- CHECK(win32_fix_path_case(L"\\/\\WiNdOws") == L"\\Windows");
- CHECK(win32_fix_path_case(L"\\WiNdOws") == L"\\Windows");
- CHECK(win32_fix_path_case(L"\\WiNdOws") == L"\\Windows");
- CHECK(win32_fix_path_case(L"c:WiNdOws") == L"C:Windows");
- CHECK(win32_fix_path_case(L"c:WiNdOws/system32") == L"C:Windows\\System32");
- fs.current_path(original_cwd, VCPKG_LINE_INFO);
-
- fs.create_directories("SuB/Dir/Ectory", VCPKG_LINE_INFO);
- CHECK(win32_fix_path_case(L"sub") == L"SuB");
- CHECK(win32_fix_path_case(L"SUB") == L"SuB");
- CHECK(win32_fix_path_case(L"sub/") == L"SuB\\");
- CHECK(win32_fix_path_case(L"sub/dir") == L"SuB\\Dir");
- CHECK(win32_fix_path_case(L"sub/dir/") == L"SuB\\Dir\\");
- CHECK(win32_fix_path_case(L"sub/dir/ectory") == L"SuB\\Dir\\Ectory");
- CHECK(win32_fix_path_case(L"sub/dir/ectory/") == L"SuB\\Dir\\Ectory\\");
- fs.remove_all("SuB", VCPKG_LINE_INFO);
-
- CHECK(win32_fix_path_case(L"//nonexistent_server\\nonexistent_share\\") ==
- L"\\\\nonexistent_server\\nonexistent_share\\");
- CHECK(win32_fix_path_case(L"\\\\nonexistent_server\\nonexistent_share\\") ==
- L"\\\\nonexistent_server\\nonexistent_share\\");
- CHECK(win32_fix_path_case(L"\\\\nonexistent_server\\nonexistent_share") ==
- L"\\\\nonexistent_server\\nonexistent_share");
-
- CHECK(win32_fix_path_case(L"///three_slashes_not_a_server\\subdir\\") == L"\\three_slashes_not_a_server\\subdir\\");
-
- CHECK(win32_fix_path_case(L"\\??\\c:\\WiNdOws") == L"\\??\\c:\\WiNdOws");
- CHECK(win32_fix_path_case(L"\\\\?\\c:\\WiNdOws") == L"\\\\?\\c:\\WiNdOws");
- CHECK(win32_fix_path_case(L"\\\\.\\c:\\WiNdOws") == L"\\\\.\\c:\\WiNdOws");
- CHECK(win32_fix_path_case(L"c:\\/\\/Nonexistent\\/path/here") == L"C:\\Nonexistent\\path\\here");
-}
-#endif // _WIN32
-
-#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
-TEST_CASE ("remove all -- benchmarks", "[files][!benchmark]")
-{
- auto urbg = get_urbg(1);
- auto& fs = setup();
-
- struct
- {
- urbg_t& urbg;
- vcpkg::Files::Filesystem& fs;
-
- void operator()(Catch::Benchmark::Chronometer& meter, MaxDepth max_depth, AllowSymlinks allow_symlinks) const
- {
- std::vector<fs::path> temp_dirs;
- temp_dirs.resize(meter.runs());
-
- std::generate(begin(temp_dirs), end(temp_dirs), [&] {
- fs::path temp_dir = base_temporary_directory() / get_random_filename(urbg);
- create_directory_tree(urbg, fs, temp_dir, max_depth, allow_symlinks);
- return temp_dir;
- });
-
- meter.measure([&](int run) {
- std::error_code ec;
- fs::path fp;
- const auto& temp_dir = temp_dirs[run];
-
- fs.remove_all(temp_dir, ec, fp);
- CHECK_EC_ON_FILE(fp, ec);
- });
-
- for (const auto& dir : temp_dirs)
- {
- std::error_code ec;
- REQUIRE_FALSE(fs.exists(dir, ec));
- CHECK_EC_ON_FILE(dir, ec);
- }
- }
- } do_benchmark = {urbg, fs};
-
- BENCHMARK_ADVANCED("small directory, no symlinks")(Catch::Benchmark::Chronometer meter)
- {
- do_benchmark(meter, MaxDepth{2}, AllowSymlinks::No);
- };
-
- BENCHMARK_ADVANCED("large directory, no symlinks")(Catch::Benchmark::Chronometer meter)
- {
- do_benchmark(meter, MaxDepth{5}, AllowSymlinks::No);
- };
-
- if (can_create_symlinks())
- {
- BENCHMARK_ADVANCED("small directory, symlinks")(Catch::Benchmark::Chronometer meter)
- {
- do_benchmark(meter, MaxDepth{2}, AllowSymlinks::Yes);
- };
-
- BENCHMARK_ADVANCED("large directory, symlinks")(Catch::Benchmark::Chronometer meter)
- {
- do_benchmark(meter, MaxDepth{5}, AllowSymlinks::Yes);
- };
- }
-}
-#endif
diff --git a/toolsrc/src/vcpkg-test/hash.cpp b/toolsrc/src/vcpkg-test/hash.cpp
deleted file mode 100644
index 9f3ccc25e..000000000
--- a/toolsrc/src/vcpkg-test/hash.cpp
+++ /dev/null
@@ -1,276 +0,0 @@
-#include <catch2/catch.hpp>
-
-#include <vcpkg/base/hash.h>
-
-#include <algorithm>
-#include <iostream>
-#include <iterator>
-#include <map>
-
-namespace Hash = vcpkg::Hash;
-using vcpkg::StringView;
-
-// Require algorithm: Hash::Algorithm::Tag to be in scope
-#define CHECK_HASH(size, value, real_hash) \
- do \
- { \
- unsigned char data[size]; \
- std::fill(std::begin(data), std::end(data), static_cast<unsigned char>(value)); \
- const auto hash = Hash::get_bytes_hash(data, data + size, algorithm); \
- REQUIRE(hash == real_hash); \
- } while (0)
-
-#define CHECK_HASH_OF(data, real_hash) \
- do \
- { \
- const auto hash = Hash::get_bytes_hash(std::begin(data), std::end(data), algorithm); \
- REQUIRE(hash == real_hash); \
- } while (0)
-
-#define CHECK_HASH_STRING(data, real_hash) \
- do \
- { \
- const auto hash = Hash::get_string_hash(data, algorithm); \
- REQUIRE(hash == real_hash); \
- } while (0)
-
-// Requires hasher: std::unique_ptr<Hash::Hasher> to be in scope
-#define CHECK_HASH_LARGE(size, value, real_hash) \
- do \
- { \
- hasher->clear(); \
- std::uint64_t remaining = size; \
- unsigned char buffer[512]; \
- std::fill(std::begin(buffer), std::end(buffer), static_cast<unsigned char>(value)); \
- while (remaining) \
- { \
- if (remaining < 512) \
- { \
- hasher->add_bytes(std::begin(buffer), std::begin(buffer) + remaining); \
- remaining = 0; \
- } \
- else \
- { \
- hasher->add_bytes(std::begin(buffer), std::end(buffer)); \
- remaining -= 512; \
- } \
- } \
- REQUIRE(hasher->get_hash() == real_hash); \
- } while (0)
-
-TEST_CASE ("SHA1: basic tests", "[hash][sha1]")
-{
- const auto algorithm = Hash::Algorithm::Sha1;
-
- CHECK_HASH_STRING("", "da39a3ee5e6b4b0d3255bfef95601890afd80709");
- CHECK_HASH_STRING(";", "2d14ab97cc3dc294c51c0d6814f4ea45f4b4e312");
- CHECK_HASH_STRING("asdifasdfnas", "b77eb8a1b4c2ef6716d7d302647e4511b1a638a6");
- CHECK_HASH_STRING("asdfanvoinaoifawenflawenfiwnofvnasfjvnaslkdfjlkasjdfanm,"
- "werflawoienfowanevoinwai32910u2740918741o;j;wejfqwioaher9283hrpf;asd",
- "c69bcd30c196c7050906d212722dd7a7659aad04");
-}
-
-TEST_CASE ("SHA1: NIST test cases (small)", "[hash][sha1]")
-{
- const auto algorithm = Hash::Algorithm::Sha1;
-
- CHECK_HASH_STRING("abc", "a9993e364706816aba3e25717850c26c9cd0d89d");
- CHECK_HASH_STRING("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
- "84983e441c3bd26ebaae4aa1f95129e5e54670f1");
-}
-
-TEST_CASE ("SHA256: basic tests", "[hash][sha256]")
-{
- const auto algorithm = Hash::Algorithm::Sha256;
-
- CHECK_HASH_STRING("", "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855");
- CHECK_HASH_STRING(";", "41b805ea7ac014e23556e98bb374702a08344268f92489a02f0880849394a1e4");
- CHECK_HASH_STRING("asdifasdfnas", "2bb1fb910831fdc11d5a3996425a84ace27aeb81c9c20ace9f60ac1b3218b291");
- CHECK_HASH_STRING("asdfanvoinaoifawenflawenfiwnofvnasfjvnaslkdfjlkasjdfanm,"
- "werflawoienfowanevoinwai32910u2740918741o;j;wejfqwioaher9283hrpf;asd",
- "10c98034b424d4e40ca933bc524ea38b4e53290d76e8b38edc4ea2fec7f529aa");
-}
-
-TEST_CASE ("SHA256: NIST test cases (small)", "[hash][sha256]")
-{
- const auto algorithm = Hash::Algorithm::Sha256;
-
- CHECK_HASH(1, 0xbd, "68325720aabd7c82f30f554b313d0570c95accbb7dc4b5aae11204c08ffe732b");
- {
- const unsigned char data[] = {0xc9, 0x8c, 0x8e, 0x55};
- CHECK_HASH_OF(data, "7abc22c0ae5af26ce93dbb94433a0e0b2e119d014f8e7f65bd56c61ccccd9504");
- }
- CHECK_HASH(55, 0, "02779466cdec163811d078815c633f21901413081449002f24aa3e80f0b88ef7");
- CHECK_HASH(56, 0, "d4817aa5497628e7c77e6b606107042bbba3130888c5f47a375e6179be789fbb");
- CHECK_HASH(57, 0, "65a16cb7861335d5ace3c60718b5052e44660726da4cd13bb745381b235a1785");
- CHECK_HASH(64, 0, "f5a5fd42d16a20302798ef6ed309979b43003d2320d9f0e8ea9831a92759fb4b");
- CHECK_HASH(1000, 0, "541b3e9daa09b20bf85fa273e5cbd3e80185aa4ec298e765db87742b70138a53");
- CHECK_HASH(1000, 'A', "c2e686823489ced2017f6059b8b239318b6364f6dcd835d0a519105a1eadd6e4");
- CHECK_HASH(1005, 'U', "f4d62ddec0f3dd90ea1380fa16a5ff8dc4c54b21740650f24afc4120903552b0");
-}
-
-TEST_CASE ("SHA512: NIST test cases (small)", "[hash][sha512]")
-{
- const auto algorithm = Hash::Algorithm::Sha512;
-
- CHECK_HASH_STRING("",
- "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f"
- "63b931bd47417a81a538327af927da3e");
-
- CHECK_HASH(111,
- 0,
- "77ddd3a542e530fd047b8977c657ba6ce72f1492e360b2b2212cd264e75ec03882e4ff0525517ab4207d14c70c2259ba88d4d33"
- "5ee0e7e20543d22102ab1788c");
- CHECK_HASH(112,
- 0,
- "2be2e788c8a8adeaa9c89a7f78904cacea6e39297d75e0573a73c756234534d6627ab4156b48a6657b29ab8beb73334040ad39e"
- "ad81446bb09c70704ec707952");
- CHECK_HASH(113,
- 0,
- "0e67910bcf0f9ccde5464c63b9c850a12a759227d16b040d98986d54253f9f34322318e56b8feb86c5fb2270ed87f31252f7f68"
- "493ee759743909bd75e4bb544");
- CHECK_HASH(122,
- 0,
- "4f3f095d015be4a7a7cc0b8c04da4aa09e74351e3a97651f744c23716ebd9b3e822e5077a01baa5cc0ed45b9249e88ab343d433"
- "3539df21ed229da6f4a514e0f");
- CHECK_HASH(1000,
- 0,
- "ca3dff61bb23477aa6087b27508264a6f9126ee3a004f53cb8db942ed345f2f2d229b4b59c859220a1cf1913f34248e3803bab6"
- "50e849a3d9a709edc09ae4a76");
- CHECK_HASH(1000,
- 'A',
- "329c52ac62d1fe731151f2b895a00475445ef74f50b979c6f7bb7cae349328c1d4cb4f7261a0ab43f936a24b000651d4a824fcd"
- "d577f211aef8f806b16afe8af");
- CHECK_HASH(1005,
- 'U',
- "59f5e54fe299c6a8764c6b199e44924a37f59e2b56c3ebad939b7289210dc8e4c21b9720165b0f4d4374c90f1bf4fb4a5ace17a"
- "1161798015052893a48c3d161");
-}
-
-TEST_CASE ("SHA256: NIST test cases (large)", "[.][hash-expensive][sha256-expensive]")
-{
- auto hasher = Hash::get_hasher_for(Hash::Algorithm::Sha256);
- CHECK_HASH_LARGE(1'000'000, 0, "d29751f2649b32ff572b5e0a9f541ea660a50f94ff0beedfb0b692b924cc8025");
- CHECK_HASH_LARGE(0x2000'0000, 'Z', "15a1868c12cc53951e182344277447cd0979536badcc512ad24c67e9b2d4f3dd");
- CHECK_HASH_LARGE(0x4100'0000, 0, "461c19a93bd4344f9215f5ec64357090342bc66b15a148317d276e31cbc20b53");
- CHECK_HASH_LARGE(0x6000'003E, 'B', "c23ce8a7895f4b21ec0daf37920ac0a262a220045a03eb2dfed48ef9b05aabea");
-}
-
-TEST_CASE ("SHA512: NIST test cases (large)", "[.][hash-expensive][sha512-expensive]")
-{
- auto hasher = Hash::get_hasher_for(Hash::Algorithm::Sha512);
- CHECK_HASH_LARGE(1'000'000,
- 0,
- "ce044bc9fd43269d5bbc946cbebc3bb711341115cc4abdf2edbc3ff2c57ad4b15deb699bda257fea5aef9c6e55fcf4cf9"
- "dc25a8c3ce25f2efe90908379bff7ed");
- CHECK_HASH_LARGE(0x2000'0000,
- 'Z',
- "da172279f3ebbda95f6b6e1e5f0ebec682c25d3d93561a1624c2fa9009d64c7e9923f3b46bcaf11d39a531f43297992ba"
- "4155c7e827bd0f1e194ae7ed6de4cac");
- CHECK_HASH_LARGE(0x4100'0000,
- 0,
- "14b1be901cb43549b4d831e61e5f9df1c791c85b50e85f9d6bc64135804ad43ce8402750edbe4e5c0fc170b99cf78b9f4"
- "ecb9c7e02a157911d1bd1832d76784f");
- CHECK_HASH_LARGE(0x6000'003E,
- 'B',
- "fd05e13eb771f05190bd97d62647157ea8f1f6949a52bb6daaedbad5f578ec59b1b8d6c4a7ecb2feca6892b4dc1387716"
- "70a0f3bd577eea326aed40ab7dd58b1");
-}
-
-#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
-using Catch::Benchmark::Chronometer;
-void benchmark_hasher(Chronometer& meter, Hash::Hasher& hasher, std::uint64_t size, unsigned char byte) noexcept
-{
- unsigned char buffer[1024];
- std::fill(std::begin(buffer), std::end(buffer), byte);
-
- meter.measure([&] {
- hasher.clear();
- std::uint64_t remaining = size;
- while (remaining)
- {
- if (remaining < 512)
- {
- hasher.add_bytes(std::begin(buffer), std::begin(buffer) + remaining);
- remaining = 0;
- }
- else
- {
- hasher.add_bytes(std::begin(buffer), std::end(buffer));
- remaining -= 512;
- }
- }
- hasher.get_hash();
- });
-}
-
-TEST_CASE ("SHA1: benchmark", "[.][hash][sha256][!benchmark]")
-{
- using Catch::Benchmark::Chronometer;
-
- auto hasher = Hash::get_hasher_for(Hash::Algorithm::Sha1);
-
- BENCHMARK_ADVANCED("0 x 1'000'000")(Catch::Benchmark::Chronometer meter)
- {
- benchmark_hasher(meter, *hasher, 1'000'000, 0);
- };
- BENCHMARK_ADVANCED("'Z' x 0x2000'0000")(Catch::Benchmark::Chronometer meter)
- {
- benchmark_hasher(meter, *hasher, 0x2000'0000, 'Z');
- };
- BENCHMARK_ADVANCED("0 x 0x4100'0000")(Catch::Benchmark::Chronometer meter)
- {
- benchmark_hasher(meter, *hasher, 0x4100'0000, 0);
- };
- BENCHMARK_ADVANCED("'B' x 0x6000'003E")(Catch::Benchmark::Chronometer meter)
- {
- benchmark_hasher(meter, *hasher, 0x6000'003E, 'B');
- };
-}
-
-TEST_CASE ("SHA256: benchmark", "[.][hash][sha256][!benchmark]")
-{
- using Catch::Benchmark::Chronometer;
-
- auto hasher = Hash::get_hasher_for(Hash::Algorithm::Sha256);
-
- BENCHMARK_ADVANCED("0 x 1'000'000")(Catch::Benchmark::Chronometer meter)
- {
- benchmark_hasher(meter, *hasher, 1'000'000, 0);
- };
- BENCHMARK_ADVANCED("'Z' x 0x2000'0000")(Catch::Benchmark::Chronometer meter)
- {
- benchmark_hasher(meter, *hasher, 0x2000'0000, 'Z');
- };
- BENCHMARK_ADVANCED("0 x 0x4100'0000")(Catch::Benchmark::Chronometer meter)
- {
- benchmark_hasher(meter, *hasher, 0x4100'0000, 0);
- };
- BENCHMARK_ADVANCED("'B' x 0x6000'003E")(Catch::Benchmark::Chronometer meter)
- {
- benchmark_hasher(meter, *hasher, 0x6000'003E, 'B');
- };
-}
-
-TEST_CASE ("SHA512: large -- benchmark", "[.][hash][sha512][!benchmark]")
-{
- auto hasher = Hash::get_hasher_for(Hash::Algorithm::Sha512);
-
- BENCHMARK_ADVANCED("0 x 1'000'000")(Catch::Benchmark::Chronometer meter)
- {
- benchmark_hasher(meter, *hasher, 1'000'000, 0);
- };
- BENCHMARK_ADVANCED("'Z' x 0x2000'0000")(Catch::Benchmark::Chronometer meter)
- {
- benchmark_hasher(meter, *hasher, 0x2000'0000, 'Z');
- };
- BENCHMARK_ADVANCED("0 x 0x4100'0000")(Catch::Benchmark::Chronometer meter)
- {
- benchmark_hasher(meter, *hasher, 0x4100'0000, 0);
- };
- BENCHMARK_ADVANCED("'B' x 0x6000'003E")(Catch::Benchmark::Chronometer meter)
- {
- benchmark_hasher(meter, *hasher, 0x6000'003E, 'B');
- };
-}
-#endif
diff --git a/toolsrc/src/vcpkg-test/json.cpp b/toolsrc/src/vcpkg-test/json.cpp
deleted file mode 100644
index b03fe2aec..000000000
--- a/toolsrc/src/vcpkg-test/json.cpp
+++ /dev/null
@@ -1,241 +0,0 @@
-#include <catch2/catch.hpp>
-
-#include <vcpkg/base/json.h>
-#include <vcpkg/base/unicode.h>
-
-#include <iostream>
-
-#include "math.h"
-
-// TODO: remove this once we switch to C++20 completely
-// This is the worst, but we also can't really deal with it any other way.
-#if __cpp_char8_t
-template<size_t Sz>
-static auto _u8_string_to_char_string(const char8_t (&literal)[Sz]) -> const char (&)[Sz]
-{
- return reinterpret_cast<const char(&)[Sz]>(literal);
-}
-
-#define U8_STR(s) (::vcpkg::Unicode::_u8_string_to_char_string(u8"" s))
-#else
-#define U8_STR(s) (u8"" s)
-#endif
-
-namespace Json = vcpkg::Json;
-using Json::Value;
-
-static std::string mystringify(const Value& val) { return Json::stringify(val, Json::JsonStyle{}); }
-
-TEST_CASE ("JSON stringify weird strings", "[json]")
-{
- std::string str = U8_STR("😀 😁 😂 🤣 😃 😄 😅 😆 😉");
- REQUIRE(mystringify(Value::string(str)) == ('"' + str + "\"\n"));
- REQUIRE(mystringify(Value::string("\xED\xA0\x80")) == "\"\\ud800\"\n"); // unpaired surrogate
-}
-
-TEST_CASE ("JSON parse keywords", "[json]")
-{
- auto res = Json::parse("true");
- REQUIRE(res);
- REQUIRE(res.get()->first.is_boolean());
- REQUIRE(res.get()->first.boolean());
- res = Json::parse(" false ");
- REQUIRE(res);
- REQUIRE(res.get()->first.is_boolean());
- REQUIRE(!res.get()->first.boolean());
- res = Json::parse(" null\t ");
- REQUIRE(res);
- REQUIRE(res.get()->first.is_null());
-}
-
-TEST_CASE ("JSON parse strings", "[json]")
-{
- auto res = Json::parse(R"("")");
- REQUIRE(res);
- REQUIRE(res.get()->first.is_string());
- REQUIRE(res.get()->first.string().size() == 0);
-
- res = Json::parse(R"("\ud800")"); // unpaired surrogate
- REQUIRE(res);
- REQUIRE(res.get()->first.is_string());
- REQUIRE(res.get()->first.string() == "\xED\xA0\x80");
-
- const auto make_json_string = [](vcpkg::StringView sv) { return '"' + sv.to_string() + '"'; };
- const vcpkg::StringView radical = U8_STR("⎷");
- const vcpkg::StringView grin = U8_STR("😁");
-
- res = Json::parse(R"("\uD83D\uDE01")"); // paired surrogates for grin
- REQUIRE(res);
- REQUIRE(res.get()->first.is_string());
- REQUIRE(res.get()->first.string() == grin.to_string());
-
- res = Json::parse(make_json_string(radical)); // character in BMP
- REQUIRE(res);
- REQUIRE(res.get()->first.is_string());
- REQUIRE(res.get()->first.string() == radical);
-
- res = Json::parse(make_json_string(grin)); // character above BMP
- REQUIRE(res);
- REQUIRE(res.get()->first.is_string());
- REQUIRE(res.get()->first.string() == grin);
-}
-
-TEST_CASE ("JSON parse strings with escapes", "[json]")
-{
- auto res = Json::parse(R"("\t")");
- REQUIRE(res);
- REQUIRE(res.get()->first.is_string());
- REQUIRE(res.get()->first.string() == "\t");
-
- res = Json::parse(R"("\\")");
- REQUIRE(res);
- REQUIRE(res.get()->first.is_string());
- REQUIRE(res.get()->first.string() == "\\");
-
- res = Json::parse(R"("\/")");
- REQUIRE(res);
- REQUIRE(res.get()->first.is_string());
- REQUIRE(res.get()->first.string() == "/");
-
- res = Json::parse(R"("\b")");
- REQUIRE(res);
- REQUIRE(res.get()->first.is_string());
- REQUIRE(res.get()->first.string() == "\b");
-
- res = Json::parse(R"("\f")");
- REQUIRE(res);
- REQUIRE(res.get()->first.is_string());
- REQUIRE(res.get()->first.string() == "\f");
-
- res = Json::parse(R"("\n")");
- REQUIRE(res);
- REQUIRE(res.get()->first.is_string());
- REQUIRE(res.get()->first.string() == "\n");
-
- res = Json::parse(R"("\r")");
- REQUIRE(res);
- REQUIRE(res.get()->first.is_string());
- REQUIRE(res.get()->first.string() == "\r");
-
- res = Json::parse(R"("This is a \"test\", hopefully it worked")");
- REQUIRE(res);
- REQUIRE(res.get()->first.is_string());
- REQUIRE(res.get()->first.string() == R"(This is a "test", hopefully it worked)");
-}
-
-TEST_CASE ("JSON parse integers", "[json]")
-{
- auto res = Json::parse("0");
- REQUIRE(res);
- REQUIRE(res.get()->first.is_integer());
- REQUIRE(res.get()->first.integer() == 0);
- res = Json::parse("12345");
- REQUIRE(res);
- REQUIRE(res.get()->first.is_integer());
- REQUIRE(res.get()->first.integer() == 12345);
- res = Json::parse("-12345");
- REQUIRE(res);
- REQUIRE(res.get()->first.is_integer());
- REQUIRE(res.get()->first.integer() == -12345);
- res = Json::parse("9223372036854775807"); // INT64_MAX
- REQUIRE(res);
- REQUIRE(res.get()->first.is_integer());
- REQUIRE(res.get()->first.integer() == 9223372036854775807);
- res = Json::parse("-9223372036854775808");
- REQUIRE(res);
- REQUIRE(res.get()->first.is_integer());
- REQUIRE(res.get()->first.integer() == (-9223372036854775807 - 1)); // INT64_MIN (C++'s parser is fun)
-}
-
-TEST_CASE ("JSON parse floats", "[json]")
-{
- auto res = Json::parse("0.0");
- REQUIRE(res);
- REQUIRE(res.get()->first.is_number());
- REQUIRE(!res.get()->first.is_integer());
- REQUIRE(res.get()->first.number() == 0.0);
- REQUIRE(!signbit(res.get()->first.number()));
- res = Json::parse("-0.0");
- REQUIRE(res);
- REQUIRE(res.get()->first.is_number());
- REQUIRE(res.get()->first.number() == 0.0);
- REQUIRE(signbit(res.get()->first.number()));
- res = Json::parse("12345.6789");
- REQUIRE(res);
- REQUIRE(res.get()->first.is_number());
- REQUIRE_THAT(res.get()->first.number(), Catch::WithinULP(12345.6789, 3));
- res = Json::parse("-12345.6789");
- REQUIRE(res);
- REQUIRE(res.get()->first.is_number());
- REQUIRE_THAT(res.get()->first.number(), Catch::WithinULP(-12345.6789, 3));
-}
-
-TEST_CASE ("JSON parse arrays", "[json]")
-{
- auto res = Json::parse("[]");
- REQUIRE(res);
- auto val = std::move(res.get()->first);
- REQUIRE(val.is_array());
- REQUIRE(val.array().size() == 0);
-
- res = Json::parse("[123]");
- REQUIRE(res);
- val = std::move(res.get()->first);
- REQUIRE(val.is_array());
- REQUIRE(val.array().size() == 1);
- REQUIRE(val.array()[0].is_integer());
- REQUIRE(val.array()[0].integer() == 123);
-
- res = Json::parse("[123, 456]");
- REQUIRE(res);
- val = std::move(res.get()->first);
- REQUIRE(val.is_array());
- REQUIRE(val.array().size() == 2);
- REQUIRE(val.array()[0].is_integer());
- REQUIRE(val.array()[0].integer() == 123);
- REQUIRE(val.array()[1].is_integer());
- REQUIRE(val.array()[1].integer() == 456);
-
- res = Json::parse("[123, 456, [null]]");
- REQUIRE(res);
- val = std::move(res.get()->first);
- REQUIRE(val.is_array());
- REQUIRE(val.array().size() == 3);
- REQUIRE(val.array()[2].is_array());
- REQUIRE(val.array()[2].array().size() == 1);
- REQUIRE(val.array()[2].array()[0].is_null());
-}
-
-TEST_CASE ("JSON parse objects", "[json]")
-{
- auto res = Json::parse("{}");
- REQUIRE(res);
- auto val = std::move(res.get()->first);
- REQUIRE(val.is_object());
- REQUIRE(val.object().size() == 0);
-}
-
-TEST_CASE ("JSON parse full file", "[json]")
-{
- vcpkg::StringView json =
-#include "large-json-document.json.inc"
- ;
-
- auto res = Json::parse(json);
- if (!res)
- {
- std::cerr << res.error()->format() << '\n';
- }
- REQUIRE(res);
-}
-
-TEST_CASE ("JSON track newlines", "[json]")
-{
- auto res = Json::parse("{\n,", fs::u8path("filename"));
- REQUIRE(!res);
- REQUIRE(res.error()->format() ==
- R"(filename:2:1: error: Unexpected character; expected property name
- on expression: ,
- ^
-)");
-}
diff --git a/toolsrc/src/vcpkg-test/large-json-document.json.inc b/toolsrc/src/vcpkg-test/large-json-document.json.inc
deleted file mode 100644
index 6cab7cf21..000000000
--- a/toolsrc/src/vcpkg-test/large-json-document.json.inc
+++ /dev/null
@@ -1,516 +0,0 @@
-// randomly generated by json-generator.com
-R"json([
- {
- "_id": "5e7a86c71cf688019f4c4b9f",
- "index": 0,
- "guid": "0e3c8a89-9960-4d87-8634-f9d3fcdaf735",
- "isActive": false,
- "balance": "$2,473.46",
- "picture": "http://placehold.it/32x32",
- "age": 21,
- "eyeColor": "blue",
- "name": {
- "first": "Dana",
- "last": "Romero"
- },
- "company": "NETPLODE",
- "email": "dana.romero@netplode.info",
- "phone": "+1 (981) 479-2769",
- "address": "501 Cass Place, Strykersville, Missouri, 8329",
- "about": "Incididunt in fugiat ipsum proident aliqua voluptate Lorem nostrud laboris ut velit minim. Dolor culpa magna tempor cupidatat. Id esse quis ipsum incididunt. Aliqua deserunt aliquip esse minim cillum esse aliquip veniam non labore dolor incididunt. Sint ea consectetur exercitation aliqua proident reprehenderit tempor ea eu. Amet ipsum labore magna elit.",
- "registered": "Wednesday, September 4, 2019 8:29 AM",
- "latitude": "-49.844379",
- "longitude": "-5.565357",
- "tags": [
- "dolor",
- "fugiat",
- "ea",
- "nisi",
- "non"
- ],
- "range": [
- 0,
- 1,
- 2,
- 3,
- 4,
- 5,
- 6,
- 7,
- 8,
- 9
- ],
- "friends": [
- {
- "id": 0,
- "name": "Elena Suarez"
- },
- {
- "id": 1,
- "name": "Pruitt Leach"
- },
- {
- "id": 2,
- "name": "Pugh Robinson"
- }
- ],
- "greeting": "Hello, Dana! You have 8 unread messages.",
- "favoriteFruit": "apple"
- },
- {
- "_id": "5e7a86c70efbf62ab5579408",
- "index": 1,
- "guid": "2c64c2d3-a830-4598-a399-f68f798ba6dc",
- "isActive": true,
- "balance": "$1,838.58",
- "picture": "http://placehold.it/32x32",
- "age": 33,
- "eyeColor": "brown",
- "name": {
- "first": "Ladonna",
- "last": "Willis"
- },
- "company": "JOVIOLD",
- "email": "ladonna.willis@joviold.us",
- "phone": "+1 (921) 591-2296",
- "address": "441 Highland Place, Leyner, Pennsylvania, 1788",
- "about": "Consequat deserunt nisi sit ex occaecat. Magna pariatur irure nisi duis laborum proident ipsum duis. Tempor qui consectetur consequat sunt proident ex ad id sint cupidatat sint.",
- "registered": "Wednesday, January 13, 2016 6:03 PM",
- "latitude": "-62.130182",
- "longitude": "-102.884995",
- "tags": [
- "fugiat",
- "ipsum",
- "ut",
- "pariatur",
- "enim"
- ],
- "range": [
- 0,
- 1,
- 2,
- 3,
- 4,
- 5,
- 6,
- 7,
- 8,
- 9
- ],
- "friends": [
- {
- "id": 0,
- "name": "Gamble Rose"
- },
- {
- "id": 1,
- "name": "Olive Horn"
- },
- {
- "id": 2,
- "name": "Benita Ochoa"
- }
- ],
- "greeting": "Hello, Ladonna! You have 6 unread messages.",
- "favoriteFruit": "banana"
- },
- {
- "_id": "5e7a86c71e30c95bbb0ff386",
- "index": 2,
- "guid": "04e45222-d785-461b-99be-b330585eb1a1",
- "isActive": true,
- "balance": "$3,591.60",
- "picture": "http://placehold.it/32x32",
- "age": 32,
- "eyeColor": "brown",
- "name": {
- "first": "Lee",
- "last": "Buckley"
- },
- "company": "TELEQUIET",
- "email": "lee.buckley@telequiet.biz",
- "phone": "+1 (897) 511-2132",
- "address": "675 Argyle Road, Kempton, Ohio, 4411",
- "about": "Sunt aliquip excepteur veniam fugiat consequat commodo ex est nulla laboris cillum enim. Laboris cupidatat et ipsum anim reprehenderit officia officia aute aliqua tempor. Incididunt sunt cupidatat mollit deserunt id nisi esse elit nisi est eiusmod aliquip. Lorem cillum ipsum quis aliquip laboris ex minim eu quis. Dolore incididunt officia labore enim Lorem in occaecat aliquip. Mollit ad duis non non qui et Lorem cillum.",
- "registered": "Tuesday, January 16, 2018 3:14 PM",
- "latitude": "-51.283144",
- "longitude": "-112.569722",
- "tags": [
- "id",
- "veniam",
- "dolor",
- "nulla",
- "pariatur"
- ],
- "range": [
- 0,
- 1,
- 2,
- 3,
- 4,
- 5,
- 6,
- 7,
- 8,
- 9
- ],
- "friends": [
- {
- "id": 0,
- "name": "Dina Craft"
- },
- {
- "id": 1,
- "name": "Ashlee Ferrell"
- },
- {
- "id": 2,
- "name": "Mcbride Gill"
- }
- ],
- "greeting": "Hello, Lee! You have 7 unread messages.",
- "favoriteFruit": "banana"
- },
- {
- "_id": "5e7a86c70e08bf0c278749f9",
- "index": 3,
- "guid": "0928ccac-e028-405a-a614-76628ba131b4",
- "isActive": false,
- "balance": "$2,867.88",
- "picture": "http://placehold.it/32x32",
- "age": 26,
- "eyeColor": "green",
- "name": {
- "first": "Chen",
- "last": "Rosa"
- },
- "company": "EXPOSA",
- "email": "chen.rosa@exposa.me",
- "phone": "+1 (956) 519-3064",
- "address": "239 Amersfort Place, Fillmore, South Carolina, 2443",
- "about": "Est ipsum cillum proident veniam voluptate enim sit eu excepteur veniam sit. Sunt aliqua qui incididunt id irure nulla qui. Et consequat ad anim proident minim dolor quis aliquip Lorem qui fugiat voluptate ex.",
- "registered": "Wednesday, April 9, 2014 12:45 PM",
- "latitude": "-15.222992",
- "longitude": "76.730424",
- "tags": [
- "eiusmod",
- "sit",
- "do",
- "aute",
- "ea"
- ],
- "range": [
- 0,
- 1,
- 2,
- 3,
- 4,
- 5,
- 6,
- 7,
- 8,
- 9
- ],
- "friends": [
- {
- "id": 0,
- "name": "Huff Townsend"
- },
- {
- "id": 1,
- "name": "Stacie Downs"
- },
- {
- "id": 2,
- "name": "Liza Barron"
- }
- ],
- "greeting": "Hello, Chen! You have 8 unread messages.",
- "favoriteFruit": "banana"
- },
- {
- "_id": "5e7a86c7086fc15efc387abc",
- "index": 4,
- "guid": "c71e62aa-8428-44cd-a2a5-7c30aaf963fe",
- "isActive": true,
- "balance": "$3,022.64",
- "picture": "http://placehold.it/32x32",
- "age": 32,
- "eyeColor": "blue",
- "name": {
- "first": "Walton",
- "last": "Mendez"
- },
- "company": "BUZZNESS",
- "email": "walton.mendez@buzzness.tv",
- "phone": "+1 (849) 560-2058",
- "address": "507 Colonial Court, Collins, New York, 7941",
- "about": "Et nisi in excepteur velit non incididunt sit. Consectetur magna sunt dolor eu Lorem adipisicing incididunt laborum consequat proident. Laboris ut dolor laboris esse ut dolor adipisicing ad fugiat commodo fugiat incididunt pariatur anim. Amet reprehenderit aute fugiat incididunt irure eu duis sint amet aliquip excepteur tempor dolore. Anim reprehenderit commodo irure sint et tempor occaecat fugiat ex commodo consectetur. Id ex dolor et culpa mollit. Voluptate magna est ex proident deserunt ullamco enim quis nulla cupidatat voluptate culpa exercitation Lorem.",
- "registered": "Tuesday, May 9, 2017 2:38 PM",
- "latitude": "86.083203",
- "longitude": "57.386268",
- "tags": [
- "Lorem",
- "aute",
- "proident",
- "eu",
- "incididunt"
- ],
- "range": [
- 0,
- 1,
- 2,
- 3,
- 4,
- 5,
- 6,
- 7,
- 8,
- 9
- ],
- "friends": [
- {
- "id": 0,
- "name": "Byers Sims"
- },
- {
- "id": 1,
- "name": "Suzanne Gonzalez"
- },
- {
- "id": 2,
- "name": "Vicki Velasquez"
- }
- ],
- "greeting": "Hello, Walton! You have 5 unread messages.",
- "favoriteFruit": "banana"
- },
- {
- "_id": "5e7a86c7dc9b82ffcb2868a2",
- "index": 5,
- "guid": "76f1c1cc-9164-43df-8858-633ee696df1c",
- "isActive": true,
- "balance": "$2,625.28",
- "picture": "http://placehold.it/32x32",
- "age": 40,
- "eyeColor": "green",
- "name": {
- "first": "Wise",
- "last": "Head"
- },
- "company": "FARMEX",
- "email": "wise.head@farmex.com",
- "phone": "+1 (850) 478-3280",
- "address": "425 Kent Street, Witmer, New Jersey, 2411",
- "about": "Velit amet fugiat enim occaecat do. Nulla sint officia anim ullamco. Ea quis excepteur excepteur enim ullamco. Amet aliqua mollit ad excepteur minim voluptate in velit sunt elit duis quis consequat nulla. Est dolor quis culpa aute id occaecat adipisicing mollit do consectetur fugiat. Mollit elit ex nostrud pariatur. Deserunt proident et voluptate occaecat labore occaecat Lorem exercitation est minim magna.",
- "registered": "Monday, March 23, 2015 10:14 PM",
- "latitude": "29.880281",
- "longitude": "126.094567",
- "tags": [
- "enim",
- "sunt",
- "cupidatat",
- "officia",
- "aute"
- ],
- "range": [
- 0,
- 1,
- 2,
- 3,
- 4,
- 5,
- 6,
- 7,
- 8,
- 9
- ],
- "friends": [
- {
- "id": 0,
- "name": "Fuentes Tyler"
- },
- {
- "id": 1,
- "name": "Flora Massey"
- },
- {
- "id": 2,
- "name": "Manuela Parks"
- }
- ],
- "greeting": "Hello, Wise! You have 8 unread messages.",
- "favoriteFruit": "strawberry"
- },
- {
- "_id": "5e7a86c7b3605b4ab198b25f",
- "index": 6,
- "guid": "818a0d46-9595-4066-a819-c93979220983",
- "isActive": true,
- "balance": "$3,193.77",
- "picture": "http://placehold.it/32x32",
- "age": 30,
- "eyeColor": "brown",
- "name": {
- "first": "Baldwin",
- "last": "Mcguire"
- },
- "company": "ZILCH",
- "email": "baldwin.mcguire@zilch.io",
- "phone": "+1 (803) 562-3968",
- "address": "address replaced",
- "about": "Nostrud exercitation Lorem reprehenderit commodo aliquip. Exercitation exercitation proident aliquip et do cillum id ad ad reprehenderit ipsum elit nostrud. Occaecat velit sit commodo aliquip esse.",
- "registered": "Saturday, January 14, 2017 3:13 AM",
- "latitude": "-38.674801",
- "longitude": "78.160951",
- "tags": [
- "reprehenderit",
- "eu",
- "magna",
- "nulla",
- "non"
- ],
- "range": [
- 0,
- 1,
- 2,
- 3,
- 4,
- 5,
- 6,
- 7,
- 8,
- 9
- ],
- "friends": [
- {
- "id": 0,
- "name": "Austin Gonzales"
- },
- {
- "id": 1,
- "name": "Polly Mcknight"
- },
- {
- "id": 2,
- "name": "Lucy Wagner"
- }
- ],
- "greeting": "Hello, Baldwin! You have 7 unread messages.",
- "favoriteFruit": "banana"
- },
- {
- "_id": "5e7a86c700d93af1dcbe69f3",
- "index": 7,
- "guid": "09dc8fc1-207f-45f2-9d2c-f1e70e278e9a",
- "isActive": true,
- "balance": "$3,895.90",
- "picture": "http://placehold.it/32x32",
- "age": 21,
- "eyeColor": "brown",
- "name": {
- "first": "Key",
- "last": "Bolton"
- },
- "company": "MAGNINA",
- "email": "key.bolton@magnina.net",
- "phone": "+1 (918) 466-2785",
- "address": "139 Blake Court, Chautauqua, Georgia, 3570",
- "about": "Cupidatat excepteur reprehenderit eiusmod aute ea commodo ipsum pariatur dolore veniam adipisicing dolor. Excepteur ex in laborum cupidatat cillum cillum qui dolore consequat excepteur. Lorem deserunt eiusmod esse proident et ullamco reprehenderit ad ea. Cupidatat veniam deserunt magna eu labore ipsum et officia officia irure non eiusmod.",
- "registered": "Wednesday, October 5, 2016 8:28 AM",
- "latitude": "89.82294",
- "longitude": "45.807834",
- "tags": [
- "et",
- "excepteur",
- "sunt",
- "ea",
- "irure"
- ],
- "range": [
- 0,
- 1,
- 2,
- 3,
- 4,
- 5,
- 6,
- 7,
- 8,
- 9
- ],
- "friends": [
- {
- "id": 0,
- "name": "Farmer Adkins"
- },
- {
- "id": 1,
- "name": "Summers Huffman"
- },
- {
- "id": 2,
- "name": "Lessie Holden"
- }
- ],
- "greeting": "Hello, Key! You have 9 unread messages.",
- "favoriteFruit": "strawberry"
- },
- {
- "_id": "5e7a86c7a3fcbd25660a493d",
- "index": 8,
- "guid": "7d58a9c2-6940-499e-ba24-75227b1a09d9",
- "isActive": true,
- "balance": "$1,606.76",
- "picture": "http://placehold.it/32x32",
- "age": 31,
- "eyeColor": "green",
- "name": {
- "first": "Gonzales",
- "last": "Manning"
- },
- "company": "ORGANICA",
- "email": "gonzales.manning@organica.name",
- "phone": "+1 (993) 556-2745",
- "address": "690 Regent Place, Rodman, Marshall Islands, 7114",
- "about": "Magna ullamco voluptate nostrud et magna ea aute sint id quis proident ad excepteur ullamco. Aliquip nostrud qui quis duis occaecat commodo laborum labore aute. Mollit ullamco in qui eu voluptate dolore aute mollit sint do sit nulla aliqua. Occaecat laborum ex velit ea ex ad eiusmod enim fugiat.",
- "registered": "Monday, December 1, 2014 6:32 AM",
- "latitude": "48.780262",
- "longitude": "-75.333042",
- "tags": [
- "non",
- "laborum",
- "et",
- "Lorem",
- "id"
- ],
- "range": [
- 0,
- 1,
- 2,
- 3,
- 4,
- 5,
- 6,
- 7,
- 8,
- 9
- ],
- "friends": [
- {
- "id": 0,
- "name": "Hester Finch"
- },
- {
- "id": 1,
- "name": "Tia Cooley"
- },
- {
- "id": 2,
- "name": "Cathryn Howe"
- }
- ],
- "greeting": "Hello, Gonzales! You have 5 unread messages.",
- "favoriteFruit": "apple"
- }
-])json"
diff --git a/toolsrc/src/vcpkg-test/manifests.cpp b/toolsrc/src/vcpkg-test/manifests.cpp
deleted file mode 100644
index bbbe0c96c..000000000
--- a/toolsrc/src/vcpkg-test/manifests.cpp
+++ /dev/null
@@ -1,733 +0,0 @@
-#include <catch2/catch.hpp>
-
-#include <vcpkg/base/json.h>
-#include <vcpkg/base/util.h>
-
-#include <vcpkg/paragraphs.h>
-#include <vcpkg/sourceparagraph.h>
-#include <vcpkg/vcpkgcmdarguments.h>
-#include <vcpkg/vcpkgpaths.h>
-
-#include <vcpkg-test/util.h>
-
-#if defined(_MSC_VER)
-#pragma warning(disable : 6237)
-#endif
-
-using namespace vcpkg;
-using namespace vcpkg::Paragraphs;
-using namespace vcpkg::Test;
-
-static Json::Object parse_json_object(StringView sv)
-{
- auto json = Json::parse(sv);
- // we're not testing json parsing here, so just fail on errors
- if (auto r = json.get())
- {
- return std::move(r->first.object());
- }
- else
- {
- Checks::exit_with_message(VCPKG_LINE_INFO, json.error()->format());
- }
-}
-
-static Parse::ParseExpected<SourceControlFile> test_parse_manifest(StringView sv, bool expect_fail = false)
-{
- auto object = parse_json_object(sv);
- auto res = SourceControlFile::parse_manifest_file(fs::u8path("<test manifest>"), object);
- if (!res.has_value() && !expect_fail)
- {
- print_error_message(res.error());
- }
- REQUIRE(res.has_value() == !expect_fail);
- return res;
-}
-
-static const FeatureFlagSettings feature_flags_with_versioning{false, false, false, true};
-static const FeatureFlagSettings feature_flags_without_versioning{false, false, false, false};
-
-TEST_CASE ("manifest construct minimum", "[manifests]")
-{
- auto m_pgh = test_parse_manifest(R"json({
- "name": "zlib",
- "version-string": "1.2.8"
- })json");
-
- REQUIRE(m_pgh.has_value());
- auto& pgh = **m_pgh.get();
-
- REQUIRE(pgh.core_paragraph->name == "zlib");
- REQUIRE(pgh.core_paragraph->version == "1.2.8");
- REQUIRE(pgh.core_paragraph->maintainers.empty());
- REQUIRE(pgh.core_paragraph->description.empty());
- REQUIRE(pgh.core_paragraph->dependencies.empty());
- REQUIRE(!pgh.core_paragraph->builtin_baseline.has_value());
-
- REQUIRE(!pgh.check_against_feature_flags({}, feature_flags_without_versioning));
-}
-
-TEST_CASE ("manifest versioning", "[manifests]")
-{
- std::tuple<StringLiteral, Versions::Scheme, StringLiteral> data[] = {
- {R"json({
- "name": "zlib",
- "version-string": "abcd"
-}
-)json",
- Versions::Scheme::String,
- "abcd"},
- {R"json({
- "name": "zlib",
- "version-date": "2020-01-01"
-}
-)json",
- Versions::Scheme::Date,
- "2020-01-01"},
- {R"json({
- "name": "zlib",
- "version": "1.2.3.4.5"
-}
-)json",
- Versions::Scheme::Relaxed,
- "1.2.3.4.5"},
- {R"json({
- "name": "zlib",
- "version-semver": "1.2.3-rc3"
-}
-)json",
- Versions::Scheme::Semver,
- "1.2.3-rc3"},
- };
- for (auto v : data)
- {
- auto m_pgh = test_parse_manifest(std::get<0>(v));
-
- REQUIRE(m_pgh.has_value());
- auto& pgh = **m_pgh.get();
- REQUIRE(Json::stringify(serialize_manifest(pgh), Json::JsonStyle::with_spaces(4)) == std::get<0>(v));
- REQUIRE(pgh.core_paragraph->version_scheme == std::get<1>(v));
- REQUIRE(pgh.core_paragraph->version == std::get<2>(v));
- }
-
- test_parse_manifest(R"json({
- "name": "zlib",
- "version-string": "abcd",
- "version-semver": "1.2.3-rc3"
- })json",
- true);
-
- test_parse_manifest(R"json({
- "name": "zlib",
- "version-string": "abcd#1"
- })json",
- true);
- test_parse_manifest(R"json({
- "name": "zlib",
- "version": "abcd#1"
- })json",
- true);
- test_parse_manifest(R"json({
- "name": "zlib",
- "version-date": "abcd#1"
- })json",
- true);
- test_parse_manifest(R"json({
- "name": "zlib",
- "version-semver": "abcd#1"
- })json",
- true);
-
- SECTION ("version syntax")
- {
- test_parse_manifest(R"json({
- "name": "zlib",
- "version-semver": "2020-01-01"
- })json",
- true);
- test_parse_manifest(R"json({
- "name": "zlib",
- "version-date": "1.1.1"
- })json",
- true);
- test_parse_manifest(R"json({
- "name": "zlib",
- "version": "1.2.3-rc3"
- })json",
- true);
- }
-}
-
-TEST_CASE ("manifest constraints hash", "[manifests]")
-{
- auto p = unwrap(test_parse_manifest(R"json({
- "name": "zlib",
- "version-string": "abcd",
- "dependencies": [
- {
- "name": "d",
- "version>=": "2018-09-01#1"
- }
- ]
-})json"));
- REQUIRE(p->core_paragraph->dependencies.at(0).constraint.value == "2018-09-01");
- REQUIRE(p->core_paragraph->dependencies.at(0).constraint.port_version == 1);
-
- test_parse_manifest(R"json({
- "name": "zlib",
- "version-string": "abcd",
- "dependencies": [
- {
- "name": "d",
- "version>=": "2018-09-01#0"
- }
- ]
-})json",
- true);
-
- test_parse_manifest(R"json({
- "name": "zlib",
- "version-string": "abcd",
- "dependencies": [
- {
- "name": "d",
- "version>=": "2018-09-01#-1"
- }
- ]
-})json",
- true);
-
- test_parse_manifest(R"json({
- "name": "zlib",
- "version-string": "abcd",
- "dependencies": [
- {
- "name": "d",
- "version>=": "2018-09-01",
- "port-version": 1
- }
- ]
-})json",
- true);
-}
-
-TEST_CASE ("manifest overrides error hash", "[manifests]")
-{
- test_parse_manifest(R"json({
- "name": "zlib",
- "version-string": "abcd",
- "overrides": [
- {
- "name": "d",
- "version-string": "abcd#1"
- }
- ]
-})json",
- true);
- test_parse_manifest(R"json({
- "name": "zlib",
- "version-string": "abcd",
- "overrides": [
- {
- "name": "d",
- "version-date": "2018-01-01#1"
- }
- ]
-})json",
- true);
- test_parse_manifest(R"json({
- "name": "zlib",
- "version-string": "abcd",
- "overrides": [
- {
- "name": "d",
- "version": "1.2#1"
- }
- ]
-})json",
- true);
- test_parse_manifest(R"json({
- "name": "zlib",
- "version-string": "abcd",
- "overrides": [
- {
- "name": "d",
- "version-semver": "1.2#1"
- }
- ]
-})json",
- true);
-}
-
-TEST_CASE ("manifest constraints", "[manifests]")
-{
- std::string raw = R"json({
- "name": "zlib",
- "version-string": "abcd",
- "builtin-baseline": "089fa4de7dca22c67dcab631f618d5cd0697c8d4",
- "dependencies": [
- "a",
- {
- "$extra": null,
- "name": "c"
- },
- {
- "name": "d",
- "version>=": "2018-09-01"
- }
- ]
-}
-)json";
- auto m_pgh = test_parse_manifest(raw);
-
- REQUIRE(m_pgh.has_value());
- auto& pgh = **m_pgh.get();
- REQUIRE(pgh.check_against_feature_flags({}, feature_flags_without_versioning));
- REQUIRE(!pgh.check_against_feature_flags({}, feature_flags_with_versioning));
- REQUIRE(Json::stringify(serialize_manifest(pgh), Json::JsonStyle::with_spaces(4)) == raw);
- REQUIRE(pgh.core_paragraph->dependencies.size() == 3);
- REQUIRE(pgh.core_paragraph->dependencies[0].name == "a");
- REQUIRE(pgh.core_paragraph->dependencies[0].constraint ==
- DependencyConstraint{Versions::Constraint::Type::None, "", 0});
- REQUIRE(pgh.core_paragraph->dependencies[1].name == "c");
- REQUIRE(pgh.core_paragraph->dependencies[1].constraint ==
- DependencyConstraint{Versions::Constraint::Type::None, "", 0});
- REQUIRE(pgh.core_paragraph->dependencies[2].name == "d");
- REQUIRE(pgh.core_paragraph->dependencies[2].constraint ==
- DependencyConstraint{Versions::Constraint::Type::Minimum, "2018-09-01", 0});
- REQUIRE(pgh.core_paragraph->builtin_baseline == "089fa4de7dca22c67dcab631f618d5cd0697c8d4");
-
- test_parse_manifest(R"json({
- "name": "zlib",
- "version-string": "abcd",
- "dependencies": [
- {
- "name": "d",
- "port-version": 5
- }
- ]
- })json",
- true);
-}
-
-TEST_CASE ("manifest builtin-baseline", "[manifests]")
-{
- SECTION ("valid baseline")
- {
- std::string raw = R"json({
- "name": "zlib",
- "version-string": "abcd",
- "builtin-baseline": "089fa4de7dca22c67dcab631f618d5cd0697c8d4"
-}
-)json";
- auto m_pgh = test_parse_manifest(raw);
-
- REQUIRE(m_pgh.has_value());
- auto& pgh = **m_pgh.get();
- REQUIRE(pgh.check_against_feature_flags({}, feature_flags_without_versioning));
- REQUIRE(!pgh.check_against_feature_flags({}, feature_flags_with_versioning));
- REQUIRE(pgh.core_paragraph->builtin_baseline.value_or("does not have a value") ==
- "089fa4de7dca22c67dcab631f618d5cd0697c8d4");
- }
-
- SECTION ("empty baseline")
- {
- std::string raw = R"json({
- "name": "zlib",
- "version-string": "abcd",
- "builtin-baseline": ""
-}
-)json";
-
- auto m_pgh = test_parse_manifest(raw);
-
- REQUIRE(m_pgh.has_value());
- auto& pgh = **m_pgh.get();
- REQUIRE(pgh.check_against_feature_flags({}, feature_flags_without_versioning));
- REQUIRE(!pgh.check_against_feature_flags({}, feature_flags_with_versioning));
- REQUIRE(pgh.core_paragraph->builtin_baseline.value_or("does not have a value") == "");
- }
-}
-
-TEST_CASE ("manifest overrides", "[manifests]")
-{
- std::tuple<StringLiteral, Versions::Scheme, StringLiteral> data[] = {
- {R"json({
- "name": "zlib",
- "version-date": "2020-01-01",
- "overrides": [
- {
- "name": "abc",
- "version-string": "abcd"
- }
- ]
-}
-)json",
- Versions::Scheme::String,
- "abcd"},
- {R"json({
- "name": "zlib",
- "version": "1.2.3.4.5",
- "overrides": [
- {
- "name": "abc",
- "version-date": "2020-01-01"
- }
- ]
-}
-)json",
- Versions::Scheme::Date,
- "2020-01-01"},
- {R"json({
- "name": "zlib",
- "version-date": "2020-01-01",
- "overrides": [
- {
- "name": "abc",
- "version": "1.2.3.4.5"
- }
- ]
-}
-)json",
- Versions::Scheme::Relaxed,
- "1.2.3.4.5"},
- {R"json({
- "name": "zlib",
- "version-date": "2020-01-01",
- "overrides": [
- {
- "name": "abc",
- "version-semver": "1.2.3-rc3"
- }
- ]
-}
-)json",
- Versions::Scheme::Semver,
- "1.2.3-rc3"},
- };
- for (auto v : data)
- {
- auto m_pgh = test_parse_manifest(std::get<0>(v));
-
- REQUIRE(m_pgh.has_value());
- auto& pgh = **m_pgh.get();
- REQUIRE(Json::stringify(serialize_manifest(pgh), Json::JsonStyle::with_spaces(4)) == std::get<0>(v));
- REQUIRE(pgh.core_paragraph->overrides.size() == 1);
- REQUIRE(pgh.core_paragraph->overrides[0].version_scheme == std::get<1>(v));
- REQUIRE(pgh.core_paragraph->overrides[0].version == std::get<2>(v));
- REQUIRE(pgh.check_against_feature_flags({}, feature_flags_without_versioning));
- REQUIRE(!pgh.check_against_feature_flags({}, feature_flags_with_versioning));
- }
-
- test_parse_manifest(R"json({
- "name": "zlib",
- "version-string": "abcd",
- "overrides": [
- {
- "name": "abc",
- "version-semver": "1.2.3-rc3",
- "version-string": "1.2.3-rc3"
- }
- ]})json",
- true);
-
- test_parse_manifest(R"json({
- "name": "zlib",
- "version-string": "abcd",
- "overrides": [
- {
- "name": "abc",
- "port-version": 5
- }
- ]})json",
- true);
-
- std::string raw = R"json({
- "name": "zlib",
- "version-string": "abcd",
- "overrides": [
- {
- "name": "abc",
- "version-string": "hello",
- "port-version": 5
- },
- {
- "name": "abcd",
- "version-string": "hello",
- "port-version": 7
- }
- ]
-}
-)json";
- auto m_pgh = test_parse_manifest(raw);
-
- REQUIRE(m_pgh.has_value());
- auto& pgh = **m_pgh.get();
- REQUIRE(Json::stringify(serialize_manifest(pgh), Json::JsonStyle::with_spaces(4)) == raw);
- REQUIRE(pgh.core_paragraph->overrides.size() == 2);
- REQUIRE(pgh.core_paragraph->overrides[0].name == "abc");
- REQUIRE(pgh.core_paragraph->overrides[0].port_version == 5);
- REQUIRE(pgh.core_paragraph->overrides[1].name == "abcd");
- REQUIRE(pgh.core_paragraph->overrides[1].port_version == 7);
-
- REQUIRE(pgh.check_against_feature_flags({}, feature_flags_without_versioning));
- REQUIRE(!pgh.check_against_feature_flags({}, feature_flags_with_versioning));
-}
-
-TEST_CASE ("manifest construct maximum", "[manifests]")
-{
- auto m_pgh = test_parse_manifest(R"json({
- "name": "s",
- "version-string": "v",
- "maintainers": ["m"],
- "description": "d",
- "dependencies": ["bd"],
- "default-features": ["df"],
- "features": [
- {
- "name": "iroh",
- "description": "zuko's uncle",
- "dependencies": [
- "firebending",
- {
- "name": "tea"
- },
- {
- "name": "order.white-lotus",
- "features": [ "the-ancient-ways" ],
- "platform": "!(windows & arm)"
- }
- ]
- },
- {
- "name": "zuko",
- "description": ["son of the fire lord", "firebending 師父"]
- }
- ]
- })json");
- REQUIRE(m_pgh.has_value());
- auto& pgh = **m_pgh.get();
-
- REQUIRE(pgh.core_paragraph->name == "s");
- REQUIRE(pgh.core_paragraph->version == "v");
- REQUIRE(pgh.core_paragraph->maintainers.size() == 1);
- REQUIRE(pgh.core_paragraph->maintainers[0] == "m");
- REQUIRE(pgh.core_paragraph->description.size() == 1);
- REQUIRE(pgh.core_paragraph->description[0] == "d");
- REQUIRE(pgh.core_paragraph->dependencies.size() == 1);
- REQUIRE(pgh.core_paragraph->dependencies[0].name == "bd");
- REQUIRE(pgh.core_paragraph->default_features.size() == 1);
- REQUIRE(pgh.core_paragraph->default_features[0] == "df");
-
- REQUIRE(pgh.feature_paragraphs.size() == 2);
-
- REQUIRE(pgh.feature_paragraphs[0]->name == "iroh");
- REQUIRE(pgh.feature_paragraphs[0]->description.size() == 1);
- REQUIRE(pgh.feature_paragraphs[0]->description[0] == "zuko's uncle");
- REQUIRE(pgh.feature_paragraphs[0]->dependencies.size() == 3);
- REQUIRE(pgh.feature_paragraphs[0]->dependencies[0].name == "firebending");
-
- REQUIRE(pgh.feature_paragraphs[0]->dependencies[1].name == "order.white-lotus");
- REQUIRE(pgh.feature_paragraphs[0]->dependencies[1].features.size() == 1);
- REQUIRE(pgh.feature_paragraphs[0]->dependencies[1].features[0] == "the-ancient-ways");
- REQUIRE_FALSE(pgh.feature_paragraphs[0]->dependencies[1].platform.evaluate(
- {{"VCPKG_CMAKE_SYSTEM_NAME", ""}, {"VCPKG_TARGET_ARCHITECTURE", "arm"}}));
- REQUIRE(pgh.feature_paragraphs[0]->dependencies[1].platform.evaluate(
- {{"VCPKG_CMAKE_SYSTEM_NAME", ""}, {"VCPKG_TARGET_ARCHITECTURE", "x86"}}));
- REQUIRE(pgh.feature_paragraphs[0]->dependencies[1].platform.evaluate(
- {{"VCPKG_CMAKE_SYSTEM_NAME", "Linux"}, {"VCPKG_TARGET_ARCHITECTURE", "x86"}}));
-
- REQUIRE(pgh.feature_paragraphs[0]->dependencies[2].name == "tea");
-
- REQUIRE(pgh.feature_paragraphs[1]->name == "zuko");
- REQUIRE(pgh.feature_paragraphs[1]->description.size() == 2);
- REQUIRE(pgh.feature_paragraphs[1]->description[0] == "son of the fire lord");
- REQUIRE(pgh.feature_paragraphs[1]->description[1] == "firebending 師父");
-
- REQUIRE(!pgh.check_against_feature_flags({}, feature_flags_without_versioning));
-}
-
-TEST_CASE ("SourceParagraph manifest two dependencies", "[manifests]")
-{
- auto m_pgh = test_parse_manifest(R"json({
- "name": "zlib",
- "version-string": "1.2.8",
- "dependencies": ["z", "openssl"]
- })json");
- REQUIRE(m_pgh.has_value());
- auto& pgh = **m_pgh.get();
-
- REQUIRE(pgh.core_paragraph->dependencies.size() == 2);
- REQUIRE(pgh.core_paragraph->dependencies[0].name == "openssl");
- REQUIRE(pgh.core_paragraph->dependencies[1].name == "z");
-}
-
-TEST_CASE ("SourceParagraph manifest three dependencies", "[manifests]")
-{
- auto m_pgh = test_parse_manifest(R"json({
- "name": "zlib",
- "version-string": "1.2.8",
- "dependencies": ["z", "openssl", "xyz"]
- })json");
- REQUIRE(m_pgh.has_value());
- auto& pgh = **m_pgh.get();
-
- REQUIRE(pgh.core_paragraph->dependencies.size() == 3);
- // should be ordered
- REQUIRE(pgh.core_paragraph->dependencies[0].name == "openssl");
- REQUIRE(pgh.core_paragraph->dependencies[1].name == "xyz");
- REQUIRE(pgh.core_paragraph->dependencies[2].name == "z");
-}
-
-TEST_CASE ("SourceParagraph manifest construct qualified dependencies", "[manifests]")
-{
- auto m_pgh = test_parse_manifest(R"json({
- "name": "zlib",
- "version-string": "1.2.8",
- "dependencies": [
- {
- "name": "liba",
- "platform": "windows"
- },
- {
- "name": "libb",
- "platform": "uwp"
- }
- ]
- })json");
- REQUIRE(m_pgh.has_value());
- auto& pgh = **m_pgh.get();
-
- REQUIRE(pgh.core_paragraph->name == "zlib");
- REQUIRE(pgh.core_paragraph->version == "1.2.8");
- REQUIRE(pgh.core_paragraph->maintainers.empty());
- REQUIRE(pgh.core_paragraph->description.empty());
- REQUIRE(pgh.core_paragraph->dependencies.size() == 2);
- REQUIRE(pgh.core_paragraph->dependencies[0].name == "liba");
- REQUIRE(pgh.core_paragraph->dependencies[0].platform.evaluate({{"VCPKG_CMAKE_SYSTEM_NAME", ""}}));
- REQUIRE(pgh.core_paragraph->dependencies[1].name == "libb");
- REQUIRE(pgh.core_paragraph->dependencies[1].platform.evaluate({{"VCPKG_CMAKE_SYSTEM_NAME", "WindowsStore"}}));
-}
-
-TEST_CASE ("SourceParagraph manifest default features", "[manifests]")
-{
- auto m_pgh = test_parse_manifest(R"json({
- "name": "a",
- "version-string": "1.0",
- "default-features": ["a1"]
- })json");
- REQUIRE(m_pgh.has_value());
- auto& pgh = **m_pgh.get();
-
- REQUIRE(pgh.core_paragraph->default_features.size() == 1);
- REQUIRE(pgh.core_paragraph->default_features[0] == "a1");
-}
-
-TEST_CASE ("SourceParagraph manifest description paragraph", "[manifests]")
-{
- auto m_pgh = test_parse_manifest(R"json({
- "name": "a",
- "version-string": "1.0",
- "description": ["line 1", "line 2", "line 3"]
- })json");
- REQUIRE(m_pgh.has_value());
- auto& pgh = **m_pgh.get();
-
- REQUIRE(pgh.core_paragraph->description.size() == 3);
- REQUIRE(pgh.core_paragraph->description[0] == "line 1");
- REQUIRE(pgh.core_paragraph->description[1] == "line 2");
- REQUIRE(pgh.core_paragraph->description[2] == "line 3");
-}
-
-TEST_CASE ("SourceParagraph manifest supports", "[manifests]")
-{
- auto m_pgh = test_parse_manifest(R"json({
- "name": "a",
- "version-string": "1.0",
- "supports": "!(windows | osx)"
- })json");
- REQUIRE(m_pgh.has_value());
- auto& pgh = **m_pgh.get();
-
- REQUIRE(pgh.core_paragraph->supports_expression.evaluate({{"VCPKG_CMAKE_SYSTEM_NAME", "Linux"}}));
- REQUIRE_FALSE(pgh.core_paragraph->supports_expression.evaluate({{"VCPKG_CMAKE_SYSTEM_NAME", ""}}));
- REQUIRE_FALSE(pgh.core_paragraph->supports_expression.evaluate({{"VCPKG_CMAKE_SYSTEM_NAME", "Darwin"}}));
-}
-
-TEST_CASE ("SourceParagraph manifest empty supports", "[manifests]")
-{
- auto m_pgh = test_parse_manifest(R"json({
- "name": "a",
- "version-string": "1.0",
- "supports": ""
- })json",
- true);
- REQUIRE_FALSE(m_pgh.has_value());
-}
-
-TEST_CASE ("SourceParagraph manifest non-string supports", "[manifests]")
-{
- auto m_pgh = test_parse_manifest(R"json({
- "name": "a",
- "version-string": "1.0",
- "supports": true
- })json",
- true);
- REQUIRE_FALSE(m_pgh.has_value());
-}
-
-TEST_CASE ("Serialize all the ports", "[manifests]")
-{
- std::vector<std::string> args_list = {"format-manifest"};
- auto& fs = Files::get_real_filesystem();
- auto args = VcpkgCmdArguments::create_from_arg_sequence(args_list.data(), args_list.data() + args_list.size());
- args.imbue_from_environment();
- VcpkgPaths paths{fs, args};
-
- std::vector<SourceControlFile> scfs;
-
- for (auto dir : fs::directory_iterator(paths.builtin_ports_directory()))
- {
- const auto control = dir / fs::u8path("CONTROL");
- const auto manifest = dir / fs::u8path("vcpkg.json");
- if (fs.exists(control))
- {
- INFO(fs::u8string(control));
- auto contents = fs.read_contents(control, VCPKG_LINE_INFO);
- auto pghs = Paragraphs::parse_paragraphs(contents, fs::u8string(control));
- REQUIRE(pghs);
-
- auto scf = SourceControlFile::parse_control_file(fs::u8string(control),
- std::move(pghs).value_or_exit(VCPKG_LINE_INFO));
- if (!scf)
- {
- INFO(scf.error()->name);
- INFO(scf.error()->error);
- REQUIRE(scf);
- }
-
- scfs.push_back(std::move(*scf.value_or_exit(VCPKG_LINE_INFO)));
- }
- else if (fs.exists(manifest))
- {
- std::error_code ec;
- auto contents = Json::parse_file(fs, manifest, ec);
- REQUIRE_FALSE(ec);
- REQUIRE(contents);
-
- auto scf = SourceControlFile::parse_manifest_file(manifest,
- contents.value_or_exit(VCPKG_LINE_INFO).first.object());
- REQUIRE(scf);
-
- scfs.push_back(std::move(*scf.value_or_exit(VCPKG_LINE_INFO)));
- }
- }
-
- for (auto& scf : scfs)
- {
- auto serialized = serialize_manifest(scf);
- auto serialized_scf = SourceControlFile::parse_manifest_file({}, serialized).value_or_exit(VCPKG_LINE_INFO);
-
- REQUIRE(*serialized_scf == scf);
- }
-}
diff --git a/toolsrc/src/vcpkg-test/mockcmakevarsprovider.cpp b/toolsrc/src/vcpkg-test/mockcmakevarsprovider.cpp
deleted file mode 100644
index 77a796fad..000000000
--- a/toolsrc/src/vcpkg-test/mockcmakevarsprovider.cpp
+++ /dev/null
@@ -1,28 +0,0 @@
-#include <vcpkg-test/mockcmakevarprovider.h>
-
-namespace vcpkg::Test
-{
- Optional<const std::unordered_map<std::string, std::string>&> MockCMakeVarProvider::get_generic_triplet_vars(
- Triplet triplet) const
- {
- auto it = generic_triplet_vars.find(triplet);
- if (it == generic_triplet_vars.end()) return nullopt;
- return it->second;
- }
-
- Optional<const std::unordered_map<std::string, std::string>&> MockCMakeVarProvider::get_dep_info_vars(
- const PackageSpec& spec) const
- {
- auto it = dep_info_vars.find(spec);
- if (it == dep_info_vars.end()) return nullopt;
- return it->second;
- }
-
- Optional<const std::unordered_map<std::string, std::string>&> MockCMakeVarProvider::get_tag_vars(
- const PackageSpec& spec) const
- {
- auto it = tag_vars.find(spec);
- if (it == tag_vars.end()) return nullopt;
- return it->second;
- }
-}
diff --git a/toolsrc/src/vcpkg-test/optional.cpp b/toolsrc/src/vcpkg-test/optional.cpp
deleted file mode 100644
index f18efb359..000000000
--- a/toolsrc/src/vcpkg-test/optional.cpp
+++ /dev/null
@@ -1,121 +0,0 @@
-#include <catch2/catch.hpp>
-
-#include <vcpkg/base/lineinfo.h>
-#include <vcpkg/base/optional.h>
-#include <vcpkg/base/util.h>
-
-#include <vector>
-
-namespace
-{
- struct identity_projection
- {
- template<class T>
- const T& operator()(const T& val) noexcept
- {
- return val;
- }
- };
-}
-
-TEST_CASE ("equal", "[optional]")
-{
- using vcpkg::Optional;
-
- CHECK(Optional<int>{} == Optional<int>{});
- CHECK_FALSE(Optional<int>{} == Optional<int>{42});
- CHECK_FALSE(Optional<int>{42} == Optional<int>{});
- CHECK_FALSE(Optional<int>{1729} == Optional<int>{42});
- CHECK(Optional<int>{42} == Optional<int>{42});
-}
-
-TEST_CASE ("ref conversion", "[optional]")
-{
- using vcpkg::Optional;
-
- Optional<int> i_empty;
- Optional<int> i_1 = 1;
- const Optional<int> ci_1 = 1;
-
- Optional<int&> ref_empty = i_empty;
- Optional<const int&> cref_empty = i_empty;
-
- Optional<int&> ref_1 = i_1;
- Optional<const int&> cref_1 = ci_1;
-
- REQUIRE(ref_empty.has_value() == false);
- REQUIRE(cref_empty.has_value() == false);
-
- REQUIRE(ref_1.get() == i_1.get());
- REQUIRE(cref_1.get() == ci_1.get());
-
- ref_empty = i_1;
- cref_empty = ci_1;
- REQUIRE(ref_empty.get() == i_1.get());
- REQUIRE(cref_empty.get() == ci_1.get());
-
- const int x = 5;
- cref_1 = x;
- REQUIRE(cref_1.get() == &x);
-}
-
-TEST_CASE ("value conversion", "[optional]")
-{
- using vcpkg::Optional;
-
- Optional<long> j = 1;
- Optional<int> i = j;
- Optional<const char*> cstr = "hello, world!";
- Optional<std::string> cppstr = cstr;
-
- std::vector<int> v{1, 2, 3};
- Optional<std::vector<int>&> o_v(v);
- REQUIRE(o_v.has_value());
- REQUIRE(o_v.get()->size() == 3);
- Optional<std::vector<int>> o_w(std::move(o_v));
- REQUIRE(o_w.has_value());
- REQUIRE(o_w.get()->size() == 3);
- // Moving from Optional<&> should not move the underlying object
- REQUIRE(o_v.has_value());
- REQUIRE(o_v.get()->size() == 3);
-}
-
-TEST_CASE ("optional.map", "[optional]")
-{
- using vcpkg::NullOpt;
- using vcpkg::nullopt;
- using vcpkg::Optional;
-
- const Optional<std::unique_ptr<int>> move_only;
-
- Optional<int*> m = move_only.map([](auto&& p) { return p.get(); });
- Optional<Optional<int*>> n =
- move_only.map([](auto&& p) -> Optional<int*> { return p ? Optional<int*>{p.get()} : nullopt; });
- Optional<NullOpt> o = move_only.map([](auto&&) { return nullopt; });
-
- Optional<int> five = 5;
-
- struct MoveTest
- {
- int operator()(int&&) { return 1; }
- int operator()(const int&) { return -1; }
- } move_test;
-
- Optional<int> dst = std::move(five).map(move_test);
- REQUIRE(dst == 1);
- Optional<int> dst2 = five.map(move_test);
- REQUIRE(dst2 == -1);
-}
-
-TEST_CASE ("common_projection", "[optional]")
-{
- using vcpkg::Util::common_projection;
- std::vector<int> input;
- CHECK(!common_projection(input, identity_projection{}).has_value());
- input.push_back(42);
- CHECK(common_projection(input, identity_projection{}).value_or_exit(VCPKG_LINE_INFO) == 42);
- input.push_back(42);
- CHECK(common_projection(input, identity_projection{}).value_or_exit(VCPKG_LINE_INFO) == 42);
- input.push_back(1729);
- CHECK(!common_projection(input, identity_projection{}).has_value());
-}
diff --git a/toolsrc/src/vcpkg-test/paragraph.cpp b/toolsrc/src/vcpkg-test/paragraph.cpp
deleted file mode 100644
index cb3f8e620..000000000
--- a/toolsrc/src/vcpkg-test/paragraph.cpp
+++ /dev/null
@@ -1,516 +0,0 @@
-#include <catch2/catch.hpp>
-
-#include <vcpkg/base/strings.h>
-
-#include <vcpkg/paragraphs.h>
-
-#include <vcpkg-test/util.h>
-
-namespace Strings = vcpkg::Strings;
-using vcpkg::Parse::Paragraph;
-
-namespace
-{
- auto test_parse_control_file(const std::vector<std::unordered_map<std::string, std::string>>& v)
- {
- std::vector<Paragraph> pghs;
- for (auto&& p : v)
- {
- pghs.emplace_back();
- for (auto&& kv : p)
- pghs.back().emplace(kv.first, std::make_pair(kv.second, vcpkg::Parse::TextRowCol{}));
- }
- return vcpkg::SourceControlFile::parse_control_file("", std::move(pghs));
- }
-
- auto test_make_binary_paragraph(const std::unordered_map<std::string, std::string>& v)
- {
- Paragraph pgh;
- for (auto&& kv : v)
- pgh.emplace(kv.first, std::make_pair(kv.second, vcpkg::Parse::TextRowCol{}));
-
- return vcpkg::BinaryParagraph(std::move(pgh));
- }
-
-}
-
-TEST_CASE ("SourceParagraph construct minimum", "[paragraph]")
-{
- auto m_pgh = test_parse_control_file({{
- {"Source", "zlib"},
- {"Version", "1.2.8"},
- }});
-
- REQUIRE(m_pgh.has_value());
- auto& pgh = **m_pgh.get();
-
- REQUIRE(pgh.core_paragraph->name == "zlib");
- REQUIRE(pgh.core_paragraph->version == "1.2.8");
- REQUIRE(pgh.core_paragraph->maintainers.empty());
- REQUIRE(pgh.core_paragraph->description.empty());
- REQUIRE(pgh.core_paragraph->dependencies.size() == 0);
-}
-
-TEST_CASE ("SourceParagraph construct invalid", "[paragraph]")
-{
- auto m_pgh = test_parse_control_file({{
- {"Source", "zlib"},
- {"Version", "1.2.8"},
- {"Build-Depends", "1.2.8"},
- }});
-
- REQUIRE(!m_pgh.has_value());
- REQUIRE(m_pgh.error()->has_error());
-
- m_pgh = test_parse_control_file({{
- {"Source", "zlib"},
- {"Version", "1.2.8"},
- {"Default-Features", "1.2.8"},
- }});
-
- REQUIRE(!m_pgh.has_value());
- REQUIRE(m_pgh.error()->has_error());
-
- m_pgh = test_parse_control_file({
- {
- {"Source", "zlib"},
- {"Version", "1.2.8"},
- },
- {
- {"Feature", "a"},
- {"Build-Depends", "1.2.8"},
- },
- });
-
- REQUIRE(!m_pgh.has_value());
- REQUIRE(m_pgh.error()->has_error());
-
- // invalid field`s name
- m_pgh = test_parse_control_file({{
- {"Surce", "zlib"},
- {"Vursion", "1.2.8"},
- }});
-
- REQUIRE(!m_pgh.has_value());
- REQUIRE(m_pgh.error()->has_error());
-}
-
-TEST_CASE ("SourceParagraph construct maximum", "[paragraph]")
-{
- auto m_pgh = test_parse_control_file({{
- {"Source", "s"},
- {"Version", "v"},
- {"Maintainer", "m"},
- {"Description", "d"},
- {"Build-Depends", "bd"},
- {"Default-Features", "df"},
- }});
- REQUIRE(m_pgh.has_value());
- auto& pgh = **m_pgh.get();
-
- REQUIRE(pgh.core_paragraph->name == "s");
- REQUIRE(pgh.core_paragraph->version == "v");
- REQUIRE(pgh.core_paragraph->maintainers.size() == 1);
- REQUIRE(pgh.core_paragraph->maintainers[0] == "m");
- REQUIRE(pgh.core_paragraph->description.size() == 1);
- REQUIRE(pgh.core_paragraph->description[0] == "d");
- REQUIRE(pgh.core_paragraph->dependencies.size() == 1);
- REQUIRE(pgh.core_paragraph->dependencies[0].name == "bd");
- REQUIRE(pgh.core_paragraph->default_features.size() == 1);
- REQUIRE(pgh.core_paragraph->default_features[0] == "df");
-}
-
-TEST_CASE ("SourceParagraph construct feature", "[paragraph]")
-{
- auto m_pgh = test_parse_control_file({
- {
- {"Source", "s"},
- {"Version", "v"},
- },
- {{"Feature", "f"}, {"Description", "d2"}, {"Build-Depends", "bd2"}},
- });
- REQUIRE(m_pgh.has_value());
- auto& pgh = **m_pgh.get();
-
- REQUIRE(pgh.feature_paragraphs.size() == 1);
- REQUIRE(pgh.feature_paragraphs[0]->name == "f");
- REQUIRE(pgh.feature_paragraphs[0]->description == std::vector<std::string>{"d2"});
- REQUIRE(pgh.feature_paragraphs[0]->dependencies.size() == 1);
-}
-
-TEST_CASE ("SourceParagraph two dependencies", "[paragraph]")
-{
- auto m_pgh = test_parse_control_file({{
- {"Source", "zlib"},
- {"Version", "1.2.8"},
- {"Build-Depends", "z, openssl"},
- }});
- REQUIRE(m_pgh.has_value());
- auto& pgh = **m_pgh.get();
-
- REQUIRE(pgh.core_paragraph->dependencies.size() == 2);
- // should be ordered
- REQUIRE(pgh.core_paragraph->dependencies[0].name == "openssl");
- REQUIRE(pgh.core_paragraph->dependencies[1].name == "z");
-}
-
-TEST_CASE ("SourceParagraph three dependencies", "[paragraph]")
-{
- auto m_pgh = test_parse_control_file({{
- {"Source", "zlib"},
- {"Version", "1.2.8"},
- {"Build-Depends", "z, openssl, xyz"},
- }});
- REQUIRE(m_pgh.has_value());
- auto& pgh = **m_pgh.get();
-
- REQUIRE(pgh.core_paragraph->dependencies.size() == 3);
- // should be ordered
- REQUIRE(pgh.core_paragraph->dependencies[0].name == "openssl");
- REQUIRE(pgh.core_paragraph->dependencies[1].name == "xyz");
- REQUIRE(pgh.core_paragraph->dependencies[2].name == "z");
-}
-
-TEST_CASE ("SourceParagraph construct qualified dependencies", "[paragraph]")
-{
- auto m_pgh = test_parse_control_file({{
- {"Source", "zlib"},
- {"Version", "1.2.8"},
- {"Build-Depends", "liba (windows), libb (uwp)"},
- }});
- REQUIRE(m_pgh.has_value());
- auto& pgh = **m_pgh.get();
-
- REQUIRE(pgh.core_paragraph->name == "zlib");
- REQUIRE(pgh.core_paragraph->version == "1.2.8");
- REQUIRE(pgh.core_paragraph->maintainers.empty());
- REQUIRE(pgh.core_paragraph->description.empty());
- REQUIRE(pgh.core_paragraph->dependencies.size() == 2);
- REQUIRE(pgh.core_paragraph->dependencies[0].name == "liba");
- REQUIRE(pgh.core_paragraph->dependencies[0].platform.evaluate({{"VCPKG_CMAKE_SYSTEM_NAME", ""}}));
- REQUIRE(pgh.core_paragraph->dependencies[1].name == "libb");
- REQUIRE(pgh.core_paragraph->dependencies[1].platform.evaluate({{"VCPKG_CMAKE_SYSTEM_NAME", "WindowsStore"}}));
-}
-
-TEST_CASE ("SourceParagraph default features", "[paragraph]")
-{
- auto m_pgh = test_parse_control_file({{
- {"Source", "a"},
- {"Version", "1.0"},
- {"Default-Features", "a1"},
- }});
- REQUIRE(m_pgh.has_value());
- auto& pgh = **m_pgh.get();
-
- REQUIRE(pgh.core_paragraph->default_features.size() == 1);
- REQUIRE(pgh.core_paragraph->default_features[0] == "a1");
-}
-
-TEST_CASE ("BinaryParagraph construct minimum", "[paragraph]")
-{
- auto pgh = test_make_binary_paragraph({
- {"Package", "zlib"},
- {"Version", "1.2.8"},
- {"Architecture", "x86-windows"},
- {"Multi-Arch", "same"},
- });
-
- REQUIRE(pgh.spec.name() == "zlib");
- REQUIRE(pgh.version == "1.2.8");
- REQUIRE(pgh.maintainers.empty());
- REQUIRE(pgh.description.empty());
- REQUIRE(pgh.spec.triplet().canonical_name() == "x86-windows");
- REQUIRE(pgh.dependencies.size() == 0);
-}
-
-TEST_CASE ("BinaryParagraph construct maximum", "[paragraph]")
-{
- auto pgh = test_make_binary_paragraph({
- {"Package", "s"},
- {"Version", "v"},
- {"Architecture", "x86-windows"},
- {"Multi-Arch", "same"},
- {"Maintainer", "m"},
- {"Description", "d"},
- {"Depends", "bd"},
- });
-
- REQUIRE(pgh.spec.name() == "s");
- REQUIRE(pgh.version == "v");
- REQUIRE(pgh.maintainers.size() == 1);
- REQUIRE(pgh.maintainers[0] == "m");
- REQUIRE(pgh.description.size() == 1);
- REQUIRE(pgh.description[0] == "d");
- REQUIRE(pgh.dependencies.size() == 1);
- REQUIRE(pgh.dependencies[0] == "bd");
-}
-
-TEST_CASE ("BinaryParagraph three dependencies", "[paragraph]")
-{
- auto pgh = test_make_binary_paragraph({
- {"Package", "zlib"},
- {"Version", "1.2.8"},
- {"Architecture", "x86-windows"},
- {"Multi-Arch", "same"},
- {"Depends", "a, b, c"},
- });
-
- REQUIRE(pgh.dependencies.size() == 3);
- REQUIRE(pgh.dependencies[0] == "a");
- REQUIRE(pgh.dependencies[1] == "b");
- REQUIRE(pgh.dependencies[2] == "c");
-}
-
-TEST_CASE ("BinaryParagraph abi", "[paragraph]")
-{
- auto pgh = test_make_binary_paragraph({
- {"Package", "zlib"},
- {"Version", "1.2.8"},
- {"Architecture", "x86-windows"},
- {"Multi-Arch", "same"},
- {"Abi", "abcd123"},
- });
-
- REQUIRE(pgh.dependencies.size() == 0);
- REQUIRE(pgh.abi == "abcd123");
-}
-
-TEST_CASE ("BinaryParagraph default features", "[paragraph]")
-{
- auto pgh = test_make_binary_paragraph({
- {"Package", "a"},
- {"Version", "1.0"},
- {"Architecture", "x86-windows"},
- {"Multi-Arch", "same"},
- {"Default-Features", "a1"},
- });
-
- REQUIRE(pgh.dependencies.size() == 0);
- REQUIRE(pgh.default_features.size() == 1);
- REQUIRE(pgh.default_features[0] == "a1");
-}
-
-TEST_CASE ("parse paragraphs empty", "[paragraph]")
-{
- const char* str = "";
- auto pghs = vcpkg::Paragraphs::parse_paragraphs(str, "").value_or_exit(VCPKG_LINE_INFO);
- REQUIRE(pghs.empty());
-}
-
-TEST_CASE ("parse paragraphs one field", "[paragraph]")
-{
- const char* str = "f1: v1";
- auto pghs = vcpkg::Paragraphs::parse_paragraphs(str, "").value_or_exit(VCPKG_LINE_INFO);
- REQUIRE(pghs.size() == 1);
- REQUIRE(pghs[0].size() == 1);
- REQUIRE(pghs[0]["f1"].first == "v1");
-}
-
-TEST_CASE ("parse paragraphs one pgh", "[paragraph]")
-{
- const char* str = "f1: v1\n"
- "f2: v2";
- auto pghs = vcpkg::Paragraphs::parse_paragraphs(str, "").value_or_exit(VCPKG_LINE_INFO);
- REQUIRE(pghs.size() == 1);
- REQUIRE(pghs[0].size() == 2);
- REQUIRE(pghs[0]["f1"].first == "v1");
- REQUIRE(pghs[0]["f2"].first == "v2");
-}
-
-TEST_CASE ("parse paragraphs two pgh", "[paragraph]")
-{
- const char* str = "f1: v1\n"
- "f2: v2\n"
- "\n"
- "f3: v3\n"
- "f4: v4";
- auto pghs = vcpkg::Paragraphs::parse_paragraphs(str, "").value_or_exit(VCPKG_LINE_INFO);
-
- REQUIRE(pghs.size() == 2);
- REQUIRE(pghs[0].size() == 2);
- REQUIRE(pghs[0]["f1"].first == "v1");
- REQUIRE(pghs[0]["f2"].first == "v2");
- REQUIRE(pghs[1].size() == 2);
- REQUIRE(pghs[1]["f3"].first == "v3");
- REQUIRE(pghs[1]["f4"].first == "v4");
-}
-
-TEST_CASE ("parse paragraphs field names", "[paragraph]")
-{
- const char* str = "1:\n"
- "f:\n"
- "F:\n"
- "0:\n"
- "F-2:\n";
- auto pghs = vcpkg::Paragraphs::parse_paragraphs(str, "").value_or_exit(VCPKG_LINE_INFO);
-
- REQUIRE(pghs.size() == 1);
- REQUIRE(pghs[0].size() == 5);
-}
-
-TEST_CASE ("parse paragraphs multiple blank lines", "[paragraph]")
-{
- const char* str = "f1: v1\n"
- "f2: v2\n"
- "\n"
- "\n"
- "f3: v3\n"
- "f4: v4";
- auto pghs = vcpkg::Paragraphs::parse_paragraphs(str, "").value_or_exit(VCPKG_LINE_INFO);
-
- REQUIRE(pghs.size() == 2);
-}
-
-TEST_CASE ("parse paragraphs empty fields", "[paragraph]")
-{
- const char* str = "f1:\n"
- "f2: ";
- auto pghs = vcpkg::Paragraphs::parse_paragraphs(str, "").value_or_exit(VCPKG_LINE_INFO);
-
- REQUIRE(pghs.size() == 1);
- REQUIRE(pghs[0].size() == 2);
- REQUIRE(pghs[0]["f1"].first.empty());
- REQUIRE(pghs[0]["f2"].first.empty());
- REQUIRE(pghs[0].size() == 2);
-}
-
-TEST_CASE ("parse paragraphs multiline fields", "[paragraph]")
-{
- const char* str = "f1: simple\n"
- " f1\r\n"
- "f2:\r\n"
- " f2\r\n"
- " continue\r\n";
- auto pghs = vcpkg::Paragraphs::parse_paragraphs(str, "").value_or_exit(VCPKG_LINE_INFO);
-
- REQUIRE(pghs.size() == 1);
- REQUIRE(pghs[0]["f1"].first == "simple\n f1");
- REQUIRE(pghs[0]["f2"].first == "\n f2\n continue");
-}
-
-TEST_CASE ("parse paragraphs crlfs", "[paragraph]")
-{
- const char* str = "f1: v1\r\n"
- "f2: v2\r\n"
- "\r\n"
- "f3: v3\r\n"
- "f4: v4";
- auto pghs = vcpkg::Paragraphs::parse_paragraphs(str, "").value_or_exit(VCPKG_LINE_INFO);
-
- REQUIRE(pghs.size() == 2);
- REQUIRE(pghs[0].size() == 2);
- REQUIRE(pghs[0]["f1"].first == "v1");
- REQUIRE(pghs[0]["f2"].first == "v2");
- REQUIRE(pghs[1].size() == 2);
- REQUIRE(pghs[1]["f3"].first == "v3");
- REQUIRE(pghs[1]["f4"].first == "v4");
-}
-
-TEST_CASE ("parse paragraphs comment", "[paragraph]")
-{
- const char* str = "f1: v1\r\n"
- "#comment\r\n"
- "f2: v2\r\n"
- "#comment\r\n"
- "\r\n"
- "#comment\r\n"
- "f3: v3\r\n"
- "#comment\r\n"
- "f4: v4";
- auto pghs = vcpkg::Paragraphs::parse_paragraphs(str, "").value_or_exit(VCPKG_LINE_INFO);
-
- REQUIRE(pghs.size() == 2);
- REQUIRE(pghs[0].size() == 2);
- REQUIRE(pghs[0]["f1"].first == "v1");
- REQUIRE(pghs[0]["f2"].first == "v2");
- REQUIRE(pghs[1].size());
- REQUIRE(pghs[1]["f3"].first == "v3");
- REQUIRE(pghs[1]["f4"].first == "v4");
-}
-
-TEST_CASE ("parse comment before single line feed", "[paragraph]")
-{
- const char* str = "f1: v1\r\n"
- "#comment\n";
- auto pghs = vcpkg::Paragraphs::parse_paragraphs(str, "").value_or_exit(VCPKG_LINE_INFO);
- REQUIRE(pghs[0].size() == 1);
- REQUIRE(pghs[0]["f1"].first == "v1");
-}
-
-TEST_CASE ("BinaryParagraph serialize min", "[paragraph]")
-{
- auto pgh = test_make_binary_paragraph({
- {"Package", "zlib"},
- {"Version", "1.2.8"},
- {"Architecture", "x86-windows"},
- {"Multi-Arch", "same"},
- });
- std::string ss = Strings::serialize(pgh);
- auto pghs = vcpkg::Paragraphs::parse_paragraphs(ss, "").value_or_exit(VCPKG_LINE_INFO);
-
- REQUIRE(pghs.size() == 1);
- REQUIRE(pghs[0].size() == 5);
- REQUIRE(pghs[0]["Package"].first == "zlib");
- REQUIRE(pghs[0]["Version"].first == "1.2.8");
- REQUIRE(pghs[0]["Architecture"].first == "x86-windows");
- REQUIRE(pghs[0]["Multi-Arch"].first == "same");
- REQUIRE(pghs[0]["Type"].first == "Port");
-}
-
-TEST_CASE ("BinaryParagraph serialize max", "[paragraph]")
-{
- auto pgh = test_make_binary_paragraph({
- {"Package", "zlib"},
- {"Version", "1.2.8"},
- {"Architecture", "x86-windows"},
- {"Description", "first line\n second line"},
- {"Maintainer", "abc <abc@abc.abc>"},
- {"Depends", "dep"},
- {"Multi-Arch", "same"},
- });
- std::string ss = Strings::serialize(pgh);
- auto pghs = vcpkg::Paragraphs::parse_paragraphs(ss, "").value_or_exit(VCPKG_LINE_INFO);
-
- REQUIRE(pghs.size() == 1);
- REQUIRE(pghs[0].size() == 8);
- REQUIRE(pghs[0]["Package"].first == "zlib");
- REQUIRE(pghs[0]["Version"].first == "1.2.8");
- REQUIRE(pghs[0]["Architecture"].first == "x86-windows");
- REQUIRE(pghs[0]["Multi-Arch"].first == "same");
- REQUIRE(pghs[0]["Description"].first == "first line\n second line");
- REQUIRE(pghs[0]["Depends"].first == "dep");
- REQUIRE(pghs[0]["Type"].first == "Port");
-}
-
-TEST_CASE ("BinaryParagraph serialize multiple deps", "[paragraph]")
-{
- auto pgh = test_make_binary_paragraph({
- {"Package", "zlib"},
- {"Version", "1.2.8"},
- {"Architecture", "x86-windows"},
- {"Multi-Arch", "same"},
- {"Depends", "a, b, c"},
- });
- std::string ss = Strings::serialize(pgh);
- auto pghs = vcpkg::Paragraphs::parse_paragraphs(ss, "").value_or_exit(VCPKG_LINE_INFO);
-
- REQUIRE(pghs.size() == 1);
- REQUIRE(pghs[0]["Depends"].first == "a, b, c");
-}
-
-TEST_CASE ("BinaryParagraph serialize abi", "[paragraph]")
-{
- auto pgh = test_make_binary_paragraph({
- {"Package", "zlib"},
- {"Version", "1.2.8"},
- {"Architecture", "x86-windows"},
- {"Multi-Arch", "same"},
- {"Depends", "a, b, c"},
- {"Abi", "123abc"},
- });
- std::string ss = Strings::serialize(pgh);
- auto pghs = vcpkg::Paragraphs::parse_paragraphs(ss, "").value_or_exit(VCPKG_LINE_INFO);
-
- REQUIRE(pghs.size() == 1);
- REQUIRE(pghs[0]["Abi"].first == "123abc");
-}
diff --git a/toolsrc/src/vcpkg-test/plan.cpp b/toolsrc/src/vcpkg-test/plan.cpp
deleted file mode 100644
index 363a2d9b4..000000000
--- a/toolsrc/src/vcpkg-test/plan.cpp
+++ /dev/null
@@ -1,1297 +0,0 @@
-#include <catch2/catch.hpp>
-
-#include <vcpkg/base/graphs.h>
-
-#include <vcpkg/dependencies.h>
-#include <vcpkg/portfileprovider.h>
-#include <vcpkg/sourceparagraph.h>
-#include <vcpkg/triplet.h>
-
-#include <memory>
-#include <unordered_map>
-#include <vector>
-
-#include <vcpkg-test/mockcmakevarprovider.h>
-#include <vcpkg-test/util.h>
-
-using namespace vcpkg;
-
-using Test::make_control_file;
-using Test::make_status_feature_pgh;
-using Test::make_status_pgh;
-using Test::MockCMakeVarProvider;
-using Test::PackageSpecMap;
-
-/// <summary>
-/// Assert that the given action an install of given features from given package.
-/// </summary>
-static void features_check(Dependencies::InstallPlanAction& plan,
- std::string pkg_name,
- std::vector<std::string> expected_features,
- Triplet triplet = Test::X86_WINDOWS)
-{
- const auto& feature_list = plan.feature_list;
-
- REQUIRE(plan.spec.triplet().to_string() == triplet.to_string());
- REQUIRE(pkg_name == plan.spec.name());
- REQUIRE(feature_list.size() == expected_features.size());
-
- for (auto&& feature_name : expected_features)
- {
- // TODO: see if this can be simplified
- if (feature_name == "core" || feature_name.empty())
- {
- REQUIRE((Util::find(feature_list, "core") != feature_list.end() ||
- Util::find(feature_list, "") != feature_list.end()));
- continue;
- }
- REQUIRE(Util::find(feature_list, feature_name) != feature_list.end());
- }
-}
-
-/// <summary>
-/// Assert that the given action is a remove of given package.
-/// </summary>
-static void remove_plan_check(Dependencies::RemovePlanAction& plan,
- std::string pkg_name,
- Triplet triplet = Test::X86_WINDOWS)
-{
- REQUIRE(plan.spec.triplet().to_string() == triplet.to_string());
- REQUIRE(pkg_name == plan.spec.name());
-}
-
-TEST_CASE ("basic install scheme", "[plan]")
-{
- std::vector<std::unique_ptr<StatusParagraph>> status_paragraphs;
-
- PackageSpecMap spec_map;
- auto spec_a = spec_map.emplace("a", "b");
- auto spec_b = spec_map.emplace("b", "c");
- auto spec_c = spec_map.emplace("c");
-
- PortFileProvider::MapPortFileProvider map_port(spec_map.map);
- MockCMakeVarProvider var_provider;
-
- auto install_plan = Dependencies::create_feature_install_plan(
- map_port, var_provider, {FullPackageSpec{spec_a, {}}}, StatusParagraphs(std::move(status_paragraphs)));
-
- REQUIRE(install_plan.size() == 3);
- REQUIRE(install_plan.install_actions.at(0).spec.name() == "c");
- REQUIRE(install_plan.install_actions.at(1).spec.name() == "b");
- REQUIRE(install_plan.install_actions.at(2).spec.name() == "a");
-}
-
-TEST_CASE ("multiple install scheme", "[plan]")
-{
- std::vector<std::unique_ptr<StatusParagraph>> status_paragraphs;
-
- PackageSpecMap spec_map;
- auto spec_a = spec_map.emplace("a", "d");
- auto spec_b = spec_map.emplace("b", "d, e");
- auto spec_c = spec_map.emplace("c", "e, h");
- auto spec_d = spec_map.emplace("d", "f, g, h");
- auto spec_e = spec_map.emplace("e", "g");
- auto spec_f = spec_map.emplace("f");
- auto spec_g = spec_map.emplace("g");
- auto spec_h = spec_map.emplace("h");
-
- PortFileProvider::MapPortFileProvider map_port(spec_map.map);
- MockCMakeVarProvider var_provider;
-
- auto install_plan = Dependencies::create_feature_install_plan(
- map_port,
- var_provider,
- {FullPackageSpec{spec_a}, FullPackageSpec{spec_b}, FullPackageSpec{spec_c}},
- StatusParagraphs(std::move(status_paragraphs)));
-
- auto iterator_pos = [&](const PackageSpec& spec) {
- auto it = std::find_if(install_plan.install_actions.begin(),
- install_plan.install_actions.end(),
- [&](auto& action) { return action.spec == spec; });
- REQUIRE(it != install_plan.install_actions.end());
- return it - install_plan.install_actions.begin();
- };
-
- const auto a_pos = iterator_pos(spec_a);
- const auto b_pos = iterator_pos(spec_b);
- const auto c_pos = iterator_pos(spec_c);
- const auto d_pos = iterator_pos(spec_d);
- const auto e_pos = iterator_pos(spec_e);
- const auto f_pos = iterator_pos(spec_f);
- const auto g_pos = iterator_pos(spec_g);
- const auto h_pos = iterator_pos(spec_h);
-
- REQUIRE(a_pos > d_pos);
- REQUIRE(b_pos > e_pos);
- REQUIRE(b_pos > d_pos);
- REQUIRE(c_pos > e_pos);
- REQUIRE(c_pos > h_pos);
- REQUIRE(d_pos > f_pos);
- REQUIRE(d_pos > g_pos);
- REQUIRE(d_pos > h_pos);
- REQUIRE(e_pos > g_pos);
-}
-
-TEST_CASE ("existing package scheme", "[plan]")
-{
- std::vector<std::unique_ptr<StatusParagraph>> status_paragraphs;
- status_paragraphs.push_back(vcpkg::Test::make_status_pgh("a"));
-
- PackageSpecMap spec_map;
- auto spec_a = FullPackageSpec{spec_map.emplace("a")};
-
- PortFileProvider::MapPortFileProvider map_port{spec_map.map};
- MockCMakeVarProvider var_provider;
-
- auto install_plan = Dependencies::create_feature_install_plan(
- map_port, var_provider, {spec_a}, StatusParagraphs(std::move(status_paragraphs)));
-
- REQUIRE(install_plan.size() == 1);
- const auto p = &install_plan.already_installed.at(0);
- REQUIRE(p->spec.name() == "a");
- REQUIRE(p->plan_type == Dependencies::InstallPlanType::ALREADY_INSTALLED);
- REQUIRE(p->request_type == Dependencies::RequestType::USER_REQUESTED);
-}
-
-TEST_CASE ("user requested package scheme", "[plan]")
-{
- std::vector<std::unique_ptr<StatusParagraph>> status_paragraphs;
-
- PackageSpecMap spec_map;
- const auto spec_a = FullPackageSpec{spec_map.emplace("a", "b")};
- const auto spec_b = FullPackageSpec{spec_map.emplace("b")};
-
- PortFileProvider::MapPortFileProvider map_port{spec_map.map};
- MockCMakeVarProvider var_provider;
-
- const auto install_plan = Dependencies::create_feature_install_plan(
- map_port, var_provider, {spec_a}, StatusParagraphs(std::move(status_paragraphs)));
-
- REQUIRE(install_plan.size() == 2);
- const auto p = &install_plan.install_actions.at(0);
- REQUIRE(p->spec.name() == "b");
- REQUIRE(p->plan_type == Dependencies::InstallPlanType::BUILD_AND_INSTALL);
- REQUIRE(p->request_type == Dependencies::RequestType::AUTO_SELECTED);
-
- const auto p2 = &install_plan.install_actions.at(1);
- REQUIRE(p2->spec.name() == "a");
- REQUIRE(p2->plan_type == Dependencies::InstallPlanType::BUILD_AND_INSTALL);
- REQUIRE(p2->request_type == Dependencies::RequestType::USER_REQUESTED);
-}
-
-TEST_CASE ("long install scheme", "[plan]")
-{
- std::vector<std::unique_ptr<StatusParagraph>> status_paragraphs;
- status_paragraphs.push_back(make_status_pgh("j", "k"));
- status_paragraphs.push_back(make_status_pgh("k"));
-
- PackageSpecMap spec_map;
-
- auto spec_a = spec_map.emplace("a", "b, c, d, e, f, g, h, j, k");
- auto spec_b = spec_map.emplace("b", "c, d, e, f, g, h, j, k");
- auto spec_c = spec_map.emplace("c", "d, e, f, g, h, j, k");
- auto spec_d = spec_map.emplace("d", "e, f, g, h, j, k");
- auto spec_e = spec_map.emplace("e", "f, g, h, j, k");
- auto spec_f = spec_map.emplace("f", "g, h, j, k");
- auto spec_g = spec_map.emplace("g", "h, j, k");
- auto spec_h = spec_map.emplace("h", "j, k");
- auto spec_j = spec_map.emplace("j", "k");
- auto spec_k = spec_map.emplace("k");
-
- PortFileProvider::MapPortFileProvider map_port(spec_map.map);
- MockCMakeVarProvider var_provider;
- auto plan = Dependencies::create_feature_install_plan(
- map_port, var_provider, {FullPackageSpec{spec_a}}, StatusParagraphs(std::move(status_paragraphs)));
-
- auto& install_plan = plan.install_actions;
- REQUIRE(install_plan.size() == 8);
- REQUIRE(install_plan.at(0).spec.name() == "h");
- REQUIRE(install_plan.at(1).spec.name() == "g");
- REQUIRE(install_plan.at(2).spec.name() == "f");
- REQUIRE(install_plan.at(3).spec.name() == "e");
- REQUIRE(install_plan.at(4).spec.name() == "d");
- REQUIRE(install_plan.at(5).spec.name() == "c");
- REQUIRE(install_plan.at(6).spec.name() == "b");
- REQUIRE(install_plan.at(7).spec.name() == "a");
-}
-
-TEST_CASE ("basic feature test 1", "[plan]")
-{
- std::vector<std::unique_ptr<StatusParagraph>> status_paragraphs;
- status_paragraphs.push_back(make_status_pgh("a", "b, b[b1]"));
- status_paragraphs.push_back(make_status_pgh("b"));
- status_paragraphs.push_back(make_status_feature_pgh("b", "b1"));
-
- PackageSpecMap spec_map;
- auto spec_a = FullPackageSpec{spec_map.emplace("a", "b, b[b1]", {{"a1", "b[b2]"}}), {"a1"}};
- auto spec_b = FullPackageSpec{spec_map.emplace("b", "", {{"b1", ""}, {"b2", ""}, {"b3", ""}})};
-
- PortFileProvider::MapPortFileProvider map_port{spec_map.map};
- MockCMakeVarProvider var_provider;
-
- auto plan = Dependencies::create_feature_install_plan(
- map_port, var_provider, {spec_a}, StatusParagraphs(std::move(status_paragraphs)));
-
- REQUIRE(plan.size() == 4);
- remove_plan_check(plan.remove_actions.at(0), "a");
- remove_plan_check(plan.remove_actions.at(1), "b");
- features_check(plan.install_actions.at(0), "b", {"b1", "core", "b1"});
- features_check(plan.install_actions.at(1), "a", {"a1", "core"});
-}
-
-TEST_CASE ("basic feature test 2", "[plan]")
-{
- std::vector<std::unique_ptr<StatusParagraph>> status_paragraphs;
-
- PackageSpecMap spec_map;
-
- auto spec_a = FullPackageSpec{spec_map.emplace("a", "b[b1]", {{"a1", "b[b2]"}}), {"a1"}};
- auto spec_b = FullPackageSpec{spec_map.emplace("b", "", {{"b1", ""}, {"b2", ""}, {"b3", ""}})};
-
- PortFileProvider::MapPortFileProvider map_port{spec_map.map};
- MockCMakeVarProvider var_provider;
-
- auto plan = Dependencies::create_feature_install_plan(
- map_port, var_provider, {spec_a}, StatusParagraphs(std::move(status_paragraphs)));
-
- auto& install_plan = plan.install_actions;
- REQUIRE(install_plan.size() == 2);
- features_check(install_plan.at(0), "b", {"b1", "b2", "core"});
- features_check(install_plan.at(1), "a", {"a1", "core"});
-}
-
-TEST_CASE ("basic feature test 3", "[plan]")
-{
- std::vector<std::unique_ptr<StatusParagraph>> status_paragraphs;
- status_paragraphs.push_back(make_status_pgh("a"));
-
- PackageSpecMap spec_map;
-
- auto spec_a = FullPackageSpec{spec_map.emplace("a", "b", {{"a1", ""}}), {"core"}};
- auto spec_b = FullPackageSpec{spec_map.emplace("b")};
- auto spec_c = FullPackageSpec{spec_map.emplace("c", "a[a1]"), {"core"}};
-
- PortFileProvider::MapPortFileProvider map_port{spec_map.map};
- MockCMakeVarProvider var_provider;
-
- auto plan = Dependencies::create_feature_install_plan(
- map_port, var_provider, {spec_c, spec_a}, StatusParagraphs(std::move(status_paragraphs)));
-
- REQUIRE(plan.size() == 4);
- remove_plan_check(plan.remove_actions.at(0), "a");
- auto& install_plan = plan.install_actions;
- features_check(install_plan.at(0), "b", {"core"});
- features_check(install_plan.at(1), "a", {"a1", "core"});
- features_check(install_plan.at(2), "c", {"core"});
-}
-
-TEST_CASE ("basic feature test 4", "[plan]")
-{
- std::vector<std::unique_ptr<StatusParagraph>> status_paragraphs;
- status_paragraphs.push_back(make_status_pgh("a"));
- status_paragraphs.push_back(make_status_feature_pgh("a", "a1", ""));
-
- PackageSpecMap spec_map;
-
- auto spec_a = FullPackageSpec{spec_map.emplace("a", "b", {{"a1", ""}})};
- auto spec_b = FullPackageSpec{spec_map.emplace("b")};
- auto spec_c = FullPackageSpec{spec_map.emplace("c", "a[a1]"), {"core"}};
-
- PortFileProvider::MapPortFileProvider map_port{spec_map.map};
- MockCMakeVarProvider var_provider;
-
- auto install_plan = Dependencies::create_feature_install_plan(
- map_port, var_provider, {spec_c}, StatusParagraphs(std::move(status_paragraphs)));
-
- REQUIRE(install_plan.size() == 1);
- features_check(install_plan.install_actions.at(0), "c", {"core"});
-}
-
-TEST_CASE ("basic feature test 5", "[plan]")
-{
- std::vector<std::unique_ptr<StatusParagraph>> status_paragraphs;
-
- PackageSpecMap spec_map;
-
- auto spec_a =
- FullPackageSpec{spec_map.emplace("a", "", {{"a1", "b[b1]"}, {"a2", "b[b2]"}, {"a3", "a[a2]"}}), {"a3"}};
- auto spec_b = FullPackageSpec{spec_map.emplace("b", "", {{"b1", ""}, {"b2", ""}})};
-
- PortFileProvider::MapPortFileProvider map_port{spec_map.map};
- MockCMakeVarProvider var_provider;
-
- auto install_plan = Dependencies::create_feature_install_plan(
- map_port, var_provider, {spec_a}, StatusParagraphs(std::move(status_paragraphs)));
-
- REQUIRE(install_plan.size() == 2);
- features_check(install_plan.install_actions.at(0), "b", {"core", "b2"});
- features_check(install_plan.install_actions.at(1), "a", {"core", "a3", "a2"});
-}
-
-TEST_CASE ("basic feature test 6", "[plan]")
-{
- std::vector<std::unique_ptr<StatusParagraph>> status_paragraphs;
- status_paragraphs.push_back(make_status_pgh("b"));
-
- PackageSpecMap spec_map;
- auto spec_a = FullPackageSpec{spec_map.emplace("a", "b[core]"), {"core"}};
- auto spec_b = FullPackageSpec{spec_map.emplace("b", "", {{"b1", ""}}), {"b1"}};
-
- PortFileProvider::MapPortFileProvider map_port{spec_map.map};
- MockCMakeVarProvider var_provider;
-
- auto plan = Dependencies::create_feature_install_plan(
- map_port, var_provider, {spec_a, spec_b}, StatusParagraphs(std::move(status_paragraphs)));
-
- REQUIRE(plan.size() == 3);
- remove_plan_check(plan.remove_actions.at(0), "b");
- features_check(plan.install_actions.at(0), "b", {"core", "b1"});
- features_check(plan.install_actions.at(1), "a", {"core"});
-}
-
-TEST_CASE ("basic feature test 7", "[plan]")
-{
- std::vector<std::unique_ptr<StatusParagraph>> status_paragraphs;
- status_paragraphs.push_back(make_status_pgh("x", "b"));
- status_paragraphs.push_back(make_status_pgh("b"));
-
- PackageSpecMap spec_map;
-
- auto spec_a = FullPackageSpec{spec_map.emplace("a")};
- auto spec_x = FullPackageSpec{spec_map.emplace("x", "a"), {"core"}};
- auto spec_b = FullPackageSpec{spec_map.emplace("b", "", {{"b1", ""}}), {"b1"}};
-
- PortFileProvider::MapPortFileProvider map_port{spec_map.map};
- MockCMakeVarProvider var_provider;
-
- auto plan = Dependencies::create_feature_install_plan(
- map_port, var_provider, {spec_b}, StatusParagraphs(std::move(status_paragraphs)));
-
- REQUIRE(plan.size() == 5);
- remove_plan_check(plan.remove_actions.at(0), "x");
- remove_plan_check(plan.remove_actions.at(1), "b");
-
- features_check(plan.install_actions.at(0), "a", {"core"});
- features_check(plan.install_actions.at(1), "b", {"core", "b1"});
- features_check(plan.install_actions.at(2), "x", {"core"});
-}
-
-TEST_CASE ("basic feature test 8", "[plan]")
-{
- std::vector<std::unique_ptr<StatusParagraph>> status_paragraphs;
- status_paragraphs.push_back(make_status_pgh("a"));
- status_paragraphs.push_back(make_status_pgh("a"));
- status_paragraphs.back()->package.spec = PackageSpec("a", Test::X64_WINDOWS);
-
- PackageSpecMap spec_map(Test::X64_WINDOWS);
- auto spec_a_64 = FullPackageSpec{spec_map.emplace("a", "b", {{"a1", ""}}), {"core"}};
- auto spec_b_64 = FullPackageSpec{spec_map.emplace("b")};
- auto spec_c_64 = FullPackageSpec{spec_map.emplace("c", "a[a1]"), {"core"}};
-
- spec_map.triplet = Test::X86_WINDOWS;
- auto spec_a_86 = FullPackageSpec{PackageSpec{"a", Test::X86_WINDOWS}};
- auto spec_b_86 = FullPackageSpec{PackageSpec{"b", Test::X86_WINDOWS}};
- auto spec_c_86 = FullPackageSpec{PackageSpec{"c", Test::X86_WINDOWS}};
-
- PortFileProvider::MapPortFileProvider map_port{spec_map.map};
- MockCMakeVarProvider var_provider;
-
- auto plan = Dependencies::create_feature_install_plan(map_port,
- var_provider,
- {spec_c_64, spec_a_86, spec_a_64, spec_c_86},
- StatusParagraphs(std::move(status_paragraphs)));
-
- remove_plan_check(plan.remove_actions.at(0), "a", Test::X64_WINDOWS);
- remove_plan_check(plan.remove_actions.at(1), "a");
- auto& install_plan = plan.install_actions;
- features_check(install_plan.at(0), "b", {"core"}, Test::X64_WINDOWS);
- features_check(install_plan.at(1), "a", {"a1", "core"}, Test::X64_WINDOWS);
- features_check(install_plan.at(2), "b", {"core"});
- features_check(install_plan.at(3), "a", {"a1", "core"});
- features_check(install_plan.at(4), "c", {"core"}, Test::X64_WINDOWS);
- features_check(install_plan.at(5), "c", {"core"});
-}
-
-TEST_CASE ("install all features test", "[plan]")
-{
- std::vector<std::unique_ptr<StatusParagraph>> status_paragraphs;
-
- PackageSpecMap spec_map(Test::X64_WINDOWS);
- auto spec_a_64 = FullPackageSpec{spec_map.emplace("a", "", {{"0", ""}, {"1", ""}}), {"core"}};
-
- auto install_specs = FullPackageSpec::from_string("a[*]", Test::X64_WINDOWS);
- REQUIRE(install_specs.has_value());
- if (!install_specs.has_value()) return;
-
- PortFileProvider::MapPortFileProvider map_port{spec_map.map};
- MockCMakeVarProvider var_provider;
-
- auto install_plan = Dependencies::create_feature_install_plan(map_port,
- var_provider,
- {install_specs.value_or_exit(VCPKG_LINE_INFO)},
- StatusParagraphs(std::move(status_paragraphs)));
-
- REQUIRE(install_plan.size() == 1);
- features_check(install_plan.install_actions.at(0), "a", {"0", "1", "core"}, Test::X64_WINDOWS);
-}
-
-TEST_CASE ("install default features test 1", "[plan]")
-{
- std::vector<std::unique_ptr<StatusParagraph>> status_paragraphs;
-
- // Add a port "a" with default features "1" and features "0" and "1".
- PackageSpecMap spec_map(Test::X64_WINDOWS);
- spec_map.emplace("a", "", {{"0", ""}, {"1", ""}}, {"1"});
-
- // Install "a" (without explicit feature specification)
- auto install_specs = FullPackageSpec::from_string("a", Test::X64_WINDOWS);
-
- PortFileProvider::MapPortFileProvider map_port{spec_map.map};
- MockCMakeVarProvider var_provider;
-
- auto install_plan = Dependencies::create_feature_install_plan(map_port,
- var_provider,
- {install_specs.value_or_exit(VCPKG_LINE_INFO)},
- StatusParagraphs(std::move(status_paragraphs)));
-
- // Expect the default feature "1" to be installed, but not "0"
- REQUIRE(install_plan.size() == 1);
- features_check(install_plan.install_actions.at(0), "a", {"1", "core"}, Test::X64_WINDOWS);
-}
-
-TEST_CASE ("install default features test 2", "[plan]")
-{
- std::vector<std::unique_ptr<StatusParagraph>> status_paragraphs;
- status_paragraphs.push_back(make_status_pgh("a"));
- status_paragraphs.back()->package.spec = PackageSpec("a", Test::X64_WINDOWS);
-
- // Add a port "a" of which "core" is already installed, but we will
- // install the default features "explicitly"
- // "a" has two features, of which "a1" is default.
- PackageSpecMap spec_map(Test::X64_WINDOWS);
- spec_map.emplace("a", "", {{"a0", ""}, {"a1", ""}}, {"a1"});
-
- // Install "a" (without explicit feature specification)
- auto install_specs = FullPackageSpec::from_string("a", Test::X64_WINDOWS);
-
- PortFileProvider::MapPortFileProvider map_port{spec_map.map};
- MockCMakeVarProvider var_provider;
-
- auto install_plan = Dependencies::create_feature_install_plan(map_port,
- var_provider,
- {install_specs.value_or_exit(VCPKG_LINE_INFO)},
- StatusParagraphs(std::move(status_paragraphs)));
-
- // Expect "a" to get removed for rebuild and then installed with default
- // features.
- REQUIRE(install_plan.size() == 2);
- remove_plan_check(install_plan.remove_actions.at(0), "a", Test::X64_WINDOWS);
- features_check(install_plan.install_actions.at(0), "a", {"a1", "core"}, Test::X64_WINDOWS);
-}
-
-TEST_CASE ("install default features test 3", "[plan]")
-{
- std::vector<std::unique_ptr<StatusParagraph>> status_paragraphs;
-
- // "a" has two features, of which "a1" is default.
- PackageSpecMap spec_map(Test::X64_WINDOWS);
- spec_map.emplace("a", "", {{"a0", ""}, {"a1", ""}}, {"a1"});
-
- // Explicitly install "a" without default features
- auto install_specs = FullPackageSpec::from_string("a[core]", Test::X64_WINDOWS);
-
- PortFileProvider::MapPortFileProvider map_port{spec_map.map};
- MockCMakeVarProvider var_provider;
-
- auto install_plan = Dependencies::create_feature_install_plan(map_port,
- var_provider,
- {install_specs.value_or_exit(VCPKG_LINE_INFO)},
- StatusParagraphs(std::move(status_paragraphs)));
-
- // Expect the default feature not to get installed.
- REQUIRE(install_plan.size() == 1);
- features_check(install_plan.install_actions.at(0), "a", {"core"}, Test::X64_WINDOWS);
-}
-
-TEST_CASE ("install default features of dependency test 1", "[plan]")
-{
- std::vector<std::unique_ptr<StatusParagraph>> status_paragraphs;
-
- // Add a port "a" which depends on the core of "b"
- PackageSpecMap spec_map(Test::X64_WINDOWS);
- spec_map.emplace("a", "b[core]");
- // "b" has two features, of which "b1" is default.
- spec_map.emplace("b", "", {{"b0", ""}, {"b1", ""}}, {"b1"});
-
- // Install "a" (without explicit feature specification)
- auto install_specs = FullPackageSpec::from_string("a", Test::X64_WINDOWS);
- PortFileProvider::MapPortFileProvider map_port{spec_map.map};
- MockCMakeVarProvider var_provider;
-
- auto install_plan = Dependencies::create_feature_install_plan(map_port,
- var_provider,
- {install_specs.value_or_exit(VCPKG_LINE_INFO)},
- StatusParagraphs(std::move(status_paragraphs)));
-
- // Expect "a" to get installed and defaults of "b" through the dependency,
- // as no explicit features of "b" are installed by the user.
- REQUIRE(install_plan.size() == 2);
- features_check(install_plan.install_actions.at(0), "b", {"b1", "core"}, Test::X64_WINDOWS);
- features_check(install_plan.install_actions.at(1), "a", {"core"}, Test::X64_WINDOWS);
-}
-
-TEST_CASE ("do not install default features of dependency test 1", "[plan]")
-{
- std::vector<std::unique_ptr<StatusParagraph>> status_paragraphs;
-
- // Add a port "a" which depends on the core of "b"
- PackageSpecMap spec_map(Test::X64_WINDOWS);
- spec_map.emplace("a", "b[core]");
- // "b" has two features, of which "b1" is default.
- spec_map.emplace("b", "", {{"b0", ""}, {"b1", ""}}, {"b1"});
-
- // Install "a" (without explicit feature specification)
- auto spec_a = FullPackageSpec::from_string("a", Test::X64_WINDOWS);
- auto spec_b = FullPackageSpec::from_string("b[core]", Test::X64_WINDOWS);
- PortFileProvider::MapPortFileProvider map_port{spec_map.map};
- MockCMakeVarProvider var_provider;
-
- auto install_plan = Dependencies::create_feature_install_plan(
- map_port,
- var_provider,
- {spec_a.value_or_exit(VCPKG_LINE_INFO), spec_b.value_or_exit(VCPKG_LINE_INFO)},
- StatusParagraphs(std::move(status_paragraphs)));
-
- // Expect "a" to get installed and defaults of "b" through the dependency,
- // as no explicit features of "b" are installed by the user.
- REQUIRE(install_plan.size() == 2);
- features_check(install_plan.install_actions.at(0), "b", {"core"}, Test::X64_WINDOWS);
- features_check(install_plan.install_actions.at(1), "a", {"core"}, Test::X64_WINDOWS);
-}
-
-TEST_CASE ("install default features of dependency test 2", "[plan]")
-{
- std::vector<std::unique_ptr<StatusParagraph>> status_paragraphs;
-
- // Add a port "a" which depends on the default features of "b"
- PackageSpecMap spec_map(Test::X64_WINDOWS);
- spec_map.emplace("a", "b");
- // "b" has two features, of which "b1" is default.
- spec_map.emplace("b", "", {{"b0", ""}, {"b1", ""}}, {"b1"});
-
- // Install "a" (without explicit feature specification)
- auto spec_a = FullPackageSpec::from_string("a", Test::X64_WINDOWS);
- auto spec_b = FullPackageSpec::from_string("b[core]", Test::X64_WINDOWS);
- PortFileProvider::MapPortFileProvider map_port{spec_map.map};
- MockCMakeVarProvider var_provider;
-
- auto install_plan = Dependencies::create_feature_install_plan(
- map_port,
- var_provider,
- {spec_a.value_or_exit(VCPKG_LINE_INFO), spec_b.value_or_exit(VCPKG_LINE_INFO)},
- StatusParagraphs(std::move(status_paragraphs)));
-
- // Expect "a" to get installed and defaults of "b" through the dependency
- REQUIRE(install_plan.size() == 2);
- features_check(install_plan.install_actions.at(0), "b", {"b1", "core"}, Test::X64_WINDOWS);
- features_check(install_plan.install_actions.at(1), "a", {"core"}, Test::X64_WINDOWS);
-}
-
-TEST_CASE ("do not install default features of existing dependency", "[plan]")
-{
- // Add a port "a" which depends on the core of "b"
- PackageSpecMap spec_map(Test::X64_WINDOWS);
- spec_map.emplace("a", "b[core]");
- // "b" has two features, of which "b1" is default.
- spec_map.emplace("b", "", {{"b0", ""}, {"b1", ""}}, {"b1"});
-
- std::vector<std::unique_ptr<StatusParagraph>> status_paragraphs;
- // "b[core]" is already installed
- status_paragraphs.push_back(make_status_pgh("b"));
- status_paragraphs.back()->package.spec = PackageSpec("b", Test::X64_WINDOWS);
-
- // Install "a" (without explicit feature specification)
- auto install_specs = FullPackageSpec::from_string("a", Test::X64_WINDOWS);
- PortFileProvider::MapPortFileProvider map_port{spec_map.map};
- MockCMakeVarProvider var_provider;
-
- auto install_plan = Dependencies::create_feature_install_plan(map_port,
- var_provider,
- {install_specs.value_or_exit(VCPKG_LINE_INFO)},
- StatusParagraphs(std::move(status_paragraphs)));
-
- // Expect "a" to get installed, but not require rebuilding "b"
- REQUIRE(install_plan.size() == 1);
- features_check(install_plan.install_actions.at(0), "a", {"core"}, Test::X64_WINDOWS);
-}
-
-TEST_CASE ("install default features of existing dependency", "[plan]")
-{
- // Add a port "a" which depends on the default features of "b"
- PackageSpecMap spec_map(Test::X64_WINDOWS);
- spec_map.emplace("a", "b");
- // "b" has a default feature
- spec_map.emplace("b", "", {{"b1", ""}}, {"b1"});
-
- std::vector<std::unique_ptr<StatusParagraph>> status_paragraphs;
- // "b[core]" is already installed
- status_paragraphs.push_back(make_status_pgh("b", "", "b1"));
- status_paragraphs.back()->package.spec = PackageSpec("b", Test::X64_WINDOWS);
-
- // Install "a" (without explicit feature specification)
- auto install_specs = FullPackageSpec::from_string("a", Test::X64_WINDOWS);
- PortFileProvider::MapPortFileProvider map_port{spec_map.map};
- MockCMakeVarProvider var_provider;
-
- auto install_plan = Dependencies::create_feature_install_plan(map_port,
- var_provider,
- {install_specs.value_or_exit(VCPKG_LINE_INFO)},
- StatusParagraphs(std::move(status_paragraphs)));
-
- // Expect "b" to be rebuilt
- REQUIRE(install_plan.install_actions.size() == 2);
- features_check(install_plan.install_actions.at(0), "b", {"core", "b1"}, Test::X64_WINDOWS);
-}
-
-TEST_CASE ("install default features of dependency test 3", "[plan]")
-{
- std::vector<std::unique_ptr<StatusParagraph>> status_paragraphs;
- status_paragraphs.push_back(make_status_pgh("b"));
- status_paragraphs.back()->package.spec = PackageSpec("b", Test::X64_WINDOWS);
-
- // Add a port "a" which depends on the core of "b", which was already
- // installed explicitly
- PackageSpecMap spec_map(Test::X64_WINDOWS);
- spec_map.emplace("a", "b[core]");
- // "b" has two features, of which "b1" is default.
- spec_map.emplace("b", "", {{"b0", ""}, {"b1", ""}}, {"b1"});
-
- // Install "a" (without explicit feature specification)
- auto install_specs = FullPackageSpec::from_string("a", Test::X64_WINDOWS);
- PortFileProvider::MapPortFileProvider map_port{spec_map.map};
- MockCMakeVarProvider var_provider;
-
- auto install_plan = Dependencies::create_feature_install_plan(map_port,
- var_provider,
- {install_specs.value_or_exit(VCPKG_LINE_INFO)},
- StatusParagraphs(std::move(status_paragraphs)));
-
- // Expect "a" to get installed, not the defaults of "b", as the required
- // dependencies are already there, installed explicitly by the user.
- REQUIRE(install_plan.size() == 1);
- features_check(install_plan.install_actions.at(0), "a", {"core"}, Test::X64_WINDOWS);
-}
-
-TEST_CASE ("install plan action dependencies", "[plan]")
-{
- std::vector<std::unique_ptr<StatusParagraph>> status_paragraphs;
-
- // Add a port "a" which depends on the core of "b", which was already
- // installed explicitly
- PackageSpecMap spec_map(Test::X64_WINDOWS);
- auto spec_c = spec_map.emplace("c");
- auto spec_b = spec_map.emplace("b", "c");
- spec_map.emplace("a", "b");
-
- // Install "a" (without explicit feature specification)
- auto install_specs = FullPackageSpec::from_string("a", Test::X64_WINDOWS);
- PortFileProvider::MapPortFileProvider map_port{spec_map.map};
- MockCMakeVarProvider var_provider;
-
- auto install_plan = Dependencies::create_feature_install_plan(map_port,
- var_provider,
- {install_specs.value_or_exit(VCPKG_LINE_INFO)},
- StatusParagraphs(std::move(status_paragraphs)));
-
- REQUIRE(install_plan.size() == 3);
- features_check(install_plan.install_actions.at(0), "c", {"core"}, Test::X64_WINDOWS);
-
- // TODO: Figure out what to do with these tests
- features_check(install_plan.install_actions.at(1), "b", {"core"}, Test::X64_WINDOWS);
- // REQUIRE(install_plan.at(1).install_action.get()->computed_dependencies == std::vector<PackageSpec>{spec_c});
-
- features_check(install_plan.install_actions.at(2), "a", {"core"}, Test::X64_WINDOWS);
- // REQUIRE(install_plan.at(2).install_action.get()->computed_dependencies == std::vector<PackageSpec>{spec_b});
-}
-
-TEST_CASE ("install plan action dependencies 2", "[plan]")
-{
- std::vector<std::unique_ptr<StatusParagraph>> status_paragraphs;
-
- // Add a port "a" which depends on the core of "b", which was already
- // installed explicitly
- PackageSpecMap spec_map(Test::X64_WINDOWS);
- auto spec_c = spec_map.emplace("c");
- auto spec_b = spec_map.emplace("b", "c");
- spec_map.emplace("a", "c, b");
-
- // Install "a" (without explicit feature specification)
- auto install_specs = FullPackageSpec::from_string("a", Test::X64_WINDOWS);
- PortFileProvider::MapPortFileProvider map_port{spec_map.map};
- MockCMakeVarProvider var_provider;
-
- auto install_plan = Dependencies::create_feature_install_plan(map_port,
- var_provider,
- {install_specs.value_or_exit(VCPKG_LINE_INFO)},
- StatusParagraphs(std::move(status_paragraphs)));
-
- REQUIRE(install_plan.size() == 3);
- features_check(install_plan.install_actions.at(0), "c", {"core"}, Test::X64_WINDOWS);
-
- features_check(install_plan.install_actions.at(1), "b", {"core"}, Test::X64_WINDOWS);
- // REQUIRE(install_plan.at(1).install_action.get()->computed_dependencies == std::vector<PackageSpec>{spec_c});
-
- features_check(install_plan.install_actions.at(2), "a", {"core"}, Test::X64_WINDOWS);
- // REQUIRE(install_plan.at(2).install_action.get()->computed_dependencies == std::vector<PackageSpec>{spec_b,
- // spec_c});
-}
-
-TEST_CASE ("install plan action dependencies 3", "[plan]")
-{
- std::vector<std::unique_ptr<StatusParagraph>> status_paragraphs;
-
- // Add a port "a" which depends on the core of "b", which was already
- // installed explicitly
- PackageSpecMap spec_map(Test::X64_WINDOWS);
- spec_map.emplace("a", "", {{"0", ""}, {"1", "a[0]"}}, {"1"});
-
- // Install "a" (without explicit feature specification)
- auto install_specs = FullPackageSpec::from_string("a", Test::X64_WINDOWS);
- PortFileProvider::MapPortFileProvider map_port{spec_map.map};
- MockCMakeVarProvider var_provider;
-
- auto install_plan = Dependencies::create_feature_install_plan(map_port,
- var_provider,
- {install_specs.value_or_exit(VCPKG_LINE_INFO)},
- StatusParagraphs(std::move(status_paragraphs)));
-
- REQUIRE(install_plan.size() == 1);
- features_check(install_plan.install_actions.at(0), "a", {"1", "0", "core"}, Test::X64_WINDOWS);
- // REQUIRE(install_plan.at(0).install_action.get()->computed_dependencies == std::vector<PackageSpec>{});
-}
-
-TEST_CASE ("install with default features", "[plan]")
-{
- std::vector<std::unique_ptr<StatusParagraph>> pghs;
- pghs.push_back(make_status_pgh("a", ""));
- StatusParagraphs status_db(std::move(pghs));
-
- PackageSpecMap spec_map;
- auto b_spec = spec_map.emplace("b", "", {{"0", ""}}, {"0"});
- auto a_spec = spec_map.emplace("a", "b[core]", {{"0", ""}});
-
- PortFileProvider::MapPortFileProvider map_port{spec_map.map};
- MockCMakeVarProvider var_provider;
-
- auto install_plan =
- Dependencies::create_feature_install_plan(map_port,
- var_provider,
- {FullPackageSpec{a_spec, {"0"}}, FullPackageSpec{b_spec, {"core"}}},
- StatusParagraphs(std::move(status_db)));
-
- // Install "a" and indicate that "b" should not install default features
- REQUIRE(install_plan.size() == 3);
- remove_plan_check(install_plan.remove_actions.at(0), "a");
- features_check(install_plan.install_actions.at(0), "b", {"core"});
- features_check(install_plan.install_actions.at(1), "a", {"0", "core"});
-}
-
-TEST_CASE ("upgrade with default features 1", "[plan]")
-{
- std::vector<std::unique_ptr<StatusParagraph>> pghs;
- pghs.push_back(make_status_pgh("a", "", "1"));
- pghs.push_back(make_status_feature_pgh("a", "0"));
- StatusParagraphs status_db(std::move(pghs));
-
- // Add a port "a" of which "core" and "0" are already installed.
- PackageSpecMap spec_map;
- auto spec_a = spec_map.emplace("a", "", {{"0", ""}, {"1", ""}}, {"1"});
-
- PortFileProvider::MapPortFileProvider provider(spec_map.map);
- MockCMakeVarProvider var_provider;
- auto plan = Dependencies::create_upgrade_plan(provider, var_provider, {spec_a}, status_db);
-
- // The upgrade should not install the default feature
- REQUIRE(plan.size() == 2);
-
- remove_plan_check(plan.remove_actions.at(0), "a");
- features_check(plan.install_actions.at(0), "a", {"core", "0"});
-}
-
-TEST_CASE ("upgrade with default features 2", "[plan]")
-{
- std::vector<std::unique_ptr<StatusParagraph>> pghs;
- // B is currently installed _without_ default feature b0
- pghs.push_back(make_status_pgh("b", "", "b0", "x64-windows"));
- pghs.push_back(make_status_pgh("a", "b[core]", "", "x64-windows"));
-
- StatusParagraphs status_db(std::move(pghs));
-
- PackageSpecMap spec_map(Test::X64_WINDOWS);
- auto spec_a = spec_map.emplace("a", "b[core]");
- auto spec_b = spec_map.emplace("b", "", {{"b0", ""}, {"b1", ""}}, {"b0", "b1"});
-
- PortFileProvider::MapPortFileProvider provider(spec_map.map);
- MockCMakeVarProvider var_provider;
- auto plan = Dependencies::create_upgrade_plan(provider, var_provider, {spec_a, spec_b}, status_db);
-
- // The upgrade should install the new default feature b1 but not b0
- REQUIRE(plan.size() == 4);
- remove_plan_check(plan.remove_actions.at(0), "a", Test::X64_WINDOWS);
- remove_plan_check(plan.remove_actions.at(1), "b", Test::X64_WINDOWS);
- features_check(plan.install_actions.at(0), "b", {"core", "b1"}, Test::X64_WINDOWS);
- features_check(plan.install_actions.at(1), "a", {"core"}, Test::X64_WINDOWS);
-}
-
-TEST_CASE ("upgrade with default features 3", "[plan]")
-{
- std::vector<std::unique_ptr<StatusParagraph>> pghs;
- // note: unrelated package due to x86 triplet
- pghs.push_back(make_status_pgh("b", "", "", "x86-windows"));
- pghs.push_back(make_status_pgh("a", "", "", "x64-windows"));
-
- StatusParagraphs status_db(std::move(pghs));
-
- PackageSpecMap spec_map(Test::X64_WINDOWS);
- auto spec_a = spec_map.emplace("a", "b[core]");
- spec_map.emplace("b", "", {{"b0", ""}, {"b1", ""}}, {"b0"});
-
- PortFileProvider::MapPortFileProvider provider(spec_map.map);
- MockCMakeVarProvider var_provider;
- auto plan = Dependencies::create_upgrade_plan(provider, var_provider, {spec_a}, status_db);
-
- // The upgrade should install the default feature
- REQUIRE(plan.size() == 3);
- remove_plan_check(plan.remove_actions.at(0), "a", Test::X64_WINDOWS);
- features_check(plan.install_actions.at(0), "b", {"b0", "core"}, Test::X64_WINDOWS);
- features_check(plan.install_actions.at(1), "a", {"core"}, Test::X64_WINDOWS);
-}
-
-TEST_CASE ("upgrade with new default feature", "[plan]")
-{
- std::vector<std::unique_ptr<StatusParagraph>> pghs;
- pghs.push_back(make_status_pgh("a", "", "0", "x86-windows"));
-
- StatusParagraphs status_db(std::move(pghs));
-
- PackageSpecMap spec_map;
- auto spec_a = spec_map.emplace("a", "", {{"0", ""}, {"1", ""}, {"2", ""}}, {"0", "1"});
-
- PortFileProvider::MapPortFileProvider provider(spec_map.map);
- MockCMakeVarProvider var_provider;
- auto plan = Dependencies::create_upgrade_plan(provider, var_provider, {spec_a}, status_db);
-
- // The upgrade should install the new default feature but not the old default feature 0
- REQUIRE(plan.size() == 2);
- remove_plan_check(plan.remove_actions.at(0), "a", Test::X86_WINDOWS);
- features_check(plan.install_actions.at(0), "a", {"core", "1"}, Test::X86_WINDOWS);
-}
-
-TEST_CASE ("transitive features test", "[plan]")
-{
- std::vector<std::unique_ptr<StatusParagraph>> status_paragraphs;
-
- PackageSpecMap spec_map(Test::X64_WINDOWS);
- auto spec_a_64 = FullPackageSpec{spec_map.emplace("a", "b", {{"0", "b[0]"}}), {"core"}};
- auto spec_b_64 = FullPackageSpec{spec_map.emplace("b", "c", {{"0", "c[0]"}}), {"core"}};
- auto spec_c_64 = FullPackageSpec{spec_map.emplace("c", "", {{"0", ""}}), {"core"}};
-
- auto install_specs = FullPackageSpec::from_string("a[*]", Test::X64_WINDOWS);
- REQUIRE(install_specs.has_value());
- if (!install_specs.has_value()) return;
-
- PortFileProvider::MapPortFileProvider provider(spec_map.map);
- MockCMakeVarProvider var_provider;
- auto install_plan = Dependencies::create_feature_install_plan(provider,
- var_provider,
- {install_specs.value_or_exit(VCPKG_LINE_INFO)},
- StatusParagraphs(std::move(status_paragraphs)));
-
- REQUIRE(install_plan.size() == 3);
- features_check(install_plan.install_actions.at(0), "c", {"0", "core"}, Test::X64_WINDOWS);
- features_check(install_plan.install_actions.at(1), "b", {"0", "core"}, Test::X64_WINDOWS);
- features_check(install_plan.install_actions.at(2), "a", {"0", "core"}, Test::X64_WINDOWS);
-}
-
-TEST_CASE ("no transitive features test", "[plan]")
-{
- std::vector<std::unique_ptr<StatusParagraph>> status_paragraphs;
-
- PackageSpecMap spec_map(Test::X64_WINDOWS);
- auto spec_a_64 = FullPackageSpec{spec_map.emplace("a", "b", {{"0", ""}}), {"core"}};
- auto spec_b_64 = FullPackageSpec{spec_map.emplace("b", "c", {{"0", ""}}), {"core"}};
- auto spec_c_64 = FullPackageSpec{spec_map.emplace("c", "", {{"0", ""}}), {"core"}};
-
- auto install_specs = FullPackageSpec::from_string("a[*]", Test::X64_WINDOWS);
- REQUIRE(install_specs.has_value());
- if (!install_specs.has_value()) return;
- PortFileProvider::MapPortFileProvider provider(spec_map.map);
- MockCMakeVarProvider var_provider;
- auto install_plan = Dependencies::create_feature_install_plan(provider,
- var_provider,
- {install_specs.value_or_exit(VCPKG_LINE_INFO)},
- StatusParagraphs(std::move(status_paragraphs)));
-
- REQUIRE(install_plan.size() == 3);
- features_check(install_plan.install_actions.at(0), "c", {"core"}, Test::X64_WINDOWS);
- features_check(install_plan.install_actions.at(1), "b", {"core"}, Test::X64_WINDOWS);
- features_check(install_plan.install_actions.at(2), "a", {"0", "core"}, Test::X64_WINDOWS);
-}
-
-TEST_CASE ("only transitive features test", "[plan]")
-{
- std::vector<std::unique_ptr<StatusParagraph>> status_paragraphs;
-
- PackageSpecMap spec_map(Test::X64_WINDOWS);
- auto spec_a_64 = FullPackageSpec{spec_map.emplace("a", "", {{"0", "b[0]"}}), {"core"}};
- auto spec_b_64 = FullPackageSpec{spec_map.emplace("b", "", {{"0", "c[0]"}}), {"core"}};
- auto spec_c_64 = FullPackageSpec{spec_map.emplace("c", "", {{"0", ""}}), {"core"}};
-
- auto install_specs = FullPackageSpec::from_string("a[*]", Test::X64_WINDOWS);
- REQUIRE(install_specs.has_value());
- if (!install_specs.has_value()) return;
- PortFileProvider::MapPortFileProvider provider(spec_map.map);
- MockCMakeVarProvider var_provider;
- auto install_plan = Dependencies::create_feature_install_plan(provider,
- var_provider,
- {install_specs.value_or_exit(VCPKG_LINE_INFO)},
- StatusParagraphs(std::move(status_paragraphs)));
-
- REQUIRE(install_plan.size() == 3);
- features_check(install_plan.install_actions.at(0), "c", {"0", "core"}, Test::X64_WINDOWS);
- features_check(install_plan.install_actions.at(1), "b", {"0", "core"}, Test::X64_WINDOWS);
- features_check(install_plan.install_actions.at(2), "a", {"0", "core"}, Test::X64_WINDOWS);
-}
-
-TEST_CASE ("basic remove scheme", "[plan]")
-{
- std::vector<std::unique_ptr<StatusParagraph>> pghs;
- pghs.push_back(make_status_pgh("a"));
- StatusParagraphs status_db(std::move(pghs));
-
- auto remove_plan = Dependencies::create_remove_plan({{"a", Test::X86_WINDOWS}}, status_db);
-
- REQUIRE(remove_plan.size() == 1);
- REQUIRE(remove_plan.at(0).spec.name() == "a");
-}
-
-TEST_CASE ("recurse remove scheme", "[plan]")
-{
- std::vector<std::unique_ptr<StatusParagraph>> pghs;
- pghs.push_back(make_status_pgh("a"));
- pghs.push_back(make_status_pgh("b", "a"));
- StatusParagraphs status_db(std::move(pghs));
-
- auto remove_plan = Dependencies::create_remove_plan({{"a", Test::X86_WINDOWS}}, status_db);
-
- REQUIRE(remove_plan.size() == 2);
- REQUIRE(remove_plan.at(0).spec.name() == "b");
- REQUIRE(remove_plan.at(1).spec.name() == "a");
-}
-
-TEST_CASE ("features depend remove scheme", "[plan]")
-{
- std::vector<std::unique_ptr<StatusParagraph>> pghs;
- pghs.push_back(make_status_pgh("a"));
- pghs.push_back(make_status_pgh("b"));
- pghs.push_back(make_status_feature_pgh("b", "0", "a"));
- StatusParagraphs status_db(std::move(pghs));
-
- auto remove_plan = Dependencies::create_remove_plan({{"a", Test::X86_WINDOWS}}, status_db);
-
- REQUIRE(remove_plan.size() == 2);
- REQUIRE(remove_plan.at(0).spec.name() == "b");
- REQUIRE(remove_plan.at(1).spec.name() == "a");
-}
-
-TEST_CASE ("features depend remove scheme once removed", "[plan]")
-{
- std::vector<std::unique_ptr<StatusParagraph>> pghs;
- pghs.push_back(make_status_pgh("expat"));
- pghs.push_back(make_status_pgh("vtk", "expat"));
- pghs.push_back(make_status_pgh("opencv"));
- pghs.push_back(make_status_feature_pgh("opencv", "vtk", "vtk"));
- StatusParagraphs status_db(std::move(pghs));
-
- auto remove_plan = Dependencies::create_remove_plan({{"expat", Test::X86_WINDOWS}}, status_db);
-
- REQUIRE(remove_plan.size() == 3);
- REQUIRE(remove_plan.at(0).spec.name() == "opencv");
- REQUIRE(remove_plan.at(1).spec.name() == "vtk");
- REQUIRE(remove_plan.at(2).spec.name() == "expat");
-}
-
-TEST_CASE ("features depend remove scheme once removed x64", "[plan]")
-{
- std::vector<std::unique_ptr<StatusParagraph>> pghs;
- pghs.push_back(make_status_pgh("expat", "", "", "x64"));
- pghs.push_back(make_status_pgh("vtk", "expat", "", "x64"));
- pghs.push_back(make_status_pgh("opencv", "", "", "x64"));
- pghs.push_back(make_status_feature_pgh("opencv", "vtk", "vtk", "x64"));
- StatusParagraphs status_db(std::move(pghs));
-
- auto remove_plan = Dependencies::create_remove_plan({{"expat", Triplet::from_canonical_name("x64")}}, status_db);
-
- REQUIRE(remove_plan.size() == 3);
- REQUIRE(remove_plan.at(0).spec.name() == "opencv");
- REQUIRE(remove_plan.at(1).spec.name() == "vtk");
- REQUIRE(remove_plan.at(2).spec.name() == "expat");
-}
-
-TEST_CASE ("features depend core remove scheme", "[plan]")
-{
- std::vector<std::unique_ptr<StatusParagraph>> pghs;
- pghs.push_back(make_status_pgh("curl", "", "", "x64"));
- pghs.push_back(make_status_pgh("cpr", "curl[core]", "", "x64"));
- StatusParagraphs status_db(std::move(pghs));
-
- auto remove_plan = Dependencies::create_remove_plan({{"curl", Triplet::from_canonical_name("x64")}}, status_db);
-
- REQUIRE(remove_plan.size() == 2);
- REQUIRE(remove_plan.at(0).spec.name() == "cpr");
- REQUIRE(remove_plan.at(1).spec.name() == "curl");
-}
-
-TEST_CASE ("features depend core remove scheme 2", "[plan]")
-{
- std::vector<std::unique_ptr<StatusParagraph>> pghs;
- pghs.push_back(make_status_pgh("curl", "", "", "x64"));
- pghs.push_back(make_status_feature_pgh("curl", "a", "", "x64"));
- pghs.push_back(make_status_feature_pgh("curl", "b", "curl[a]", "x64"));
- StatusParagraphs status_db(std::move(pghs));
-
- auto remove_plan = Dependencies::create_remove_plan({{"curl", Triplet::from_canonical_name("x64")}}, status_db);
-
- REQUIRE(remove_plan.size() == 1);
- REQUIRE(remove_plan.at(0).spec.name() == "curl");
-}
-
-TEST_CASE ("basic upgrade scheme", "[plan]")
-{
- std::vector<std::unique_ptr<StatusParagraph>> pghs;
- pghs.push_back(make_status_pgh("a"));
- StatusParagraphs status_db(std::move(pghs));
-
- PackageSpecMap spec_map;
- auto spec_a = spec_map.emplace("a");
-
- PortFileProvider::MapPortFileProvider provider(spec_map.map);
- MockCMakeVarProvider var_provider;
- auto plan = Dependencies::create_upgrade_plan(provider, var_provider, {spec_a}, status_db);
-
- REQUIRE(plan.size() == 2);
- remove_plan_check(plan.remove_actions.at(0), "a");
- features_check(plan.install_actions.at(0), "a", {"core"});
-}
-
-TEST_CASE ("basic upgrade scheme with recurse", "[plan]")
-{
- std::vector<std::unique_ptr<StatusParagraph>> pghs;
- pghs.push_back(make_status_pgh("a"));
- pghs.push_back(make_status_pgh("b", "a"));
- StatusParagraphs status_db(std::move(pghs));
-
- PackageSpecMap spec_map;
- auto spec_a = spec_map.emplace("a");
- spec_map.emplace("b", "a");
-
- PortFileProvider::MapPortFileProvider provider(spec_map.map);
- MockCMakeVarProvider var_provider;
- auto plan = Dependencies::create_upgrade_plan(provider, var_provider, {spec_a}, status_db);
-
- REQUIRE(plan.size() == 4);
- remove_plan_check(plan.remove_actions.at(0), "b");
- remove_plan_check(plan.remove_actions.at(1), "a");
- features_check(plan.install_actions.at(0), "a", {"core"});
- features_check(plan.install_actions.at(1), "b", {"core"});
-}
-
-TEST_CASE ("basic upgrade scheme with bystander", "[plan]")
-{
- std::vector<std::unique_ptr<StatusParagraph>> pghs;
- pghs.push_back(make_status_pgh("a"));
- pghs.push_back(make_status_pgh("b"));
- StatusParagraphs status_db(std::move(pghs));
-
- PackageSpecMap spec_map;
- auto spec_a = spec_map.emplace("a");
- spec_map.emplace("b", "a");
-
- PortFileProvider::MapPortFileProvider provider(spec_map.map);
- MockCMakeVarProvider var_provider;
- auto plan = Dependencies::create_upgrade_plan(provider, var_provider, {spec_a}, status_db);
-
- REQUIRE(plan.size() == 2);
- remove_plan_check(plan.remove_actions.at(0), "a");
- features_check(plan.install_actions.at(0), "a", {"core"});
-}
-
-TEST_CASE ("basic upgrade scheme with new dep", "[plan]")
-{
- std::vector<std::unique_ptr<StatusParagraph>> pghs;
- pghs.push_back(make_status_pgh("a"));
- StatusParagraphs status_db(std::move(pghs));
-
- PackageSpecMap spec_map;
- auto spec_a = spec_map.emplace("a", "b");
- spec_map.emplace("b");
-
- PortFileProvider::MapPortFileProvider provider(spec_map.map);
- MockCMakeVarProvider var_provider;
- auto plan = Dependencies::create_upgrade_plan(provider, var_provider, {spec_a}, status_db);
-
- REQUIRE(plan.size() == 3);
- remove_plan_check(plan.remove_actions.at(0), "a");
- features_check(plan.install_actions.at(0), "b", {"core"});
- features_check(plan.install_actions.at(1), "a", {"core"});
-}
-
-TEST_CASE ("basic upgrade scheme with features", "[plan]")
-{
- std::vector<std::unique_ptr<StatusParagraph>> pghs;
- pghs.push_back(make_status_pgh("a"));
- pghs.push_back(make_status_feature_pgh("a", "a1"));
- StatusParagraphs status_db(std::move(pghs));
-
- PackageSpecMap spec_map;
- auto spec_a = spec_map.emplace("a", "", {{"a1", ""}});
-
- PortFileProvider::MapPortFileProvider provider(spec_map.map);
- MockCMakeVarProvider var_provider;
- auto plan = Dependencies::create_upgrade_plan(provider, var_provider, {spec_a}, status_db);
-
- REQUIRE(plan.size() == 2);
- remove_plan_check(plan.remove_actions.at(0), "a");
- features_check(plan.install_actions.at(0), "a", {"core", "a1"});
-}
-
-TEST_CASE ("basic upgrade scheme with new default feature", "[plan]")
-{
- // only core of package "a" is installed
- std::vector<std::unique_ptr<StatusParagraph>> pghs;
- pghs.push_back(make_status_pgh("a"));
- StatusParagraphs status_db(std::move(pghs));
-
- // a1 was added as a default feature and should be installed in upgrade
- PackageSpecMap spec_map;
- auto spec_a = spec_map.emplace("a", "", {{"a1", ""}}, {"a1"});
-
- PortFileProvider::MapPortFileProvider provider(spec_map.map);
- MockCMakeVarProvider var_provider;
- auto plan = Dependencies::create_upgrade_plan(provider, var_provider, {spec_a}, status_db);
-
- REQUIRE(plan.size() == 2);
- remove_plan_check(plan.remove_actions.at(0), "a");
- features_check(plan.install_actions.at(0), "a", {"core", "a1"});
-}
-
-TEST_CASE ("basic upgrade scheme with self features", "[plan]")
-{
- std::vector<std::unique_ptr<StatusParagraph>> pghs;
- pghs.push_back(make_status_pgh("a"));
- pghs.push_back(make_status_feature_pgh("a", "a1", ""));
- pghs.push_back(make_status_feature_pgh("a", "a2", "a[a1]"));
- StatusParagraphs status_db(std::move(pghs));
-
- PackageSpecMap spec_map;
- auto spec_a = spec_map.emplace("a", "", {{"a1", ""}, {"a2", "a[a1]"}});
-
- PortFileProvider::MapPortFileProvider provider(spec_map.map);
- MockCMakeVarProvider var_provider;
- auto plan = Dependencies::create_upgrade_plan(provider, var_provider, {spec_a}, status_db);
-
- REQUIRE(plan.size() == 2);
- remove_plan_check(plan.remove_actions.at(0), "a");
- features_check(plan.install_actions.at(0), "a", {"a1", "a2", "core"});
-}
-
-TEST_CASE ("basic export scheme", "[plan]")
-{
- std::vector<std::unique_ptr<StatusParagraph>> pghs;
- pghs.push_back(make_status_pgh("a"));
- StatusParagraphs status_db(std::move(pghs));
-
- PackageSpecMap spec_map;
- auto spec_a = spec_map.emplace("a");
-
- auto plan = Dependencies::create_export_plan({spec_a}, status_db);
-
- REQUIRE(plan.size() == 1);
- REQUIRE(plan.at(0).spec.name() == "a");
- REQUIRE(plan.at(0).plan_type == Dependencies::ExportPlanType::ALREADY_BUILT);
-}
-
-TEST_CASE ("basic export scheme with recurse", "[plan]")
-{
- std::vector<std::unique_ptr<StatusParagraph>> pghs;
- pghs.push_back(make_status_pgh("a"));
- pghs.push_back(make_status_pgh("b", "a"));
- StatusParagraphs status_db(std::move(pghs));
-
- PackageSpecMap spec_map;
- auto spec_a = spec_map.emplace("a");
- auto spec_b = spec_map.emplace("b", "a");
-
- auto plan = Dependencies::create_export_plan({spec_b}, status_db);
-
- REQUIRE(plan.size() == 2);
- REQUIRE(plan.at(0).spec.name() == "a");
- REQUIRE(plan.at(0).plan_type == Dependencies::ExportPlanType::ALREADY_BUILT);
-
- REQUIRE(plan.at(1).spec.name() == "b");
- REQUIRE(plan.at(1).plan_type == Dependencies::ExportPlanType::ALREADY_BUILT);
-}
-
-TEST_CASE ("basic export scheme with bystander", "[plan]")
-{
- std::vector<std::unique_ptr<StatusParagraph>> pghs;
- pghs.push_back(make_status_pgh("a"));
- pghs.push_back(make_status_pgh("b"));
- StatusParagraphs status_db(std::move(pghs));
-
- PackageSpecMap spec_map;
- auto spec_a = spec_map.emplace("a");
- auto spec_b = spec_map.emplace("b", "a");
-
- auto plan = Dependencies::create_export_plan({spec_a}, status_db);
-
- REQUIRE(plan.size() == 1);
- REQUIRE(plan.at(0).spec.name() == "a");
- REQUIRE(plan.at(0).plan_type == Dependencies::ExportPlanType::ALREADY_BUILT);
-}
-
-TEST_CASE ("basic export scheme with missing", "[plan]")
-{
- StatusParagraphs status_db;
-
- PackageSpecMap spec_map;
- auto spec_a = spec_map.emplace("a");
-
- auto plan = Dependencies::create_export_plan({spec_a}, status_db);
-
- REQUIRE(plan.size() == 1);
- REQUIRE(plan.at(0).spec.name() == "a");
- REQUIRE(plan.at(0).plan_type == Dependencies::ExportPlanType::NOT_BUILT);
-}
-
-TEST_CASE ("basic export scheme with features", "[plan]")
-{
- std::vector<std::unique_ptr<StatusParagraph>> pghs;
- pghs.push_back(make_status_pgh("b"));
- pghs.push_back(make_status_pgh("a"));
- pghs.push_back(make_status_feature_pgh("a", "a1", "b[core]"));
- StatusParagraphs status_db(std::move(pghs));
-
- PackageSpecMap spec_map;
- auto spec_a = spec_map.emplace("a", "", {{"a1", ""}});
-
- auto plan = Dependencies::create_export_plan({spec_a}, status_db);
-
- REQUIRE(plan.size() == 2);
-
- REQUIRE(plan.at(0).spec.name() == "b");
- REQUIRE(plan.at(0).plan_type == Dependencies::ExportPlanType::ALREADY_BUILT);
-
- REQUIRE(plan.at(1).spec.name() == "a");
- REQUIRE(plan.at(1).plan_type == Dependencies::ExportPlanType::ALREADY_BUILT);
-}
diff --git a/toolsrc/src/vcpkg-test/platform-expression.cpp b/toolsrc/src/vcpkg-test/platform-expression.cpp
deleted file mode 100644
index aef999230..000000000
--- a/toolsrc/src/vcpkg-test/platform-expression.cpp
+++ /dev/null
@@ -1,80 +0,0 @@
-#include <catch2/catch.hpp>
-
-#include <vcpkg/platform-expression.h>
-
-using vcpkg::StringView;
-using namespace vcpkg::PlatformExpression;
-
-static vcpkg::ExpectedS<Expr> parse_expr(StringView s)
-{
- return parse_platform_expression(s, MultipleBinaryOperators::Deny);
-}
-
-TEST_CASE ("platform-expression-identifier", "[platform-expression]")
-{
- auto m_expr = parse_expr("windows");
- REQUIRE(m_expr);
- auto& expr = *m_expr.get();
-
- CHECK(expr.evaluate({{"VCPKG_CMAKE_SYSTEM_NAME", ""}}));
- CHECK(expr.evaluate({{"VCPKG_CMAKE_SYSTEM_NAME", "WindowsStore"}}));
- CHECK_FALSE(expr.evaluate({{"VCPKG_CMAKE_SYSTEM_NAME", "Linux"}}));
- CHECK_FALSE(expr.evaluate({{"VCPKG_CMAKE_SYSTEM_NAME", "Darwin"}}));
-}
-
-TEST_CASE ("platform-expression-not", "[platform-expression]")
-{
- auto m_expr = parse_expr("!windows");
- REQUIRE(m_expr);
- auto& expr = *m_expr.get();
-
- CHECK_FALSE(expr.evaluate({{"VCPKG_CMAKE_SYSTEM_NAME", ""}}));
- CHECK_FALSE(expr.evaluate({{"VCPKG_CMAKE_SYSTEM_NAME", "WindowsStore"}}));
- CHECK(expr.evaluate({{"VCPKG_CMAKE_SYSTEM_NAME", "Linux"}}));
- CHECK(expr.evaluate({{"VCPKG_CMAKE_SYSTEM_NAME", "Darwin"}}));
-}
-
-TEST_CASE ("platform-expression-and", "[platform-expression]")
-{
- auto m_expr = parse_expr("!windows & !arm");
- REQUIRE(m_expr);
- auto& expr = *m_expr.get();
-
- CHECK_FALSE(expr.evaluate({{"VCPKG_CMAKE_SYSTEM_NAME", ""}}));
- CHECK_FALSE(expr.evaluate({{"VCPKG_CMAKE_SYSTEM_NAME", "WindowsStore"}}));
- CHECK(expr.evaluate({{"VCPKG_CMAKE_SYSTEM_NAME", "Linux"}}));
- CHECK_FALSE(expr.evaluate({
- {"VCPKG_CMAKE_SYSTEM_NAME", "Linux"},
- {"VCPKG_TARGET_ARCHITECTURE", "arm"},
- }));
-}
-
-TEST_CASE ("platform-expression-or", "[platform-expression]")
-{
- auto m_expr = parse_expr("!windows | arm");
- REQUIRE(m_expr);
- auto& expr = *m_expr.get();
-
- CHECK_FALSE(expr.evaluate({{"VCPKG_CMAKE_SYSTEM_NAME", ""}}));
- CHECK(expr.evaluate({{"VCPKG_CMAKE_SYSTEM_NAME", ""}, {"VCPKG_TARGET_ARCHITECTURE", "arm"}}));
- CHECK(expr.evaluate({{"VCPKG_CMAKE_SYSTEM_NAME", "Linux"}}));
-}
-
-TEST_CASE ("weird platform-expressions whitespace", "[platform-expression]")
-{
- auto m_expr = parse_expr(" ! \t windows \n| arm \r");
- REQUIRE(m_expr);
- auto& expr = *m_expr.get();
-
- CHECK_FALSE(expr.evaluate({{"VCPKG_CMAKE_SYSTEM_NAME", ""}}));
- CHECK(expr.evaluate({{"VCPKG_CMAKE_SYSTEM_NAME", ""}, {"VCPKG_TARGET_ARCHITECTURE", "arm"}}));
- CHECK(expr.evaluate({{"VCPKG_CMAKE_SYSTEM_NAME", "Linux"}}));
-}
-
-TEST_CASE ("no mixing &, | in platform expressions", "[platform-expression]")
-{
- auto m_expr = parse_expr("windows & arm | linux");
- CHECK_FALSE(m_expr);
- m_expr = parse_expr("windows | !arm & linux");
- CHECK_FALSE(m_expr);
-}
diff --git a/toolsrc/src/vcpkg-test/registries.cpp b/toolsrc/src/vcpkg-test/registries.cpp
deleted file mode 100644
index 1c839409d..000000000
--- a/toolsrc/src/vcpkg-test/registries.cpp
+++ /dev/null
@@ -1,132 +0,0 @@
-#include <catch2/catch.hpp>
-
-#include <vcpkg/base/jsonreader.h>
-
-#include <vcpkg/registries.h>
-
-using namespace vcpkg;
-
-namespace
-{
- struct TestRegistryImplementation final : RegistryImplementation
- {
- std::unique_ptr<RegistryEntry> get_port_entry(const VcpkgPaths&, StringView) const override { return nullptr; }
-
- void get_all_port_names(std::vector<std::string>&, const VcpkgPaths&) const override { }
-
- Optional<VersionT> get_baseline_version(const VcpkgPaths&, StringView) const override { return nullopt; }
-
- int number;
-
- TestRegistryImplementation(int n) : number(n) { }
- };
-
- Registry make_registry(int n, std::vector<std::string>&& port_names)
- {
- return {std::move(port_names), std::make_unique<TestRegistryImplementation>(n)};
- }
-
- int get_tri_num(const RegistryImplementation& r)
- {
- if (auto tri = dynamic_cast<const TestRegistryImplementation*>(&r))
- {
- return tri->number;
- }
- else
- {
- return -1;
- }
- }
-
- // test functions which parse string literals, so no concerns about failure
- Json::Value parse_json(StringView sv) { return Json::parse(sv).value_or_exit(VCPKG_LINE_INFO).first; }
-}
-
-TEST_CASE ("registry_set_selects_registry", "[registries]")
-{
- RegistrySet set;
- set.set_default_registry(std::make_unique<TestRegistryImplementation>(0));
-
- set.add_registry(make_registry(1, {"p1", "q1", "r1"}));
- set.add_registry(make_registry(2, {"p2", "q2", "r2"}));
-
- auto reg = set.registry_for_port("p1");
- REQUIRE(reg);
- CHECK(get_tri_num(*reg) == 1);
- reg = set.registry_for_port("r2");
- REQUIRE(reg);
- CHECK(get_tri_num(*reg) == 2);
- reg = set.registry_for_port("a");
- REQUIRE(reg);
- CHECK(get_tri_num(*reg) == 0);
-
- set.set_default_registry(nullptr);
-
- reg = set.registry_for_port("q1");
- REQUIRE(reg);
- CHECK(get_tri_num(*reg) == 1);
- reg = set.registry_for_port("p2");
- REQUIRE(reg);
- CHECK(get_tri_num(*reg) == 2);
- reg = set.registry_for_port("a");
- CHECK_FALSE(reg);
-}
-
-TEST_CASE ("registry_parsing", "[registries]")
-{
- Json::Reader r;
- auto registry_impl_des = get_registry_implementation_deserializer({});
-
- auto test_json = parse_json(R"json(
-{
- "kind": "builtin"
-}
- )json");
- auto registry_impl = r.visit(test_json, *registry_impl_des);
- REQUIRE(registry_impl);
- CHECK(*registry_impl.get());
- CHECK(r.errors().empty());
-
- test_json = parse_json(R"json(
-{
- "kind": "builtin",
- "baseline": "hi"
-}
- )json");
- registry_impl = r.visit(test_json, *registry_impl_des);
- REQUIRE(registry_impl);
- CHECK(*registry_impl.get());
- CHECK(r.errors().empty());
-
- test_json = parse_json(R"json(
-{
- "kind": "builtin",
- "path": "a/b"
-}
- )json");
- registry_impl = r.visit(test_json, *registry_impl_des);
- CHECK_FALSE(r.errors().empty());
- r.errors().clear();
-
- test_json = parse_json(R"json(
-{
- "kind": "filesystem",
- "path": "a/b/c"
-}
- )json");
- registry_impl = r.visit(test_json, *registry_impl_des);
- REQUIRE(registry_impl);
- CHECK(*registry_impl.get());
- CHECK(r.errors().empty());
-
- test_json = parse_json(R"json(
-{
- "kind": "filesystem",
- "path": "/a/b/c"
-}
- )json");
- registry_impl = r.visit(test_json, *registry_impl_des);
- REQUIRE(registry_impl);
- CHECK(*registry_impl.get());
- CHECK(r.errors().empty());
-}
diff --git a/toolsrc/src/vcpkg-test/specifier.cpp b/toolsrc/src/vcpkg-test/specifier.cpp
deleted file mode 100644
index f750f4144..000000000
--- a/toolsrc/src/vcpkg-test/specifier.cpp
+++ /dev/null
@@ -1,130 +0,0 @@
-#include <catch2/catch.hpp>
-
-#include <vcpkg/base/system.print.h>
-#include <vcpkg/base/util.h>
-
-#include <vcpkg/packagespec.h>
-
-#include <vcpkg-test/util.h>
-
-using namespace vcpkg;
-
-TEST_CASE ("specifier conversion", "[specifier]")
-{
- SECTION ("full package spec to feature specs")
- {
- constexpr std::size_t SPEC_SIZE = 6;
-
- PackageSpec a_spec("a", Test::X64_WINDOWS);
- PackageSpec b_spec("b", Test::X64_WINDOWS);
-
- auto fspecs = FullPackageSpec{a_spec, {"0", "1"}}.to_feature_specs({}, {});
- auto fspecs2 = FullPackageSpec{b_spec, {"2", "3"}}.to_feature_specs({}, {});
- Util::Vectors::append(&fspecs, fspecs2);
- Util::sort(fspecs);
- REQUIRE(fspecs.size() == SPEC_SIZE);
-
- std::array<const char*, SPEC_SIZE> features = {"0", "1", "core", "2", "3", "core"};
- std::array<PackageSpec*, SPEC_SIZE> specs = {&a_spec, &a_spec, &a_spec, &b_spec, &b_spec, &b_spec};
-
- for (std::size_t i = 0; i < SPEC_SIZE; ++i)
- {
- REQUIRE(features.at(i) == fspecs.at(i).feature());
- REQUIRE(*specs.at(i) == fspecs.at(i).spec());
- }
- }
-}
-
-TEST_CASE ("specifier parsing", "[specifier]")
-{
- SECTION ("parsed specifier from string")
- {
- auto maybe_spec = vcpkg::parse_qualified_specifier("zlib");
- REQUIRE(maybe_spec.has_value());
-
- auto& spec = *maybe_spec.get();
- REQUIRE(spec.name == "zlib");
- REQUIRE(!spec.features);
- REQUIRE(!spec.triplet);
- }
-
- SECTION ("parsed specifier from string with triplet")
- {
- auto maybe_spec = vcpkg::parse_qualified_specifier("zlib:x64-uwp");
- REQUIRE(maybe_spec);
-
- auto& spec = *maybe_spec.get();
- REQUIRE(spec.name == "zlib");
- REQUIRE(spec.triplet.value_or("") == "x64-uwp");
- }
-
- SECTION ("parsed specifier from string with colons")
- {
- auto s = vcpkg::parse_qualified_specifier("zlib:x86-uwp:");
- REQUIRE(!s);
- }
-
- SECTION ("parsed specifier from string with feature")
- {
- auto maybe_spec = vcpkg::parse_qualified_specifier("zlib[feature]:x64-uwp");
- REQUIRE(maybe_spec);
-
- auto& spec = *maybe_spec.get();
- REQUIRE(spec.name == "zlib");
- REQUIRE(spec.features.value_or(std::vector<std::string>{}) == std::vector<std::string>{"feature"});
- REQUIRE(spec.triplet.value_or("") == "x64-uwp");
- }
-
- SECTION ("parsed specifier from string with many features")
- {
- auto maybe_spec = vcpkg::parse_qualified_specifier("zlib[0, 1,2]");
- REQUIRE(maybe_spec);
-
- auto& spec = *maybe_spec.get();
- REQUIRE(spec.features.value_or(std::vector<std::string>{}) == std::vector<std::string>{"0", "1", "2"});
- }
-
- SECTION ("parsed specifier wildcard feature")
- {
- auto maybe_spec = vcpkg::parse_qualified_specifier("zlib[*]");
- System::print2(maybe_spec.error());
- REQUIRE(maybe_spec);
-
- auto& spec = *maybe_spec.get();
- REQUIRE(spec.features.value_or(std::vector<std::string>{}) == std::vector<std::string>{"*"});
- }
-
- SECTION ("expand wildcards")
- {
- auto zlib = vcpkg::FullPackageSpec::from_string("zlib[0,1]", Test::X86_UWP).value_or_exit(VCPKG_LINE_INFO);
- auto openssl = vcpkg::FullPackageSpec::from_string("openssl[*]", Test::X86_UWP).value_or_exit(VCPKG_LINE_INFO);
- auto specs = zlib.to_feature_specs({}, {});
- auto specs2 = openssl.to_feature_specs({}, {});
- Util::Vectors::append(&specs, specs2);
- Util::sort(specs);
-
- std::vector<FeatureSpec> spectargets{
- {{"openssl", Test::X86_UWP}, "core"},
- {{"zlib", Test::X86_UWP}, "core"},
- {{"zlib", Test::X86_UWP}, "0"},
- {{"zlib", Test::X86_UWP}, "1"},
- };
- Util::sort(spectargets);
- REQUIRE(specs.size() == spectargets.size());
- REQUIRE(specs == spectargets);
- }
-
-#if defined(_WIN32)
- SECTION ("ASCII to utf16")
- {
- auto str = vcpkg::Strings::to_utf16("abc");
- REQUIRE(str == L"abc");
- }
-
- SECTION ("ASCII to utf16 with whitespace")
- {
- auto str = vcpkg::Strings::to_utf16("abc -x86-windows");
- REQUIRE(str == L"abc -x86-windows");
- }
-#endif
-}
diff --git a/toolsrc/src/vcpkg-test/statusparagraphs.cpp b/toolsrc/src/vcpkg-test/statusparagraphs.cpp
deleted file mode 100644
index f647484e6..000000000
--- a/toolsrc/src/vcpkg-test/statusparagraphs.cpp
+++ /dev/null
@@ -1,116 +0,0 @@
-#include <catch2/catch.hpp>
-
-#include <vcpkg/base/util.h>
-
-#include <vcpkg/paragraphs.h>
-#include <vcpkg/statusparagraphs.h>
-
-#include <vcpkg-test/util.h>
-
-using namespace vcpkg;
-using namespace vcpkg::Paragraphs;
-using namespace vcpkg::Test;
-
-TEST_CASE ("find installed", "[statusparagraphs]")
-{
- auto pghs = parse_paragraphs(R"(
-Package: ffmpeg
-Version: 3.3.3
-Architecture: x64-windows
-Multi-Arch: same
-Description:
-Status: install ok installed
-)",
- "");
-
- REQUIRE(pghs);
-
- StatusParagraphs status_db(
- Util::fmap(*pghs.get(), [](Paragraph& rpgh) { return std::make_unique<StatusParagraph>(std::move(rpgh)); }));
-
- auto it = status_db.find_installed({"ffmpeg", Test::X64_WINDOWS});
- REQUIRE(it != status_db.end());
-}
-
-TEST_CASE ("find not installed", "[statusparagraphs]")
-{
- auto pghs = parse_paragraphs(R"(
-Package: ffmpeg
-Version: 3.3.3
-Architecture: x64-windows
-Multi-Arch: same
-Description:
-Status: purge ok not-installed
-)",
- "");
-
- REQUIRE(pghs);
-
- StatusParagraphs status_db(
- Util::fmap(*pghs.get(), [](Paragraph& rpgh) { return std::make_unique<StatusParagraph>(std::move(rpgh)); }));
-
- auto it = status_db.find_installed({"ffmpeg", Test::X64_WINDOWS});
- REQUIRE(it == status_db.end());
-}
-
-TEST_CASE ("find with feature packages", "[statusparagraphs]")
-{
- auto pghs = parse_paragraphs(R"(
-Package: ffmpeg
-Version: 3.3.3
-Architecture: x64-windows
-Multi-Arch: same
-Description:
-Status: install ok installed
-
-Package: ffmpeg
-Feature: openssl
-Depends: openssl
-Architecture: x64-windows
-Multi-Arch: same
-Description:
-Status: purge ok not-installed
-)",
- "");
-
- REQUIRE(pghs);
-
- StatusParagraphs status_db(
- Util::fmap(*pghs.get(), [](Paragraph& rpgh) { return std::make_unique<StatusParagraph>(std::move(rpgh)); }));
-
- auto it = status_db.find_installed({"ffmpeg", Test::X64_WINDOWS});
- REQUIRE(it != status_db.end());
-
- // Feature "openssl" is not installed and should not be found
- auto it1 = status_db.find_installed({{"ffmpeg", Test::X64_WINDOWS}, "openssl"});
- REQUIRE(it1 == status_db.end());
-}
-
-TEST_CASE ("find for feature packages", "[statusparagraphs]")
-{
- auto pghs = parse_paragraphs(R"(
-Package: ffmpeg
-Version: 3.3.3
-Architecture: x64-windows
-Multi-Arch: same
-Description:
-Status: install ok installed
-
-Package: ffmpeg
-Feature: openssl
-Depends: openssl
-Architecture: x64-windows
-Multi-Arch: same
-Description:
-Status: install ok installed
-)",
- "");
- REQUIRE(pghs);
-
- StatusParagraphs status_db(
- Util::fmap(*pghs.get(), [](Paragraph& rpgh) { return std::make_unique<StatusParagraph>(std::move(rpgh)); }));
-
- // Feature "openssl" is installed and should therefore be found
- auto it = status_db.find_installed({{"ffmpeg", Test::X64_WINDOWS}, "openssl"});
- REQUIRE(it != status_db.end());
-}
diff --git a/toolsrc/src/vcpkg-test/strings.cpp b/toolsrc/src/vcpkg-test/strings.cpp
deleted file mode 100644
index 32fe5b3af..000000000
--- a/toolsrc/src/vcpkg-test/strings.cpp
+++ /dev/null
@@ -1,114 +0,0 @@
-#include <catch2/catch.hpp>
-
-#include <vcpkg/base/strings.h>
-
-#include <stdint.h>
-
-#include <string>
-#include <utility>
-#include <vector>
-
-#if defined(_MSC_VER)
-#pragma warning(disable : 6237)
-#endif
-
-TEST_CASE ("b32 encoding", "[strings]")
-{
- using u64 = uint64_t;
-
- std::vector<std::pair<u64, std::string>> map;
-
- map.emplace_back(0, "AAAAAAAAAAAAA");
- map.emplace_back(1, "BAAAAAAAAAAAA");
-
- map.emplace_back(u64(1) << 32, "AAAAAAEAAAAAA");
- map.emplace_back((u64(1) << 32) + 1, "BAAAAAEAAAAAA");
-
- map.emplace_back(0xE4D0'1065'D11E'0229, "JRA4RIXMQAUJO");
- map.emplace_back(0xA626'FE45'B135'07FF, "77BKTYWI6XJMK");
- map.emplace_back(0xEE36'D228'0C31'D405, "FAVDDGAFSWN4O");
- map.emplace_back(0x1405'64E7'FE7E'A88C, "MEK5H774ELBIB");
- map.emplace_back(0xFFFF'FFFF'FFFF'FFFF, "777777777777P");
-
- for (const auto& pr : map)
- {
- REQUIRE(vcpkg::Strings::b32_encode(pr.first) == pr.second);
- }
-}
-
-TEST_CASE ("split by char", "[strings]")
-{
- using vcpkg::Strings::split;
- using result_t = std::vector<std::string>;
- REQUIRE(split(",,,,,,", ',').empty());
- REQUIRE(split(",,a,,b,,", ',') == result_t{"a", "b"});
- REQUIRE(split("hello world", ' ') == result_t{"hello", "world"});
- REQUIRE(split(" hello world ", ' ') == result_t{"hello", "world"});
- REQUIRE(split("no delimiters", ',') == result_t{"no delimiters"});
-}
-
-TEST_CASE ("find_first_of", "[strings]")
-{
- using vcpkg::Strings::find_first_of;
- REQUIRE(find_first_of("abcdefg", "hij") == std::string());
- REQUIRE(find_first_of("abcdefg", "a") == std::string("abcdefg"));
- REQUIRE(find_first_of("abcdefg", "g") == std::string("g"));
- REQUIRE(find_first_of("abcdefg", "bg") == std::string("bcdefg"));
- REQUIRE(find_first_of("abcdefg", "gb") == std::string("bcdefg"));
-}
-
-TEST_CASE ("edit distance", "[strings]")
-{
- using vcpkg::Strings::byte_edit_distance;
- REQUIRE(byte_edit_distance("", "") == 0);
- REQUIRE(byte_edit_distance("a", "a") == 0);
- REQUIRE(byte_edit_distance("abcd", "abcd") == 0);
- REQUIRE(byte_edit_distance("aaa", "aa") == 1);
- REQUIRE(byte_edit_distance("aa", "aaa") == 1);
- REQUIRE(byte_edit_distance("abcdef", "bcdefa") == 2);
- REQUIRE(byte_edit_distance("hello", "world") == 4);
- REQUIRE(byte_edit_distance("CAPITAL", "capital") == 7);
- REQUIRE(byte_edit_distance("", "hello") == 5);
- REQUIRE(byte_edit_distance("world", "") == 5);
-}
-
-TEST_CASE ("replace_all", "[strings]")
-{
- REQUIRE(vcpkg::Strings::replace_all("literal", "ter", "x") == "lixal");
-}
-
-TEST_CASE ("inplace_replace_all", "[strings]")
-{
- using vcpkg::Strings::inplace_replace_all;
- std::string target;
- inplace_replace_all(target, "", "content");
- REQUIRE(target.empty());
- target = "aa";
- inplace_replace_all(target, "a", "content");
- REQUIRE(target == "contentcontent");
- inplace_replace_all(target, "content", "");
- REQUIRE(target.empty());
- target = "ababababa";
- inplace_replace_all(target, "aba", "X");
- REQUIRE(target == "XbXba");
- target = "ababababa";
- inplace_replace_all(target, "aba", "aba");
- REQUIRE(target == "ababababa");
-}
-
-TEST_CASE ("inplace_replace_all(char)", "[strings]")
-{
- using vcpkg::Strings::inplace_replace_all;
- static_assert(noexcept(inplace_replace_all(std::declval<std::string&>(), 'a', 'a')));
-
- std::string target;
- inplace_replace_all(target, ' ', '?');
- REQUIRE(target.empty());
- target = "hello";
- inplace_replace_all(target, 'l', 'w');
- REQUIRE(target == "hewwo");
- inplace_replace_all(target, 'w', 'w');
- REQUIRE(target == "hewwo");
- inplace_replace_all(target, 'x', '?');
- REQUIRE(target == "hewwo");
-}
diff --git a/toolsrc/src/vcpkg-test/stringview.cpp b/toolsrc/src/vcpkg-test/stringview.cpp
deleted file mode 100644
index 953a7de99..000000000
--- a/toolsrc/src/vcpkg-test/stringview.cpp
+++ /dev/null
@@ -1,19 +0,0 @@
-#include <catch2/catch.hpp>
-
-#include <vcpkg/base/stringview.h>
-
-template<std::size_t N>
-static vcpkg::StringView sv(const char (&cstr)[N])
-{
- return cstr;
-}
-
-TEST_CASE ("string view operator==", "[stringview]")
-{
- // these are due to a bug in operator==
- // see commit 782723959399a1a0725ac49
- REQUIRE(sv("hey") != sv("heys"));
- REQUIRE(sv("heys") != sv("hey"));
- REQUIRE(sv("hey") == sv("hey"));
- REQUIRE(sv("hey") != sv("hex"));
-}
diff --git a/toolsrc/src/vcpkg-test/system.cpp b/toolsrc/src/vcpkg-test/system.cpp
deleted file mode 100644
index 4c8b533bc..000000000
--- a/toolsrc/src/vcpkg-test/system.cpp
+++ /dev/null
@@ -1,149 +0,0 @@
-#include <vcpkg/base/system_headers.h>
-
-#include <catch2/catch.hpp>
-
-#include <vcpkg/base/optional.h>
-#include <vcpkg/base/strings.h>
-#include <vcpkg/base/stringview.h>
-#include <vcpkg/base/system.h>
-#include <vcpkg/base/system.process.h>
-#include <vcpkg/base/zstringview.h>
-
-#include <string>
-
-#if defined(_MSC_VER)
-#pragma warning(disable : 6237)
-#endif
-
-using vcpkg::nullopt;
-using vcpkg::Optional;
-using vcpkg::StringView;
-using vcpkg::ZStringView;
-using vcpkg::Checks::check_exit;
-using vcpkg::System::CPUArchitecture;
-using vcpkg::System::get_environment_variable;
-using vcpkg::System::guess_visual_studio_prompt_target_architecture;
-using vcpkg::System::set_environment_variable;
-using vcpkg::System::to_cpu_architecture;
-
-namespace
-{
- struct environment_variable_resetter
- {
- explicit environment_variable_resetter(ZStringView varname_)
- : varname(varname_), old_value(get_environment_variable(varname))
- {
- }
-
- ~environment_variable_resetter() { set_environment_variable(varname, old_value); }
-
- environment_variable_resetter(const environment_variable_resetter&) = delete;
- environment_variable_resetter& operator=(const environment_variable_resetter&) = delete;
-
- private:
- ZStringView varname;
- Optional<std::string> old_value;
- };
-}
-
-TEST_CASE ("[to_cpu_architecture]", "system")
-{
- struct test_case
- {
- Optional<CPUArchitecture> expected;
- StringView input;
- };
-
- const test_case test_cases[] = {
- {CPUArchitecture::X86, "x86"},
- {CPUArchitecture::X86, "X86"},
- {CPUArchitecture::X64, "x64"},
- {CPUArchitecture::X64, "X64"},
- {CPUArchitecture::X64, "AmD64"},
- {CPUArchitecture::ARM, "ARM"},
- {CPUArchitecture::ARM64, "ARM64"},
- {nullopt, "ARM6"},
- {nullopt, "AR"},
- {nullopt, "Intel"},
- };
-
- for (auto&& instance : test_cases)
- {
- CHECK(to_cpu_architecture(instance.input) == instance.expected);
- }
-}
-
-TEST_CASE ("from_cpu_architecture", "[system]")
-{
- struct test_case
- {
- CPUArchitecture input;
- ZStringView expected;
- };
-
- const test_case test_cases[] = {
- {CPUArchitecture::X86, "x86"},
- {CPUArchitecture::X64, "x64"},
- {CPUArchitecture::ARM, "arm"},
- {CPUArchitecture::ARM64, "arm64"},
- };
-
- for (auto&& instance : test_cases)
- {
- CHECK(to_zstring_view(instance.input) == instance.expected);
- }
-}
-
-TEST_CASE ("guess_visual_studio_prompt", "[system]")
-{
- environment_variable_resetter reset_VSCMD_ARG_TGT_ARCH{"VSCMD_ARG_TGT_ARCH"};
- environment_variable_resetter reset_VCINSTALLDIR{"VCINSTALLDIR"};
- environment_variable_resetter reset_Platform{"Platform"};
-
- set_environment_variable("Platform", "x86"); // ignored if VCINSTALLDIR unset
- set_environment_variable("VCINSTALLDIR", nullopt);
- set_environment_variable("VSCMD_ARG_TGT_ARCH", nullopt);
- CHECK(!guess_visual_studio_prompt_target_architecture().has_value());
- set_environment_variable("VSCMD_ARG_TGT_ARCH", "x86");
- CHECK(guess_visual_studio_prompt_target_architecture().value_or_exit(VCPKG_LINE_INFO) == CPUArchitecture::X86);
- set_environment_variable("VSCMD_ARG_TGT_ARCH", "x64");
- CHECK(guess_visual_studio_prompt_target_architecture().value_or_exit(VCPKG_LINE_INFO) == CPUArchitecture::X64);
- set_environment_variable("VSCMD_ARG_TGT_ARCH", "arm");
- CHECK(guess_visual_studio_prompt_target_architecture().value_or_exit(VCPKG_LINE_INFO) == CPUArchitecture::ARM);
- set_environment_variable("VSCMD_ARG_TGT_ARCH", "arm64");
- CHECK(guess_visual_studio_prompt_target_architecture().value_or_exit(VCPKG_LINE_INFO) == CPUArchitecture::ARM64);
-
- // check that apparent "nested" prompts defer to "vsdevcmd"
- set_environment_variable("VCINSTALLDIR", "anything");
- CHECK(guess_visual_studio_prompt_target_architecture().value_or_exit(VCPKG_LINE_INFO) == CPUArchitecture::ARM64);
- set_environment_variable("VSCMD_ARG_TGT_ARCH", nullopt);
- set_environment_variable("Platform", nullopt);
- CHECK(guess_visual_studio_prompt_target_architecture().value_or_exit(VCPKG_LINE_INFO) == CPUArchitecture::X86);
- set_environment_variable("Platform", "x86");
- CHECK(guess_visual_studio_prompt_target_architecture().value_or_exit(VCPKG_LINE_INFO) == CPUArchitecture::X86);
- set_environment_variable("Platform", "x64");
- CHECK(guess_visual_studio_prompt_target_architecture().value_or_exit(VCPKG_LINE_INFO) == CPUArchitecture::X64);
-}
-
-TEST_CASE ("cmdlinebuilder", "[system]")
-{
- using vcpkg::System::Command;
-
- Command cmd;
- cmd.path_arg(fs::u8path("relative/path.exe"));
- cmd.string_arg("abc");
- cmd.string_arg("hello world!");
- cmd.string_arg("|");
- cmd.string_arg(";");
- REQUIRE(cmd.command_line() == "relative/path.exe abc \"hello world!\" \"|\" \";\"");
-
- cmd.clear();
-
- cmd.path_arg(fs::u8path("trailing\\slash\\"));
- cmd.string_arg("inner\"quotes");
-#ifdef _WIN32
- REQUIRE(cmd.command_line() == "\"trailing\\slash\\\\\" \"inner\\\"quotes\"");
-#else
- REQUIRE(cmd.command_line() == "\"trailing\\\\slash\\\\\" \"inner\\\"quotes\"");
-#endif
-}
diff --git a/toolsrc/src/vcpkg-test/uint128.cpp b/toolsrc/src/vcpkg-test/uint128.cpp
deleted file mode 100644
index a13b25e4f..000000000
--- a/toolsrc/src/vcpkg-test/uint128.cpp
+++ /dev/null
@@ -1,68 +0,0 @@
-#include <catch2/catch.hpp>
-
-#include <vcpkg/base/uint128.h>
-
-TEST_CASE ("uint128 constructor and assign", "[uint128]")
-{
- vcpkg::UInt128 x = 120;
- REQUIRE(x.bottom_64_bits() == 120);
- REQUIRE(x.top_64_bits() == 0);
-
- x = 3201;
- REQUIRE(x.bottom_64_bits() == 3201);
- REQUIRE(x.top_64_bits() == 0);
-
- x = 0xFFFF'FFFF'FFFF'FFFF;
- REQUIRE(x.bottom_64_bits() == 0xFFFF'FFFF'FFFF'FFFF);
- REQUIRE(x.top_64_bits() == 0);
-}
-
-TEST_CASE ("uint128 add-assign", "[uint128]")
-{
- vcpkg::UInt128 x = 0xFFFF'FFFF'FFFF'FFFF;
- x += 1;
- REQUIRE(x.bottom_64_bits() == 0);
- REQUIRE(x.top_64_bits() == 1);
-}
-
-TEST_CASE ("uint128 shl-assign", "[uint128]")
-{
- vcpkg::UInt128 x = 0xFFFF'FFFF'FFFF'FFFF;
- x <<= 32;
- REQUIRE(x.bottom_64_bits() == 0xFFFF'FFFF'0000'0000);
- REQUIRE(x.top_64_bits() == 0x0000'0000'FFFF'FFFF);
-
- x <<= 60;
- REQUIRE(x.bottom_64_bits() == 0);
- REQUIRE(x.top_64_bits() == 0xFFFF'FFFF'F000'0000);
-
- x = 1;
- x <<= 96;
- REQUIRE(x.bottom_64_bits() == 0);
- REQUIRE(x.top_64_bits() == (uint64_t(1) << 32));
-}
-
-TEST_CASE ("uint128 shr-assign", "[uint128]")
-{
- vcpkg::UInt128 x = 0xFFFF'FFFF'FFFF'FFFF;
- x <<= 64;
- REQUIRE(x.bottom_64_bits() == 0x0000'0000'0000'0000);
- REQUIRE(x.top_64_bits() == 0xFFFF'FFFF'FFFF'FFFF);
-
- x >>= 32;
- REQUIRE(x.bottom_64_bits() == 0xFFFF'FFFF'0000'0000);
- REQUIRE(x.top_64_bits() == 0x0000'0000'FFFF'FFFF);
-
- x >>= 60;
- REQUIRE(x.bottom_64_bits() == 0x0000'000F'FFFF'FFFF);
- REQUIRE(x.top_64_bits() == 0x0000'0000'0000'0000);
-
- x = 0x8000'0000'0000'0000;
- x <<= 64;
- REQUIRE(x.bottom_64_bits() == 0);
- REQUIRE(x.top_64_bits() == 0x8000'0000'0000'0000);
-
- x >>= 96;
- REQUIRE(x.bottom_64_bits() == (uint64_t(1) << 31));
- REQUIRE(x.top_64_bits() == 0);
-}
diff --git a/toolsrc/src/vcpkg-test/update.cpp b/toolsrc/src/vcpkg-test/update.cpp
deleted file mode 100644
index bce663d28..000000000
--- a/toolsrc/src/vcpkg-test/update.cpp
+++ /dev/null
@@ -1,105 +0,0 @@
-#include <catch2/catch.hpp>
-
-#include <vcpkg/base/sortedvector.h>
-
-#include <vcpkg/portfileprovider.h>
-#include <vcpkg/statusparagraphs.h>
-#include <vcpkg/update.h>
-
-#include <vcpkg-test/util.h>
-
-using namespace vcpkg;
-using namespace vcpkg::Update;
-using namespace vcpkg::Test;
-
-using Pgh = std::vector<std::unordered_map<std::string, std::string>>;
-
-TEST_CASE ("find outdated packages basic", "[update]")
-{
- std::vector<std::unique_ptr<StatusParagraph>> status_paragraphs;
- status_paragraphs.push_back(make_status_pgh("a"));
- status_paragraphs.back()->package.version = "2";
-
- StatusParagraphs status_db(std::move(status_paragraphs));
-
- std::unordered_map<std::string, SourceControlFileLocation> map;
- auto scf = unwrap(test_parse_control_file({{{"Source", "a"}, {"Version", "0"}}}));
- map.emplace("a", SourceControlFileLocation{std::move(scf), ""});
- PortFileProvider::MapPortFileProvider provider(map);
-
- auto pkgs = SortedVector<OutdatedPackage>(Update::find_outdated_packages(provider, status_db),
- &OutdatedPackage::compare_by_name);
-
- REQUIRE(pkgs.size() == 1);
- REQUIRE(pkgs[0].version_diff.left.to_string() == "2");
- REQUIRE(pkgs[0].version_diff.right.to_string() == "0");
-}
-
-TEST_CASE ("find outdated packages features", "[update]")
-{
- std::vector<std::unique_ptr<StatusParagraph>> status_paragraphs;
- status_paragraphs.push_back(make_status_pgh("a"));
- status_paragraphs.back()->package.version = "2";
-
- status_paragraphs.push_back(make_status_feature_pgh("a", "b"));
- status_paragraphs.back()->package.version = "2";
-
- StatusParagraphs status_db(std::move(status_paragraphs));
-
- std::unordered_map<std::string, SourceControlFileLocation> map;
- auto scf = unwrap(test_parse_control_file({{{"Source", "a"}, {"Version", "0"}}}));
- map.emplace("a", SourceControlFileLocation{std::move(scf), ""});
- PortFileProvider::MapPortFileProvider provider(map);
-
- auto pkgs = SortedVector<OutdatedPackage>(Update::find_outdated_packages(provider, status_db),
- &OutdatedPackage::compare_by_name);
-
- REQUIRE(pkgs.size() == 1);
- REQUIRE(pkgs[0].version_diff.left.to_string() == "2");
- REQUIRE(pkgs[0].version_diff.right.to_string() == "0");
-}
-
-TEST_CASE ("find outdated packages features 2", "[update]")
-{
- std::vector<std::unique_ptr<StatusParagraph>> status_paragraphs;
- status_paragraphs.push_back(make_status_pgh("a"));
- status_paragraphs.back()->package.version = "2";
-
- status_paragraphs.push_back(make_status_feature_pgh("a", "b"));
- status_paragraphs.back()->package.version = "0";
- status_paragraphs.back()->state = InstallState::NOT_INSTALLED;
- status_paragraphs.back()->want = Want::PURGE;
-
- StatusParagraphs status_db(std::move(status_paragraphs));
-
- std::unordered_map<std::string, SourceControlFileLocation> map;
- auto scf = unwrap(test_parse_control_file({{{"Source", "a"}, {"Version", "0"}}}));
- map.emplace("a", SourceControlFileLocation{std::move(scf), ""});
- PortFileProvider::MapPortFileProvider provider(map);
-
- auto pkgs = SortedVector<OutdatedPackage>(Update::find_outdated_packages(provider, status_db),
- &OutdatedPackage::compare_by_name);
-
- REQUIRE(pkgs.size() == 1);
- REQUIRE(pkgs[0].version_diff.left.to_string() == "2");
- REQUIRE(pkgs[0].version_diff.right.to_string() == "0");
-}
-
-TEST_CASE ("find outdated packages none", "[update]")
-{
- std::vector<std::unique_ptr<StatusParagraph>> status_paragraphs;
- status_paragraphs.push_back(make_status_pgh("a"));
- status_paragraphs.back()->package.version = "2";
-
- StatusParagraphs status_db(std::move(status_paragraphs));
-
- std::unordered_map<std::string, SourceControlFileLocation> map;
- auto scf = unwrap(test_parse_control_file({{{"Source", "a"}, {"Version", "2"}}}));
- map.emplace("a", SourceControlFileLocation{std::move(scf), ""});
- PortFileProvider::MapPortFileProvider provider(map);
-
- auto pkgs = SortedVector<OutdatedPackage>(Update::find_outdated_packages(provider, status_db),
- &OutdatedPackage::compare_by_name);
-
- REQUIRE(pkgs.size() == 0);
-}
diff --git a/toolsrc/src/vcpkg-test/util.cpp b/toolsrc/src/vcpkg-test/util.cpp
deleted file mode 100644
index 73ff9db5c..000000000
--- a/toolsrc/src/vcpkg-test/util.cpp
+++ /dev/null
@@ -1,230 +0,0 @@
-#include <vcpkg/base/system_headers.h>
-
-#include <catch2/catch.hpp>
-
-#include <vcpkg/base/checks.h>
-#include <vcpkg/base/files.h>
-#include <vcpkg/base/util.h>
-
-#include <vcpkg/statusparagraph.h>
-
-#include <vcpkg-test/util.h>
-
-// used to get the implementation specific compiler flags (i.e., __cpp_lib_filesystem)
-#include <ciso646>
-#include <iostream>
-#include <memory>
-
-#if defined(_WIN32)
-#include <windows.h>
-#endif
-
-#define FILESYSTEM_SYMLINK_STD 0
-#define FILESYSTEM_SYMLINK_UNIX 1
-#define FILESYSTEM_SYMLINK_NONE 2
-
-#if VCPKG_USE_STD_FILESYSTEM
-
-#define FILESYSTEM_SYMLINK FILESYSTEM_SYMLINK_STD
-
-#elif !defined(_MSC_VER)
-
-#define FILESYSTEM_SYMLINK FILESYSTEM_SYMLINK_UNIX
-
-#else
-
-#define FILESYSTEM_SYMLINK FILESYSTEM_SYMLINK_NONE
-
-#endif
-
-namespace vcpkg::Test
-{
- const Triplet X86_WINDOWS = Triplet::from_canonical_name("x86-windows");
- const Triplet X64_WINDOWS = Triplet::from_canonical_name("x64-windows");
- const Triplet X86_UWP = Triplet::from_canonical_name("x86-uwp");
- const Triplet ARM_UWP = Triplet::from_canonical_name("arm-uwp");
- const Triplet X64_ANDROID = Triplet::from_canonical_name("x64-android");
-
- std::unique_ptr<SourceControlFile> make_control_file(
- const char* name,
- const char* depends,
- const std::vector<std::pair<const char*, const char*>>& features,
- const std::vector<const char*>& default_features)
- {
- using Pgh = std::unordered_map<std::string, std::string>;
- std::vector<Pgh> scf_pghs;
- scf_pghs.push_back(Pgh{{"Source", name},
- {"Version", "0"},
- {"Build-Depends", depends},
- {"Default-Features", Strings::join(", ", default_features)}});
- for (auto&& feature : features)
- {
- scf_pghs.push_back(Pgh{
- {"Feature", feature.first},
- {"Description", "feature"},
- {"Build-Depends", feature.second},
- });
- }
- auto m_pgh = test_parse_control_file(std::move(scf_pghs));
- REQUIRE(m_pgh.has_value());
- return std::move(*m_pgh.get());
- }
-
- std::unique_ptr<vcpkg::StatusParagraph> make_status_pgh(const char* name,
- const char* depends,
- const char* default_features,
- const char* triplet)
- {
- return std::make_unique<StatusParagraph>(Parse::Paragraph{{"Package", {name, {}}},
- {"Version", {"1", {}}},
- {"Architecture", {triplet, {}}},
- {"Multi-Arch", {"same", {}}},
- {"Depends", {depends, {}}},
- {"Default-Features", {default_features, {}}},
- {"Status", {"install ok installed", {}}}});
- }
-
- std::unique_ptr<StatusParagraph> make_status_feature_pgh(const char* name,
- const char* feature,
- const char* depends,
- const char* triplet)
- {
- return std::make_unique<StatusParagraph>(Parse::Paragraph{{"Package", {name, {}}},
- {"Feature", {feature, {}}},
- {"Architecture", {triplet, {}}},
- {"Multi-Arch", {"same", {}}},
- {"Depends", {depends, {}}},
- {"Status", {"install ok installed", {}}}});
- }
-
- PackageSpec PackageSpecMap::emplace(const char* name,
- const char* depends,
- const std::vector<std::pair<const char*, const char*>>& features,
- const std::vector<const char*>& default_features)
- {
- auto scfl = SourceControlFileLocation{make_control_file(name, depends, features, default_features), ""};
- return emplace(std::move(scfl));
- }
-
- PackageSpec PackageSpecMap::emplace(vcpkg::SourceControlFileLocation&& scfl)
- {
- const auto& name = scfl.source_control_file->core_paragraph->name;
- REQUIRE(map.find(name) == map.end());
- map.emplace(name, std::move(scfl));
- return {name, triplet};
- }
-
- static AllowSymlinks internal_can_create_symlinks() noexcept
- {
-#if FILESYSTEM_SYMLINK == FILESYSTEM_SYMLINK_NONE
- return AllowSymlinks::No;
-#elif FILESYSTEM_SYMLINK == FILESYSTEM_SYMLINK_UNIX
- return AllowSymlinks::Yes;
-#elif !defined(_WIN32) // FILESYSTEM_SYMLINK == FILESYSTEM_SYMLINK_STD
- return AllowSymlinks::Yes;
-#else
- constexpr static const wchar_t regkey[] = LR"(SOFTWARE\Microsoft\Windows\CurrentVersion\AppModelUnlock)";
- constexpr static const wchar_t regkey_member[] = LR"(AllowDevelopmentWithoutDevLicense)";
-
- DWORD data;
- DWORD dataSize = sizeof(data);
- const auto status =
- RegGetValueW(HKEY_LOCAL_MACHINE, regkey, regkey_member, RRF_RT_DWORD, nullptr, &data, &dataSize);
-
- if (status == ERROR_SUCCESS && data == 1)
- {
- return AllowSymlinks::Yes;
- }
- else
- {
- std::cout << "Symlinks are not allowed on this system\n";
- return AllowSymlinks::No;
- }
-#endif
- }
- const static AllowSymlinks CAN_CREATE_SYMLINKS = internal_can_create_symlinks();
-
- AllowSymlinks can_create_symlinks() noexcept { return CAN_CREATE_SYMLINKS; }
-
- static fs::path internal_base_temporary_directory()
- {
-#if defined(_WIN32)
- wchar_t* tmp = static_cast<wchar_t*>(std::calloc(32'767, 2));
-
- if (!GetEnvironmentVariableW(L"TEMP", tmp, 32'767))
- {
- std::cerr << "No temporary directory found.\n";
- std::abort();
- }
-
- fs::path result = tmp;
- std::free(tmp);
-
- return result / L"vcpkg-test";
-#else
- return "/tmp/vcpkg-test";
-#endif
- }
-
- const fs::path& base_temporary_directory() noexcept
- {
- const static fs::path BASE_TEMPORARY_DIRECTORY = internal_base_temporary_directory();
- return BASE_TEMPORARY_DIRECTORY;
- }
-
-#if FILESYSTEM_SYMLINK == FILESYSTEM_SYMLINK_NONE
- constexpr char no_filesystem_message[] =
- "<filesystem> doesn't exist; on windows, we don't attempt to use the win32 calls to create symlinks";
-#endif
-
- void create_symlink(const fs::path& target, const fs::path& file, std::error_code& ec)
- {
-#if FILESYSTEM_SYMLINK == FILESYSTEM_SYMLINK_STD
- if (can_create_symlinks())
- {
- fs::path targetp = target.native();
- fs::path filep = file.native();
-
- fs::stdfs::create_symlink(targetp, filep, ec);
- }
- else
- {
- vcpkg::Checks::exit_with_message(VCPKG_LINE_INFO, "Symlinks are not allowed on this system");
- }
-#elif FILESYSTEM_SYMLINK == FILESYSTEM_SYMLINK_UNIX
- if (symlink(target.c_str(), file.c_str()) != 0)
- {
- ec.assign(errno, std::system_category());
- }
-#else
- (void)target;
- (void)file;
- (void)ec;
- vcpkg::Checks::exit_with_message(VCPKG_LINE_INFO, no_filesystem_message);
-#endif
- }
-
- void create_directory_symlink(const fs::path& target, const fs::path& file, std::error_code& ec)
- {
-#if FILESYSTEM_SYMLINK == FILESYSTEM_SYMLINK_STD
- if (can_create_symlinks())
- {
- std::filesystem::path targetp = target.native();
- std::filesystem::path filep = file.native();
-
- std::filesystem::create_directory_symlink(targetp, filep, ec);
- }
- else
- {
- vcpkg::Checks::exit_with_message(VCPKG_LINE_INFO, "Symlinks are not allowed on this system");
- }
-#elif FILESYSTEM_SYMLINK == FILESYSTEM_SYMLINK_UNIX
- ::vcpkg::Test::create_symlink(target, file, ec);
-#else
- (void)target;
- (void)file;
- (void)ec;
- vcpkg::Checks::exit_with_message(VCPKG_LINE_INFO, no_filesystem_message);
-#endif
- }
-}
diff --git a/toolsrc/src/vcpkg-test/versionplan.cpp b/toolsrc/src/vcpkg-test/versionplan.cpp
deleted file mode 100644
index 2f82d21b4..000000000
--- a/toolsrc/src/vcpkg-test/versionplan.cpp
+++ /dev/null
@@ -1,152 +0,0 @@
-#include <catch2/catch.hpp>
-
-#include <vcpkg/dependencies.h>
-#include <vcpkg/paragraphparser.h>
-#include <vcpkg/portfileprovider.h>
-#include <vcpkg/sourceparagraph.h>
-
-#include <vcpkg-test/mockcmakevarprovider.h>
-#include <vcpkg-test/util.h>
-
-using namespace vcpkg;
-using namespace vcpkg::Parse;
-
-TEST_CASE ("parse depends", "[dependencies]")
-{
- auto w = parse_dependencies_list("liba (windows)");
- REQUIRE(w);
- auto& v = *w.get();
- REQUIRE(v.size() == 1);
- REQUIRE(v.at(0).name == "liba");
- REQUIRE(v.at(0).platform.evaluate({{"VCPKG_CMAKE_SYSTEM_NAME", ""}}));
- REQUIRE(v.at(0).platform.evaluate({{"VCPKG_CMAKE_SYSTEM_NAME", "WindowsStore"}}));
- REQUIRE(!v.at(0).platform.evaluate({{"VCPKG_CMAKE_SYSTEM_NAME", "Darwin"}}));
-}
-
-TEST_CASE ("filter depends", "[dependencies]")
-{
- const std::unordered_map<std::string, std::string> x64_win_cmake_vars{{"VCPKG_TARGET_ARCHITECTURE", "x64"},
- {"VCPKG_CMAKE_SYSTEM_NAME", ""}};
-
- const std::unordered_map<std::string, std::string> arm_uwp_cmake_vars{{"VCPKG_TARGET_ARCHITECTURE", "arm"},
- {"VCPKG_CMAKE_SYSTEM_NAME", "WindowsStore"}};
-
- auto deps_ = parse_dependencies_list("liba (!uwp), libb, libc (uwp)");
- REQUIRE(deps_);
- auto& deps = *deps_.get();
- auto v = filter_dependencies(deps, Test::X64_WINDOWS, x64_win_cmake_vars);
- REQUIRE(v.size() == 2);
- REQUIRE(v.at(0).package_spec.name() == "liba");
- REQUIRE(v.at(1).package_spec.name() == "libb");
-
- auto v2 = filter_dependencies(deps, Test::ARM_UWP, arm_uwp_cmake_vars);
- REQUIRE(v.size() == 2);
- REQUIRE(v2.at(0).package_spec.name() == "libb");
- REQUIRE(v2.at(1).package_spec.name() == "libc");
-}
-
-TEST_CASE ("parse feature depends", "[dependencies]")
-{
- auto u_ = parse_dependencies_list("libwebp[anim, gif2webp, img2webp, info, mux, nearlossless, "
- "simd, cwebp, dwebp], libwebp[vwebp-sdl, extras] (!osx)");
- REQUIRE(u_);
- auto& v = *u_.get();
- REQUIRE(v.size() == 2);
- auto&& a0 = v.at(0);
- REQUIRE(a0.name == "libwebp");
- REQUIRE(a0.features.size() == 9);
- REQUIRE(a0.platform.is_empty());
-
- auto&& a1 = v.at(1);
- REQUIRE(a1.name == "libwebp");
- REQUIRE(a1.features.size() == 2);
- REQUIRE(!a1.platform.is_empty());
- REQUIRE(a1.platform.evaluate({{"VCPKG_CMAKE_SYSTEM_NAME", ""}}));
- REQUIRE(a1.platform.evaluate({{"VCPKG_CMAKE_SYSTEM_NAME", "Linux"}}));
- REQUIRE_FALSE(a1.platform.evaluate({{"VCPKG_CMAKE_SYSTEM_NAME", "Darwin"}}));
-}
-
-TEST_CASE ("qualified dependency", "[dependencies]")
-{
- using namespace Test;
- PackageSpecMap spec_map;
- auto spec_a = FullPackageSpec{spec_map.emplace("a", "b, b[b1] (linux)"), {}};
- auto spec_b = FullPackageSpec{spec_map.emplace("b", "", {{"b1", ""}}), {}};
-
- PortFileProvider::MapPortFileProvider map_port{spec_map.map};
- MockCMakeVarProvider var_provider;
-
- auto plan = vcpkg::Dependencies::create_feature_install_plan(map_port, var_provider, {spec_a}, {});
- REQUIRE(plan.install_actions.size() == 2);
- REQUIRE(plan.install_actions.at(0).feature_list == std::vector<std::string>{"core"});
-
- FullPackageSpec linspec_a{{"a", Triplet::from_canonical_name("x64-linux")}, {}};
- var_provider.dep_info_vars[linspec_a.package_spec].emplace("VCPKG_CMAKE_SYSTEM_NAME", "Linux");
- auto plan2 = vcpkg::Dependencies::create_feature_install_plan(map_port, var_provider, {linspec_a}, {});
- REQUIRE(plan2.install_actions.size() == 2);
- REQUIRE(plan2.install_actions.at(0).feature_list == std::vector<std::string>{"b1", "core"});
-}
-
-TEST_CASE ("resolve_deps_as_top_level", "[dependencies]")
-{
- using namespace Test;
- PackageSpecMap spec_map;
- FullPackageSpec spec_a{spec_map.emplace("a", "b, b[b1] (linux)"), {}};
- FullPackageSpec spec_b{spec_map.emplace("b", "", {{"b1", ""}}), {}};
- FullPackageSpec spec_c{spec_map.emplace("c", "b", {{"c1", "b[b1]"}, {"c2", "c[c1], a"}}, {"c1"}), {"core"}};
- FullPackageSpec spec_d{spec_map.emplace("d", "c[core]"), {}};
-
- PortFileProvider::MapPortFileProvider map_port{spec_map.map};
- MockCMakeVarProvider var_provider;
- Triplet t_linux = Triplet::from_canonical_name("x64-linux");
- var_provider.dep_info_vars[{"a", t_linux}].emplace("VCPKG_CMAKE_SYSTEM_NAME", "Linux");
- {
- auto deps = vcpkg::Dependencies::resolve_deps_as_top_level(
- *spec_map.map.at("a").source_control_file, Test::X86_WINDOWS, {}, var_provider);
- REQUIRE(deps.size() == 1);
- REQUIRE(deps.at(0) == spec_b);
- }
- {
- auto deps = vcpkg::Dependencies::resolve_deps_as_top_level(
- *spec_map.map.at("a").source_control_file, t_linux, {}, var_provider);
- REQUIRE(deps.size() == 1);
- REQUIRE(deps.at(0) == FullPackageSpec({"b", t_linux}, {"b1"}));
- }
- {
- // without defaults
- auto deps = vcpkg::Dependencies::resolve_deps_as_top_level(
- *spec_map.map.at("c").source_control_file, Test::X86_WINDOWS, {}, var_provider);
- REQUIRE(deps.size() == 1);
- REQUIRE(deps.at(0) == spec_b);
- }
- FullPackageSpec spec_b_with_b1{spec_b.package_spec, {"b1"}};
- {
- // with defaults of c (c1)
- auto deps = vcpkg::Dependencies::resolve_deps_as_top_level(
- *spec_map.map.at("c").source_control_file, Test::X86_WINDOWS, {"default"}, var_provider);
- REQUIRE(deps.size() == 1);
- REQUIRE(deps.at(0) == spec_b_with_b1);
- }
- {
- // with c1
- auto deps = vcpkg::Dependencies::resolve_deps_as_top_level(
- *spec_map.map.at("c").source_control_file, Test::X86_WINDOWS, {"c1"}, var_provider);
- REQUIRE(deps.size() == 1);
- REQUIRE(deps.at(0) == spec_b_with_b1);
- }
- {
- // with c2 implying c1
- auto deps = vcpkg::Dependencies::resolve_deps_as_top_level(
- *spec_map.map.at("c").source_control_file, Test::X86_WINDOWS, {"c2"}, var_provider);
- REQUIRE(deps.size() == 2);
- REQUIRE(deps.at(0) == spec_a);
- REQUIRE(deps.at(1) == spec_b_with_b1);
- }
- {
- // d -> c[core]
- auto deps = vcpkg::Dependencies::resolve_deps_as_top_level(
- *spec_map.map.at("d").source_control_file, Test::X86_WINDOWS, {}, var_provider);
- REQUIRE(deps.size() == 1);
- REQUIRE(deps.at(0) == spec_c);
- }
-}
diff --git a/toolsrc/src/vcpkg.cpp b/toolsrc/src/vcpkg.cpp
deleted file mode 100644
index f25a0c3b6..000000000
--- a/toolsrc/src/vcpkg.cpp
+++ /dev/null
@@ -1,313 +0,0 @@
-#include <vcpkg/base/system_headers.h>
-
-#include <vcpkg/base/chrono.h>
-#include <vcpkg/base/files.h>
-#include <vcpkg/base/pragmas.h>
-#include <vcpkg/base/strings.h>
-#include <vcpkg/base/system.debug.h>
-#include <vcpkg/base/system.print.h>
-#include <vcpkg/base/system.process.h>
-
-#include <vcpkg/commands.contact.h>
-#include <vcpkg/commands.h>
-#include <vcpkg/commands.version.h>
-#include <vcpkg/globalstate.h>
-#include <vcpkg/help.h>
-#include <vcpkg/input.h>
-#include <vcpkg/metrics.h>
-#include <vcpkg/paragraphs.h>
-#include <vcpkg/userconfig.h>
-#include <vcpkg/vcpkgcmdarguments.h>
-#include <vcpkg/vcpkglib.h>
-#include <vcpkg/vcpkgpaths.h>
-
-#include <cassert>
-#include <fstream>
-#include <memory>
-#include <random>
-
-#if defined(_WIN32)
-#pragma comment(lib, "ole32")
-#pragma comment(lib, "shell32")
-#endif
-
-using namespace vcpkg;
-
-// 24 hours/day * 30 days/month * 6 months
-static constexpr int SURVEY_INTERVAL_IN_HOURS = 24 * 30 * 6;
-
-// Initial survey appears after 10 days. Therefore, subtract 24 hours/day * 10 days
-static constexpr int SURVEY_INITIAL_OFFSET_IN_HOURS = SURVEY_INTERVAL_IN_HOURS - 24 * 10;
-
-static void invalid_command(const std::string& cmd)
-{
- System::print2(System::Color::error, "invalid command: ", cmd, '\n');
- print_usage();
- Checks::exit_fail(VCPKG_LINE_INFO);
-}
-
-static void inner(vcpkg::Files::Filesystem& fs, const VcpkgCmdArguments& args)
-{
- Metrics::g_metrics.lock()->track_property("command", args.command);
- if (args.command.empty())
- {
- print_usage();
- Checks::exit_fail(VCPKG_LINE_INFO);
- }
-
- static const auto find_command = [&](auto&& commands) {
- auto it = Util::find_if(commands, [&](auto&& commandc) {
- return Strings::case_insensitive_ascii_equals(commandc.name, args.command);
- });
- using std::end;
- if (it != end(commands))
- {
- return &*it;
- }
- else
- {
- return static_cast<decltype(&*it)>(nullptr);
- }
- };
-
- if (const auto command_function = find_command(Commands::get_available_basic_commands()))
- {
- return command_function->function->perform_and_exit(args, fs);
- }
-
- const VcpkgPaths paths(fs, args);
- paths.track_feature_flag_metrics();
-
- fs.current_path(paths.root, VCPKG_LINE_INFO);
-
- if (const auto command_function = find_command(Commands::get_available_paths_commands()))
- {
- return command_function->function->perform_and_exit(args, paths);
- }
-
- Triplet default_triplet = vcpkg::default_triplet(args);
- Input::check_triplet(default_triplet, paths);
-
- if (const auto command_function = find_command(Commands::get_available_triplet_commands()))
- {
- return command_function->function->perform_and_exit(args, paths, default_triplet);
- }
-
- return invalid_command(args.command);
-}
-
-static void load_config(vcpkg::Files::Filesystem& fs)
-{
- auto config = UserConfig::try_read_data(fs);
-
- bool write_config = false;
-
- // config file not found, could not be read, or invalid
- if (config.user_id.empty() || config.user_time.empty())
- {
- ::vcpkg::Metrics::Metrics::init_user_information(config.user_id, config.user_time);
- write_config = true;
- }
-
-#if defined(_WIN32)
- if (config.user_mac.empty())
- {
- config.user_mac = Metrics::get_MAC_user();
- write_config = true;
- }
-#endif
-
- {
- auto locked_metrics = Metrics::g_metrics.lock();
- locked_metrics->set_user_information(config.user_id, config.user_time);
-#if defined(_WIN32)
- locked_metrics->track_property("user_mac", config.user_mac);
-#endif
- }
-
- if (config.last_completed_survey.empty())
- {
- const auto now = Chrono::CTime::parse(config.user_time).value_or_exit(VCPKG_LINE_INFO);
- const Chrono::CTime offset = now.add_hours(-SURVEY_INITIAL_OFFSET_IN_HOURS);
- config.last_completed_survey = offset.to_string();
- }
-
- GlobalState::g_surveydate.lock()->assign(config.last_completed_survey);
-
- if (write_config)
- {
- config.try_write_data(fs);
- }
-}
-
-#if defined(_WIN32)
-// note: this prevents a false positive for -Wmissing-prototypes on clang-cl
-int wmain(int, const wchar_t* const* const);
-
-#if !defined(_MSC_VER)
-#include <shellapi.h>
-int main(int argc, const char* const* const /*argv*/)
-{
- wchar_t** wargv;
- wargv = CommandLineToArgvW(GetCommandLineW(), &argc);
- return wmain(argc, wargv);
-}
-#endif
-
-int wmain(const int argc, const wchar_t* const* const argv)
-#else
-int main(const int argc, const char* const* const argv)
-#endif
-{
- if (argc == 0) std::abort();
-
- auto& fs = Files::get_real_filesystem();
- *GlobalState::timer.lock() = Chrono::ElapsedTimer::create_started();
-
-#if defined(_WIN32)
- GlobalState::g_init_console_cp = GetConsoleCP();
- GlobalState::g_init_console_output_cp = GetConsoleOutputCP();
- GlobalState::g_init_console_initialized = true;
-
- SetConsoleCP(CP_UTF8);
- SetConsoleOutputCP(CP_UTF8);
-
- System::initialize_global_job_object();
-#endif
- System::set_environment_variable("VCPKG_COMMAND", fs::generic_u8string(System::get_exe_path_of_current_process()));
-
- Checks::register_global_shutdown_handler([]() {
- const auto elapsed_us_inner = GlobalState::timer.lock()->microseconds();
-
- bool debugging = Debug::g_debugging;
-
- auto metrics = Metrics::g_metrics.lock();
- metrics->track_metric("elapsed_us", elapsed_us_inner);
- Debug::g_debugging = false;
- metrics->flush(Files::get_real_filesystem());
-
-#if defined(_WIN32)
- if (GlobalState::g_init_console_initialized)
- {
- SetConsoleCP(GlobalState::g_init_console_cp);
- SetConsoleOutputCP(GlobalState::g_init_console_output_cp);
- }
-#endif
-
- auto elapsed_us = GlobalState::timer.lock()->microseconds();
- if (debugging)
- System::printf("[DEBUG] Exiting after %d us (%d us)\n",
- static_cast<int>(elapsed_us),
- static_cast<int>(elapsed_us_inner));
- });
-
- {
- auto locked_metrics = Metrics::g_metrics.lock();
- locked_metrics->track_property("version", Commands::Version::version());
- }
-
- System::register_console_ctrl_handler();
-
- load_config(fs);
-
-#if (defined(__aarch64__) || defined(__arm__) || defined(__s390x__) || \
- ((defined(__ppc64__) || defined(__PPC64__) || defined(__ppc64le__) || defined(__PPC64LE__)) && \
- defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)) || \
- defined(_M_ARM) || defined(_M_ARM64)) && \
- !defined(_WIN32) && !defined(__APPLE__)
- if (!System::get_environment_variable("VCPKG_FORCE_SYSTEM_BINARIES").has_value())
- {
- Checks::exit_with_message(
- VCPKG_LINE_INFO,
- "Environment variable VCPKG_FORCE_SYSTEM_BINARIES must be set on arm, s390x, and ppc64le platforms.");
- }
-#endif
-
- VcpkgCmdArguments args = VcpkgCmdArguments::create_from_command_line(fs, argc, argv);
- if (const auto p = args.debug.get()) Debug::g_debugging = *p;
- args.imbue_from_environment();
- VcpkgCmdArguments::imbue_or_apply_process_recursion(args);
- args.check_feature_flag_consistency();
-
- {
- auto metrics = Metrics::g_metrics.lock();
- if (const auto p = args.disable_metrics.get())
- {
- metrics->set_disabled(*p);
- }
-
- auto disable_metrics_tag_file_path =
- System::get_exe_path_of_current_process().replace_filename(fs::u8path("vcpkg.disable-metrics"));
- std::error_code ec;
- if (fs.exists(disable_metrics_tag_file_path, ec) || ec)
- {
- metrics->set_disabled(true);
- }
-
- if (const auto p = args.print_metrics.get())
- {
- metrics->set_print_metrics(*p);
- }
-
- if (const auto p = args.send_metrics.get())
- {
- metrics->set_send_metrics(*p);
- }
-
- if (args.send_metrics.value_or(false) && !metrics->metrics_enabled())
- {
- System::print2(System::Color::warning, "Warning: passed --sendmetrics, but metrics are disabled.\n");
- }
- } // unlock Metrics::g_metrics
-
- args.debug_print_feature_flags();
- args.track_feature_flag_metrics();
-
- if (Debug::g_debugging)
- {
- inner(fs, args);
- Checks::exit_fail(VCPKG_LINE_INFO);
- }
-
- std::string exc_msg;
- try
- {
- inner(fs, args);
- Checks::exit_fail(VCPKG_LINE_INFO);
- }
- catch (std::exception& e)
- {
- exc_msg = e.what();
- }
- catch (...)
- {
- exc_msg = "unknown error(...)";
- }
- Metrics::g_metrics.lock()->track_property("error", exc_msg);
-
- fflush(stdout);
- System::printf("vcpkg.exe has crashed.\n"
- "Please send an email to:\n"
- " %s\n"
- "containing a brief summary of what you were trying to do and the following data blob:\n"
- "\n"
- "Version=%s\n"
- "EXCEPTION='%s'\n"
- "CMD=\n",
- Commands::Contact::email(),
- Commands::Version::version(),
- exc_msg);
- fflush(stdout);
- for (int x = 0; x < argc; ++x)
- {
-#if defined(_WIN32)
- System::print2(Strings::to_utf8(argv[x]), "|\n");
-#else
- System::print2(argv[x], "|\n");
-#endif
- }
- fflush(stdout);
-
- // It is expected that one of the sub-commands will exit cleanly before we get here.
- Checks::exit_fail(VCPKG_LINE_INFO);
-}
diff --git a/toolsrc/src/vcpkg/archives.cpp b/toolsrc/src/vcpkg/archives.cpp
deleted file mode 100644
index 5008b3223..000000000
--- a/toolsrc/src/vcpkg/archives.cpp
+++ /dev/null
@@ -1,130 +0,0 @@
-#include <vcpkg/base/system.print.h>
-#include <vcpkg/base/system.process.h>
-
-#include <vcpkg/archives.h>
-#include <vcpkg/commands.h>
-#include <vcpkg/tools.h>
-#include <vcpkg/vcpkgpaths.h>
-
-namespace vcpkg::Archives
-{
- void extract_archive(const VcpkgPaths& paths, const fs::path& archive, const fs::path& to_path)
- {
- Files::Filesystem& fs = paths.get_filesystem();
- const fs::path to_path_partial = fs::u8string(to_path) + ".partial"
-#if defined(_WIN32)
- + "." + std::to_string(GetCurrentProcessId())
-#endif
- ;
-
- fs.remove_all(to_path, VCPKG_LINE_INFO);
- fs.remove_all(to_path_partial, VCPKG_LINE_INFO);
- // TODO: check this error code
- std::error_code ec;
- fs.create_directories(to_path_partial, ec);
- const auto ext = archive.extension();
-#if defined(_WIN32)
- if (ext == ".nupkg")
- {
- static bool recursion_limiter_sevenzip_old = false;
- Checks::check_exit(VCPKG_LINE_INFO, !recursion_limiter_sevenzip_old);
- recursion_limiter_sevenzip_old = true;
- const auto nuget_exe = paths.get_tool_exe(Tools::NUGET);
-
- const std::string stem = fs::u8string(archive.stem());
- // assuming format of [name].[version in the form d.d.d]
- // This assumption may not always hold
- std::smatch match;
- const bool has_match = std::regex_match(stem, match, std::regex{R"###(^(.+)\.(\d+\.\d+\.\d+)$)###"});
- Checks::check_exit(VCPKG_LINE_INFO,
- has_match,
- "Could not deduce nuget id and version from filename: %s",
- fs::u8string(archive));
-
- const std::string nugetid = match[1];
- const std::string version = match[2];
-
- const auto code_and_output = System::cmd_execute_and_capture_output(System::Command{nuget_exe}
- .string_arg("install")
- .string_arg(nugetid)
- .string_arg("-Version")
- .string_arg(version)
- .string_arg("-OutputDirectory")
- .path_arg(to_path_partial)
- .string_arg("-Source")
- .path_arg(paths.downloads)
- .string_arg("-nocache")
- .string_arg("-DirectDownload")
- .string_arg("-NonInteractive")
- .string_arg("-ForceEnglishOutput")
- .string_arg("-PackageSaveMode")
- .string_arg("nuspec"));
-
- Checks::check_exit(VCPKG_LINE_INFO,
- code_and_output.exit_code == 0,
- "Failed to extract '%s' with message:\n%s",
- fs::u8string(archive),
- code_and_output.output);
- recursion_limiter_sevenzip_old = false;
- }
- else
- {
- static bool recursion_limiter_sevenzip = false;
- Checks::check_exit(VCPKG_LINE_INFO, !recursion_limiter_sevenzip);
- recursion_limiter_sevenzip = true;
- const auto seven_zip = paths.get_tool_exe(Tools::SEVEN_ZIP);
- const auto code_and_output = System::cmd_execute_and_capture_output(
- System::Command{seven_zip}
- .string_arg("x")
- .path_arg(archive)
- .string_arg(Strings::format("-o%s", fs::u8string(to_path_partial)))
- .string_arg("-y"));
- Checks::check_exit(VCPKG_LINE_INFO,
- code_and_output.exit_code == 0,
- "7zip failed while extracting '%s' with message:\n%s",
- fs::u8string(archive),
- code_and_output.output);
- recursion_limiter_sevenzip = false;
- }
-#else
- if (ext == ".gz" && ext.extension() != ".tar")
- {
- const auto code = System::cmd_execute(System::Command{"tar"}.string_arg("xzf").path_arg(archive),
- System::InWorkingDirectory{to_path_partial});
- Checks::check_exit(VCPKG_LINE_INFO, code == 0, "tar failed while extracting %s", fs::u8string(archive));
- }
- else if (ext == ".zip")
- {
- const auto code = System::cmd_execute(System::Command{"unzip"}.string_arg("-qqo").path_arg(archive),
- System::InWorkingDirectory{to_path_partial});
- Checks::check_exit(VCPKG_LINE_INFO, code == 0, "unzip failed while extracting %s", fs::u8string(archive));
- }
- else
- {
- Checks::exit_maybe_upgrade(VCPKG_LINE_INFO, "Unexpected archive extension: %s", fs::u8string(ext));
- }
-#endif
-
- fs.rename(to_path_partial, to_path, ec);
-
- using namespace std::chrono_literals;
-
- auto retry_delay = 8ms;
-
- for (int i = 0; i < 10 && ec; i++)
- {
- using namespace std::chrono_literals;
- std::this_thread::sleep_for(retry_delay);
- fs.rename(to_path_partial, to_path, ec);
- retry_delay *= 2;
- }
-
- Checks::check_exit(VCPKG_LINE_INFO,
- !ec,
- "Failed to do post-extract rename-in-place.\n"
- "fs.rename(%s, %s, %s)",
- fs::u8string(to_path_partial),
- fs::u8string(to_path),
- ec.message());
- }
-}
diff --git a/toolsrc/src/vcpkg/base/checks.cpp b/toolsrc/src/vcpkg/base/checks.cpp
deleted file mode 100644
index e3ab22dae..000000000
--- a/toolsrc/src/vcpkg/base/checks.cpp
+++ /dev/null
@@ -1,120 +0,0 @@
-#include <vcpkg/base/checks.h>
-#include <vcpkg/base/stringview.h>
-#include <vcpkg/base/system.debug.h>
-
-#include <stdlib.h>
-
-namespace vcpkg
-{
- static void (*g_shutdown_handler)() = nullptr;
-
- void Checks::register_global_shutdown_handler(void (*func)())
- {
- if (g_shutdown_handler)
- // Setting the handler twice is a program error. Terminate.
- std::abort();
- g_shutdown_handler = func;
- }
-
- [[noreturn]] void Checks::final_cleanup_and_exit(const int exit_code)
- {
- static std::atomic<bool> have_entered{false};
- if (have_entered.exchange(true))
- {
-#if defined(_WIN32)
- ::TerminateProcess(::GetCurrentProcess(), exit_code);
-#else
- std::abort();
-#endif
- }
-
- if (g_shutdown_handler) g_shutdown_handler();
-
- fflush(nullptr);
-
-#if defined(_WIN32)
- ::TerminateProcess(::GetCurrentProcess(), exit_code);
-#endif
- std::exit(exit_code);
- }
-
- [[noreturn]] void Checks::unreachable(const LineInfo& line_info)
- {
- System::printf(System::Color::error,
- "Error: Unreachable code was reached\n%s(%d)\n",
- line_info.file_name,
- line_info.line_number);
-#ifndef NDEBUG
- std::abort();
-#else
- final_cleanup_and_exit(EXIT_FAILURE);
-#endif
- }
-
- [[noreturn]] void Checks::exit_with_code(const LineInfo& line_info, const int exit_code)
- {
- Debug::print(Strings::format("%s(%d)\n", line_info.file_name, line_info.line_number));
- final_cleanup_and_exit(exit_code);
- }
-
- [[noreturn]] void Checks::exit_fail(const LineInfo& line_info) { exit_with_code(line_info, EXIT_FAILURE); }
-
- [[noreturn]] void Checks::exit_success(const LineInfo& line_info) { exit_with_code(line_info, EXIT_SUCCESS); }
-
- [[noreturn]] void Checks::exit_with_message(const LineInfo& line_info, StringView error_message)
- {
- System::print2(System::Color::error, error_message, '\n');
- exit_fail(line_info);
- }
-
- void Checks::check_exit(const LineInfo& line_info, bool expression)
- {
- if (!expression)
- {
- exit_fail(line_info);
- }
- }
-
- void Checks::check_exit(const LineInfo& line_info, bool expression, StringView error_message)
- {
- if (!expression)
- {
- exit_with_message(line_info, error_message);
- }
- }
-
- static void display_upgrade_message()
- {
- System::print2(System::Color::error,
- "Note: Updating vcpkg by rerunning bootstrap-vcpkg may resolve this failure.\n");
- }
-
- [[noreturn]] void Checks::exit_maybe_upgrade(const LineInfo& line_info)
- {
- display_upgrade_message();
- exit_fail(line_info);
- }
-
- [[noreturn]] void Checks::exit_maybe_upgrade(const LineInfo& line_info, StringView error_message)
- {
- System::print2(System::Color::error, error_message, '\n');
- display_upgrade_message();
- exit_fail(line_info);
- }
-
- void Checks::check_maybe_upgrade(const LineInfo& line_info, bool expression)
- {
- if (!expression)
- {
- exit_maybe_upgrade(line_info);
- }
- }
-
- void Checks::check_maybe_upgrade(const LineInfo& line_info, bool expression, StringView error_message)
- {
- if (!expression)
- {
- exit_maybe_upgrade(line_info, error_message);
- }
- }
-}
diff --git a/toolsrc/src/vcpkg/base/chrono.cpp b/toolsrc/src/vcpkg/base/chrono.cpp
deleted file mode 100644
index 971d5f37e..000000000
--- a/toolsrc/src/vcpkg/base/chrono.cpp
+++ /dev/null
@@ -1,180 +0,0 @@
-#include <vcpkg/base/checks.h>
-#include <vcpkg/base/chrono.h>
-
-namespace vcpkg::Chrono
-{
- static std::time_t get_current_time_as_time_since_epoch()
- {
- using std::chrono::system_clock;
- return system_clock::to_time_t(system_clock::now());
- }
-
- static std::time_t utc_mktime(tm* time_ptr)
- {
-#if defined(_WIN32)
- return _mkgmtime(time_ptr);
-#else
- return timegm(time_ptr);
-#endif
- }
-
- static tm to_local_time(const std::time_t& t)
- {
- tm parts{};
-#if defined(_WIN32)
- localtime_s(&parts, &t);
-#else
- parts = *localtime(&t);
-#endif
- return parts;
- }
-
- static Optional<tm> to_utc_time(const std::time_t& t)
- {
- tm parts{};
-#if defined(_WIN32)
- const errno_t err = gmtime_s(&parts, &t);
- if (err)
- {
- return nullopt;
- }
-#else
- auto null_if_failed = gmtime_r(&t, &parts);
- if (null_if_failed == nullptr)
- {
- return nullopt;
- }
-#endif
- return parts;
- }
-
- static tm date_plus_hours(tm* date, const int hours)
- {
- using namespace std::chrono_literals;
- static constexpr std::chrono::seconds SECONDS_IN_ONE_HOUR =
- std::chrono::duration_cast<std::chrono::seconds>(1h);
-
- const std::time_t date_in_seconds = utc_mktime(date) + (hours * SECONDS_IN_ONE_HOUR.count());
- return to_utc_time(date_in_seconds).value_or_exit(VCPKG_LINE_INFO);
- }
-
- static std::string format_time_userfriendly(const std::chrono::nanoseconds& nanos)
- {
- using std::chrono::duration_cast;
- using std::chrono::hours;
- using std::chrono::microseconds;
- using std::chrono::milliseconds;
- using std::chrono::minutes;
- using std::chrono::nanoseconds;
- using std::chrono::seconds;
-
- const auto nanos_as_double = static_cast<double>(nanos.count());
-
- if (duration_cast<hours>(nanos) > hours())
- {
- const auto t = nanos_as_double / duration_cast<nanoseconds>(hours(1)).count();
- return Strings::format("%.4g h", t);
- }
-
- if (duration_cast<minutes>(nanos) > minutes())
- {
- const auto t = nanos_as_double / duration_cast<nanoseconds>(minutes(1)).count();
- return Strings::format("%.4g min", t);
- }
-
- if (duration_cast<seconds>(nanos) > seconds())
- {
- const auto t = nanos_as_double / duration_cast<nanoseconds>(seconds(1)).count();
- return Strings::format("%.4g s", t);
- }
-
- if (duration_cast<milliseconds>(nanos) > milliseconds())
- {
- const auto t = nanos_as_double / duration_cast<nanoseconds>(milliseconds(1)).count();
- return Strings::format("%.4g ms", t);
- }
-
- if (duration_cast<microseconds>(nanos) > microseconds())
- {
- const auto t = nanos_as_double / duration_cast<nanoseconds>(microseconds(1)).count();
- return Strings::format("%.4g us", t);
- }
-
- return Strings::format("%.4g ns", nanos_as_double);
- }
-
- ElapsedTimer ElapsedTimer::create_started()
- {
- ElapsedTimer t;
- t.m_start_tick = std::chrono::high_resolution_clock::now();
- return t;
- }
-
- std::string ElapsedTime::to_string() const { return format_time_userfriendly(as<std::chrono::nanoseconds>()); }
- void ElapsedTime::to_string(std::string& into) const
- {
- into += format_time_userfriendly(as<std::chrono::nanoseconds>());
- }
-
- std::string ElapsedTimer::to_string() const { return elapsed().to_string(); }
- void ElapsedTimer::to_string(std::string& into) const { return elapsed().to_string(into); }
-
- Optional<CTime> CTime::get_current_date_time()
- {
- const std::time_t ct = get_current_time_as_time_since_epoch();
- const Optional<tm> opt = to_utc_time(ct);
- if (auto p_tm = opt.get())
- {
- return CTime{*p_tm};
- }
-
- return nullopt;
- }
-
- Optional<CTime> CTime::parse(CStringView str)
- {
- CTime ret;
- const auto assigned =
-#if defined(_WIN32)
- sscanf_s
-#else
- sscanf
-#endif
- (str.c_str(),
- "%d-%d-%dT%d:%d:%d.",
- &ret.m_tm.tm_year,
- &ret.m_tm.tm_mon,
- &ret.m_tm.tm_mday,
- &ret.m_tm.tm_hour,
- &ret.m_tm.tm_min,
- &ret.m_tm.tm_sec);
- if (assigned != 6) return nullopt;
- if (ret.m_tm.tm_year < 1900) return nullopt;
- ret.m_tm.tm_year -= 1900;
- if (ret.m_tm.tm_mon < 1) return nullopt;
- ret.m_tm.tm_mon -= 1;
- utc_mktime(&ret.m_tm);
-
- return ret;
- }
-
- CTime CTime::add_hours(const int hours) const { return CTime{date_plus_hours(&this->m_tm, hours)}; }
-
- std::string CTime::to_string() const
- {
- std::array<char, 80> date{};
- strftime(&date[0], date.size(), "%Y-%m-%dT%H:%M:%S.0Z", &m_tm);
- return &date[0];
- }
- std::chrono::system_clock::time_point CTime::to_time_point() const
- {
- const time_t t = utc_mktime(&m_tm);
- return std::chrono::system_clock::from_time_t(t);
- }
-
- tm get_current_date_time_local()
- {
- const std::time_t now_time = get_current_time_as_time_since_epoch();
- return Chrono::to_local_time(now_time);
- }
-}
diff --git a/toolsrc/src/vcpkg/base/cofffilereader.cpp b/toolsrc/src/vcpkg/base/cofffilereader.cpp
deleted file mode 100644
index 30e0f8588..000000000
--- a/toolsrc/src/vcpkg/base/cofffilereader.cpp
+++ /dev/null
@@ -1,311 +0,0 @@
-#include <vcpkg/base/checks.h>
-#include <vcpkg/base/cofffilereader.h>
-#include <vcpkg/base/stringliteral.h>
-
-using namespace std;
-
-namespace vcpkg::CoffFileReader
-{
-#if defined(_WIN32)
- template<class T>
- static T reinterpret_bytes(const char* data)
- {
- return (*reinterpret_cast<const T*>(&data[0]));
- }
-
- template<class T>
- static T read_value_from_stream(fstream& fs)
- {
- T data;
- fs.read(reinterpret_cast<char*>(&data), sizeof data);
- return data;
- }
-
- template<class T>
- static T peek_value_from_stream(fstream& fs)
- {
- const std::streampos original_pos = fs.tellg();
- T data;
- fs.read(reinterpret_cast<char*>(&data), sizeof data);
- fs.seekg(original_pos);
- return data;
- }
-
- static void verify_equal_strings(const LineInfo& line_info,
- StringView expected,
- StringView actual,
- const char* label)
- {
- Checks::check_exit(line_info,
- expected == actual,
- "Incorrect string (%s) found. Expected: (%s) but found (%s)",
- label,
- expected,
- actual);
- }
-
- static void read_and_verify_pe_signature(fstream& fs)
- {
- static constexpr size_t OFFSET_TO_PE_SIGNATURE_OFFSET = 0x3c;
-
- static constexpr StringLiteral PE_SIGNATURE = "PE\0\0";
- static constexpr size_t PE_SIGNATURE_SIZE = 4;
-
- fs.seekg(OFFSET_TO_PE_SIGNATURE_OFFSET, ios_base::beg);
- const auto offset_to_pe_signature = read_value_from_stream<int32_t>(fs);
-
- fs.seekg(offset_to_pe_signature);
- char signature[PE_SIGNATURE_SIZE];
- fs.read(signature, PE_SIGNATURE_SIZE);
- verify_equal_strings(VCPKG_LINE_INFO, PE_SIGNATURE, {signature, PE_SIGNATURE_SIZE}, "PE_SIGNATURE");
- fs.seekg(offset_to_pe_signature + PE_SIGNATURE_SIZE, ios_base::beg);
- }
-
- static fpos_t align_to_size(const uint64_t unaligned, const uint64_t alignment_size)
- {
- fpos_t aligned = unaligned - 1;
- aligned /= alignment_size;
- aligned += 1;
- aligned *= alignment_size;
- return aligned;
- }
-
- struct CoffFileHeader
- {
- static constexpr size_t HEADER_SIZE = 20;
-
- static CoffFileHeader read(fstream& fs)
- {
- CoffFileHeader ret;
- ret.data.resize(HEADER_SIZE);
- fs.read(&ret.data[0], HEADER_SIZE);
- return ret;
- }
-
- MachineType machine_type() const
- {
- static constexpr size_t MACHINE_TYPE_OFFSET = 0;
- static constexpr size_t MACHINE_TYPE_SIZE = 2;
-
- std::string machine_field_as_string = data.substr(MACHINE_TYPE_OFFSET, MACHINE_TYPE_SIZE);
- const auto machine = reinterpret_bytes<uint16_t>(machine_field_as_string.c_str());
- return to_machine_type(machine);
- }
-
- private:
- std::string data;
- };
-
- struct ArchiveMemberHeader
- {
- static constexpr size_t HEADER_SIZE = 60;
-
- static ArchiveMemberHeader read(fstream& fs)
- {
- static constexpr size_t HEADER_END_OFFSET = 58;
- static constexpr StringLiteral HEADER_END = "`\n";
- static constexpr size_t HEADER_END_SIZE = 2;
-
- ArchiveMemberHeader ret;
- ret.data.resize(HEADER_SIZE);
- fs.read(&ret.data[0], HEADER_SIZE);
-
- if (ret.data[0] != '\0') // Due to freeglut. github issue #223
- {
- const std::string header_end = ret.data.substr(HEADER_END_OFFSET, HEADER_END_SIZE);
- verify_equal_strings(VCPKG_LINE_INFO, HEADER_END, header_end, "LIB HEADER_END");
- }
-
- return ret;
- }
-
- std::string name() const
- {
- static constexpr size_t HEADER_NAME_OFFSET = 0;
- static constexpr size_t HEADER_NAME_SIZE = 16;
- return data.substr(HEADER_NAME_OFFSET, HEADER_NAME_SIZE);
- }
-
- uint64_t member_size() const
- {
- static constexpr size_t ALIGNMENT_SIZE = 2;
-
- static constexpr size_t HEADER_SIZE_OFFSET = 48;
- static constexpr size_t HEADER_SIZE_FIELD_SIZE = 10;
- const std::string as_string = data.substr(HEADER_SIZE_OFFSET, HEADER_SIZE_FIELD_SIZE);
- // This is in ASCII decimal representation
- const uint64_t value = std::strtoull(as_string.c_str(), nullptr, 10);
-
- const uint64_t aligned = align_to_size(value, ALIGNMENT_SIZE);
- return aligned;
- }
-
- std::string data;
- };
-
- struct OffsetsArray
- {
- static OffsetsArray read(fstream& fs, const uint32_t offset_count)
- {
- static constexpr uint32_t OFFSET_WIDTH = 4;
-
- std::string raw_offsets;
- const uint32_t raw_offset_size = offset_count * OFFSET_WIDTH;
- raw_offsets.resize(raw_offset_size);
- fs.read(&raw_offsets[0], raw_offset_size);
-
- OffsetsArray ret;
- for (uint32_t i = 0; i < offset_count; ++i)
- {
- const std::string value_as_string = raw_offsets.substr(OFFSET_WIDTH * static_cast<size_t>(i),
- OFFSET_WIDTH * (static_cast<size_t>(i) + 1));
- const auto value = reinterpret_bytes<uint32_t>(value_as_string.c_str());
-
- // Ignore offsets that point to offset 0. See vcpkg github #223 #288 #292
- if (value != 0)
- {
- ret.data.push_back(value);
- }
- }
-
- // Sort the offsets, because it is possible for them to be unsorted. See vcpkg github #292
- std::sort(ret.data.begin(), ret.data.end());
- return ret;
- }
-
- std::vector<uint32_t> data;
- };
-
- struct ImportHeader
- {
- static constexpr size_t HEADER_SIZE = 20;
-
- static ImportHeader read(fstream& fs)
- {
- static constexpr size_t SIG1_OFFSET = 0;
- static constexpr auto SIG1 = static_cast<uint16_t>(MachineType::UNKNOWN);
- static constexpr size_t SIG1_SIZE = 2;
-
- static constexpr size_t SIG2_OFFSET = 2;
- static constexpr uint16_t SIG2 = 0xFFFF;
- static constexpr size_t SIG2_SIZE = 2;
-
- ImportHeader ret;
- ret.data.resize(HEADER_SIZE);
- fs.read(&ret.data[0], HEADER_SIZE);
-
- const std::string sig1_as_string = ret.data.substr(SIG1_OFFSET, SIG1_SIZE);
- const auto sig1 = reinterpret_bytes<uint16_t>(sig1_as_string.c_str());
- Checks::check_exit(VCPKG_LINE_INFO, sig1 == SIG1, "Sig1 was incorrect. Expected %s but got %s", SIG1, sig1);
-
- const std::string sig2_as_string = ret.data.substr(SIG2_OFFSET, SIG2_SIZE);
- const auto sig2 = reinterpret_bytes<uint16_t>(sig2_as_string.c_str());
- Checks::check_exit(VCPKG_LINE_INFO, sig2 == SIG2, "Sig2 was incorrect. Expected %s but got %s", SIG2, sig2);
-
- return ret;
- }
-
- MachineType machine_type() const
- {
- static constexpr size_t MACHINE_TYPE_OFFSET = 6;
- static constexpr size_t MACHINE_TYPE_SIZE = 2;
-
- std::string machine_field_as_string = data.substr(MACHINE_TYPE_OFFSET, MACHINE_TYPE_SIZE);
- const auto machine = reinterpret_bytes<uint16_t>(machine_field_as_string.c_str());
- return to_machine_type(machine);
- }
-
- private:
- std::string data;
- };
-
- static void read_and_verify_archive_file_signature(fstream& fs)
- {
- static constexpr StringLiteral FILE_START = "!<arch>\n";
- static constexpr size_t FILE_START_SIZE = 8;
-
- fs.seekg(std::fstream::beg);
-
- char file_start[FILE_START_SIZE];
- fs.read(file_start, FILE_START_SIZE);
- verify_equal_strings(VCPKG_LINE_INFO, FILE_START, {file_start, FILE_START_SIZE}, "LIB FILE_START");
- }
-
- DllInfo read_dll(const fs::path& path)
- {
- std::fstream fs(path, std::ios::in | std::ios::binary | std::ios::ate);
- Checks::check_exit(VCPKG_LINE_INFO, fs.is_open(), "Could not open file %s for reading", path.generic_string());
-
- read_and_verify_pe_signature(fs);
- CoffFileHeader header = CoffFileHeader::read(fs);
- const MachineType machine = header.machine_type();
- return {machine};
- }
-
- struct Marker
- {
- void set_to_offset(const fpos_t position) { this->m_absolute_position = position; }
-
- void set_to_current_pos(fstream& fs) { this->m_absolute_position = fs.tellg(); }
-
- void seek_to_marker(fstream& fs) const { fs.seekg(this->m_absolute_position, ios_base::beg); }
-
- void advance_by(const uint64_t offset) { this->m_absolute_position += offset; }
-
- private:
- fpos_t m_absolute_position = 0;
- };
-
- LibInfo read_lib(const fs::path& path)
- {
- std::fstream fs(path, std::ios::in | std::ios::binary | std::ios::ate);
- Checks::check_exit(VCPKG_LINE_INFO, fs.is_open(), "Could not open file %s for reading", path.generic_string());
-
- read_and_verify_archive_file_signature(fs);
-
- Marker marker;
- marker.set_to_current_pos(fs);
-
- // First Linker Member
- const ArchiveMemberHeader first_linker_member_header = ArchiveMemberHeader::read(fs);
- Checks::check_exit(VCPKG_LINE_INFO,
- first_linker_member_header.name().substr(0, 2) == "/ ",
- "Could not find proper first linker member");
- marker.advance_by(ArchiveMemberHeader::HEADER_SIZE + first_linker_member_header.member_size());
- marker.seek_to_marker(fs);
-
- const ArchiveMemberHeader second_linker_member_header = ArchiveMemberHeader::read(fs);
- Checks::check_exit(VCPKG_LINE_INFO,
- second_linker_member_header.name().substr(0, 2) == "/ ",
- "Could not find proper second linker member");
- // The first 4 bytes contains the number of archive members
- const auto archive_member_count = read_value_from_stream<uint32_t>(fs);
- const OffsetsArray offsets = OffsetsArray::read(fs, archive_member_count);
- marker.advance_by(ArchiveMemberHeader::HEADER_SIZE + second_linker_member_header.member_size());
- marker.seek_to_marker(fs);
-
- const bool has_longname_member_header = peek_value_from_stream<uint16_t>(fs) == 0x2F2F;
- if (has_longname_member_header)
- {
- const ArchiveMemberHeader longnames_member_header = ArchiveMemberHeader::read(fs);
- marker.advance_by(ArchiveMemberHeader::HEADER_SIZE + longnames_member_header.member_size());
- marker.seek_to_marker(fs);
- }
-
- std::set<MachineType> machine_types;
- // Next we have the obj and pseudo-object files
- for (const uint32_t offset : offsets.data)
- {
- marker.set_to_offset(offset + ArchiveMemberHeader::HEADER_SIZE); // Skip the header, no need to read it.
- marker.seek_to_marker(fs);
- const auto first_two_bytes = peek_value_from_stream<uint16_t>(fs);
- const bool is_import_header = to_machine_type(first_two_bytes) == MachineType::UNKNOWN;
- const MachineType machine =
- is_import_header ? ImportHeader::read(fs).machine_type() : CoffFileHeader::read(fs).machine_type();
- machine_types.insert(machine);
- }
-
- return {std::vector<MachineType>(machine_types.cbegin(), machine_types.cend())};
- }
-#endif
-}
diff --git a/toolsrc/src/vcpkg/base/downloads.cpp b/toolsrc/src/vcpkg/base/downloads.cpp
deleted file mode 100644
index 9fd3351d0..000000000
--- a/toolsrc/src/vcpkg/base/downloads.cpp
+++ /dev/null
@@ -1,467 +0,0 @@
-#include <vcpkg/base/cache.h>
-#include <vcpkg/base/downloads.h>
-#include <vcpkg/base/hash.h>
-#include <vcpkg/base/lockguarded.h>
-#include <vcpkg/base/system.debug.h>
-#include <vcpkg/base/system.h>
-#include <vcpkg/base/system.print.h>
-#include <vcpkg/base/system.process.h>
-#include <vcpkg/base/util.h>
-
-#if defined(_WIN32)
-#include <VersionHelpers.h>
-#endif
-
-namespace vcpkg::Downloads
-{
-#if defined(_WIN32)
- struct WinHttpHandleDeleter
- {
- void operator()(HINTERNET h) const { WinHttpCloseHandle(h); }
- };
-
- struct WinHttpRequest
- {
- static ExpectedS<WinHttpRequest> make(HINTERNET hConnect, StringView url_path, const wchar_t* method = L"GET")
- {
- WinHttpRequest ret;
- // Create an HTTP request handle.
- auto h = WinHttpOpenRequest(hConnect,
- method,
- Strings::to_utf16(url_path).c_str(),
- nullptr,
- WINHTTP_NO_REFERER,
- WINHTTP_DEFAULT_ACCEPT_TYPES,
- WINHTTP_FLAG_SECURE);
- if (!h) return Strings::concat("WinHttpOpenRequest() failed: ", GetLastError());
- ret.m_hRequest.reset(h);
-
- // Send a request.
- auto bResults = WinHttpSendRequest(
- ret.m_hRequest.get(), WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0);
-
- if (!bResults) return Strings::concat("WinHttpSendRequest() failed: ", GetLastError());
-
- // End the request.
- bResults = WinHttpReceiveResponse(ret.m_hRequest.get(), NULL);
- if (!bResults) return Strings::concat("WinHttpReceiveResponse() failed: ", GetLastError());
-
- DWORD dwStatusCode = 0;
- DWORD dwSize = sizeof(dwStatusCode);
-
- bResults = WinHttpQueryHeaders(ret.m_hRequest.get(),
- WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER,
- WINHTTP_HEADER_NAME_BY_INDEX,
- &dwStatusCode,
- &dwSize,
- WINHTTP_NO_HEADER_INDEX);
- if (!bResults) return Strings::concat("WinHttpQueryHeaders() failed: ", GetLastError());
- if (dwStatusCode < 200 || dwStatusCode >= 300) return Strings::concat("failed: status code ", dwStatusCode);
-
- return std::move(ret);
- }
-
- template<class F>
- ExpectedS<int> forall_data(F f)
- {
- std::vector<char> buf;
-
- size_t total_downloaded_size = 0;
- DWORD dwSize = 0;
- do
- {
- DWORD downloaded_size = 0;
- auto bResults = WinHttpQueryDataAvailable(m_hRequest.get(), &dwSize);
- if (!bResults) return Strings::concat("WinHttpQueryDataAvailable() failed: ", GetLastError());
-
- if (buf.size() < dwSize) buf.resize(static_cast<size_t>(dwSize) * 2);
-
- bResults = WinHttpReadData(m_hRequest.get(), (LPVOID)buf.data(), dwSize, &downloaded_size);
- if (!bResults) return Strings::concat("WinHttpReadData() failed: ", GetLastError());
- f(Span<char>(buf.data(), downloaded_size));
-
- total_downloaded_size += downloaded_size;
- } while (dwSize > 0);
- return 1;
- }
-
- std::unique_ptr<void, WinHttpHandleDeleter> m_hRequest;
- };
-
- struct WinHttpSession
- {
- static ExpectedS<WinHttpSession> make()
- {
- auto h = WinHttpOpen(L"vcpkg/1.0",
- IsWindows8Point1OrGreater() ? WINHTTP_ACCESS_TYPE_AUTOMATIC_PROXY
- : WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
- WINHTTP_NO_PROXY_NAME,
- WINHTTP_NO_PROXY_BYPASS,
- 0);
- if (!h) return Strings::concat("WinHttpOpen() failed: ", GetLastError());
- WinHttpSession ret;
- ret.m_hSession.reset(h);
-
- // If the environment variable HTTPS_PROXY is set
- // use that variable as proxy. This situation might exist when user is in a company network
- // with restricted network/proxy settings
- auto maybe_https_proxy_env = System::get_environment_variable("HTTPS_PROXY");
- if (auto p_https_proxy = maybe_https_proxy_env.get())
- {
- std::wstring env_proxy_settings = Strings::to_utf16(*p_https_proxy);
- WINHTTP_PROXY_INFO proxy;
- proxy.dwAccessType = WINHTTP_ACCESS_TYPE_NAMED_PROXY;
- proxy.lpszProxy = env_proxy_settings.data();
- proxy.lpszProxyBypass = nullptr;
-
- WinHttpSetOption(ret.m_hSession.get(), WINHTTP_OPTION_PROXY, &proxy, sizeof(proxy));
- }
- // Win7 IE Proxy fallback
- else if (IsWindows7OrGreater() && !IsWindows8Point1OrGreater())
- {
- // First check if any proxy has been found automatically
- WINHTTP_PROXY_INFO proxyInfo;
- DWORD proxyInfoSize = sizeof(WINHTTP_PROXY_INFO);
- auto noProxyFound =
- !WinHttpQueryOption(ret.m_hSession.get(), WINHTTP_OPTION_PROXY, &proxyInfo, &proxyInfoSize) ||
- proxyInfo.dwAccessType == WINHTTP_ACCESS_TYPE_NO_PROXY;
-
- // If no proxy was found automatically, use IE's proxy settings, if any
- if (noProxyFound)
- {
- WINHTTP_CURRENT_USER_IE_PROXY_CONFIG ieProxy;
- if (WinHttpGetIEProxyConfigForCurrentUser(&ieProxy) && ieProxy.lpszProxy != nullptr)
- {
- WINHTTP_PROXY_INFO proxy;
- proxy.dwAccessType = WINHTTP_ACCESS_TYPE_NAMED_PROXY;
- proxy.lpszProxy = ieProxy.lpszProxy;
- proxy.lpszProxyBypass = ieProxy.lpszProxyBypass;
- WinHttpSetOption(ret.m_hSession.get(), WINHTTP_OPTION_PROXY, &proxy, sizeof(proxy));
- GlobalFree(ieProxy.lpszProxy);
- GlobalFree(ieProxy.lpszProxyBypass);
- GlobalFree(ieProxy.lpszAutoConfigUrl);
- }
- }
- }
-
- // Use Windows 10 defaults on Windows 7
- DWORD secure_protocols(WINHTTP_FLAG_SECURE_PROTOCOL_TLS1 | WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_1 |
- WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_2);
- WinHttpSetOption(
- ret.m_hSession.get(), WINHTTP_OPTION_SECURE_PROTOCOLS, &secure_protocols, sizeof(secure_protocols));
-
- return ret;
- }
-
- std::unique_ptr<void, WinHttpHandleDeleter> m_hSession;
- };
-
- struct WinHttpConnection
- {
- static ExpectedS<WinHttpConnection> make(HINTERNET hSession, StringView hostname, INTERNET_PORT port)
- {
- // Specify an HTTP server.
- auto h = WinHttpConnect(hSession, Strings::to_utf16(hostname).c_str(), port, 0);
- if (!h) return Strings::concat("WinHttpConnect() failed: ", GetLastError());
- WinHttpConnection ret;
- ret.m_hConnect.reset(h);
- return ret;
- }
-
- std::unique_ptr<void, WinHttpHandleDeleter> m_hConnect;
- };
-#endif
-
- Optional<details::SplitURIView> details::split_uri_view(StringView uri)
- {
- auto sep = std::find(uri.begin(), uri.end(), ':');
- if (sep == uri.end()) return nullopt;
-
- StringView scheme(uri.begin(), sep);
- if (Strings::starts_with({sep + 1, uri.end()}, "//"))
- {
- auto path_start = std::find(sep + 3, uri.end(), '/');
- return details::SplitURIView{scheme, StringView{sep + 1, path_start}, {path_start, uri.end()}};
- }
- // no authority
- return details::SplitURIView{scheme, {}, {sep + 1, uri.end()}};
- }
-
- void verify_downloaded_file_hash(const Files::Filesystem& fs,
- const std::string& url,
- const fs::path& path,
- const std::string& sha512)
- {
- std::string actual_hash = vcpkg::Hash::get_file_hash(VCPKG_LINE_INFO, fs, path, Hash::Algorithm::Sha512);
-
- // <HACK to handle NuGet.org changing nupkg hashes.>
- // This is the NEW hash for 7zip
- if (actual_hash == "a9dfaaafd15d98a2ac83682867ec5766720acf6e99d40d1a00d480692752603bf3f3742623f0ea85647a92374df"
- "405f331afd6021c5cf36af43ee8db198129c0")
- // This is the OLD hash for 7zip
- actual_hash = "8c75314102e68d2b2347d592f8e3eb05812e1ebb525decbac472231633753f1d4ca31c8e6881a36144a8da26b257"
- "1305b3ae3f4e2b85fc4a290aeda63d1a13b8";
- // </HACK>
-
- Checks::check_exit(VCPKG_LINE_INFO,
- sha512 == actual_hash,
- "File does not have the expected hash:\n"
- " url : [ %s ]\n"
- " File path : [ %s ]\n"
- " Expected hash : [ %s ]\n"
- " Actual hash : [ %s ]\n",
- url,
- fs::u8string(path),
- sha512,
- actual_hash);
- }
-
- static void url_heads_inner(View<std::string> urls, std::vector<int>* out)
- {
- static constexpr StringLiteral guid_marker = "8a1db05f-a65d-419b-aa72-037fb4d0672e";
-
- System::Command cmd;
- cmd.string_arg("curl")
- .string_arg("--head")
- .string_arg("--location")
- .string_arg("-w")
- .string_arg(Strings::concat(guid_marker, " %{http_code}\\n"));
- for (auto&& url : urls)
- {
- cmd.string_arg(url);
- }
- auto res = System::cmd_execute_and_stream_lines(cmd, [out](StringView line) {
- if (Strings::starts_with(line, guid_marker))
- {
- out->push_back(std::strtol(line.data() + guid_marker.size(), nullptr, 10));
- }
- });
- Checks::check_exit(VCPKG_LINE_INFO, res == 0, "curl failed to execute with exit code: %d", res);
- }
- std::vector<int> url_heads(View<std::string> urls)
- {
- static constexpr size_t batch_size = 100;
-
- std::vector<int> ret;
-
- size_t i = 0;
- for (; i + batch_size <= urls.size(); i += batch_size)
- {
- url_heads_inner({urls.data() + i, batch_size}, &ret);
- }
- if (i != urls.size()) url_heads_inner({urls.begin() + i, urls.end()}, &ret);
-
- return ret;
- }
-
- static void download_files_inner(Files::Filesystem&,
- View<std::pair<std::string, fs::path>> url_pairs,
- std::vector<int>* out)
- {
- static constexpr StringLiteral guid_marker = "8a1db05f-a65d-419b-aa72-037fb4d0672e";
-
- System::Command cmd;
- cmd.string_arg("curl")
- .string_arg("--location")
- .string_arg("-w")
- .string_arg(Strings::concat(guid_marker, " %{http_code}\\n"));
- for (auto&& url : url_pairs)
- {
- cmd.string_arg(url.first).string_arg("-o").path_arg(url.second);
- }
- auto res = System::cmd_execute_and_stream_lines(cmd, [out](StringView line) {
- if (Strings::starts_with(line, guid_marker))
- {
- out->push_back(std::strtol(line.data() + guid_marker.size(), nullptr, 10));
- }
- });
- Checks::check_exit(VCPKG_LINE_INFO, res == 0, "curl failed to execute with exit code: %d", res);
- }
- std::vector<int> download_files(Files::Filesystem& fs, View<std::pair<std::string, fs::path>> url_pairs)
- {
- static constexpr size_t batch_size = 50;
-
- std::vector<int> ret;
-
- size_t i = 0;
- for (; i + batch_size <= url_pairs.size(); i += batch_size)
- {
- download_files_inner(fs, {url_pairs.data() + i, batch_size}, &ret);
- }
- if (i != url_pairs.size()) download_files_inner(fs, {url_pairs.begin() + i, url_pairs.end()}, &ret);
-
- Checks::check_exit(VCPKG_LINE_INFO, ret.size() == url_pairs.size());
- return ret;
- }
-
- int put_file(const Files::Filesystem&, StringView url, const fs::path& file)
- {
- static constexpr StringLiteral guid_marker = "9a1db05f-a65d-419b-aa72-037fb4d0672e";
-
- System::Command cmd;
- cmd.string_arg("curl").string_arg("-X").string_arg("PUT");
- cmd.string_arg("-w").string_arg(Strings::concat("\\n", guid_marker, "%{http_code}"));
- cmd.string_arg(url);
- cmd.string_arg("-T").path_arg(file);
- cmd.string_arg("-H").string_arg("x-ms-version: 2020-04-08");
- cmd.string_arg("-H").string_arg("x-ms-blob-type: BlockBlob");
- int code = 0;
- auto res = System::cmd_execute_and_stream_lines(cmd, [&code](StringView line) {
- if (Strings::starts_with(line, guid_marker))
- {
- code = std::strtol(line.data() + guid_marker.size(), nullptr, 10);
- }
- });
- if (res != 0)
- {
- System::print2(System::Color::warning, "curl failed to execute with exit code: ", res, '\n');
- }
- return code;
- }
-
- void download_file(Files::Filesystem& fs,
- const std::string& url,
- const fs::path& download_path,
- const std::string& sha512)
- {
- download_file(fs, {&url, 1}, download_path, sha512);
- }
-
-#if defined(_WIN32)
- namespace
- {
- struct WriteFlushFile
- {
- WriteFlushFile(const fs::path& p)
- {
- auto err = _wfopen_s(&f, p.c_str(), L"wb");
- Checks::check_exit(VCPKG_LINE_INFO,
- !err,
- "Failed to open file %s. Error code was %s",
- fs::u8string(p),
- std::to_string(err));
- ASSUME(f != nullptr);
- }
- ~WriteFlushFile()
- {
- if (f)
- {
- fflush(f);
- fclose(f);
- }
- }
- FILE* f = nullptr;
- };
-
- /// <summary>
- /// Download a file using WinHTTP -- only supports HTTP and HTTPS
- /// </summary>
- static bool download_winhttp(Files::Filesystem& fs,
- const fs::path& download_path_part_path,
- details::SplitURIView split_uri,
- const std::string& url,
- std::string& errors)
- {
- // `download_winhttp` does not support user or port syntax in authorities
- auto hostname = split_uri.authority.value_or_exit(VCPKG_LINE_INFO).substr(2);
- INTERNET_PORT port;
- if (split_uri.scheme == "https")
- {
- port = INTERNET_DEFAULT_HTTPS_PORT;
- }
- else if (split_uri.scheme == "http")
- {
- port = INTERNET_DEFAULT_HTTP_PORT;
- }
- else
- {
- Checks::unreachable(VCPKG_LINE_INFO);
- }
-
- // Make sure the directories are present, otherwise fopen_s fails
- const auto dir = download_path_part_path.parent_path();
- fs.create_directories(dir, VCPKG_LINE_INFO);
-
- WriteFlushFile f(download_path_part_path);
-
- Debug::print("Downloading ", url, "\n");
- static auto s = WinHttpSession::make().value_or_exit(VCPKG_LINE_INFO);
- auto conn = WinHttpConnection::make(s.m_hSession.get(), hostname, port);
- if (!conn)
- {
- Strings::append(errors, url, ": ", conn.error(), '\n');
- return false;
- }
- auto req = WinHttpRequest::make(conn.get()->m_hConnect.get(), split_uri.path_query_fragment);
- if (!req)
- {
- Strings::append(errors, url, ": ", req.error(), '\n');
- return false;
- }
- auto forall_data =
- req.get()->forall_data([&](Span<char> span) { fwrite(span.data(), 1, span.size(), f.f); });
- if (!forall_data)
- {
- Strings::append(errors, url, ": ", forall_data.error(), '\n');
- return false;
- }
- return true;
- }
- }
-#endif
-
- std::string download_file(vcpkg::Files::Filesystem& fs,
- View<std::string> urls,
- const fs::path& download_path,
- const std::string& sha512)
- {
- Checks::check_exit(VCPKG_LINE_INFO, urls.size() > 0);
-
- auto download_path_part_path = download_path;
- download_path_part_path += fs::u8path(".part");
- fs.remove(download_path, ignore_errors);
- fs.remove(download_path_part_path, ignore_errors);
-
- std::string errors;
- for (const std::string& url : urls)
- {
-#if defined(_WIN32)
- auto split_uri = details::split_uri_view(url).value_or_exit(VCPKG_LINE_INFO);
- auto authority = split_uri.authority.value_or_exit(VCPKG_LINE_INFO).substr(2);
- if (split_uri.scheme == "https" || split_uri.scheme == "http")
- {
- // This check causes complex URLs (non-default port, embedded basic auth) to be passed down to curl.exe
- if (Strings::find_first_of(authority, ":@") == authority.end())
- {
- if (download_winhttp(fs, download_path_part_path, split_uri, url, errors))
- {
- verify_downloaded_file_hash(fs, url, download_path_part_path, sha512);
- fs.rename(download_path_part_path, download_path, VCPKG_LINE_INFO);
- return url;
- }
- continue;
- }
- }
-#endif
- System::Command cmd;
- cmd.string_arg("curl")
- .string_arg("--fail")
- .string_arg("-L")
- .string_arg(url)
- .string_arg("--create-dirs")
- .string_arg("--output")
- .path_arg(download_path_part_path);
- const auto out = System::cmd_execute_and_capture_output(cmd);
- if (out.exit_code != 0)
- {
- Strings::append(errors, url, ": ", out.output, '\n');
- continue;
- }
-
- verify_downloaded_file_hash(fs, url, download_path_part_path, sha512);
- fs.rename(download_path_part_path, download_path, VCPKG_LINE_INFO);
- return url;
- }
- Checks::exit_with_message(VCPKG_LINE_INFO, Strings::concat("Failed to download from mirror set:\n", errors));
- }
-}
diff --git a/toolsrc/src/vcpkg/base/enums.cpp b/toolsrc/src/vcpkg/base/enums.cpp
deleted file mode 100644
index 8b99ddf7b..000000000
--- a/toolsrc/src/vcpkg/base/enums.cpp
+++ /dev/null
@@ -1,12 +0,0 @@
-#include <vcpkg/base/checks.h>
-#include <vcpkg/base/enums.h>
-
-namespace vcpkg::Enums
-{
- std::string nullvalue_to_string(const CStringView enum_name) { return Strings::format("%s_NULLVALUE", enum_name); }
-
- [[noreturn]] void nullvalue_used(const LineInfo& line_info, const CStringView enum_name)
- {
- Checks::exit_with_message(line_info, "NULLVALUE of enum %s was used", enum_name);
- }
-}
diff --git a/toolsrc/src/vcpkg/base/files.cpp b/toolsrc/src/vcpkg/base/files.cpp
deleted file mode 100644
index 3d66d5629..000000000
--- a/toolsrc/src/vcpkg/base/files.cpp
+++ /dev/null
@@ -1,1595 +0,0 @@
-#include <vcpkg/base/files.h>
-#include <vcpkg/base/system.debug.h>
-#include <vcpkg/base/system.h>
-#include <vcpkg/base/system.print.h>
-#include <vcpkg/base/system.process.h>
-#include <vcpkg/base/util.h>
-
-#if defined(_WIN32)
-#include <vcpkg/base/system_headers.h>
-#else // ^^^ _WIN32 // !_WIN32 vvv
-#include <fcntl.h>
-
-#include <sys/file.h>
-#include <sys/stat.h>
-#endif // _WIN32
-
-#if defined(__linux__)
-#include <sys/sendfile.h>
-#elif defined(__APPLE__)
-#include <copyfile.h>
-#endif // ^^^ defined(__APPLE__)
-
-#include <algorithm>
-#include <list>
-#include <string>
-
-namespace
-{
- struct NativeStringView
- {
- const fs::path::value_type* first;
- const fs::path::value_type* last;
- NativeStringView() = default;
- NativeStringView(const fs::path::value_type* first, const fs::path::value_type* last) : first(first), last(last)
- {
- }
- bool empty() const { return first == last; }
- bool is_dot() const { return (last - first) == 1 && *first == '.'; }
- bool is_dot_dot() const { return (last - first) == 2 && *first == '.' && *(first + 1) == '.'; }
- };
-}
-
-#if defined(_WIN32)
-namespace
-{
- template<size_t N>
- bool wide_starts_with(const std::wstring& haystack, const wchar_t (&needle)[N]) noexcept
- {
- const size_t without_null = N - 1;
- return haystack.size() >= without_null && std::equal(needle, needle + without_null, haystack.begin());
- }
-
- bool starts_with_drive_letter(std::wstring::const_iterator first, const std::wstring::const_iterator last) noexcept
- {
- if (last - first < 2)
- {
- return false;
- }
-
- if (!(first[0] >= L'a' && first[0] <= L'z') && !(first[0] >= L'A' && first[0] <= L'Z'))
- {
- return false;
- }
-
- if (first[1] != L':')
- {
- return false;
- }
-
- return true;
- }
-
- struct FindFirstOp
- {
- HANDLE h_find = INVALID_HANDLE_VALUE;
- WIN32_FIND_DATAW find_data;
-
- unsigned long find_first(const wchar_t* const path) noexcept
- {
- assert(h_find == INVALID_HANDLE_VALUE);
- h_find = FindFirstFileW(path, &find_data);
- if (h_find == INVALID_HANDLE_VALUE)
- {
- return GetLastError();
- }
-
- return ERROR_SUCCESS;
- }
-
- FindFirstOp() = default;
- FindFirstOp(const FindFirstOp&) = delete;
- FindFirstOp& operator=(const FindFirstOp&) = delete;
-
- ~FindFirstOp()
- {
- if (h_find != INVALID_HANDLE_VALUE)
- {
- (void)FindClose(h_find);
- }
- }
- };
-} // unnamed namespace
-#endif // _WIN32
-
-fs::path fs::u8path(vcpkg::StringView s)
-{
- if (s.size() == 0)
- {
- return fs::path();
- }
-
-#if defined(_WIN32)
- return fs::path(vcpkg::Strings::to_utf16(s));
-#else
- return fs::path(s.begin(), s.end());
-#endif
-}
-
-std::string fs::u8string(const fs::path& p)
-{
-#if defined(_WIN32)
- return vcpkg::Strings::to_utf8(p.native());
-#else
- return p.native();
-#endif
-}
-std::string fs::generic_u8string(const fs::path& p)
-{
-#if defined(_WIN32)
- return vcpkg::Strings::to_utf8(p.generic_wstring());
-#else
- return p.generic_string();
-#endif
-}
-
-fs::path fs::lexically_normal(const fs::path& p)
-{
- // copied from microsoft/STL, stl/inc/filesystem:lexically_normal()
- // relicensed under MIT for the vcpkg repository.
-
- // N4810 29.11.7.1 [fs.path.generic]/6:
- // "Normalization of a generic format pathname means:"
-
- // "1. If the path is empty, stop."
- if (p.empty())
- {
- return {};
- }
-
- // "2. Replace each slash character in the root-name with a preferred-separator."
- const auto first = p.native().data();
- const auto last = first + p.native().size();
- const auto root_name_end = first + p.root_name().native().size();
-
- fs::path::string_type normalized(first, root_name_end);
-
-#if defined(_WIN32)
- std::replace(normalized.begin(), normalized.end(), L'/', L'\\');
-#endif
-
- // "3. Replace each directory-separator with a preferred-separator.
- // [ Note: The generic pathname grammar (29.11.7.1) defines directory-separator
- // as one or more slashes and preferred-separators. -end note ]"
- std::list<NativeStringView> lst; // Empty string_view means directory-separator
- // that will be normalized to a preferred-separator.
- // Non-empty string_view means filename.
- for (auto next = root_name_end; next != last;)
- {
- if (is_slash(*next))
- {
- if (lst.empty() || !lst.back().empty())
- {
- // collapse one or more slashes and preferred-separators to one empty wstring_view
- lst.emplace_back();
- }
-
- ++next;
- }
- else
- {
- const auto filename_end = std::find_if(next + 1, last, is_slash);
- lst.emplace_back(next, filename_end);
- next = filename_end;
- }
- }
-
- // "4. Remove each dot filename and any immediately following directory-separator."
- for (auto next = lst.begin(); next != lst.end();)
- {
- if (next->is_dot())
- {
- next = lst.erase(next); // erase dot filename
-
- if (next != lst.end())
- {
- next = lst.erase(next); // erase immediately following directory-separator
- }
- }
- else
- {
- ++next;
- }
- }
-
- // "5. As long as any appear, remove a non-dot-dot filename immediately followed by a
- // directory-separator and a dot-dot filename, along with any immediately following directory-separator."
- for (auto next = lst.begin(); next != lst.end();)
- {
- auto prev = next;
-
- // If we aren't going to erase, keep advancing.
- // If we're going to erase, next now points past the dot-dot filename.
- ++next;
-
- if (prev->is_dot_dot() && prev != lst.begin() && --prev != lst.begin() && !(--prev)->is_dot_dot())
- {
- if (next != lst.end())
- { // dot-dot filename has an immediately following directory-separator
- ++next;
- }
-
- lst.erase(prev, next); // next remains valid
- }
- }
-
- // "6. If there is a root-directory, remove all dot-dot filenames
- // and any directory-separators immediately following them.
- // [ Note: These dot-dot filenames attempt to refer to nonexistent parent directories. -end note ]"
- if (!lst.empty() && lst.front().empty())
- { // we have a root-directory
- for (auto next = lst.begin(); next != lst.end();)
- {
- if (next->is_dot_dot())
- {
- next = lst.erase(next); // erase dot-dot filename
-
- if (next != lst.end())
- {
- next = lst.erase(next); // erase immediately following directory-separator
- }
- }
- else
- {
- ++next;
- }
- }
- }
-
- // "7. If the last filename is dot-dot, remove any trailing directory-separator."
- if (lst.size() >= 2 && lst.back().empty() && std::prev(lst.end(), 2)->is_dot_dot())
- {
- lst.pop_back();
- }
-
- // Build up normalized by flattening lst.
- for (const auto& elem : lst)
- {
- if (elem.empty())
- {
- normalized += fs::path::preferred_separator;
- }
- else
- {
- normalized.append(elem.first, elem.last);
- }
- }
-
- // "8. If the path is empty, add a dot."
- if (normalized.empty())
- {
- normalized.push_back('.');
- }
-
- // "The result of normalization is a path in normal form, which is said to be normalized."
- return std::move(normalized);
-}
-
-namespace vcpkg::Files
-{
- static const std::regex FILESYSTEM_INVALID_CHARACTERS_REGEX = std::regex(R"([\/:*?"<>|])");
-
- namespace
- {
- fs::file_status status_implementation(bool follow_symlinks, const fs::path& p, std::error_code& ec) noexcept
- {
- using fs::file_type;
- using fs::perms;
-#if defined(_WIN32)
- WIN32_FILE_ATTRIBUTE_DATA file_attributes;
- auto ft = file_type::unknown;
- auto permissions = perms::unknown;
- ec.clear();
- if (!GetFileAttributesExW(p.c_str(), GetFileExInfoStandard, &file_attributes))
- {
- const auto err = GetLastError();
- if (err == ERROR_FILE_NOT_FOUND || err == ERROR_PATH_NOT_FOUND)
- {
- ft = file_type::not_found;
- }
- else
- {
- ec.assign(err, std::system_category());
- }
- }
- else if (!follow_symlinks && file_attributes.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
- {
- // this also gives junctions file_type::directory_symlink
- if (file_attributes.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
- {
- ft = file_type::directory_symlink;
- }
- else
- {
- ft = file_type::symlink;
- }
- }
- else if (file_attributes.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
- {
- ft = file_type::directory;
- }
- else
- {
- // otherwise, the file is a regular file
- ft = file_type::regular;
- }
-
- if (file_attributes.dwFileAttributes & FILE_ATTRIBUTE_READONLY)
- {
- constexpr auto all_write = perms::group_write | perms::owner_write | perms::others_write;
- permissions = perms::all & ~all_write;
- }
- else if (ft != file_type::none)
- {
- permissions = perms::all;
- }
-
- return fs::file_status(ft, permissions);
-
-#else // ^^^ defined(_WIN32) // !defined(_WIN32) vvv
- auto result = follow_symlinks ? fs::stdfs::status(p, ec) : fs::stdfs::symlink_status(p, ec);
- // libstdc++ doesn't correctly not-set ec on nonexistent paths
- if (ec.value() == ENOENT || ec.value() == ENOTDIR)
- {
- ec.clear();
- return fs::file_status(file_type::not_found, perms::unknown);
- }
- return fs::file_status(result.type(), result.permissions());
-#endif // ^^^ !defined(_WIN32)
- }
-
- fs::file_status status(const fs::path& p, std::error_code& ec) noexcept
- {
- return status_implementation(true, p, ec);
- }
- fs::file_status symlink_status(const fs::path& p, std::error_code& ec) noexcept
- {
- return status_implementation(false, p, ec);
- }
-
-#if defined(_WIN32) && !VCPKG_USE_STD_FILESYSTEM
- fs::path read_symlink_implementation(const fs::path& oldpath, std::error_code& ec)
- {
- ec.clear();
- auto handle = CreateFileW(oldpath.c_str(),
- 0, // open just the metadata
- FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
- nullptr /* no security attributes */,
- OPEN_EXISTING,
- FILE_ATTRIBUTE_NORMAL,
- nullptr /* no template file */);
- if (handle == INVALID_HANDLE_VALUE)
- {
- ec.assign(GetLastError(), std::system_category());
- return oldpath;
- }
- fs::path target;
- const DWORD maxsize = 32768;
- const std::unique_ptr<wchar_t[]> buffer(new wchar_t[maxsize]);
- const auto rc = GetFinalPathNameByHandleW(handle, buffer.get(), maxsize, 0);
- if (rc > 0 && rc < maxsize)
- {
- target = buffer.get();
- }
- else
- {
- ec.assign(GetLastError(), std::system_category());
- }
- CloseHandle(handle);
- return target;
- }
-#endif // ^^^ defined(_WIN32) && !VCPKG_USE_STD_FILESYSTEM
-
- void copy_symlink_implementation(const fs::path& oldpath, const fs::path& newpath, std::error_code& ec)
- {
-#if defined(_WIN32) && !VCPKG_USE_STD_FILESYSTEM
- const auto target = read_symlink_implementation(oldpath, ec);
- if (ec) return;
-
- const DWORD flags =
-#if defined(SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE)
- SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE;
-#else
- 0;
-#endif
- if (!CreateSymbolicLinkW(newpath.c_str(), target.c_str(), flags))
- {
- const auto err = GetLastError();
- ec.assign(err, std::system_category());
- return;
- }
- ec.clear();
- return;
-#else // ^^^ defined(_WIN32) && !VCPKG_USE_STD_FILESYSTEM // !defined(_WIN32) || VCPKG_USE_STD_FILESYSTEM vvv
- return fs::stdfs::copy_symlink(oldpath, newpath, ec);
-#endif // ^^^ !defined(_WIN32) || VCPKG_USE_STD_FILESYSTEM
- }
-
- // does _not_ follow symlinks
- void set_writeable(const fs::path& path, std::error_code& ec) noexcept
- {
-#if defined(_WIN32)
- auto const file_name = path.c_str();
- WIN32_FILE_ATTRIBUTE_DATA attributes;
- if (!GetFileAttributesExW(file_name, GetFileExInfoStandard, &attributes))
- {
- ec.assign(GetLastError(), std::system_category());
- return;
- }
-
- auto dw_attributes = attributes.dwFileAttributes;
- dw_attributes &= ~FILE_ATTRIBUTE_READONLY;
- if (!SetFileAttributesW(file_name, dw_attributes))
- {
- ec.assign(GetLastError(), std::system_category());
- }
-#else // ^^^ defined(_WIN32) // !defined(_WIN32) vvv
- struct stat s;
- if (lstat(path.c_str(), &s))
- {
- ec.assign(errno, std::system_category());
- return;
- }
-
- auto mode = s.st_mode;
- // if the file is a symlink, perms don't matter
- if (!(mode & S_IFLNK))
- {
- mode |= S_IWUSR;
- if (chmod(path.c_str(), mode))
- {
- ec.assign(errno, std::system_category());
- }
- }
-#endif // ^^^ !defined(_WIN32)
- }
- }
-
- std::string Filesystem::read_contents(const fs::path& path, LineInfo linfo) const
- {
- auto maybe_contents = this->read_contents(path);
- if (auto p = maybe_contents.get())
- {
- return std::move(*p);
- }
-
- Checks::exit_with_message(
- linfo, "error reading file: %s: %s", fs::u8string(path), maybe_contents.error().message());
- }
- void Filesystem::write_contents(const fs::path& path, const std::string& data, LineInfo linfo)
- {
- std::error_code ec;
- this->write_contents(path, data, ec);
- if (ec)
- {
- Checks::exit_with_message(linfo, "error writing file: %s: %s", fs::u8string(path), ec.message());
- }
- }
- void Filesystem::write_contents_and_dirs(const fs::path& path, const std::string& data, LineInfo linfo)
- {
- std::error_code ec;
- this->write_contents_and_dirs(path, data, ec);
- if (ec)
- {
- Checks::exit_with_message(
- linfo, "error writing file and creating directories: %s: %s", fs::u8string(path), ec.message());
- }
- }
- void Filesystem::rename(const fs::path& oldpath, const fs::path& newpath, LineInfo linfo)
- {
- std::error_code ec;
- this->rename(oldpath, newpath, ec);
- if (ec)
- {
- Checks::exit_with_message(
- linfo, "error renaming file: %s: %s: %s", fs::u8string(oldpath), fs::u8string(newpath), ec.message());
- }
- }
-
- bool Filesystem::remove(const fs::path& path, LineInfo linfo)
- {
- std::error_code ec;
- auto r = this->remove(path, ec);
- if (ec)
- {
- Checks::exit_with_message(linfo, "error removing file: %s: %s", fs::u8string(path), ec.message());
- }
-
- return r;
- }
-
- bool Filesystem::remove(const fs::path& path, ignore_errors_t)
- {
- std::error_code ec;
- return this->remove(path, ec);
- }
-
- bool Filesystem::exists(const fs::path& path, std::error_code& ec) const
- {
- return fs::exists(this->symlink_status(path, ec));
- }
-
- bool Filesystem::exists(LineInfo li, const fs::path& path) const
- {
- std::error_code ec;
- auto result = this->exists(path, ec);
- if (ec)
- Checks::exit_with_message(li, "error checking existence of file %s: %s", fs::u8string(path), ec.message());
- return result;
- }
-
- bool Filesystem::exists(const fs::path& path, ignore_errors_t) const
- {
- std::error_code ec;
- return this->exists(path, ec);
- }
-
- bool Filesystem::create_directory(const fs::path& path, ignore_errors_t)
- {
- std::error_code ec;
- return this->create_directory(path, ec);
- }
-
- bool Filesystem::create_directory(const fs::path& path, LineInfo li)
- {
- std::error_code ec;
- bool result = this->create_directory(path, ec);
- if (ec)
- {
- vcpkg::Checks::exit_with_message(li, "error creating directory %s", fs::u8string(path), ec.message());
- }
-
- return result;
- }
-
- bool Filesystem::create_directories(const fs::path& path, ignore_errors_t)
- {
- std::error_code ec;
- return this->create_directories(path, ec);
- }
-
- bool Filesystem::create_directories(const fs::path& path, LineInfo li)
- {
- std::error_code ec;
- bool result = this->create_directories(path, ec);
- if (ec)
- {
- vcpkg::Checks::exit_with_message(li, "error creating directories %s", fs::u8string(path), ec.message());
- }
-
- return result;
- }
-
- void Filesystem::copy_file(const fs::path& oldpath, const fs::path& newpath, fs::copy_options opts, LineInfo li)
- {
- std::error_code ec;
- this->copy_file(oldpath, newpath, opts, ec);
- if (ec)
- {
- vcpkg::Checks::exit_with_message(
- li, "error copying file from %s to %s: %s", fs::u8string(oldpath), fs::u8string(newpath), ec.message());
- }
- }
-
- fs::file_status Filesystem::status(vcpkg::LineInfo li, const fs::path& p) const noexcept
- {
- std::error_code ec;
- auto result = this->status(p, ec);
- if (ec)
- {
- vcpkg::Checks::exit_with_message(li, "error getting status of path %s: %s", p.string(), ec.message());
- }
-
- return result;
- }
-
- fs::file_status Filesystem::status(const fs::path& p, ignore_errors_t) const noexcept
- {
- std::error_code ec;
- return this->status(p, ec);
- }
-
- fs::file_status Filesystem::symlink_status(vcpkg::LineInfo li, const fs::path& p) const noexcept
- {
- std::error_code ec;
- auto result = this->symlink_status(p, ec);
- if (ec)
- {
- vcpkg::Checks::exit_with_message(li, "error getting status of path %s: %s", p.string(), ec.message());
- }
-
- return result;
- }
-
- fs::file_status Filesystem::symlink_status(const fs::path& p, ignore_errors_t) const noexcept
- {
- std::error_code ec;
- return this->symlink_status(p, ec);
- }
-
- void Filesystem::write_lines(const fs::path& path, const std::vector<std::string>& lines, LineInfo linfo)
- {
- std::error_code ec;
- this->write_lines(path, lines, ec);
- if (ec)
- {
- Checks::exit_with_message(linfo, "error writing lines: %s: %s", fs::u8string(path), ec.message());
- }
- }
-
- void Filesystem::remove_all(const fs::path& path, LineInfo li)
- {
- std::error_code ec;
- fs::path failure_point;
-
- this->remove_all(path, ec, failure_point);
-
- if (ec)
- {
- Checks::exit_with_message(li,
- "Failure to remove_all(%s) due to file %s: %s",
- path.string(),
- failure_point.string(),
- ec.message());
- }
- }
-
- void Filesystem::remove_all(const fs::path& path, ignore_errors_t)
- {
- std::error_code ec;
- fs::path failure_point;
-
- this->remove_all(path, ec, failure_point);
- }
-
- void Filesystem::remove_all_inside(const fs::path& path, LineInfo li)
- {
- std::error_code ec;
- fs::path failure_point;
-
- this->remove_all_inside(path, ec, failure_point);
-
- if (ec)
- {
- Checks::exit_with_message(li,
- "Failure to remove_all_inside(%s) due to file %s: %s",
- path.string(),
- failure_point.string(),
- ec.message());
- }
- }
-
- void Filesystem::remove_all_inside(const fs::path& path, ignore_errors_t)
- {
- std::error_code ec;
- fs::path failure_point;
-
- this->remove_all_inside(path, ec, failure_point);
- }
-
- fs::path Filesystem::absolute(LineInfo li, const fs::path& path) const
- {
- std::error_code ec;
- const auto result = this->absolute(path, ec);
- if (ec)
- {
- Checks::exit_with_message(li, "Error getting absolute path of %s: %s", path.string(), ec.message());
- }
-
- return result;
- }
-
- fs::path Filesystem::canonical(LineInfo li, const fs::path& path) const
- {
- std::error_code ec;
- const auto result = this->canonical(path, ec);
- if (ec)
- {
- Checks::exit_with_message(li, "Error getting canonicalization of %s: %s", path.string(), ec.message());
- }
-
- return result;
- }
- fs::path Filesystem::canonical(const fs::path& path, ignore_errors_t) const
- {
- std::error_code ec;
- return this->canonical(path, ec);
- }
- fs::path Filesystem::current_path(LineInfo li) const
- {
- std::error_code ec;
- const auto result = this->current_path(ec);
- if (ec)
- {
- Checks::exit_with_message(li, "Error getting current path: %s", ec.message());
- }
-
- return result;
- }
- void Filesystem::current_path(const fs::path& path, LineInfo li)
- {
- std::error_code ec;
- this->current_path(path, ec);
- if (ec)
- {
- Checks::exit_with_message(li, "Error setting current path: %s", ec.message());
- }
- }
-
- struct RealFilesystem final : Filesystem
- {
- virtual Expected<std::string> read_contents(const fs::path& file_path) const override
- {
- std::fstream file_stream(file_path, std::ios_base::in | std::ios_base::binary);
- if (file_stream.fail())
- {
- return std::make_error_code(std::errc::no_such_file_or_directory);
- }
-
- file_stream.seekg(0, file_stream.end);
- auto length = file_stream.tellg();
- file_stream.seekg(0, file_stream.beg);
-
- if (length == std::streampos(-1))
- {
- return std::make_error_code(std::errc::io_error);
- }
-
- std::string output;
- output.resize(static_cast<size_t>(length));
- file_stream.read(&output[0], length);
-
- return output;
- }
- virtual Expected<std::vector<std::string>> read_lines(const fs::path& file_path) const override
- {
- std::fstream file_stream(file_path, std::ios_base::in | std::ios_base::binary);
- if (file_stream.fail())
- {
- Debug::print("Missing path: ", fs::u8string(file_path), '\n');
- return std::make_error_code(std::errc::no_such_file_or_directory);
- }
-
- std::vector<std::string> output;
- std::string line;
- while (std::getline(file_stream, line))
- {
- // Remove the trailing \r to accomodate Windows line endings.
- if ((!line.empty()) && (line.back() == '\r')) line.pop_back();
-
- output.push_back(line);
- }
-
- return output;
- }
- virtual fs::path find_file_recursively_up(const fs::path& starting_dir, const fs::path& filename) const override
- {
- fs::path current_dir = starting_dir;
- if (exists(VCPKG_LINE_INFO, current_dir / filename))
- {
- return current_dir;
- }
-
- int counter = 10000;
- for (;;)
- {
- // This is a workaround for VS2015's experimental filesystem implementation
- if (!current_dir.has_relative_path())
- {
- current_dir.clear();
- return current_dir;
- }
-
- auto parent = current_dir.parent_path();
- if (parent == current_dir)
- {
- current_dir.clear();
- return current_dir;
- }
-
- current_dir = std::move(parent);
-
- const fs::path candidate = current_dir / filename;
- if (exists(VCPKG_LINE_INFO, candidate))
- {
- return current_dir;
- }
-
- --counter;
- Checks::check_exit(VCPKG_LINE_INFO,
- counter > 0,
- "infinite loop encountered while trying to find_file_recursively_up()");
- }
- }
-
- virtual std::vector<fs::path> get_files_recursive(const fs::path& dir) const override
- {
- std::vector<fs::path> ret;
-
- std::error_code ec;
- fs::stdfs::recursive_directory_iterator b(dir, ec), e{};
- if (ec) return ret;
- for (; b != e; ++b)
- {
- ret.push_back(b->path());
- }
-
- return ret;
- }
-
- virtual std::vector<fs::path> get_files_non_recursive(const fs::path& dir) const override
- {
- std::vector<fs::path> ret;
-
- std::error_code ec;
- fs::stdfs::directory_iterator b(dir, ec), e{};
- if (ec) return ret;
- for (; b != e; ++b)
- {
- ret.push_back(b->path());
- }
-
- return ret;
- }
-
- virtual void write_lines(const fs::path& file_path,
- const std::vector<std::string>& lines,
- std::error_code& ec) override
- {
- std::fstream output(file_path, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
- auto first = lines.begin();
- const auto last = lines.end();
- for (;;)
- {
- if (!output)
- {
- ec.assign(static_cast<int>(std::errc::io_error), std::generic_category());
- return;
- }
-
- if (first == last)
- {
- return;
- }
-
- output << *first << "\n";
- ++first;
- }
- }
- virtual void rename(const fs::path& oldpath, const fs::path& newpath, std::error_code& ec) override
- {
- fs::stdfs::rename(oldpath, newpath, ec);
- }
- virtual void rename_or_copy(const fs::path& oldpath,
- const fs::path& newpath,
- StringLiteral temp_suffix,
- std::error_code& ec) override
- {
- this->rename(oldpath, newpath, ec);
- (void)temp_suffix;
-#if !defined(_WIN32)
- if (ec)
- {
- auto dst = newpath;
- dst.replace_filename(dst.filename() + temp_suffix.c_str());
-
- int i_fd = open(oldpath.c_str(), O_RDONLY);
- if (i_fd == -1) return;
-
- int o_fd = creat(dst.c_str(), 0664);
- if (o_fd == -1)
- {
- close(i_fd);
- return;
- }
-
-#if defined(__linux__)
- off_t bytes = 0;
- struct stat info = {0};
- fstat(i_fd, &info);
- auto written_bytes = sendfile(o_fd, i_fd, &bytes, info.st_size);
-#elif defined(__APPLE__)
- auto written_bytes = fcopyfile(i_fd, o_fd, 0, COPYFILE_ALL);
-#else // ^^^ defined(__APPLE__) // !(defined(__APPLE__) || defined(__linux__)) vvv
- ssize_t written_bytes = 0;
- {
- constexpr std::size_t buffer_length = 4096;
- auto buffer = std::make_unique<unsigned char[]>(buffer_length);
- while (auto read_bytes = read(i_fd, buffer.get(), buffer_length))
- {
- if (read_bytes == -1)
- {
- written_bytes = -1;
- break;
- }
- auto remaining = read_bytes;
- while (remaining > 0)
- {
- auto read_result = write(o_fd, buffer.get(), remaining);
- if (read_result == -1)
- {
- written_bytes = -1;
- // break two loops
- goto copy_failure;
- }
- remaining -= read_result;
- }
- }
-
- copy_failure:;
- }
-#endif // ^^^ !(defined(__APPLE__) || defined(__linux__))
- if (written_bytes == -1)
- {
- ec.assign(errno, std::generic_category());
- close(i_fd);
- close(o_fd);
-
- return;
- }
-
- close(i_fd);
- close(o_fd);
-
- this->rename(dst, newpath, ec);
- if (ec) return;
- this->remove(oldpath, ec);
- }
-#endif // ^^^ !defined(_WIN32)
- }
- virtual bool remove(const fs::path& path, std::error_code& ec) override { return fs::stdfs::remove(path, ec); }
- virtual void remove_all(const fs::path& path, std::error_code& ec, fs::path& failure_point) override
- {
- /*
- does not use the std::experimental::filesystem call since this is
- quite a bit faster, and also supports symlinks
- */
-
- struct remove
- {
- struct ErrorInfo : Util::ResourceBase
- {
- std::error_code ec;
- fs::path failure_point;
- };
- /*
- if `current_path` is a directory, first `remove`s all
- elements of the directory, then removes current_path.
-
- else if `current_path` exists, removes current_path
-
- else does nothing
- */
- static void do_remove(const fs::path& current_path, ErrorInfo& err)
- {
- std::error_code ec;
- const auto path_status = Files::symlink_status(current_path, ec);
- if (check_ec(ec, current_path, err)) return;
- if (!fs::exists(path_status)) return;
-
- const auto path_type = path_status.type();
-
- if ((path_status.permissions() & fs::perms::owner_write) != fs::perms::owner_write)
- {
- set_writeable(current_path, ec);
- if (check_ec(ec, current_path, err)) return;
- }
-
- if (path_type == fs::file_type::directory)
- {
- for (const auto& entry : fs::stdfs::directory_iterator(current_path))
- {
- do_remove(entry, err);
- if (err.ec) return;
- }
-#if defined(_WIN32)
- if (!RemoveDirectoryW(current_path.c_str()))
- {
- ec.assign(GetLastError(), std::system_category());
- }
-#else // ^^^ defined(_WIN32) // !defined(_WIN32) vvv
- if (rmdir(current_path.c_str()))
- {
- ec.assign(errno, std::system_category());
- }
-#endif // ^^^ !defined(_WIN32)
- }
-#if VCPKG_USE_STD_FILESYSTEM
- else
- {
- fs::stdfs::remove(current_path, ec);
- if (check_ec(ec, current_path, err)) return;
- }
-#else // ^^^ VCPKG_USE_STD_FILESYSTEM // !VCPKG_USE_STD_FILESYSTEM vvv
-#if defined(_WIN32)
- else if (path_type == fs::file_type::directory_symlink)
- {
- if (!RemoveDirectoryW(current_path.c_str()))
- {
- ec.assign(GetLastError(), std::system_category());
- }
- }
- else
- {
- if (!DeleteFileW(current_path.c_str()))
- {
- ec.assign(GetLastError(), std::system_category());
- }
- }
-#else // ^^^ defined(_WIN32) // !defined(_WIN32) vvv
- else
- {
- if (unlink(current_path.c_str()))
- {
- ec.assign(errno, std::system_category());
- }
- }
-#endif // ^^^ !defined(_WIN32)
-#endif // ^^^ !VCPKG_USE_STD_FILESYSTEM
-
- check_ec(ec, current_path, err);
- }
-
- static bool check_ec(const std::error_code& ec, const fs::path& current_path, ErrorInfo& err)
- {
- if (ec)
- {
- err.ec = ec;
- err.failure_point = current_path;
-
- return true;
- }
- else
- {
- return false;
- }
- }
- };
-
- /*
- we need to do backoff on the removal of the top level directory,
- so we can only delete the directory after all the
- lower levels have been deleted.
- */
-
- remove::ErrorInfo err;
- for (int backoff = 0; backoff < 5; ++backoff)
- {
- if (backoff)
- {
- using namespace std::chrono_literals;
- auto backoff_time = 100ms * backoff;
- std::this_thread::sleep_for(backoff_time);
- }
-
- remove::do_remove(path, err);
- if (!err.ec)
- {
- break;
- }
- }
-
- ec = std::move(err.ec);
- failure_point = std::move(err.failure_point);
- }
-
- virtual void remove_all_inside(const fs::path& path, std::error_code& ec, fs::path& failure_point) override
- {
- fs::directory_iterator last{};
- fs::directory_iterator first(path, ec);
- if (ec)
- {
- failure_point = path;
- return;
- }
-
- for (;;)
- {
- if (first == last)
- {
- return;
- }
-
- auto stats = first->status(ec);
- if (ec)
- {
- break;
- }
-
- auto& thisPath = first->path();
- if (stats.type() == fs::stdfs::file_type::directory)
- {
- this->remove_all(thisPath, ec, failure_point);
- if (ec)
- {
- return; // keep inner failure_point
- }
- }
- else
- {
- this->remove(thisPath, ec);
- if (ec)
- {
- break;
- }
- }
-
- first.increment(ec);
- if (ec)
- {
- break;
- }
- }
-
- failure_point = first->path();
- }
-
- virtual bool is_directory(const fs::path& path) const override { return fs::stdfs::is_directory(path); }
- virtual bool is_regular_file(const fs::path& path) const override { return fs::stdfs::is_regular_file(path); }
- virtual bool is_empty(const fs::path& path) const override { return fs::stdfs::is_empty(path); }
- virtual bool create_directory(const fs::path& path, std::error_code& ec) override
- {
- return fs::stdfs::create_directory(path, ec);
- }
- virtual bool create_directories(const fs::path& path, std::error_code& ec) override
- {
- return fs::stdfs::create_directories(path, ec);
- }
- virtual void copy(const fs::path& oldpath, const fs::path& newpath, fs::copy_options opts) override
- {
- fs::stdfs::copy(oldpath, newpath, opts);
- }
- virtual bool copy_file(const fs::path& oldpath,
- const fs::path& newpath,
- fs::copy_options opts,
- std::error_code& ec) override
- {
- return fs::stdfs::copy_file(oldpath, newpath, opts, ec);
- }
- virtual void copy_symlink(const fs::path& oldpath, const fs::path& newpath, std::error_code& ec) override
- {
- return Files::copy_symlink_implementation(oldpath, newpath, ec);
- }
-
- virtual fs::file_status status(const fs::path& path, std::error_code& ec) const override
- {
- return Files::status(path, ec);
- }
- virtual fs::file_status symlink_status(const fs::path& path, std::error_code& ec) const override
- {
- return Files::symlink_status(path, ec);
- }
- virtual void write_contents(const fs::path& file_path, const std::string& data, std::error_code& ec) override
- {
- ec.clear();
-
- FILE* f = nullptr;
-#if defined(_WIN32)
- auto err = _wfopen_s(&f, file_path.native().c_str(), L"wb");
-#else // ^^^ defined(_WIN32) // !defined(_WIN32) vvv
- f = fopen(file_path.native().c_str(), "wb");
- int err = f != nullptr ? 0 : 1;
-#endif // ^^^ !defined(_WIN32)
- if (err != 0)
- {
- ec.assign(err, std::system_category());
- return;
- }
-
- if (f != nullptr)
- {
- auto count = fwrite(data.data(), sizeof(data[0]), data.size(), f);
- fclose(f);
-
- if (count != data.size())
- {
- ec = std::make_error_code(std::errc::no_space_on_device);
- }
- }
- }
-
- virtual void write_contents_and_dirs(const fs::path& file_path,
- const std::string& data,
- std::error_code& ec) override
- {
- write_contents(file_path, data, ec);
- if (ec)
- {
- create_directories(file_path.parent_path(), ec);
- if (ec)
- {
- return;
- }
- write_contents(file_path, data, ec);
- }
- }
-
- virtual fs::path absolute(const fs::path& path, std::error_code& ec) const override
- {
-#if VCPKG_USE_STD_FILESYSTEM
- return fs::stdfs::absolute(path, ec);
-#else // ^^^ VCPKG_USE_STD_FILESYSTEM / !VCPKG_USE_STD_FILESYSTEM vvv
-#if defined(_WIN32)
- // absolute was called system_complete in experimental filesystem
- return fs::stdfs::system_complete(path, ec);
-#else // ^^^ defined(_WIN32) / !defined(_WIN32) vvv
- if (path.is_absolute())
- {
- return path;
- }
- else
- {
- auto current_path = this->current_path(ec);
- if (ec) return fs::path();
- return std::move(current_path) / path;
- }
-#endif // ^^^ !defined(_WIN32)
-#endif // ^^^ !VCPKG_USE_STD_FILESYSTEM
- }
-
- virtual fs::path canonical(const fs::path& path, std::error_code& ec) const override
- {
- return fs::stdfs::canonical(path, ec);
- }
-
- virtual fs::path current_path(std::error_code& ec) const override { return fs::stdfs::current_path(ec); }
- virtual void current_path(const fs::path& path, std::error_code& ec) override
- {
- fs::stdfs::current_path(path, ec);
- }
-
- struct TakeExclusiveFileLockHelper
- {
- fs::SystemHandle& res;
- const fs::path::string_type& native;
- TakeExclusiveFileLockHelper(fs::SystemHandle& res, const fs::path::string_type& native)
- : res(res), native(native)
- {
- }
-
-#if defined(_WIN32)
- void assign_busy_error(std::error_code& ec) { ec.assign(ERROR_BUSY, std::system_category()); }
-
- bool operator()(std::error_code& ec)
- {
- ec.clear();
- auto handle = CreateFileW(native.c_str(),
- GENERIC_READ,
- 0 /* no sharing */,
- nullptr /* no security attributes */,
- OPEN_ALWAYS,
- FILE_ATTRIBUTE_NORMAL,
- nullptr /* no template file */);
- if (handle == INVALID_HANDLE_VALUE)
- {
- const auto err = GetLastError();
- if (err != ERROR_SHARING_VIOLATION)
- {
- ec.assign(err, std::system_category());
- }
- return false;
- }
-
- res.system_handle = reinterpret_cast<intptr_t>(handle);
- return true;
- }
-#else // ^^^ _WIN32 / !_WIN32 vvv
- int fd = -1;
-
- void assign_busy_error(std::error_code& ec) { ec.assign(EBUSY, std::generic_category()); }
-
- bool operator()(std::error_code& ec)
- {
- ec.clear();
- if (fd == -1)
- {
- fd = ::open(native.c_str(), O_RDWR | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
- if (fd < 0)
- {
- ec.assign(errno, std::generic_category());
- return false;
- }
- }
-
- if (::flock(fd, LOCK_EX | LOCK_NB) != 0)
- {
- if (errno != EWOULDBLOCK)
- {
- ec.assign(errno, std::generic_category());
- }
- return false;
- }
-
- res.system_handle = fd;
- fd = -1;
- return true;
- };
-
- ~TakeExclusiveFileLockHelper()
- {
- if (fd != -1)
- {
- ::close(fd);
- }
- }
-#endif
- };
-
- virtual fs::SystemHandle take_exclusive_file_lock(const fs::path& path, std::error_code& ec) override
- {
- fs::SystemHandle res;
- TakeExclusiveFileLockHelper helper(res, path.native());
-
- if (helper(ec) || ec)
- {
- return res;
- }
-
- System::printf("Waiting to take filesystem lock on %s...\n", fs::u8string(path));
- const auto wait = std::chrono::milliseconds(1000);
- for (;;)
- {
- std::this_thread::sleep_for(wait);
- if (helper(ec) || ec)
- {
- return res;
- }
- }
- }
-
- virtual fs::SystemHandle try_take_exclusive_file_lock(const fs::path& path, std::error_code& ec) override
- {
- fs::SystemHandle res;
- TakeExclusiveFileLockHelper helper(res, path.native());
-
- if (helper(ec) || ec)
- {
- return res;
- }
-
- Debug::print("Waiting to take filesystem lock on ", fs::u8string(path), "...\n");
- auto wait = std::chrono::milliseconds(100);
- // waits, at most, a second and a half.
- while (wait < std::chrono::milliseconds(1000))
- {
- std::this_thread::sleep_for(wait);
- if (helper(ec) || ec)
- {
- return res;
- }
- wait *= 2;
- }
-
- helper.assign_busy_error(ec);
- return res;
- }
-
- virtual void unlock_file_lock(fs::SystemHandle handle, std::error_code& ec) override
- {
-#if defined(_WIN32)
- if (CloseHandle(reinterpret_cast<HANDLE>(handle.system_handle)) == 0)
- {
- ec.assign(GetLastError(), std::system_category());
- }
-#else
- if (flock(handle.system_handle, LOCK_UN) != 0 || close(handle.system_handle) != 0)
- {
- ec.assign(errno, std::generic_category());
- }
-#endif
- }
-
- virtual std::vector<fs::path> find_from_PATH(const std::string& name) const override
- {
-#if defined(_WIN32)
- static constexpr wchar_t const* EXTS[] = {L".cmd", L".exe", L".bat"};
-#else // ^^^ defined(_WIN32) // !defined(_WIN32) vvv
- static constexpr char const* EXTS[] = {""};
-#endif // ^^^!defined(_WIN32)
- auto paths = Strings::split_paths(System::get_environment_variable("PATH").value_or_exit(VCPKG_LINE_INFO));
-
- std::vector<fs::path> ret;
- for (auto&& path : paths)
- {
- auto base = fs::u8path(path);
- base /= fs::u8path(name);
-
- for (auto&& ext : EXTS)
- {
- auto p = fs::path(base.native() + ext);
- if (Util::find(ret, p) == ret.end() && this->exists(p, ignore_errors))
- {
- ret.push_back(p);
- Debug::print("Found path: ", fs::u8string(p), '\n');
- }
- }
- }
-
- return ret;
- }
- };
-
- Filesystem& get_real_filesystem()
- {
- static RealFilesystem real_fs;
- return real_fs;
- }
-
- bool has_invalid_chars_for_filesystem(const std::string& s)
- {
- return std::regex_search(s, FILESYSTEM_INVALID_CHARACTERS_REGEX);
- }
-
- void print_paths(const std::vector<fs::path>& paths)
- {
- std::string message = "\n";
- for (const fs::path& p : paths)
- {
- Strings::append(message, " ", p.generic_string(), '\n');
- }
- message.push_back('\n');
- System::print2(message);
- }
-
- fs::path combine(const fs::path& lhs, const fs::path& rhs)
- {
-#if VCPKG_USE_STD_FILESYSTEM
- return lhs / rhs;
-#else // ^^^ std::filesystem // std::experimental::filesystem vvv
-#if !defined(_WIN32)
- if (rhs.is_absolute())
- {
- return rhs;
- }
- else
- {
- return lhs / rhs;
- }
-#else // ^^^ unix // windows vvv
- auto rhs_root_directory = rhs.root_directory();
- auto rhs_root_name = rhs.root_name();
-
- if (rhs_root_directory.empty() && rhs_root_name.empty())
- {
- return lhs / rhs;
- }
- else if (rhs_root_directory.empty())
- {
- // !rhs_root_name.empty()
- if (rhs_root_name == lhs.root_name())
- {
- return lhs / rhs.relative_path();
- }
- else
- {
- return rhs;
- }
- }
- else if (rhs_root_name.empty())
- {
- // !rhs_root_directory.empty()
- return lhs.root_name() / rhs;
- }
- else
- {
- // rhs.absolute()
- return rhs;
- }
-#endif // ^^^ windows
-#endif // ^^^ std::experimental::filesystem
- }
-
-#ifdef _WIN32
- fs::path win32_fix_path_case(const fs::path& source)
- {
- using fs::is_slash;
- const std::wstring& native = source.native();
- if (native.empty())
- {
- return fs::path{};
- }
-
- if (wide_starts_with(native, L"\\\\?\\") || wide_starts_with(native, L"\\??\\") ||
- wide_starts_with(native, L"\\\\.\\"))
- {
- // no support to attempt to fix paths in the NT, \\GLOBAL??, or device namespaces at this time
- return source;
- }
-
- const auto last = native.end();
- auto first = native.begin();
- auto is_wildcard = [](wchar_t c) { return c == L'?' || c == L'*'; };
- if (std::any_of(first, last, is_wildcard))
- {
- Checks::exit_with_message(
- VCPKG_LINE_INFO, "Attempt to fix case of a path containing wildcards: %s", fs::u8string(source));
- }
-
- std::wstring in_progress;
- in_progress.reserve(native.size());
- if (last - first >= 3 && is_slash(first[0]) && is_slash(first[1]) && !is_slash(first[2]))
- {
- // path with UNC prefix \\server\share; this will be rejected by FindFirstFile so we skip over that
- in_progress.push_back(L'\\');
- in_progress.push_back(L'\\');
- first += 2;
- auto next_slash = std::find_if(first, last, is_slash);
- in_progress.append(first, next_slash);
- in_progress.push_back(L'\\');
- first = std::find_if_not(next_slash, last, is_slash);
- next_slash = std::find_if(first, last, is_slash);
- in_progress.append(first, next_slash);
- first = std::find_if_not(next_slash, last, is_slash);
- if (first != next_slash)
- {
- in_progress.push_back(L'\\');
- }
- }
- else if (last - first >= 1 && is_slash(first[0]))
- {
- // root relative path
- in_progress.push_back(L'\\');
- first = std::find_if_not(first, last, is_slash);
- }
- else if (starts_with_drive_letter(first, last))
- {
- // path with drive letter root
- auto letter = first[0];
- if (letter >= L'a' && letter <= L'z')
- {
- letter = letter - L'a' + L'A';
- }
-
- in_progress.push_back(letter);
- in_progress.push_back(L':');
- first += 2;
- if (first != last && is_slash(*first))
- {
- // absolute path
- in_progress.push_back(L'\\');
- first = std::find_if_not(first, last, is_slash);
- }
- }
-
- assert(!fs::path(first, last).has_root_path());
-
- while (first != last)
- {
- auto next_slash = std::find_if(first, last, is_slash);
- auto original_size = in_progress.size();
- in_progress.append(first, next_slash);
- FindFirstOp this_find;
- unsigned long last_error = this_find.find_first(in_progress.c_str());
- if (last_error == ERROR_SUCCESS)
- {
- in_progress.resize(original_size);
- in_progress.append(this_find.find_data.cFileName);
- }
- else
- {
- // we might not have access to this intermediate part of the path;
- // just guess that the case of that element is correct and move on
- }
-
- first = std::find_if_not(next_slash, last, is_slash);
- if (first != next_slash)
- {
- in_progress.push_back(L'\\');
- }
- }
-
- return fs::path(std::move(in_progress));
- }
-#endif // _WIN32
-
-}
diff --git a/toolsrc/src/vcpkg/base/hash.cpp b/toolsrc/src/vcpkg/base/hash.cpp
deleted file mode 100644
index 825489d6d..000000000
--- a/toolsrc/src/vcpkg/base/hash.cpp
+++ /dev/null
@@ -1,703 +0,0 @@
-#include <vcpkg/base/checks.h>
-#include <vcpkg/base/hash.h>
-#include <vcpkg/base/strings.h>
-#include <vcpkg/base/system.process.h>
-#include <vcpkg/base/uint128.h>
-#include <vcpkg/base/util.h>
-
-#if defined(_WIN32)
-#include <bcrypt.h>
-#pragma comment(lib, "bcrypt")
-
-#ifndef NT_SUCCESS
-#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)
-#endif
-
-#endif
-
-namespace vcpkg::Hash
-{
- using uchar = unsigned char;
-
- Optional<Algorithm> algorithm_from_string(StringView sv) noexcept
- {
- if (Strings::case_insensitive_ascii_equals(sv, "SHA1"))
- {
- return {Algorithm::Sha1};
- }
- if (Strings::case_insensitive_ascii_equals(sv, "SHA256"))
- {
- return {Algorithm::Sha256};
- }
- if (Strings::case_insensitive_ascii_equals(sv, "SHA512"))
- {
- return {Algorithm::Sha512};
- }
-
- return {};
- }
-
- const char* to_string(Algorithm algo) noexcept
- {
- switch (algo)
- {
- case Algorithm::Sha1: return "SHA1";
- case Algorithm::Sha256: return "SHA256";
- case Algorithm::Sha512: return "SHA512";
- default: vcpkg::Checks::exit_fail(VCPKG_LINE_INFO);
- }
- }
-
- template<class UIntTy>
- auto top_bits(UIntTy x) -> std::enable_if_t<std::is_unsigned<UIntTy>::value, uchar>
- {
- return static_cast<uchar>(x >> ((sizeof(x) - 1) * 8));
- }
- template<class UIntTy>
- auto top_bits(UIntTy x) -> decltype(top_bits(x.top_64_bits()))
- {
- return top_bits(x.top_64_bits());
- }
-
- // treats UIntTy as big endian for the purpose of this mapping
- template<class UIntTy>
- static std::string to_hex(const UIntTy* start, const UIntTy* end) noexcept
- {
- static constexpr char HEX_MAP[] = "0123456789abcdef";
-
- std::string output;
- output.resize(2 * sizeof(UIntTy) * (end - start));
-
- std::size_t output_index = 0;
- for (const UIntTy* it = start; it != end; ++it)
- {
- // holds *it in a big-endian buffer, for copying into output
- uchar buff[sizeof(UIntTy)];
- UIntTy tmp = *it;
- for (uchar& ch : buff)
- {
- ch = top_bits(tmp);
- tmp = UIntTy(tmp << 8);
- }
-
- for (const auto byte : buff)
- {
- // high
- output[output_index] = HEX_MAP[(byte & 0xF0) >> 4];
- ++output_index;
- // low
- output[output_index] = HEX_MAP[byte & 0x0F];
- ++output_index;
- }
- }
-
- return output;
- }
-
- namespace
- {
-#if defined(_WIN32)
- BCRYPT_ALG_HANDLE get_alg_handle(LPCWSTR algorithm_identifier) noexcept
- {
- BCRYPT_ALG_HANDLE result;
- auto error = BCryptOpenAlgorithmProvider(&result, algorithm_identifier, nullptr, 0);
- if (!NT_SUCCESS(error))
- {
- Checks::exit_with_message(VCPKG_LINE_INFO, "Failure to open algorithm: %ls", algorithm_identifier);
- }
-
- return result;
- }
-
- struct BCryptHasher : Hasher
- {
- static const BCRYPT_ALG_HANDLE sha1_alg_handle;
- static const BCRYPT_ALG_HANDLE sha256_alg_handle;
- static const BCRYPT_ALG_HANDLE sha512_alg_handle;
-
- explicit BCryptHasher(Algorithm algo) noexcept
- {
- switch (algo)
- {
- case Algorithm::Sha1: alg_handle = sha1_alg_handle; break;
- case Algorithm::Sha256: alg_handle = sha256_alg_handle; break;
- case Algorithm::Sha512: alg_handle = sha512_alg_handle; break;
- default: Checks::unreachable(VCPKG_LINE_INFO);
- }
-
- clear();
- }
-
- virtual void add_bytes(const void* start_, const void* end_) noexcept override
- {
- // BCryptHashData takes its input as non-const, but does not modify it
- uchar* start = const_cast<uchar*>(static_cast<const uchar*>(start_));
- const uchar* end = static_cast<const uchar*>(end_);
- Checks::check_exit(VCPKG_LINE_INFO, end - start >= 0);
-
- // only matters on 64-bit -- BCryptHasher takes an unsigned long
- // length, so if you have an array bigger than 2**32-1 elements,
- // you have a problem.
-#if defined(_M_AMD64) || defined(_M_ARM64)
- constexpr std::ptrdiff_t max = std::numeric_limits<unsigned long>::max();
- Checks::check_exit(VCPKG_LINE_INFO, end - start <= max);
-#endif
-
- const auto length = static_cast<unsigned long>(end - start);
- const NTSTATUS error_code = BCryptHashData(hash_handle, start, length, 0);
- Checks::check_exit(VCPKG_LINE_INFO, NT_SUCCESS(error_code), "Failed to process a chunk");
- }
-
- virtual void clear() noexcept override
- {
- if (hash_handle) BCryptDestroyHash(hash_handle);
- const NTSTATUS error_code = BCryptCreateHash(alg_handle, &hash_handle, nullptr, 0, nullptr, 0, 0);
- Checks::check_exit(VCPKG_LINE_INFO, NT_SUCCESS(error_code), "Failed to initialize the hasher");
- }
-
- virtual std::string get_hash() noexcept override
- {
- const auto hash_size = get_hash_buffer_size();
- const auto buffer = std::make_unique<uchar[]>(hash_size);
- const auto hash = buffer.get();
-
- const NTSTATUS error_code = BCryptFinishHash(hash_handle, hash, hash_size, 0);
- Checks::check_exit(VCPKG_LINE_INFO, NT_SUCCESS(error_code), "Failed to finalize the hash");
- return to_hex(hash, hash + hash_size);
- }
-
- ~BCryptHasher() { BCryptDestroyHash(hash_handle); }
-
- private:
- unsigned long get_hash_buffer_size() const
- {
- unsigned long hash_buffer_bytes;
- unsigned long cb_data;
- const NTSTATUS error_code = BCryptGetProperty(alg_handle,
- BCRYPT_HASH_LENGTH,
- reinterpret_cast<uchar*>(&hash_buffer_bytes),
- sizeof(hash_buffer_bytes),
- &cb_data,
- 0);
- Checks::check_exit(VCPKG_LINE_INFO, NT_SUCCESS(error_code), "Failed to get hash length");
-
- return hash_buffer_bytes;
- }
-
- BCRYPT_HASH_HANDLE hash_handle = nullptr;
- BCRYPT_ALG_HANDLE alg_handle = nullptr;
- };
-
- const BCRYPT_ALG_HANDLE BCryptHasher::sha1_alg_handle = get_alg_handle(BCRYPT_SHA1_ALGORITHM);
- const BCRYPT_ALG_HANDLE BCryptHasher::sha256_alg_handle = get_alg_handle(BCRYPT_SHA256_ALGORITHM);
- const BCRYPT_ALG_HANDLE BCryptHasher::sha512_alg_handle = get_alg_handle(BCRYPT_SHA512_ALGORITHM);
-#else
-
- template<class WordTy>
- static WordTy shl(WordTy value, int by) noexcept
- {
- return value << by;
- }
-
- static std::uint32_t shr32(std::uint32_t value, int by) noexcept { return value >> by; }
- static std::uint32_t rol32(std::uint32_t value, int by) noexcept
- {
- return (value << by) | (value >> (32 - by));
- }
- static std::uint32_t ror32(std::uint32_t value, int by) noexcept
- {
- return (value >> by) | (value << (32 - by));
- }
-
- static std::uint64_t shr64(std::uint64_t value, int by) noexcept { return value >> by; }
- static std::uint64_t ror64(std::uint64_t value, int by) noexcept
- {
- return (value >> by) | (value << (64 - by));
- }
-
- template<class ShaAlgorithm>
- struct ShaHasher final : Hasher
- {
- ShaHasher() = default;
-
- virtual void add_bytes(const void* start, const void* end) noexcept override
- {
- for (;;)
- {
- start = add_to_unprocessed(start, end);
- if (!start)
- {
- break; // done
- }
-
- m_impl.process_full_chunk(m_chunk);
- m_current_chunk_size = 0;
- }
- }
-
- virtual void clear() noexcept override
- {
- m_impl.clear();
-
- // m_chunk is theoretically uninitialized, so no need to reset it
- m_current_chunk_size = 0;
- m_message_length = 0;
- }
-
- virtual std::string get_hash() noexcept override
- {
- process_last_chunk();
- return to_hex(m_impl.begin(), m_impl.end());
- }
-
- private:
- // if unprocessed gets filled,
- // returns a pointer to the remainder of the block (which might be end)
- // else, returns nullptr
- const void* add_to_unprocessed(const void* start_, const void* end_) noexcept
- {
- const uchar* start = static_cast<const uchar*>(start_);
- const uchar* end = static_cast<const uchar*>(end_);
-
- const auto remaining = chunk_size - m_current_chunk_size;
-
- const std::size_t message_length = end - start;
- if (message_length >= remaining)
- {
- std::copy(start, start + remaining, chunk_begin());
- m_current_chunk_size += remaining;
- m_message_length += remaining * 8;
- return start + remaining;
- }
- else
- {
- std::copy(start, end, chunk_begin());
- m_current_chunk_size += message_length;
- m_message_length += message_length * 8;
- return nullptr;
- }
- }
-
- // called before `get_hash`
- void process_last_chunk() noexcept
- {
- const auto message_length = m_message_length;
-
- // append the bit '1' to the message
- {
- const uchar temp = 0x80;
- add_to_unprocessed(&temp, &temp + 1);
- }
-
- // append 0 to the message so that the resulting length is just enough
- // to add the message length
- if (chunk_size - m_current_chunk_size < sizeof(m_message_length))
- {
- // not enough space to add the message length
- // just resize and process full chunk
- std::fill(chunk_begin(), m_chunk.end(), static_cast<uchar>(0));
- m_impl.process_full_chunk(m_chunk);
- m_current_chunk_size = 0;
- }
-
- const auto before_length = m_chunk.end() - sizeof(m_message_length);
- std::fill(chunk_begin(), before_length, static_cast<uchar>(0));
- std::generate(before_length, m_chunk.end(), [length = message_length]() mutable {
- const auto result = top_bits(length);
- length <<= 8;
- return result;
- });
-
- m_impl.process_full_chunk(m_chunk);
- }
-
- auto chunk_begin() { return m_chunk.begin() + m_current_chunk_size; }
-
- using underlying_type = typename ShaAlgorithm::underlying_type;
- using message_length_type = typename ShaAlgorithm::message_length_type;
- constexpr static std::size_t chunk_size = ShaAlgorithm::chunk_size;
-
- ShaAlgorithm m_impl{};
-
- std::array<uchar, chunk_size> m_chunk{};
- std::size_t m_current_chunk_size = 0;
- message_length_type m_message_length = 0;
- };
- template<class WordTy>
- inline void sha_fill_initial_words(const uchar* chunk, WordTy* words)
- {
- // break chunk into 16 N-bit words
- for (std::size_t word = 0; word < 16; ++word)
- {
- words[word] = 0;
- // big-endian -- so the earliest i becomes the most significant
- for (std::size_t byte = 0; byte < sizeof(WordTy); ++byte)
- {
- const auto bits_to_shift = static_cast<int>(8 * (sizeof(WordTy) - 1 - byte));
- words[word] |= shl<WordTy>(chunk[word * sizeof(WordTy) + byte], bits_to_shift);
- }
- }
- }
-
- struct Sha1Algorithm
- {
- using underlying_type = std::uint32_t;
- using message_length_type = std::uint64_t;
- constexpr static std::size_t chunk_size = 64; // = 512 / 8
- constexpr static std::size_t number_of_rounds = 80;
-
- Sha1Algorithm() noexcept { clear(); }
-
- void process_full_chunk(const std::array<uchar, chunk_size>& chunk) noexcept
- {
- std::uint32_t words[80];
-
- sha_fill_initial_words(&chunk[0], words);
- for (std::size_t i = 16; i < number_of_rounds; ++i)
- {
- const auto sum = words[i - 3] ^ words[i - 8] ^ words[i - 14] ^ words[i - 16];
- words[i] = rol32(sum, 1);
- }
-
- std::uint32_t a = m_digest[0];
- std::uint32_t b = m_digest[1];
- std::uint32_t c = m_digest[2];
- std::uint32_t d = m_digest[3];
- std::uint32_t e = m_digest[4];
-
- for (std::size_t i = 0; i < number_of_rounds; ++i)
- {
- std::uint32_t f;
- std::uint32_t k;
-
- if (i < 20)
- {
- f = (b & c) | (~b & d);
- k = 0x5A827999;
- }
- else if (i < 40)
- {
- f = b ^ c ^ d;
- k = 0x6ED9EBA1;
- }
- else if (i < 60)
- {
- f = (b & c) | (b & d) | (c & d);
- k = 0x8F1BBCDC;
- }
- else
- {
- f = b ^ c ^ d;
- k = 0xCA62C1D6;
- }
-
- auto tmp = rol32(a, 5) + f + e + k + words[i];
- e = d;
- d = c;
- c = rol32(b, 30);
- b = a;
- a = tmp;
- }
-
- m_digest[0] += a;
- m_digest[1] += b;
- m_digest[2] += c;
- m_digest[3] += d;
- m_digest[4] += e;
- }
-
- void clear() noexcept
- {
- m_digest[0] = 0x67452301;
- m_digest[1] = 0xEFCDAB89;
- m_digest[2] = 0x98BADCFE;
- m_digest[3] = 0x10325476;
- m_digest[4] = 0xC3D2E1F0;
- }
-
- const std::uint32_t* begin() const noexcept { return &m_digest[0]; }
- const std::uint32_t* end() const noexcept { return &m_digest[5]; }
-
- std::uint32_t m_digest[5];
- };
-
- struct Sha256Algorithm
- {
- using underlying_type = std::uint32_t;
- using message_length_type = std::uint64_t;
- constexpr static std::size_t chunk_size = 64;
-
- constexpr static std::size_t number_of_rounds = 64;
-
- Sha256Algorithm() noexcept { clear(); }
-
- void process_full_chunk(const std::array<uchar, chunk_size>& chunk) noexcept
- {
- std::uint32_t words[64];
-
- sha_fill_initial_words(&chunk[0], words);
-
- for (std::size_t i = 16; i < number_of_rounds; ++i)
- {
- const auto w0 = words[i - 15];
- const auto s0 = ror32(w0, 7) ^ ror32(w0, 18) ^ shr32(w0, 3);
- const auto w1 = words[i - 2];
- const auto s1 = ror32(w1, 17) ^ ror32(w1, 19) ^ shr32(w1, 10);
- words[i] = words[i - 16] + s0 + words[i - 7] + s1;
- }
-
- std::uint32_t local[8];
- std::copy(begin(), end(), std::begin(local));
-
- for (std::size_t i = 0; i < number_of_rounds; ++i)
- {
- const auto a = local[0];
- const auto b = local[1];
- const auto c = local[2];
-
- const auto s0 = ror32(a, 2) ^ ror32(a, 13) ^ ror32(a, 22);
- const auto maj = (a & b) ^ (a & c) ^ (b & c);
- const auto tmp1 = s0 + maj;
-
- const auto e = local[4];
-
- const auto s1 = ror32(e, 6) ^ ror32(e, 11) ^ ror32(e, 25);
- const auto ch = (e & local[5]) ^ (~e & local[6]);
- const auto tmp2 = local[7] + s1 + ch + round_constants[i] + words[i];
-
- for (std::size_t j = 7; j > 0; --j)
- {
- local[j] = local[j - 1];
- }
- local[4] += tmp2;
- local[0] = tmp1 + tmp2;
- }
-
- for (std::size_t i = 0; i < 8; ++i)
- {
- m_digest[i] += local[i];
- }
- }
-
- void clear() noexcept
- {
- m_digest[0] = 0x6a09e667;
- m_digest[1] = 0xbb67ae85;
- m_digest[2] = 0x3c6ef372;
- m_digest[3] = 0xa54ff53a;
- m_digest[4] = 0x510e527f;
- m_digest[5] = 0x9b05688c;
- m_digest[6] = 0x1f83d9ab;
- m_digest[7] = 0x5be0cd19;
- }
-
- constexpr static std::array<std::uint32_t, number_of_rounds> round_constants = {
- 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
- 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
- 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
- 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
- 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
- 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
- 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
- 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2};
-
- std::uint32_t* begin() noexcept { return &m_digest[0]; }
- std::uint32_t* end() noexcept { return &m_digest[8]; }
-
- std::uint32_t m_digest[8];
- };
-
- struct Sha512Algorithm
- {
- using underlying_type = std::uint64_t;
- using message_length_type = UInt128;
- constexpr static std::size_t chunk_size = 128; // = 1024 / 8
-
- constexpr static std::size_t number_of_rounds = 80;
-
- Sha512Algorithm() noexcept { clear(); }
-
- void process_full_chunk(const std::array<uchar, chunk_size>& chunk) noexcept
- {
- std::uint64_t words[80];
-
- sha_fill_initial_words(&chunk[0], words);
-
- for (std::size_t i = 16; i < number_of_rounds; ++i)
- {
- const auto w0 = words[i - 15];
- const auto s0 = ror64(w0, 1) ^ ror64(w0, 8) ^ shr64(w0, 7);
- const auto w1 = words[i - 2];
- const auto s1 = ror64(w1, 19) ^ ror64(w1, 61) ^ shr64(w1, 6);
- words[i] = words[i - 16] + s0 + words[i - 7] + s1;
- }
-
- std::uint64_t local[8];
- std::copy(begin(), end(), std::begin(local));
-
- for (std::size_t i = 0; i < number_of_rounds; ++i)
- {
- const auto a = local[0];
- const auto b = local[1];
- const auto c = local[2];
-
- const auto s0 = ror64(a, 28) ^ ror64(a, 34) ^ ror64(a, 39);
- const auto maj = (a & b) ^ (a & c) ^ (b & c);
- const auto tmp0 = s0 + maj;
-
- const auto e = local[4];
-
- const auto s1 = ror64(e, 14) ^ ror64(e, 18) ^ ror64(e, 41);
- const auto ch = (e & local[5]) ^ (~e & local[6]);
- const auto tmp1 = local[7] + s1 + ch + round_constants[i] + words[i];
-
- for (std::size_t j = 7; j > 0; --j)
- {
- local[j] = local[j - 1];
- }
- local[4] += tmp1;
- local[0] = tmp0 + tmp1;
- }
-
- for (std::size_t i = 0; i < 8; ++i)
- {
- m_digest[i] += local[i];
- }
- }
-
- void clear() noexcept
- {
- m_digest[0] = 0x6a09e667f3bcc908;
- m_digest[1] = 0xbb67ae8584caa73b;
- m_digest[2] = 0x3c6ef372fe94f82b;
- m_digest[3] = 0xa54ff53a5f1d36f1;
- m_digest[4] = 0x510e527fade682d1;
- m_digest[5] = 0x9b05688c2b3e6c1f;
- m_digest[6] = 0x1f83d9abfb41bd6b;
- m_digest[7] = 0x5be0cd19137e2179;
- }
-
- constexpr static std::array<std::uint64_t, number_of_rounds> round_constants = {
- 0x428a2f98d728ae22, 0x7137449123ef65cd, 0xb5c0fbcfec4d3b2f, 0xe9b5dba58189dbbc, 0x3956c25bf348b538,
- 0x59f111f1b605d019, 0x923f82a4af194f9b, 0xab1c5ed5da6d8118, 0xd807aa98a3030242, 0x12835b0145706fbe,
- 0x243185be4ee4b28c, 0x550c7dc3d5ffb4e2, 0x72be5d74f27b896f, 0x80deb1fe3b1696b1, 0x9bdc06a725c71235,
- 0xc19bf174cf692694, 0xe49b69c19ef14ad2, 0xefbe4786384f25e3, 0x0fc19dc68b8cd5b5, 0x240ca1cc77ac9c65,
- 0x2de92c6f592b0275, 0x4a7484aa6ea6e483, 0x5cb0a9dcbd41fbd4, 0x76f988da831153b5, 0x983e5152ee66dfab,
- 0xa831c66d2db43210, 0xb00327c898fb213f, 0xbf597fc7beef0ee4, 0xc6e00bf33da88fc2, 0xd5a79147930aa725,
- 0x06ca6351e003826f, 0x142929670a0e6e70, 0x27b70a8546d22ffc, 0x2e1b21385c26c926, 0x4d2c6dfc5ac42aed,
- 0x53380d139d95b3df, 0x650a73548baf63de, 0x766a0abb3c77b2a8, 0x81c2c92e47edaee6, 0x92722c851482353b,
- 0xa2bfe8a14cf10364, 0xa81a664bbc423001, 0xc24b8b70d0f89791, 0xc76c51a30654be30, 0xd192e819d6ef5218,
- 0xd69906245565a910, 0xf40e35855771202a, 0x106aa07032bbd1b8, 0x19a4c116b8d2d0c8, 0x1e376c085141ab53,
- 0x2748774cdf8eeb99, 0x34b0bcb5e19b48a8, 0x391c0cb3c5c95a63, 0x4ed8aa4ae3418acb, 0x5b9cca4f7763e373,
- 0x682e6ff3d6b2b8a3, 0x748f82ee5defb2fc, 0x78a5636f43172f60, 0x84c87814a1f0ab72, 0x8cc702081a6439ec,
- 0x90befffa23631e28, 0xa4506cebde82bde9, 0xbef9a3f7b2c67915, 0xc67178f2e372532b, 0xca273eceea26619c,
- 0xd186b8c721c0c207, 0xeada7dd6cde0eb1e, 0xf57d4f7fee6ed178, 0x06f067aa72176fba, 0x0a637dc5a2c898a6,
- 0x113f9804bef90dae, 0x1b710b35131c471b, 0x28db77f523047d84, 0x32caab7b40c72493, 0x3c9ebe0a15c9bebc,
- 0x431d67c49c100d4c, 0x4cc5d4becb3e42b6, 0x597f299cfc657e2a, 0x5fcb6fab3ad6faec, 0x6c44198c4a475817};
-
- std::uint64_t* begin() noexcept { return &m_digest[0]; }
- std::uint64_t* end() noexcept { return &m_digest[8]; }
-
- std::uint64_t m_digest[8];
- };
-
- // This is required on older compilers, since it was required in C++14
- constexpr std::array<std::uint32_t, Sha256Algorithm::number_of_rounds> Sha256Algorithm::round_constants;
- constexpr std::array<std::uint64_t, Sha512Algorithm::number_of_rounds> Sha512Algorithm::round_constants;
-#endif
- }
-
- std::unique_ptr<Hasher> get_hasher_for(Algorithm algo) noexcept
- {
-#if defined(_WIN32)
- return std::make_unique<BCryptHasher>(algo);
-#else
- switch (algo)
- {
- case Algorithm::Sha1: return std::make_unique<ShaHasher<Sha1Algorithm>>();
- case Algorithm::Sha256: return std::make_unique<ShaHasher<Sha256Algorithm>>();
- case Algorithm::Sha512: return std::make_unique<ShaHasher<Sha512Algorithm>>();
- default: vcpkg::Checks::exit_with_message(VCPKG_LINE_INFO, "Unknown hashing algorithm: %s", algo);
- }
-#endif
- }
-
- template<class F>
- static std::string do_hash(Algorithm algo, const F& f) noexcept
- {
-#if defined(_WIN32)
- auto hasher = BCryptHasher(algo);
- return f(hasher);
-#else
- switch (algo)
- {
- case Algorithm::Sha1:
- {
- auto hasher = ShaHasher<Sha1Algorithm>();
- return f(hasher);
- }
- case Algorithm::Sha256:
- {
- auto hasher = ShaHasher<Sha256Algorithm>();
- return f(hasher);
- }
- case Algorithm::Sha512:
- {
- auto hasher = ShaHasher<Sha512Algorithm>();
- return f(hasher);
- }
- default: vcpkg::Checks::exit_with_message(VCPKG_LINE_INFO, "Unknown hashing algorithm: %s", algo);
- }
-#endif
- }
-
- std::string get_bytes_hash(const void* first, const void* last, Algorithm algo) noexcept
- {
- return do_hash(algo, [first, last](Hasher& hasher) {
- hasher.add_bytes(first, last);
- return hasher.get_hash();
- });
- }
-
- std::string get_string_hash(StringView sv, Algorithm algo) noexcept
- {
- return get_bytes_hash(sv.data(), sv.data() + sv.size(), algo);
- }
-
- // TODO: use Files::Filesystem to open a file
- std::string get_file_hash(const Files::Filesystem&,
- const fs::path& path,
- Algorithm algo,
- std::error_code& ec) noexcept
- {
- auto file = std::fstream(path.c_str(), std::ios_base::in | std::ios_base::binary);
- if (!file)
- {
- ec.assign(ENOENT, std::system_category());
- return {};
- }
-
- return do_hash(algo, [&file, &ec](Hasher& hasher) {
- constexpr std::size_t buffer_size = 1024 * 32;
- auto buffer = std::make_unique<char[]>(buffer_size);
- for (;;)
- {
- file.read(buffer.get(), buffer_size);
- if (file.eof())
- {
- hasher.add_bytes(buffer.get(), buffer.get() + file.gcount());
- return hasher.get_hash();
- }
- else if (file)
- {
- hasher.add_bytes(buffer.get(), buffer.get() + buffer_size);
- }
- else
- {
- ec = std::io_errc::stream;
- return std::string();
- }
- }
- });
- }
-}
diff --git a/toolsrc/src/vcpkg/base/json.cpp b/toolsrc/src/vcpkg/base/json.cpp
deleted file mode 100644
index c287eae78..000000000
--- a/toolsrc/src/vcpkg/base/json.cpp
+++ /dev/null
@@ -1,1411 +0,0 @@
-#include <vcpkg/base/files.h>
-#include <vcpkg/base/json.h>
-#include <vcpkg/base/jsonreader.h>
-#include <vcpkg/base/system.debug.h>
-#include <vcpkg/base/unicode.h>
-
-#include <inttypes.h>
-
-#include <regex>
-
-namespace vcpkg::Json
-{
- using VK = ValueKind;
-
- // struct Value {
- namespace impl
- {
- // TODO: add a value_kind value template once we get rid of VS2015 support
- template<ValueKind Vk>
- using ValueKindConstant = std::integral_constant<ValueKind, Vk>;
-
- struct ValueImpl
- {
- VK tag;
- union
- {
- std::nullptr_t null;
- bool boolean;
- int64_t integer;
- double number;
- std::string string;
- Array array;
- Object object;
- };
-
- ValueImpl(ValueKindConstant<VK::Null> vk, std::nullptr_t) : tag(vk), null() { }
- ValueImpl(ValueKindConstant<VK::Boolean> vk, bool b) : tag(vk), boolean(b) { }
- ValueImpl(ValueKindConstant<VK::Integer> vk, int64_t i) : tag(vk), integer(i) { }
- ValueImpl(ValueKindConstant<VK::Number> vk, double d) : tag(vk), number(d) { }
- ValueImpl(ValueKindConstant<VK::String> vk, std::string&& s) : tag(vk), string(std::move(s)) { }
- ValueImpl(ValueKindConstant<VK::String> vk, const std::string& s) : tag(vk), string(s) { }
- ValueImpl(ValueKindConstant<VK::Array> vk, Array&& arr) : tag(vk), array(std::move(arr)) { }
- ValueImpl(ValueKindConstant<VK::Array> vk, const Array& arr) : tag(vk), array(arr) { }
- ValueImpl(ValueKindConstant<VK::Object> vk, Object&& obj) : tag(vk), object(std::move(obj)) { }
- ValueImpl(ValueKindConstant<VK::Object> vk, const Object& obj) : tag(vk), object(obj) { }
-
- ValueImpl& operator=(ValueImpl&& other) noexcept
- {
- switch (other.tag)
- {
- case VK::Null: return internal_assign(VK::Null, &ValueImpl::null, other);
- case VK::Boolean: return internal_assign(VK::Boolean, &ValueImpl::boolean, other);
- case VK::Integer: return internal_assign(VK::Integer, &ValueImpl::integer, other);
- case VK::Number: return internal_assign(VK::Number, &ValueImpl::number, other);
- case VK::String: return internal_assign(VK::String, &ValueImpl::string, other);
- case VK::Array: return internal_assign(VK::Array, &ValueImpl::array, other);
- case VK::Object: return internal_assign(VK::Object, &ValueImpl::object, other);
- }
- }
-
- ~ValueImpl() { destroy_underlying(); }
-
- private:
- template<class T>
- ValueImpl& internal_assign(ValueKind vk, T ValueImpl::*mp, ValueImpl& other) noexcept
- {
- if (tag == vk)
- {
- this->*mp = std::move(other.*mp);
- }
- else
- {
- destroy_underlying();
- auto* address = &(this->*mp);
- new (address) T(std::move(other.*mp));
- tag = vk;
- }
-
- return *this;
- }
-
- void destroy_underlying() noexcept
- {
- switch (tag)
- {
- case VK::String: string.~basic_string(); break;
- case VK::Array: array.~Array(); break;
- case VK::Object: object.~Object(); break;
- default: break;
- }
- new (&null) std::nullptr_t();
- tag = VK::Null;
- }
- };
- }
-
- using impl::ValueImpl;
- using impl::ValueKindConstant;
-
- VK Value::kind() const noexcept
- {
- if (underlying_)
- {
- return underlying_->tag;
- }
- else
- {
- return VK::Null;
- }
- }
-
- bool Value::is_null() const noexcept { return kind() == VK::Null; }
- bool Value::is_boolean() const noexcept { return kind() == VK::Boolean; }
- bool Value::is_integer() const noexcept { return kind() == VK::Integer; }
- bool Value::is_number() const noexcept
- {
- auto k = kind();
- return k == VK::Integer || k == VK::Number;
- }
- bool Value::is_string() const noexcept { return kind() == VK::String; }
- bool Value::is_array() const noexcept { return kind() == VK::Array; }
- bool Value::is_object() const noexcept { return kind() == VK::Object; }
-
- bool Value::boolean() const noexcept
- {
- vcpkg::Checks::check_exit(VCPKG_LINE_INFO, is_boolean());
- return underlying_->boolean;
- }
- int64_t Value::integer() const noexcept
- {
- vcpkg::Checks::check_exit(VCPKG_LINE_INFO, is_integer());
- return underlying_->integer;
- }
- double Value::number() const noexcept
- {
- auto k = kind();
- if (k == VK::Number)
- {
- return underlying_->number;
- }
- else
- {
- return static_cast<double>(integer());
- }
- }
- StringView Value::string() const noexcept
- {
- vcpkg::Checks::check_exit(VCPKG_LINE_INFO, is_string(), "json value is not string");
- return underlying_->string;
- }
-
- const Array& Value::array() const& noexcept
- {
- vcpkg::Checks::check_exit(VCPKG_LINE_INFO, is_array(), "json value is not array");
- return underlying_->array;
- }
- Array& Value::array() & noexcept
- {
- vcpkg::Checks::check_exit(VCPKG_LINE_INFO, is_array(), "json value is not array");
- return underlying_->array;
- }
- Array&& Value::array() && noexcept { return std::move(this->array()); }
-
- const Object& Value::object() const& noexcept
- {
- vcpkg::Checks::check_exit(VCPKG_LINE_INFO, is_object(), "json value is not object");
- return underlying_->object;
- }
- Object& Value::object() & noexcept
- {
- vcpkg::Checks::check_exit(VCPKG_LINE_INFO, is_object(), "json value is not object");
- return underlying_->object;
- }
- Object&& Value::object() && noexcept { return std::move(this->object()); }
-
- Value::Value() noexcept = default;
- Value::Value(Value&&) noexcept = default;
- Value& Value::operator=(Value&&) noexcept = default;
-
- Value::Value(const Value& other)
- {
- switch (other.kind())
- {
- case ValueKind::Null: return; // default construct underlying_
- case ValueKind::Boolean:
- underlying_.reset(new ValueImpl(ValueKindConstant<VK::Boolean>(), other.underlying_->boolean));
- break;
- case ValueKind::Integer:
- underlying_.reset(new ValueImpl(ValueKindConstant<VK::Integer>(), other.underlying_->integer));
- break;
- case ValueKind::Number:
- underlying_.reset(new ValueImpl(ValueKindConstant<VK::Number>(), other.underlying_->number));
- break;
- case ValueKind::String:
- underlying_.reset(new ValueImpl(ValueKindConstant<VK::String>(), other.underlying_->string));
- break;
- case ValueKind::Array:
- underlying_.reset(new ValueImpl(ValueKindConstant<VK::Array>(), other.underlying_->array));
- break;
- case ValueKind::Object:
- underlying_.reset(new ValueImpl(ValueKindConstant<VK::Object>(), other.underlying_->object));
- break;
- default: Checks::unreachable(VCPKG_LINE_INFO);
- }
- }
-
- Value& Value::operator=(const Value& other)
- {
- switch (other.kind())
- {
- case ValueKind::Null: underlying_.reset(); break;
- case ValueKind::Boolean:
- underlying_.reset(new ValueImpl(ValueKindConstant<VK::Boolean>(), other.underlying_->boolean));
- break;
- case ValueKind::Integer:
- underlying_.reset(new ValueImpl(ValueKindConstant<VK::Integer>(), other.underlying_->integer));
- break;
- case ValueKind::Number:
- underlying_.reset(new ValueImpl(ValueKindConstant<VK::Number>(), other.underlying_->number));
- break;
- case ValueKind::String:
- underlying_.reset(new ValueImpl(ValueKindConstant<VK::String>(), other.underlying_->string));
- break;
- case ValueKind::Array:
- underlying_.reset(new ValueImpl(ValueKindConstant<VK::Array>(), other.underlying_->array));
- break;
- case ValueKind::Object:
- underlying_.reset(new ValueImpl(ValueKindConstant<VK::Object>(), other.underlying_->object));
- break;
- default: Checks::unreachable(VCPKG_LINE_INFO);
- }
-
- return *this;
- }
-
- Value::~Value() = default;
-
- Value Value::null(std::nullptr_t) noexcept { return Value(); }
- Value Value::boolean(bool b) noexcept
- {
- Value val;
- val.underlying_ = std::make_unique<ValueImpl>(ValueKindConstant<VK::Boolean>(), b);
- return val;
- }
- Value Value::integer(int64_t i) noexcept
- {
- Value val;
- val.underlying_ = std::make_unique<ValueImpl>(ValueKindConstant<VK::Integer>(), i);
- return val;
- }
- Value Value::number(double d) noexcept
- {
- vcpkg::Checks::check_exit(VCPKG_LINE_INFO, isfinite(d));
- Value val;
- val.underlying_ = std::make_unique<ValueImpl>(ValueKindConstant<VK::Number>(), d);
- return val;
- }
- Value Value::string(std::string s) noexcept
- {
- if (!Unicode::utf8_is_valid_string(s.data(), s.data() + s.size()))
- {
- Debug::print("Invalid string: ", s, '\n');
- vcpkg::Checks::exit_with_message(VCPKG_LINE_INFO, "Invalid utf8 passed to Value::string(std::string)");
- }
- Value val;
- val.underlying_ = std::make_unique<ValueImpl>(ValueKindConstant<VK::String>(), std::move(s));
- return val;
- }
- Value Value::array(Array&& arr) noexcept
- {
- Value val;
- val.underlying_ = std::make_unique<ValueImpl>(ValueKindConstant<VK::Array>(), std::move(arr));
- return val;
- }
- Value Value::array(const Array& arr) noexcept
- {
- Value val;
- val.underlying_ = std::make_unique<ValueImpl>(ValueKindConstant<VK::Array>(), arr);
- return val;
- }
- Value Value::object(Object&& obj) noexcept
- {
- Value val;
- val.underlying_ = std::make_unique<ValueImpl>(ValueKindConstant<VK::Object>(), std::move(obj));
- return val;
- }
- Value Value::object(const Object& obj) noexcept
- {
- Value val;
- val.underlying_ = std::make_unique<ValueImpl>(ValueKindConstant<VK::Object>(), obj);
- return val;
- }
-
- bool operator==(const Value& lhs, const Value& rhs)
- {
- if (lhs.kind() != rhs.kind()) return false;
-
- switch (lhs.kind())
- {
- case ValueKind::Null: return true;
- case ValueKind::Boolean: return lhs.underlying_->boolean == rhs.underlying_->boolean;
- case ValueKind::Integer: return lhs.underlying_->integer == rhs.underlying_->integer;
- case ValueKind::Number: return lhs.underlying_->number == rhs.underlying_->number;
- case ValueKind::String: return lhs.underlying_->string == rhs.underlying_->string;
- case ValueKind::Array: return lhs.underlying_->string == rhs.underlying_->string;
- case ValueKind::Object: return lhs.underlying_->string == rhs.underlying_->string;
- default: Checks::unreachable(VCPKG_LINE_INFO);
- }
- }
- // } struct Value
- // struct Array {
- Value& Array::push_back(Value&& value)
- {
- underlying_.push_back(std::move(value));
- return underlying_.back();
- }
- Object& Array::push_back(Object&& obj) { return push_back(Value::object(std::move(obj))).object(); }
- Array& Array::push_back(Array&& arr) { return push_back(Value::array(std::move(arr))).array(); }
- Value& Array::insert_before(iterator it, Value&& value)
- {
- size_t index = it - underlying_.begin();
- underlying_.insert(it, std::move(value));
- return underlying_[index];
- }
- Object& Array::insert_before(iterator it, Object&& obj)
- {
- return insert_before(it, Value::object(std::move(obj))).object();
- }
- Array& Array::insert_before(iterator it, Array&& arr)
- {
- return insert_before(it, Value::array(std::move(arr))).array();
- }
- bool operator==(const Array& lhs, const Array& rhs) { return lhs.underlying_ == rhs.underlying_; }
- // } struct Array
- // struct Object {
- Value& Object::insert(std::string key, Value&& value)
- {
- vcpkg::Checks::check_exit(VCPKG_LINE_INFO, !contains(key));
- underlying_.push_back({std::move(key), std::move(value)});
- return underlying_.back().second;
- }
- Value& Object::insert(std::string key, const Value& value)
- {
- vcpkg::Checks::check_exit(VCPKG_LINE_INFO, !contains(key));
- underlying_.push_back({std::move(key), value});
- return underlying_.back().second;
- }
- Array& Object::insert(std::string key, Array&& value)
- {
- return insert(std::move(key), Value::array(std::move(value))).array();
- }
- Array& Object::insert(std::string key, const Array& value)
- {
- return insert(std::move(key), Value::array(value)).array();
- }
- Object& Object::insert(std::string key, Object&& value)
- {
- return insert(std::move(key), Value::object(std::move(value))).object();
- }
- Object& Object::insert(std::string key, const Object& value)
- {
- return insert(std::move(key), Value::object(value)).object();
- }
-
- Value& Object::insert_or_replace(std::string key, Value&& value)
- {
- auto v = get(key);
- if (v)
- {
- *v = std::move(value);
- return *v;
- }
- else
- {
- underlying_.push_back({std::move(key), std::move(value)});
- return underlying_.back().second;
- }
- }
- Value& Object::insert_or_replace(std::string key, const Value& value)
- {
- auto v = get(key);
- if (v)
- {
- *v = value;
- return *v;
- }
- else
- {
- underlying_.push_back({std::move(key), std::move(value)});
- return underlying_.back().second;
- }
- }
- Array& Object::insert_or_replace(std::string key, Array&& value)
- {
- return insert_or_replace(std::move(key), Value::array(std::move(value))).array();
- }
- Array& Object::insert_or_replace(std::string key, const Array& value)
- {
- return insert_or_replace(std::move(key), Value::array(value)).array();
- }
- Object& Object::insert_or_replace(std::string key, Object&& value)
- {
- return insert_or_replace(std::move(key), Value::object(std::move(value))).object();
- }
- Object& Object::insert_or_replace(std::string key, const Object& value)
- {
- return insert_or_replace(std::move(key), Value::object(value)).object();
- }
-
- auto Object::internal_find_key(StringView key) const noexcept -> underlying_t::const_iterator
- {
- return std::find_if(
- underlying_.begin(), underlying_.end(), [key](const auto& pair) { return pair.first == key; });
- }
-
- // returns whether the key existed
- bool Object::remove(StringView key) noexcept
- {
- auto it = internal_find_key(key);
- if (it == underlying_.end())
- {
- return false;
- }
- else
- {
- underlying_.erase(it);
- return true;
- }
- }
-
- Value* Object::get(StringView key) noexcept
- {
- auto it = internal_find_key(key);
- if (it == underlying_.end())
- {
- return nullptr;
- }
- else
- {
- return &underlying_[it - underlying_.begin()].second;
- }
- }
- const Value* Object::get(StringView key) const noexcept
- {
- auto it = internal_find_key(key);
- if (it == underlying_.end())
- {
- return nullptr;
- }
- else
- {
- return &it->second;
- }
- }
-
- void Object::sort_keys()
- {
- std::sort(underlying_.begin(), underlying_.end(), [](const value_type& lhs, const value_type& rhs) {
- return lhs.first < rhs.first;
- });
- }
-
- bool operator==(const Object& lhs, const Object& rhs) { return lhs.underlying_ == rhs.underlying_; }
- // } struct Object
-
- // auto parse() {
- namespace
- {
- struct Parser : private Parse::ParserBase
- {
- Parser(StringView text, StringView origin) : Parse::ParserBase(text, origin), style_() { }
-
- char32_t next() noexcept
- {
- auto ch = cur();
- if (ch == '\r') style_.newline_kind = JsonStyle::Newline::CrLf;
- if (ch == '\t') style_.set_tabs();
- return Parse::ParserBase::next();
- }
-
- static constexpr bool is_digit(char32_t code_point) noexcept
- {
- return code_point >= '0' && code_point <= '9';
- }
- static constexpr bool is_hex_digit(char32_t code_point) noexcept
- {
- return is_digit(code_point) || (code_point >= 'a' && code_point <= 'f') ||
- (code_point >= 'A' && code_point <= 'F');
- }
- static bool is_number_start(char32_t code_point) noexcept
- {
- return code_point == '-' || is_digit(code_point);
- }
-
- static unsigned char from_hex_digit(char32_t code_point) noexcept
- {
- if (is_digit(code_point))
- {
- return static_cast<unsigned char>(code_point) - '0';
- }
- else if (code_point >= 'a' && code_point <= 'f')
- {
- return static_cast<unsigned char>(code_point) - 'a' + 10;
- }
- else if (code_point >= 'A' && code_point <= 'F')
- {
- return static_cast<unsigned char>(code_point) - 'A' + 10;
- }
- else
- {
- vcpkg::Checks::unreachable(VCPKG_LINE_INFO);
- }
- }
-
- // parses a _single_ code point of a string -- either a literal code point, or an escape sequence
- // returns end_of_file if it reaches an unescaped '"'
- // _does not_ pair escaped surrogates -- returns the literal surrogate.
- char32_t parse_string_code_point() noexcept
- {
- char32_t current = cur();
- if (current == '"')
- {
- next();
- return Unicode::end_of_file;
- }
- else if (current <= 0x001F)
- {
- add_error("Control character in string");
- next();
- return Unicode::end_of_file;
- }
- else if (current != '\\')
- {
- next();
- return current;
- }
-
- // cur == '\\'
- if (at_eof())
- {
- add_error("Unexpected EOF after escape character");
- return Unicode::end_of_file;
- }
- current = next();
-
- switch (current)
- {
- case '"': next(); return '"';
- case '\\': next(); return '\\';
- case '/': next(); return '/';
- case 'b': next(); return '\b';
- case 'f': next(); return '\f';
- case 'n': next(); return '\n';
- case 'r': next(); return '\r';
- case 't': next(); return '\t';
- case 'u':
- {
- char16_t code_unit = 0;
- for (int i = 0; i < 4; ++i)
- {
- current = next();
-
- if (current == Unicode::end_of_file)
- {
- add_error("Unexpected end of file in middle of unicode escape");
- return Unicode::end_of_file;
- }
- if (is_hex_digit(current))
- {
- code_unit *= 16;
- code_unit += from_hex_digit(current);
- }
- else
- {
- add_error("Invalid hex digit in unicode escape");
- return Unicode::end_of_file;
- }
- }
- next();
-
- return code_unit;
- }
- default: add_error("Unexpected escape sequence continuation"); return Unicode::end_of_file;
- }
- }
-
- std::string parse_string() noexcept
- {
- Checks::check_exit(VCPKG_LINE_INFO, cur() == '"');
- next();
-
- std::string res;
- char32_t previous_leading_surrogate = Unicode::end_of_file;
- while (!at_eof())
- {
- auto code_point = parse_string_code_point();
-
- if (previous_leading_surrogate != Unicode::end_of_file)
- {
- if (Unicode::utf16_is_trailing_surrogate_code_point(code_point))
- {
- const auto full_code_point =
- Unicode::utf16_surrogates_to_code_point(previous_leading_surrogate, code_point);
- Unicode::utf8_append_code_point(res, full_code_point);
- previous_leading_surrogate = Unicode::end_of_file;
- continue;
- }
- else
- {
- Unicode::utf8_append_code_point(res, previous_leading_surrogate);
- }
- }
- previous_leading_surrogate = Unicode::end_of_file;
-
- if (Unicode::utf16_is_leading_surrogate_code_point(code_point))
- {
- previous_leading_surrogate = code_point;
- }
- else if (code_point == Unicode::end_of_file)
- {
- return res;
- }
- else
- {
- Unicode::utf8_append_code_point(res, code_point);
- }
- }
-
- add_error("Unexpected EOF in middle of string");
- return res;
- }
-
- Value parse_number() noexcept
- {
- Checks::check_exit(VCPKG_LINE_INFO, is_number_start(cur()));
-
- bool floating = false;
- bool negative = false; // negative & 0 -> floating, so keep track of it
- std::string number_to_parse;
-
- char32_t current = cur();
- if (cur() == '-')
- {
- number_to_parse.push_back('-');
- negative = true;
- current = next();
- if (current == Unicode::end_of_file)
- {
- add_error("Unexpected EOF after minus sign");
- return Value();
- }
- }
-
- if (current == '0')
- {
- current = next();
- if (current == '.')
- {
- number_to_parse.append("0.");
- floating = true;
- current = next();
- }
- else if (is_digit(current))
- {
- add_error("Unexpected digits after a leading zero");
- return Value();
- }
- else
- {
- if (negative)
- {
- return Value::number(-0.0);
- }
- else
- {
- return Value::integer(0);
- }
- }
- }
-
- while (is_digit(current))
- {
- number_to_parse.push_back(static_cast<char>(current));
- current = next();
- }
- if (!floating && current == '.')
- {
- floating = true;
- number_to_parse.push_back('.');
- current = next();
- if (!is_digit(current))
- {
- add_error("Expected digits after the decimal point");
- return Value();
- }
- while (is_digit(current))
- {
- number_to_parse.push_back(static_cast<char>(current));
- current = next();
- }
- }
-
- if (floating)
- {
- auto opt = Strings::strto<double>(number_to_parse);
- if (auto res = opt.get())
- {
- if (std::abs(*res) < INFINITY)
- {
- return Value::number(*res);
- }
- else
- {
- add_error(Strings::format("Floating point constant too big: %s", number_to_parse));
- }
- }
- else
- {
- add_error(Strings::format("Invalid floating point constant: %s", number_to_parse));
- }
- }
- else
- {
- auto opt = Strings::strto<int64_t>(number_to_parse);
- if (auto res = opt.get())
- {
- return Value::integer(*res);
- }
- else
- {
- add_error(Strings::format("Invalid integer constant: %s", number_to_parse));
- }
- }
-
- return Value();
- }
-
- Value parse_keyword() noexcept
- {
- char32_t current = cur();
- const char32_t* rest;
- Value val;
- switch (current)
- {
- case 't': // parse true
- rest = U"rue";
- val = Value::boolean(true);
- break;
- case 'f': // parse false
- rest = U"alse";
- val = Value::boolean(false);
- break;
- case 'n': // parse null
- rest = U"ull";
- val = Value::null(nullptr);
- break;
- default: vcpkg::Checks::unreachable(VCPKG_LINE_INFO);
- }
-
- for (const char32_t* rest_it = rest; *rest_it != '\0'; ++rest_it)
- {
- current = next();
-
- if (current == Unicode::end_of_file)
- {
- add_error("Unexpected EOF in middle of keyword");
- return Value();
- }
- if (current != *rest_it)
- {
- add_error("Unexpected character in middle of keyword");
- }
- }
- next();
-
- return val;
- }
-
- Value parse_array() noexcept
- {
- Checks::check_exit(VCPKG_LINE_INFO, cur() == '[');
- next();
-
- Array arr;
- bool first = true;
- for (;;)
- {
- skip_whitespace();
-
- char32_t current = cur();
- if (current == Unicode::end_of_file)
- {
- add_error("Unexpected EOF in middle of array");
- return Value();
- }
- if (current == ']')
- {
- next();
- return Value::array(std::move(arr));
- }
-
- if (first)
- {
- first = false;
- }
- else if (current == ',')
- {
- auto comma_loc = cur_loc();
- next();
- skip_whitespace();
- current = cur();
- if (current == Unicode::end_of_file)
- {
- add_error("Unexpected EOF in middle of array");
- return Value();
- }
- if (current == ']')
- {
- add_error("Trailing comma in array", comma_loc);
- return Value::array(std::move(arr));
- }
- }
- else
- {
- add_error("Unexpected character in middle of array");
- return Value();
- }
-
- arr.push_back(parse_value());
- }
- }
-
- std::pair<std::string, Value> parse_kv_pair() noexcept
- {
- skip_whitespace();
-
- auto current = cur();
-
- std::pair<std::string, Value> res = {std::string(""), Value()};
-
- if (current == Unicode::end_of_file)
- {
- add_error("Unexpected EOF; expected property name");
- return res;
- }
- if (current != '"')
- {
- add_error("Unexpected character; expected property name");
- return res;
- }
- res.first = parse_string();
-
- skip_whitespace();
- current = cur();
- if (current == ':')
- {
- next();
- }
- else if (current == Unicode::end_of_file)
- {
- add_error("Unexpected EOF; expected colon");
- return res;
- }
- else
- {
- add_error("Unexpected character; expected colon");
- return res;
- }
-
- res.second = parse_value();
-
- return res;
- }
-
- Value parse_object() noexcept
- {
- char32_t current = cur();
-
- Checks::check_exit(VCPKG_LINE_INFO, current == '{');
- next();
-
- Object obj;
- bool first = true;
- for (;;)
- {
- skip_whitespace();
- current = cur();
- if (current == Unicode::end_of_file)
- {
- add_error("Unexpected EOF; expected property or close brace");
- return Value();
- }
- else if (current == '}')
- {
- next();
- return Value::object(std::move(obj));
- }
-
- if (first)
- {
- first = false;
- }
- else if (current == ',')
- {
- auto comma_loc = cur_loc();
- next();
- skip_whitespace();
- current = cur();
- if (current == Unicode::end_of_file)
- {
- add_error("Unexpected EOF; expected property");
- return Value();
- }
- else if (current == '}')
- {
- add_error("Trailing comma in an object", comma_loc);
- return Value();
- }
- }
- else
- {
- add_error("Unexpected character; expected comma or close brace");
- }
-
- auto val = parse_kv_pair();
- obj.insert(std::move(val.first), std::move(val.second));
- }
- }
-
- Value parse_value() noexcept
- {
- skip_whitespace();
- char32_t current = cur();
- if (current == Unicode::end_of_file)
- {
- add_error("Unexpected EOF; expected value");
- return Value();
- }
-
- switch (current)
- {
- case '{': return parse_object();
- case '[': return parse_array();
- case '"': return Value::string(parse_string());
- case 'n':
- case 't':
- case 'f': return parse_keyword();
- default:
- if (is_number_start(current))
- {
- return parse_number();
- }
- else
- {
- add_error("Unexpected character; expected value");
- return Value();
- }
- }
- }
-
- static ExpectedT<std::pair<Value, JsonStyle>, std::unique_ptr<Parse::IParseError>> parse(
- StringView json, StringView origin) noexcept
- {
- auto parser = Parser(json, origin);
-
- auto val = parser.parse_value();
-
- parser.skip_whitespace();
- if (!parser.at_eof())
- {
- parser.add_error("Unexpected character; expected EOF");
- return std::move(parser).extract_error();
- }
- else if (parser.get_error())
- {
- return std::move(parser).extract_error();
- }
- else
- {
- return std::make_pair(std::move(val), parser.style());
- }
- }
-
- JsonStyle style() const noexcept { return style_; }
-
- private:
- JsonStyle style_;
- };
- }
-
- NaturalNumberDeserializer NaturalNumberDeserializer::instance;
- BooleanDeserializer BooleanDeserializer::instance;
- ParagraphDeserializer ParagraphDeserializer::instance;
- IdentifierDeserializer IdentifierDeserializer::instance;
- IdentifierArrayDeserializer IdentifierArrayDeserializer::instance;
- PackageNameDeserializer PackageNameDeserializer::instance;
- PathDeserializer PathDeserializer::instance;
-
- bool IdentifierDeserializer::is_ident(StringView sv)
- {
- static const std::regex BASIC_IDENTIFIER = std::regex(R"([a-z0-9]+(-[a-z0-9]+)*)");
-
- // we only check for lowercase in RESERVED since we already remove all
- // strings with uppercase letters from the basic check
- static const std::regex RESERVED = std::regex(R"(prn|aux|nul|con|(lpt|com)[1-9]|core|default)");
-
- // back-compat
- if (sv == "all_modules")
- {
- return true;
- }
-
- if (!std::regex_match(sv.begin(), sv.end(), BASIC_IDENTIFIER))
- {
- return false; // we're not even in the shape of an identifier
- }
-
- if (std::regex_match(sv.begin(), sv.end(), RESERVED))
- {
- return false; // we're a reserved identifier
- }
-
- return true;
- }
-
- ExpectedT<std::pair<Value, JsonStyle>, std::unique_ptr<Parse::IParseError>> parse_file(const Files::Filesystem& fs,
- const fs::path& path,
- std::error_code& ec) noexcept
- {
- auto res = fs.read_contents(path);
- if (auto buf = res.get())
- {
- return parse(*buf, path);
- }
- else
- {
- ec = res.error();
- return std::unique_ptr<Parse::IParseError>();
- }
- }
-
- std::pair<Value, JsonStyle> parse_file(vcpkg::LineInfo linfo,
- const Files::Filesystem& fs,
- const fs::path& path) noexcept
- {
- std::error_code ec;
- auto ret = parse_file(fs, path, ec);
- if (ec)
- {
- System::print2(System::Color::error, "Failed to read ", fs::u8string(path), ": ", ec.message(), "\n");
- Checks::exit_fail(linfo);
- }
- else if (!ret)
- {
- System::print2(System::Color::error, "Failed to parse ", fs::u8string(path), ":\n");
- System::print2(ret.error()->format());
- Checks::exit_fail(linfo);
- }
- return ret.value_or_exit(linfo);
- }
-
- ExpectedT<std::pair<Value, JsonStyle>, std::unique_ptr<Parse::IParseError>> parse(StringView json,
- const fs::path& filepath) noexcept
- {
- return Parser::parse(json, fs::u8string(filepath));
- }
- ExpectedT<std::pair<Value, JsonStyle>, std::unique_ptr<Parse::IParseError>> parse(StringView json,
- StringView origin) noexcept
- {
- return Parser::parse(json, origin);
- }
- // } auto parse()
-
- namespace
- {
- struct Stringifier
- {
- JsonStyle style;
- std::string& buffer;
-
- void append_indent(int indent)
- {
- if (style.use_tabs())
- {
- buffer.append(indent, '\t');
- }
- else
- {
- buffer.append(indent * style.spaces(), ' ');
- }
- };
-
- void append_unicode_escape(char16_t code_unit)
- {
- buffer.append("\\u");
-
- // AFAIK, there's no standard way of doing this?
- constexpr const char hex_digit[16] = {
- '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
-
- buffer.push_back(hex_digit[(code_unit >> 12) & 0x0F]);
- buffer.push_back(hex_digit[(code_unit >> 8) & 0x0F]);
- buffer.push_back(hex_digit[(code_unit >> 4) & 0x0F]);
- buffer.push_back(hex_digit[(code_unit >> 0) & 0x0F]);
- }
-
- // taken from the ECMAScript 2020 standard, 24.5.2.2: Runtime Semantics: QuoteJSONString
- void append_quoted_json_string(StringView sv)
- {
- // Table 66: JSON Single Character Escape Sequences
- constexpr static std::array<std::pair<char32_t, const char*>, 7> escape_sequences = {{
- {0x0008, R"(\b)"}, // BACKSPACE
- {0x0009, R"(\t)"}, // CHARACTER TABULATION
- {0x000A, R"(\n)"}, // LINE FEED (LF)
- {0x000C, R"(\f)"}, // FORM FEED (FF)
- {0x000D, R"(\r)"}, // CARRIAGE RETURN (CR)
- {0x0022, R"(\")"}, // QUOTATION MARK
- {0x005C, R"(\\)"} // REVERSE SOLIDUS
- }};
- // 1. Let product be the String value consisting solely of the code unit 0x0022 (QUOTATION MARK).
- buffer.push_back('"');
-
- // 2. For each code point C in ! UTF16DecodeString(value), do
- // (note that we use utf8 instead of utf16)
- for (auto code_point : Unicode::Utf8Decoder(sv.begin(), sv.end()))
- {
- // a. If C is listed in the "Code Point" column of Table 66, then
- const auto match = std::find_if(begin(escape_sequences),
- end(escape_sequences),
- [code_point](const std::pair<char32_t, const char*>& attempt) {
- return attempt.first == code_point;
- });
- // i. Set product to the string-concatenation of product and the escape sequence for C as
- // specified in the "Escape Sequence" column of the corresponding row.
- if (match != end(escape_sequences))
- {
- buffer.append(match->second);
- continue;
- }
-
- // b. Else if C has a numeric value less than 0x0020 (SPACE), or if C has the same numeric value as
- // a leading surrogate or trailing surrogate, then
- if (code_point < 0x0020 || Unicode::utf16_is_surrogate_code_point(code_point))
- {
- // i. Let unit be the code unit whose numeric value is that of C.
- // ii. Set product to the string-concatenation of product and UnicodeEscape(unit).
- append_unicode_escape(static_cast<char16_t>(code_point));
- break;
- }
-
- // c. Else,
- // i. Set product to the string-concatenation of product and the UTF16Encoding of C.
- // (again, we use utf-8 here instead)
- Unicode::utf8_append_code_point(buffer, code_point);
- }
-
- // 3. Set product to the string-concatenation of product and the code unit 0x0022 (QUOTATION MARK).
- buffer.push_back('"');
- }
-
- void stringify_object(const Object& obj, int current_indent)
- {
- buffer.push_back('{');
- if (obj.size() != 0)
- {
- bool first = true;
-
- for (const auto& el : obj)
- {
- if (!first)
- {
- buffer.push_back(',');
- }
- first = false;
-
- buffer.append(style.newline());
- append_indent(current_indent + 1);
-
- append_quoted_json_string(el.first);
- buffer.append(": ");
- stringify(el.second, current_indent + 1);
- }
- buffer.append(style.newline());
- append_indent(current_indent);
- }
- buffer.push_back('}');
- }
-
- void stringify_array(const Array& arr, int current_indent)
- {
- buffer.push_back('[');
- if (arr.size() == 0)
- {
- buffer.push_back(']');
- }
- else
- {
- bool first = true;
-
- for (const auto& el : arr)
- {
- if (!first)
- {
- buffer.push_back(',');
- }
- first = false;
-
- buffer.append(style.newline());
- append_indent(current_indent + 1);
-
- stringify(el, current_indent + 1);
- }
- buffer.append(style.newline());
- append_indent(current_indent);
- buffer.push_back(']');
- }
- }
-
- void stringify(const Value& value, int current_indent)
- {
- switch (value.kind())
- {
- case VK::Null: buffer.append("null"); break;
- case VK::Boolean:
- {
- auto v = value.boolean();
- buffer.append(v ? "true" : "false");
- break;
- }
- // TODO: switch to `to_chars` once we are able to remove support for old compilers
- case VK::Integer: buffer.append(std::to_string(value.integer())); break;
- case VK::Number: buffer.append(std::to_string(value.number())); break;
- case VK::String:
- {
- append_quoted_json_string(value.string());
- break;
- }
- case VK::Array:
- {
- stringify_array(value.array(), current_indent);
- break;
- }
- case VK::Object:
- {
- stringify_object(value.object(), current_indent);
- break;
- }
- }
- }
- };
- }
-
- std::string stringify(const Value& value, JsonStyle style)
- {
- std::string res;
- Stringifier{style, res}.stringify(value, 0);
- res.push_back('\n');
- return res;
- }
- std::string stringify(const Object& obj, JsonStyle style)
- {
- std::string res;
- Stringifier{style, res}.stringify_object(obj, 0);
- res.push_back('\n');
- return res;
- }
- std::string stringify(const Array& arr, JsonStyle style)
- {
- std::string res;
- Stringifier{style, res}.stringify_array(arr, 0);
- res.push_back('\n');
- return res;
- }
- // } auto stringify()
-
- static std::vector<std::string> invalid_json_fields(const Json::Object& obj,
- Span<const StringView> known_fields) noexcept
- {
- const auto field_is_unknown = [known_fields](StringView sv) {
- // allow directives
- if (sv.size() != 0 && *sv.begin() == '$')
- {
- return false;
- }
- return std::find(known_fields.begin(), known_fields.end(), sv) == known_fields.end();
- };
-
- std::vector<std::string> res;
- for (const auto& kv : obj)
- {
- if (field_is_unknown(kv.first))
- {
- res.push_back(kv.first.to_string());
- }
- }
-
- return res;
- }
-
- void Reader::add_missing_field_error(StringView type, StringView key, StringView key_type)
- {
- add_generic_error(type, "missing required field '", key, "' (", key_type, ")");
- }
- void Reader::add_expected_type_error(StringView expected_type)
- {
- m_errors.push_back(Strings::concat(path(), ": mismatched type: expected ", expected_type));
- }
- void Reader::add_extra_field_error(StringView type, StringView field, StringView suggestion)
- {
- if (suggestion.size() > 0)
- {
- add_generic_error(type, "unexpected field '", field, "\', did you mean \'", suggestion, "\'?");
- }
- else
- {
- add_generic_error(type, "unexpected field '", field, '\'');
- }
- }
-
- void Reader::check_for_unexpected_fields(const Object& obj, View<StringView> valid_fields, StringView type_name)
- {
- if (valid_fields.size() == 0)
- {
- return;
- }
-
- auto extra_fields = invalid_json_fields(obj, valid_fields);
- for (auto&& f : extra_fields)
- {
- auto best_it = valid_fields.begin();
- auto best_value = Strings::byte_edit_distance(f, *best_it);
- for (auto i = best_it + 1; i != valid_fields.end(); ++i)
- {
- auto v = Strings::byte_edit_distance(f, *i);
- if (v < best_value)
- {
- best_value = v;
- best_it = i;
- }
- }
- add_extra_field_error(type_name.to_string(), f, *best_it);
- }
- }
-
- std::string Reader::path() const noexcept
- {
- std::string p("$");
- for (auto&& s : m_path)
- {
- if (s.index < 0)
- Strings::append(p, '.', s.field);
- else
- Strings::append(p, '[', s.index, ']');
- }
- return p;
- }
-
- Optional<std::vector<std::string>> ParagraphDeserializer::visit_string(Reader&, StringView sv)
- {
- std::vector<std::string> out;
- out.push_back(sv.to_string());
- return out;
- }
-
- Optional<std::vector<std::string>> ParagraphDeserializer::visit_array(Reader& r, const Array& arr)
- {
- static StringDeserializer d{"a string"};
- return r.array_elements(arr, d);
- }
-
- Optional<std::string> IdentifierDeserializer::visit_string(Json::Reader& r, StringView sv)
- {
- if (!is_ident(sv))
- {
- r.add_generic_error(type_name(), "must be lowercase alphanumeric+hyphens and not reserved");
- }
- return sv.to_string();
- }
-
- Optional<std::vector<std::string>> IdentifierArrayDeserializer::visit_array(Reader& r, const Array& arr)
- {
- return r.array_elements(arr, IdentifierDeserializer::instance);
- }
-
- bool PackageNameDeserializer::is_package_name(StringView sv)
- {
- if (sv.size() == 0)
- {
- return false;
- }
-
- for (const auto& ident : Strings::split(sv, '.'))
- {
- if (!IdentifierDeserializer::is_ident(ident))
- {
- return false;
- }
- }
-
- return true;
- }
-
- Optional<std::string> PackageNameDeserializer::visit_string(Json::Reader&, StringView sv)
- {
- if (!is_package_name(sv))
- {
- return nullopt;
- }
- return sv.to_string();
- }
-}
diff --git a/toolsrc/src/vcpkg/base/machinetype.cpp b/toolsrc/src/vcpkg/base/machinetype.cpp
deleted file mode 100644
index 9b34d4b18..000000000
--- a/toolsrc/src/vcpkg/base/machinetype.cpp
+++ /dev/null
@@ -1,39 +0,0 @@
-#include <vcpkg/base/checks.h>
-#include <vcpkg/base/machinetype.h>
-
-namespace vcpkg
-{
- MachineType to_machine_type(const uint16_t value)
- {
- const MachineType t = static_cast<MachineType>(value);
- switch (t)
- {
- case MachineType::UNKNOWN:
- case MachineType::AM33:
- case MachineType::AMD64:
- case MachineType::ARM:
- case MachineType::ARM64:
- case MachineType::ARMNT:
- case MachineType::EBC:
- case MachineType::I386:
- case MachineType::IA64:
- case MachineType::M32R:
- case MachineType::MIPS16:
- case MachineType::MIPSFPU:
- case MachineType::MIPSFPU16:
- case MachineType::POWERPC:
- case MachineType::POWERPCFP:
- case MachineType::R4000:
- case MachineType::RISCV32:
- case MachineType::RISCV64:
- case MachineType::RISCV128:
- case MachineType::SH3:
- case MachineType::SH3DSP:
- case MachineType::SH4:
- case MachineType::SH5:
- case MachineType::THUMB:
- case MachineType::WCEMIPSV2: return t;
- default: Checks::exit_maybe_upgrade(VCPKG_LINE_INFO, "Unknown machine type code 0x%hx", value);
- }
- }
-}
diff --git a/toolsrc/src/vcpkg/base/parse.cpp b/toolsrc/src/vcpkg/base/parse.cpp
deleted file mode 100644
index fb1b4c3bf..000000000
--- a/toolsrc/src/vcpkg/base/parse.cpp
+++ /dev/null
@@ -1,110 +0,0 @@
-#include <vcpkg/base/parse.h>
-#include <vcpkg/base/system.print.h>
-#include <vcpkg/base/util.h>
-
-#include <utility>
-
-using namespace vcpkg;
-
-namespace vcpkg::Parse
-{
- static void advance_rowcol(char32_t ch, int& row, int& column)
- {
- if (ch == '\t')
- column = (column + 7) / 8 * 8 + 1; // round to next 8-width tab stop
- else if (ch == '\n')
- {
- row++;
- column = 1;
- }
- else
- {
- ++column;
- }
- }
-
- std::string ParseError::format() const
- {
- auto caret_spacing = std::string(18, ' ');
- auto decoder = Unicode::Utf8Decoder(line.data(), line.data() + line.size());
- for (int i = 0; i < caret_col; ++i, ++decoder)
- {
- const char32_t cp = *decoder;
- // this may eventually want to check for full-width characters and grapheme clusters as well
- caret_spacing.push_back(cp == '\t' ? '\t' : ' ');
- }
-
- return Strings::concat(origin,
- ":",
- row,
- ":",
- column,
- ": error: ",
- message,
- "\n"
- " on expression: ", // 18 columns
- line,
- "\n",
- caret_spacing,
- "^\n");
- }
-
- const std::string& ParseError::get_message() const { return this->message; }
-
- ParserBase::ParserBase(StringView text, StringView origin, TextRowCol init_rowcol)
- : m_it(text.begin(), text.end())
- , m_start_of_line(m_it)
- , m_row(init_rowcol.row_or(1))
- , m_column(init_rowcol.column_or(1))
- , m_text(text)
- , m_origin(origin)
- {
- }
-
- char32_t ParserBase::next()
- {
- if (m_it == m_it.end())
- {
- return Unicode::end_of_file;
- }
- auto ch = *m_it;
- // See https://www.gnu.org/prep/standards/standards.html#Errors
- advance_rowcol(ch, m_row, m_column);
-
- ++m_it;
- if (ch == '\n')
- {
- m_start_of_line = m_it;
- }
- if (m_it != m_it.end() && Unicode::utf16_is_surrogate_code_point(*m_it))
- {
- m_it = m_it.end();
- }
-
- return cur();
- }
-
- void ParserBase::add_error(std::string message, const SourceLoc& loc)
- {
- // avoid cascading errors by only saving the first
- if (!m_err)
- {
- // find end of line
- auto line_end = loc.it;
- while (line_end != line_end.end() && *line_end != '\n' && *line_end != '\r')
- {
- ++line_end;
- }
- m_err = std::make_unique<ParseError>(
- m_origin.to_string(),
- loc.row,
- loc.column,
- static_cast<int>(std::distance(loc.start_of_line, loc.it)),
- std::string(loc.start_of_line.pointer_to_current(), line_end.pointer_to_current()),
- std::move(message));
- }
-
- // Avoid error loops by skipping to the end
- skip_to_eof();
- }
-}
diff --git a/toolsrc/src/vcpkg/base/strings.cpp b/toolsrc/src/vcpkg/base/strings.cpp
deleted file mode 100644
index 89b3b46de..000000000
--- a/toolsrc/src/vcpkg/base/strings.cpp
+++ /dev/null
@@ -1,381 +0,0 @@
-#include <vcpkg/base/checks.h>
-#include <vcpkg/base/strings.h>
-#include <vcpkg/base/util.h>
-
-#include <locale.h>
-#include <stdarg.h>
-#include <stdio.h>
-
-#include <algorithm>
-#include <locale>
-#include <string>
-#include <vector>
-
-namespace vcpkg::Strings::details
-{
- // To disambiguate between two overloads
- static bool is_space(const char c) { return std::isspace(static_cast<unsigned char>(c)) != 0; }
-
- // Avoids C4244 warnings because of char<->int conversion that occur when using std::tolower()
- static char toupper_char(const char c) { return (c < 'a' || c > 'z') ? c : c - 'a' + 'A'; }
-
- static bool icase_eq(char a, char b) { return tolower_char{}(a) == tolower_char{}(b); }
-
-#if defined(_WIN32)
- static _locale_t& c_locale()
- {
- static _locale_t c_locale_impl = _create_locale(LC_ALL, "C");
- return c_locale_impl;
- }
-#endif
-
- std::string format_internal(const char* fmtstr, ...)
- {
- va_list args;
- va_start(args, fmtstr);
-
-#if defined(_WIN32)
- const int sz = _vscprintf_l(fmtstr, c_locale(), args);
-#else
- const int sz = vsnprintf(nullptr, 0, fmtstr, args);
-#endif
- Checks::check_exit(VCPKG_LINE_INFO, sz > 0);
-
- std::string output(sz, '\0');
-
-#if defined(_WIN32)
- _vsnprintf_s_l(&output.at(0), output.size() + 1, output.size(), fmtstr, c_locale(), args);
-#else
- va_start(args, fmtstr);
- vsnprintf(&output.at(0), output.size() + 1, fmtstr, args);
-#endif
- va_end(args);
-
- return output;
- }
-}
-
-using namespace vcpkg;
-
-#if defined(_WIN32)
-std::wstring Strings::to_utf16(StringView s)
-{
- std::wstring output;
- if (s.size() == 0) return output;
- Checks::check_exit(VCPKG_LINE_INFO, s.size() < size_t(INT_MAX));
- int size = MultiByteToWideChar(CP_UTF8, 0, s.data(), static_cast<int>(s.size()), nullptr, 0);
- output.resize(static_cast<size_t>(size));
- MultiByteToWideChar(CP_UTF8, 0, s.data(), static_cast<int>(s.size()), output.data(), size);
- return output;
-}
-#endif
-
-#if defined(_WIN32)
-std::string Strings::to_utf8(const wchar_t* w)
-{
- std::string output;
- const size_t size = WideCharToMultiByte(CP_UTF8, 0, w, -1, nullptr, 0, nullptr, nullptr);
- if (size == 0) return output;
- output.resize(size - 1);
- WideCharToMultiByte(CP_UTF8, 0, w, -1, output.data(), static_cast<int>(size) - 1, nullptr, nullptr);
- return output;
-}
-#endif
-
-std::string Strings::escape_string(std::string&& s, char char_to_escape, char escape_char)
-{
- // Replace '\' with '\\' or '`' with '``'
- auto ret = Strings::replace_all(std::move(s), {&escape_char, 1}, std::string{escape_char, escape_char});
- // Replace '"' with '\"' or '`"'
- ret = Strings::replace_all(std::move(ret), {&char_to_escape, 1}, std::string{escape_char, char_to_escape});
- return ret;
-}
-
-static const char* case_insensitive_ascii_find(StringView s, StringView pattern)
-{
- return std::search(s.begin(), s.end(), pattern.begin(), pattern.end(), &Strings::details::icase_eq);
-}
-
-bool Strings::case_insensitive_ascii_contains(StringView s, StringView pattern)
-{
- return case_insensitive_ascii_find(s, pattern) != s.end();
-}
-
-bool Strings::case_insensitive_ascii_equals(StringView left, StringView right)
-{
- return std::equal(left.begin(), left.end(), right.begin(), right.end(), &details::icase_eq);
-}
-
-std::string Strings::ascii_to_lowercase(std::string&& s)
-{
- Strings::ascii_to_lowercase(s.begin(), s.end());
- return std::move(s);
-}
-
-std::string Strings::ascii_to_uppercase(std::string&& s)
-{
- std::transform(s.begin(), s.end(), s.begin(), &details::toupper_char);
- return std::move(s);
-}
-
-bool Strings::case_insensitive_ascii_starts_with(StringView s, StringView pattern)
-{
- if (s.size() < pattern.size()) return false;
- return std::equal(s.begin(), s.begin() + pattern.size(), pattern.begin(), pattern.end(), &details::icase_eq);
-}
-
-bool Strings::ends_with(StringView s, StringView pattern)
-{
- if (s.size() < pattern.size()) return false;
- return std::equal(s.end() - pattern.size(), s.end(), pattern.begin(), pattern.end());
-}
-bool Strings::starts_with(StringView s, StringView pattern)
-{
- if (s.size() < pattern.size()) return false;
- return std::equal(s.begin(), s.begin() + pattern.size(), pattern.begin(), pattern.end());
-}
-
-std::string Strings::replace_all(std::string&& s, StringView search, StringView rep)
-{
- inplace_replace_all(s, search, rep);
- return std::move(s);
-}
-
-void Strings::inplace_replace_all(std::string& s, StringView search, StringView rep)
-{
- if (search.empty())
- {
- return;
- }
-
- size_t pos = 0;
- while ((pos = s.find(search.data(), pos, search.size())) != std::string::npos)
- {
- s.replace(pos, search.size(), rep.data(), rep.size());
- pos += rep.size();
- }
-}
-
-void Strings::inplace_replace_all(std::string& s, char search, char rep) noexcept
-{
- std::replace(s.begin(), s.end(), search, rep);
-}
-
-std::string Strings::trim(std::string&& s)
-{
- s.erase(std::find_if_not(s.rbegin(), s.rend(), details::is_space).base(), s.end());
- s.erase(s.begin(), std::find_if_not(s.begin(), s.end(), details::is_space));
- return std::move(s);
-}
-
-StringView Strings::trim(StringView sv)
-{
- auto last = std::find_if_not(sv.rbegin(), sv.rend(), details::is_space).base();
- auto first = std::find_if_not(sv.begin(), sv.end(), details::is_space);
- return StringView(first, last);
-}
-
-void Strings::trim_all_and_remove_whitespace_strings(std::vector<std::string>* strings)
-{
- for (std::string& s : *strings)
- {
- s = trim(std::move(s));
- }
-
- Util::erase_remove_if(*strings, [](const std::string& s) { return s.empty(); });
-}
-
-std::vector<std::string> Strings::split(StringView s, const char delimiter)
-{
- std::vector<std::string> output;
- auto first = s.begin();
- const auto last = s.end();
- for (;;)
- {
- first = std::find_if(first, last, [=](const char c) { return c != delimiter; });
- if (first == last)
- {
- return output;
- }
-
- auto next = std::find(first, last, delimiter);
- output.emplace_back(first, next);
- first = next;
- }
-}
-
-std::vector<std::string> Strings::split_paths(StringView s)
-{
-#if defined(_WIN32)
- return Strings::split(s, ';');
-#else // ^^^ defined(_WIN32) // !defined(_WIN32) vvv
- return Strings::split(s, ':');
-#endif
-}
-
-const char* Strings::find_first_of(StringView input, StringView chars)
-{
- return std::find_first_of(input.begin(), input.end(), chars.begin(), chars.end());
-}
-
-std::vector<StringView> Strings::find_all_enclosed(StringView input, StringView left_delim, StringView right_delim)
-{
- auto it_left = input.begin();
- auto it_right = input.begin();
-
- std::vector<StringView> output;
-
- for (;;)
- {
- it_left = std::search(it_right, input.end(), left_delim.begin(), left_delim.end());
- if (it_left == input.end()) break;
-
- it_left += left_delim.size();
-
- it_right = std::search(it_left, input.end(), right_delim.begin(), right_delim.end());
- if (it_right == input.end()) break;
-
- output.emplace_back(it_left, it_right);
-
- ++it_right;
- }
-
- return output;
-}
-
-StringView Strings::find_exactly_one_enclosed(StringView input, StringView left_tag, StringView right_tag)
-{
- std::vector<StringView> result = find_all_enclosed(input, left_tag, right_tag);
- Checks::check_maybe_upgrade(VCPKG_LINE_INFO,
- result.size() == 1,
- "Found %d sets of %s.*%s but expected exactly 1, in block:\n%s",
- result.size(),
- left_tag,
- right_tag,
- input);
- return result.front();
-}
-
-Optional<StringView> Strings::find_at_most_one_enclosed(StringView input, StringView left_tag, StringView right_tag)
-{
- std::vector<StringView> result = find_all_enclosed(input, left_tag, right_tag);
- Checks::check_maybe_upgrade(VCPKG_LINE_INFO,
- result.size() <= 1,
- "Found %d sets of %s.*%s but expected at most 1, in block:\n%s",
- result.size(),
- left_tag,
- right_tag,
- input);
-
- if (result.empty())
- {
- return nullopt;
- }
-
- return result.front();
-}
-
-bool Strings::equals(StringView a, StringView b)
-{
- if (a.size() != b.size()) return false;
- return std::equal(a.begin(), a.end(), b.begin(), b.end());
-}
-
-const char* Strings::search(StringView haystack, StringView needle)
-{
- return std::search(haystack.begin(), haystack.end(), needle.begin(), needle.end());
-}
-
-bool Strings::contains(StringView haystack, StringView needle)
-{
- return Strings::search(haystack, needle) != haystack.end();
-}
-
-size_t Strings::byte_edit_distance(StringView a, StringView b)
-{
- static constexpr size_t max_string_size = 100;
- // For large strings, give up early to avoid performance problems
- if (a.size() > max_string_size || b.size() > max_string_size)
- {
- if (a == b)
- return 0;
- else
- return std::max(a.size(), b.size());
- }
- if (a.size() == 0 || b.size() == 0) return std::max(a.size(), b.size());
-
- auto pa = a.data();
- auto pb = b.data();
- size_t sa = a.size();
- size_t sb = b.size();
-
- // Levenshtein distance (https://en.wikipedia.org/wiki/Levenshtein_distance)
- // The first row of the edit distance matrix has been omitted because it's trivial (counting from 0)
- // Because each subsequent row only depends on the row above, we never need to store the entire matrix
- char d[max_string_size];
-
- // Useful invariants:
- // `sa` is sizeof `pa` using iterator `ia`
- // `sb` is sizeof `pb` using iterator `ib`
- // `sa` and `sb` are in (0, `max_string_size`]
-
- // To avoid dealing with edge effects, `ia` == 0 and `ib` == 0 have been unrolled.
- // Comparisons are used as the cost for the diagonal action (substitute/leave unchanged)
- d[0] = pa[0] != pb[0];
- for (size_t ia = 1; ia < sa; ++ia)
- d[ia] = std::min<char>(d[ia - 1] + 1, static_cast<char>(ia + (pa[ia] != pb[0])));
-
- for (size_t ib = 1; ib < sb; ++ib)
- {
- // The diagonal information (d[ib-1][ia-1]) is used to compute substitution cost and so must be preserved
- char diag = d[0];
- d[0] = std::min<char>(d[0] + 1, static_cast<char>(ib + (pa[0] != pb[ib])));
- for (size_t ia = 1; ia < sa; ++ia)
- {
- auto subst_or_add = std::min<char>(d[ia - 1] + 1, static_cast<char>(diag + (pa[ia] != pb[ib])));
- diag = d[ia];
- d[ia] = std::min<char>(d[ia] + 1, subst_or_add);
- }
- }
- return d[sa - 1];
-}
-
-namespace vcpkg::Strings
-{
- namespace
- {
- template<class Integral>
- std::string b32_encode_implementation(Integral x)
- {
- static_assert(std::is_integral<Integral>::value, "b64url_encode must take an integer type");
- using Unsigned = std::make_unsigned_t<Integral>;
- auto value = static_cast<Unsigned>(x);
-
- // 32 values, plus the implicit \0
- constexpr static char map[33] = "ABCDEFGHIJKLMNOP"
- "QRSTUVWXYZ234567";
-
- // log2(32)
- constexpr static int shift = 5;
- // 32 - 1
- constexpr static auto mask = 31;
-
- // ceiling(bitsize(Integral) / log2(32))
- constexpr static auto result_size = (sizeof(value) * 8 + shift - 1) / shift;
-
- std::string result;
- result.reserve(result_size);
-
- for (std::size_t i = 0; i < result_size; ++i)
- {
- result.push_back(map[value & mask]);
- value >>= shift;
- }
-
- return result;
- }
- }
-
- std::string b32_encode(std::uint64_t x) noexcept { return b32_encode_implementation(x); }
-
-}
diff --git a/toolsrc/src/vcpkg/base/stringview.cpp b/toolsrc/src/vcpkg/base/stringview.cpp
deleted file mode 100644
index fd7f787a1..000000000
--- a/toolsrc/src/vcpkg/base/stringview.cpp
+++ /dev/null
@@ -1,45 +0,0 @@
-#include <vcpkg/base/checks.h>
-#include <vcpkg/base/lineinfo.h>
-#include <vcpkg/base/stringview.h>
-
-#include <algorithm>
-#include <cstring>
-
-namespace vcpkg
-{
- StringView::StringView(const std::string& s) noexcept : m_ptr(s.data()), m_size(s.size()) { }
-
- std::string StringView::to_string() const { return std::string(m_ptr, m_size); }
- void StringView::to_string(std::string& s) const { s.append(m_ptr, m_size); }
-
- StringView StringView::substr(size_t pos, size_t count) const noexcept
- {
- if (pos > m_size)
- {
- return StringView();
- }
-
- if (count > m_size - pos)
- {
- return StringView(m_ptr + pos, m_size - pos);
- }
-
- return StringView(m_ptr + pos, count);
- }
-
- bool operator==(StringView lhs, StringView rhs) noexcept
- {
- return lhs.size() == rhs.size() && memcmp(lhs.data(), rhs.data(), lhs.size()) == 0;
- }
-
- bool operator!=(StringView lhs, StringView rhs) noexcept { return !(lhs == rhs); }
-
- bool operator<(StringView lhs, StringView rhs) noexcept
- {
- return std::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
- }
-
- bool operator>(StringView lhs, StringView rhs) noexcept { return rhs < lhs; }
- bool operator<=(StringView lhs, StringView rhs) noexcept { return !(rhs < lhs); }
- bool operator>=(StringView lhs, StringView rhs) noexcept { return !(lhs < rhs); }
-}
diff --git a/toolsrc/src/vcpkg/base/system.cpp b/toolsrc/src/vcpkg/base/system.cpp
deleted file mode 100644
index b18a41e6d..000000000
--- a/toolsrc/src/vcpkg/base/system.cpp
+++ /dev/null
@@ -1,343 +0,0 @@
-#include <vcpkg/base/checks.h>
-#include <vcpkg/base/chrono.h>
-#include <vcpkg/base/system.debug.h>
-#include <vcpkg/base/system.h>
-#include <vcpkg/base/util.h>
-
-#include <ctime>
-
-using namespace vcpkg::System;
-
-namespace vcpkg
-{
- long System::get_process_id()
- {
-#ifdef _WIN32
- return ::_getpid();
-#else
- return ::getpid();
-#endif
- }
-
- Optional<CPUArchitecture> System::to_cpu_architecture(StringView arch)
- {
- if (Strings::case_insensitive_ascii_equals(arch, "x86")) return CPUArchitecture::X86;
- if (Strings::case_insensitive_ascii_equals(arch, "x64")) return CPUArchitecture::X64;
- if (Strings::case_insensitive_ascii_equals(arch, "amd64")) return CPUArchitecture::X64;
- if (Strings::case_insensitive_ascii_equals(arch, "arm")) return CPUArchitecture::ARM;
- if (Strings::case_insensitive_ascii_equals(arch, "arm64")) return CPUArchitecture::ARM64;
- if (Strings::case_insensitive_ascii_equals(arch, "s390x")) return CPUArchitecture::S390X;
- if (Strings::case_insensitive_ascii_equals(arch, "ppc64le")) return CPUArchitecture::PPC64LE;
- return nullopt;
- }
-
- ZStringView System::to_zstring_view(CPUArchitecture arch) noexcept
- {
- switch (arch)
- {
- case CPUArchitecture::X86: return "x86";
- case CPUArchitecture::X64: return "x64";
- case CPUArchitecture::ARM: return "arm";
- case CPUArchitecture::ARM64: return "arm64";
- case CPUArchitecture::S390X: return "s390x";
- case CPUArchitecture::PPC64LE: return "ppc64le";
- default: Checks::exit_with_message(VCPKG_LINE_INFO, "unexpected vcpkg::System::CPUArchitecture");
- }
- }
-
- CPUArchitecture System::get_host_processor()
- {
-#if defined(_WIN32)
- auto w6432 = get_environment_variable("PROCESSOR_ARCHITEW6432");
- if (const auto p = w6432.get()) return to_cpu_architecture(*p).value_or_exit(VCPKG_LINE_INFO);
-
- const auto procarch = get_environment_variable("PROCESSOR_ARCHITECTURE").value_or_exit(VCPKG_LINE_INFO);
- return to_cpu_architecture(procarch).value_or_exit(VCPKG_LINE_INFO);
-#else // ^^^ defined(_WIN32) / !defined(_WIN32) vvv
-#if defined(__x86_64__) || defined(_M_X64)
- return CPUArchitecture::X64;
-#elif defined(__x86__) || defined(_M_X86) || defined(__i386__)
- return CPUArchitecture::X86;
-#elif defined(__arm__) || defined(_M_ARM)
- return CPUArchitecture::ARM;
-#elif defined(__aarch64__) || defined(_M_ARM64)
- return CPUArchitecture::ARM64;
-#elif defined(__s390x__)
- return CPUArchitecture::S390X;
-#elif (defined(__ppc64__) || defined(__PPC64__) || defined(__ppc64le__) || defined(__PPC64LE__)) && \
- defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
- return CPUArchitecture::PPC64LE;
-#else // choose architecture
-#error "Unknown host architecture"
-#endif // choose architecture
-#endif // defined(_WIN32)
- }
-
- std::vector<CPUArchitecture> System::get_supported_host_architectures()
- {
- std::vector<CPUArchitecture> supported_architectures;
- supported_architectures.push_back(get_host_processor());
-
- // AMD64 machines support running x86 applications and ARM64 machines support running ARM applications
- if (supported_architectures.back() == CPUArchitecture::X64)
- {
- supported_architectures.push_back(CPUArchitecture::X86);
- }
- else if (supported_architectures.back() == CPUArchitecture::ARM64)
- {
- supported_architectures.push_back(CPUArchitecture::ARM);
- }
-
-#if defined(_WIN32)
- // On ARM32/64 Windows we can rely on x86 emulation
- if (supported_architectures.front() == CPUArchitecture::ARM ||
- supported_architectures.front() == CPUArchitecture::ARM64)
- {
- supported_architectures.push_back(CPUArchitecture::X86);
- }
-#endif // defined(_WIN32)
-
- return supported_architectures;
- }
-
- Optional<std::string> System::get_environment_variable(ZStringView varname) noexcept
- {
-#if defined(_WIN32)
- const auto w_varname = Strings::to_utf16(varname);
- const auto sz = GetEnvironmentVariableW(w_varname.c_str(), nullptr, 0);
- if (sz == 0) return nullopt;
-
- std::wstring ret(sz, L'\0');
-
- Checks::check_exit(VCPKG_LINE_INFO, MAXDWORD >= ret.size());
- const auto sz2 = GetEnvironmentVariableW(w_varname.c_str(), ret.data(), static_cast<DWORD>(ret.size()));
- Checks::check_exit(VCPKG_LINE_INFO, sz2 + 1 == sz);
- ret.pop_back();
- return Strings::to_utf8(ret.c_str());
-#else // ^^^ defined(_WIN32) / !defined(_WIN32) vvv
- auto v = getenv(varname.c_str());
- if (!v) return nullopt;
- return std::string(v);
-#endif // defined(_WIN32)
- }
-
- void System::set_environment_variable(ZStringView varname, Optional<ZStringView> value) noexcept
- {
-#if defined(_WIN32)
- const auto w_varname = Strings::to_utf16(varname);
- const auto w_varcstr = w_varname.c_str();
- BOOL exit_code;
- if (auto v = value.get())
- {
- exit_code = SetEnvironmentVariableW(w_varcstr, Strings::to_utf16(*v).c_str());
- }
- else
- {
- exit_code = SetEnvironmentVariableW(w_varcstr, nullptr);
- }
-
- Checks::check_exit(VCPKG_LINE_INFO, exit_code != 0);
-#else // ^^^ defined(_WIN32) / !defined(_WIN32) vvv
- if (auto v = value.get())
- {
- Checks::check_exit(VCPKG_LINE_INFO, setenv(varname.c_str(), v->c_str(), 1) == 0);
- }
- else
- {
- Checks::check_exit(VCPKG_LINE_INFO, unsetenv(varname.c_str()) == 0);
- }
-#endif // defined(_WIN32)
- }
-
- const ExpectedS<fs::path>& System::get_home_dir() noexcept
- {
- static ExpectedS<fs::path> s_home = []() -> ExpectedS<fs::path> {
-#ifdef _WIN32
-#define HOMEVAR "%USERPROFILE%"
- auto maybe_home = System::get_environment_variable("USERPROFILE");
- if (!maybe_home.has_value() || maybe_home.get()->empty())
- return {"unable to read " HOMEVAR, ExpectedRightTag{}};
-#else
-#define HOMEVAR "$HOME"
- auto maybe_home = System::get_environment_variable("HOME");
- if (!maybe_home.has_value() || maybe_home.get()->empty())
- return {"unable to read " HOMEVAR, ExpectedRightTag{}};
-#endif
-
- auto p = fs::u8path(*maybe_home.get());
- if (!p.is_absolute()) return {HOMEVAR " was not an absolute path", ExpectedRightTag{}};
-
- return {std::move(p), ExpectedLeftTag{}};
- }();
- return s_home;
-#undef HOMEVAR
- }
-
-#ifdef _WIN32
- const ExpectedS<fs::path>& System::get_appdata_local() noexcept
- {
- static ExpectedS<fs::path> s_home = []() -> ExpectedS<fs::path> {
- auto maybe_home = System::get_environment_variable("LOCALAPPDATA");
- if (!maybe_home.has_value() || maybe_home.get()->empty())
- {
- // Consult %APPDATA% as a workaround for Service accounts
- // Microsoft/vcpkg#12285
- maybe_home = System::get_environment_variable("APPDATA");
- if (!maybe_home.has_value() || maybe_home.get()->empty())
- {
- return {"unable to read %LOCALAPPDATA% or %APPDATA%", ExpectedRightTag{}};
- }
-
- auto p = fs::u8path(*maybe_home.get()).parent_path();
- p /= "Local";
- if (!p.is_absolute()) return {"%APPDATA% was not an absolute path", ExpectedRightTag{}};
- return {std::move(p), ExpectedLeftTag{}};
- }
-
- auto p = fs::u8path(*maybe_home.get());
- if (!p.is_absolute()) return {"%LOCALAPPDATA% was not an absolute path", ExpectedRightTag{}};
-
- return {std::move(p), ExpectedLeftTag{}};
- }();
- return s_home;
- }
-#else
- static const ExpectedS<fs::path>& get_xdg_cache_home() noexcept
- {
- static ExpectedS<fs::path> s_home = [] {
- auto maybe_home = System::get_environment_variable("XDG_CACHE_HOME");
- if (auto p = maybe_home.get())
- {
- return ExpectedS<fs::path>(fs::u8path(*p));
- }
- else
- {
- return System::get_home_dir().map([](fs::path home) {
- home /= fs::u8path(".cache");
- return home;
- });
- }
- }();
- return s_home;
- }
-#endif
-
- const ExpectedS<fs::path>& System::get_platform_cache_home() noexcept
- {
-#ifdef _WIN32
- return System::get_appdata_local();
-#else
- return get_xdg_cache_home();
-#endif
- }
-
-#if defined(_WIN32)
- static bool is_string_keytype(const DWORD hkey_type)
- {
- return hkey_type == REG_SZ || hkey_type == REG_MULTI_SZ || hkey_type == REG_EXPAND_SZ;
- }
-
- Optional<std::string> System::get_registry_string(void* base_hkey, StringView sub_key, StringView valuename)
- {
- HKEY k = nullptr;
- const LSTATUS ec =
- RegOpenKeyExW(reinterpret_cast<HKEY>(base_hkey), Strings::to_utf16(sub_key).c_str(), 0, KEY_READ, &k);
- if (ec != ERROR_SUCCESS) return nullopt;
-
- auto w_valuename = Strings::to_utf16(valuename);
-
- DWORD dw_buffer_size = 0;
- DWORD dw_type = 0;
- auto rc = RegQueryValueExW(k, w_valuename.c_str(), nullptr, &dw_type, nullptr, &dw_buffer_size);
- if (rc != ERROR_SUCCESS || !is_string_keytype(dw_type) || dw_buffer_size == 0 ||
- dw_buffer_size % sizeof(wchar_t) != 0)
- return nullopt;
- std::wstring ret;
- ret.resize(dw_buffer_size / sizeof(wchar_t));
-
- rc = RegQueryValueExW(
- k, w_valuename.c_str(), nullptr, &dw_type, reinterpret_cast<LPBYTE>(ret.data()), &dw_buffer_size);
- if (rc != ERROR_SUCCESS || !is_string_keytype(dw_type) || dw_buffer_size != sizeof(wchar_t) * ret.size())
- return nullopt;
-
- ret.pop_back(); // remove extra trailing null byte
- return Strings::to_utf8(ret);
- }
-#else // ^^^ defined(_WIN32) / !defined(_WIN32) vvv
- Optional<std::string> System::get_registry_string(void*, StringView, StringView) { return nullopt; }
-#endif // defined(_WIN32)
-
- static const Optional<fs::path>& get_program_files()
- {
- static const auto PROGRAMFILES = []() -> Optional<fs::path> {
- auto value = System::get_environment_variable("PROGRAMFILES");
- if (auto v = value.get())
- {
- return *v;
- }
-
- return nullopt;
- }();
-
- return PROGRAMFILES;
- }
-
- const Optional<fs::path>& System::get_program_files_32_bit()
- {
- static const auto PROGRAMFILES_x86 = []() -> Optional<fs::path> {
- auto value = System::get_environment_variable("ProgramFiles(x86)");
- if (auto v = value.get())
- {
- return *v;
- }
- return get_program_files();
- }();
- return PROGRAMFILES_x86;
- }
-
- const Optional<fs::path>& System::get_program_files_platform_bitness()
- {
- static const auto ProgramW6432 = []() -> Optional<fs::path> {
- auto value = System::get_environment_variable("ProgramW6432");
- if (auto v = value.get())
- {
- return *v;
- }
- return get_program_files();
- }();
- return ProgramW6432;
- }
-
- int System::get_num_logical_cores() { return std::thread::hardware_concurrency(); }
-
- Optional<CPUArchitecture> System::guess_visual_studio_prompt_target_architecture()
- {
- // Check for the "vsdevcmd" infrastructure used by Visual Studio 2017 and later
- const auto vscmd_arg_tgt_arch_env = System::get_environment_variable("VSCMD_ARG_TGT_ARCH");
- if (vscmd_arg_tgt_arch_env)
- {
- return to_cpu_architecture(vscmd_arg_tgt_arch_env.value_or_exit(VCPKG_LINE_INFO));
- }
-
- // Check for the "vcvarsall" infrastructure used by Visual Studio 2015
- if (System::get_environment_variable("VCINSTALLDIR"))
- {
- const auto Platform = System::get_environment_variable("Platform");
- if (Platform)
- {
- return to_cpu_architecture(Platform.value_or_exit(VCPKG_LINE_INFO));
- }
- else
- {
- return CPUArchitecture::X86;
- }
- }
-
- return nullopt;
- }
-}
-
-namespace vcpkg::Debug
-{
- std::atomic<bool> g_debugging(false);
-}
diff --git a/toolsrc/src/vcpkg/base/system.print.cpp b/toolsrc/src/vcpkg/base/system.print.cpp
deleted file mode 100644
index 458f53155..000000000
--- a/toolsrc/src/vcpkg/base/system.print.cpp
+++ /dev/null
@@ -1,30 +0,0 @@
-#include <vcpkg/base/system.print.h>
-#include <vcpkg/base/util.h>
-
-namespace vcpkg::System
-{
- namespace details
- {
- void print(StringView message) { fwrite(message.data(), 1, message.size(), stdout); }
-
- void print(const Color c, StringView message)
- {
-#if defined(_WIN32)
- const HANDLE console_handle = GetStdHandle(STD_OUTPUT_HANDLE);
-
- CONSOLE_SCREEN_BUFFER_INFO console_screen_buffer_info{};
- GetConsoleScreenBufferInfo(console_handle, &console_screen_buffer_info);
- const auto original_color = console_screen_buffer_info.wAttributes;
-
- SetConsoleTextAttribute(console_handle, static_cast<WORD>(c) | (original_color & 0xF0));
- System::print2(message);
- SetConsoleTextAttribute(console_handle, original_color);
-#else
- // TODO: add color handling code
- // it should probably use VT-220 codes
- (void)c;
- System::print2(message);
-#endif
- }
- }
-}
diff --git a/toolsrc/src/vcpkg/base/system.process.cpp b/toolsrc/src/vcpkg/base/system.process.cpp
deleted file mode 100644
index 22726e42a..000000000
--- a/toolsrc/src/vcpkg/base/system.process.cpp
+++ /dev/null
@@ -1,793 +0,0 @@
-#include <vcpkg/base/checks.h>
-#include <vcpkg/base/chrono.h>
-#include <vcpkg/base/system.debug.h>
-#include <vcpkg/base/system.h>
-#include <vcpkg/base/system.process.h>
-#include <vcpkg/base/util.h>
-
-#include <ctime>
-
-#if defined(__APPLE__)
-#include <mach-o/dyld.h>
-#endif
-
-#if defined(__FreeBSD__)
-#include <sys/sysctl.h>
-#endif
-
-#if defined(_WIN32)
-#pragma comment(lib, "Advapi32")
-#endif
-
-using namespace vcpkg::System;
-
-namespace vcpkg
-{
-#if defined(_WIN32)
- namespace
- {
- struct CtrlCStateMachine
- {
- CtrlCStateMachine() : m_number_of_external_processes(0), m_global_job(NULL), m_in_interactive(0) { }
-
- void transition_to_spawn_process() noexcept
- {
- int cur = 0;
- while (!m_number_of_external_processes.compare_exchange_strong(cur, cur + 1))
- {
- if (cur < 0)
- {
- // Ctrl-C was hit and is asynchronously executing on another thread.
- // Some other processes are outstanding.
- // Sleep forever -- the other process will complete and exit the program
- while (true)
- {
- std::this_thread::sleep_for(std::chrono::seconds(10));
- System::print2("Waiting for child processes to exit...\n");
- }
- }
- }
- }
- void transition_from_spawn_process() noexcept
- {
- auto previous = m_number_of_external_processes.fetch_add(-1);
- if (previous == INT_MIN + 1)
- {
- // Ctrl-C was hit while blocked on the child process
- // This is the last external process to complete
- // Therefore, exit
- Checks::final_cleanup_and_exit(1);
- }
- else if (previous < 0)
- {
- // Ctrl-C was hit while blocked on the child process
- // Some other processes are outstanding.
- // Sleep forever -- the other process will complete and exit the program
- while (true)
- {
- std::this_thread::sleep_for(std::chrono::seconds(10));
- System::print2("Waiting for child processes to exit...\n");
- }
- }
- }
- void transition_handle_ctrl_c() noexcept
- {
- int old_value = 0;
- while (!m_number_of_external_processes.compare_exchange_strong(old_value, old_value + INT_MIN))
- {
- if (old_value < 0)
- {
- // Repeat calls to Ctrl-C -- a previous one succeeded.
- return;
- }
- }
-
- if (old_value == 0)
- {
- // Not currently blocked on a child process
- Checks::final_cleanup_and_exit(1);
- }
- else
- {
- // We are currently blocked on a child process.
- // If none of the child processes are interactive, use the Job Object to terminate the tree.
- if (m_in_interactive.load() == 0)
- {
- auto job = m_global_job.exchange(NULL);
- if (job != NULL)
- {
- ::CloseHandle(job);
- }
- }
- }
- }
-
- void initialize_job()
- {
- m_global_job = CreateJobObjectW(NULL, NULL);
- if (m_global_job != NULL)
- {
- JOBOBJECT_EXTENDED_LIMIT_INFORMATION info = {};
- info.BasicLimitInformation.LimitFlags =
- JOB_OBJECT_LIMIT_BREAKAWAY_OK | JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;
- ::SetInformationJobObject(m_global_job, JobObjectExtendedLimitInformation, &info, sizeof(info));
- ::AssignProcessToJobObject(m_global_job, ::GetCurrentProcess());
- }
- }
-
- void enter_interactive() { ++m_in_interactive; }
- void exit_interactive() { --m_in_interactive; }
-
- private:
- std::atomic<int> m_number_of_external_processes;
- std::atomic<HANDLE> m_global_job;
- std::atomic<int> m_in_interactive;
- };
-
- static CtrlCStateMachine g_ctrl_c_state;
- }
-
- void System::initialize_global_job_object() { g_ctrl_c_state.initialize_job(); }
- void System::enter_interactive_subprocess() { g_ctrl_c_state.enter_interactive(); }
- void System::exit_interactive_subprocess() { g_ctrl_c_state.exit_interactive(); }
-#endif
-
- fs::path System::get_exe_path_of_current_process()
- {
-#if defined(_WIN32)
- wchar_t buf[_MAX_PATH];
- const int bytes = GetModuleFileNameW(nullptr, buf, _MAX_PATH);
- if (bytes == 0) std::abort();
- return fs::path(buf, buf + bytes);
-#elif defined(__APPLE__)
- static constexpr const uint32_t buff_size = 1024 * 32;
- uint32_t size = buff_size;
- char buf[buff_size] = {};
- int result = _NSGetExecutablePath(buf, &size);
- Checks::check_exit(VCPKG_LINE_INFO, result != -1, "Could not determine current executable path.");
- std::unique_ptr<char> canonicalPath(realpath(buf, NULL));
- Checks::check_exit(VCPKG_LINE_INFO, result != -1, "Could not determine current executable path.");
- return fs::path(std::string(canonicalPath.get()));
-#elif defined(__FreeBSD__)
- int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1};
- char exePath[2048];
- size_t len = sizeof(exePath);
- auto rcode = sysctl(mib, 4, exePath, &len, NULL, 0);
- Checks::check_exit(VCPKG_LINE_INFO, rcode == 0, "Could not determine current executable path.");
- Checks::check_exit(VCPKG_LINE_INFO, len > 0, "Could not determine current executable path.");
- return fs::path(exePath, exePath + len - 1);
-#elif defined(__OpenBSD__)
- const char* progname = getprogname();
- char resolved_path[PATH_MAX];
- auto ret = realpath(progname, resolved_path);
- Checks::check_exit(VCPKG_LINE_INFO, ret != nullptr, "Could not determine current executable path.");
- return fs::u8path(resolved_path);
-#else /* LINUX */
- std::array<char, 1024 * 4> buf;
- auto written = readlink("/proc/self/exe", buf.data(), buf.size());
- Checks::check_exit(VCPKG_LINE_INFO, written != -1, "Could not determine current executable path.");
- return fs::path(buf.data(), buf.data() + written);
-#endif
- }
-
- System::CMakeVariable::CMakeVariable(const StringView varname, const char* varvalue)
- : s(Strings::format("-D%s=%s", varname, varvalue))
- {
- }
- System::CMakeVariable::CMakeVariable(const StringView varname, const std::string& varvalue)
- : CMakeVariable(varname, varvalue.c_str())
- {
- }
- System::CMakeVariable::CMakeVariable(const StringView varname, const fs::path& path)
- : CMakeVariable(varname, fs::generic_u8string(path))
- {
- }
- System::CMakeVariable::CMakeVariable(std::string var) : s(std::move(var)) { }
-
- System::Command System::make_basic_cmake_cmd(const fs::path& cmake_tool_path,
- const fs::path& cmake_script,
- const std::vector<CMakeVariable>& pass_variables)
- {
- System::Command cmd{cmake_tool_path};
- for (auto&& var : pass_variables)
- {
- cmd.string_arg(var.s);
- }
- cmd.string_arg("-P").path_arg(cmake_script);
- return cmd;
- }
-
- System::Command& System::Command::string_arg(StringView s) &
- {
- if (!buf.empty()) buf.push_back(' ');
- if (Strings::find_first_of(s, " \t\n\r\"\\,;&`^|'") != s.end())
- {
- // TODO: improve this to properly handle all escaping
-#if _WIN32
- // On Windows, `\`s before a double-quote must be doubled. Inner double-quotes must be escaped.
- buf.push_back('"');
- size_t n_slashes = 0;
- for (auto ch : s)
- {
- if (ch == '\\')
- {
- ++n_slashes;
- }
- else if (ch == '"')
- {
- buf.append(n_slashes + 1, '\\');
- n_slashes = 0;
- }
- else
- {
- n_slashes = 0;
- }
- buf.push_back(ch);
- }
- buf.append(n_slashes, '\\');
- buf.push_back('"');
-#else
- // On non-Windows, `\` is the escape character and always requires doubling. Inner double-quotes must be
- // escaped.
- buf.push_back('"');
- for (auto ch : s)
- {
- if (ch == '\\' || ch == '"') buf.push_back('\\');
- buf.push_back(ch);
- }
- buf.push_back('"');
-#endif
- }
- else
- {
- Strings::append(buf, s);
- }
- return *this;
- }
-
-#if defined(_WIN32)
- Environment System::get_modified_clean_environment(const std::unordered_map<std::string, std::string>& extra_env,
- const std::string& prepend_to_path)
- {
- static const std::string system_root_env =
- get_environment_variable("SystemRoot").value_or_exit(VCPKG_LINE_INFO);
- static const std::string system32_env = system_root_env + R"(\system32)";
- std::string new_path = Strings::format(R"(Path=%s%s;%s;%s\Wbem;%s\WindowsPowerShell\v1.0\)",
- prepend_to_path,
- system32_env,
- system_root_env,
- system32_env,
- system32_env);
-
- std::vector<std::wstring> env_wstrings = {
- L"ALLUSERSPROFILE",
- L"APPDATA",
- L"CommonProgramFiles",
- L"CommonProgramFiles(x86)",
- L"CommonProgramW6432",
- L"COMPUTERNAME",
- L"ComSpec",
- L"HOMEDRIVE",
- L"HOMEPATH",
- L"LOCALAPPDATA",
- L"LOGONSERVER",
- L"NUMBER_OF_PROCESSORS",
- L"OS",
- L"PATHEXT",
- L"PROCESSOR_ARCHITECTURE",
- L"PROCESSOR_ARCHITEW6432",
- L"PROCESSOR_IDENTIFIER",
- L"PROCESSOR_LEVEL",
- L"PROCESSOR_REVISION",
- L"ProgramData",
- L"ProgramFiles",
- L"ProgramFiles(x86)",
- L"ProgramW6432",
- L"PROMPT",
- L"PSModulePath",
- L"PUBLIC",
- L"SystemDrive",
- L"SystemRoot",
- L"TEMP",
- L"TMP",
- L"USERDNSDOMAIN",
- L"USERDOMAIN",
- L"USERDOMAIN_ROAMINGPROFILE",
- L"USERNAME",
- L"USERPROFILE",
- L"windir",
- // Enables proxy information to be passed to Curl, the underlying download library in cmake.exe
- L"http_proxy",
- L"https_proxy",
- // Environment variables to tell git to use custom SSH executable or command
- L"GIT_SSH",
- L"GIT_SSH_COMMAND",
- // Environment variables needed for ssh-agent based authentication
- L"SSH_AUTH_SOCK",
- L"SSH_AGENT_PID",
- // Enables find_package(CUDA) and enable_language(CUDA) in CMake
- L"CUDA_PATH",
- L"CUDA_PATH_V9_0",
- L"CUDA_PATH_V9_1",
- L"CUDA_PATH_V10_0",
- L"CUDA_PATH_V10_1",
- L"CUDA_PATH_V10_2",
- L"CUDA_PATH_V11_0",
- L"CUDA_TOOLKIT_ROOT_DIR",
- // Environmental variable generated automatically by CUDA after installation
- L"NVCUDASAMPLES_ROOT",
- L"NVTOOLSEXT_PATH",
- // Enables find_package(Vulkan) in CMake. Environmental variable generated by Vulkan SDK installer
- L"VULKAN_SDK",
- // Enable targeted Android NDK
- L"ANDROID_NDK_HOME",
- };
-
- const Optional<std::string> keep_vars = System::get_environment_variable("VCPKG_KEEP_ENV_VARS");
- const auto k = keep_vars.get();
-
- if (k && !k->empty())
- {
- auto vars = Strings::split(*k, ';');
-
- for (auto&& var : vars)
- {
- env_wstrings.push_back(Strings::to_utf16(var));
- }
- }
-
- std::wstring env_cstr;
-
- for (auto&& env_wstring : env_wstrings)
- {
- const Optional<std::string> value = System::get_environment_variable(Strings::to_utf8(env_wstring.c_str()));
- const auto v = value.get();
- if (!v || v->empty()) continue;
-
- env_cstr.append(env_wstring);
- env_cstr.push_back(L'=');
- env_cstr.append(Strings::to_utf16(*v));
- env_cstr.push_back(L'\0');
- }
-
- if (extra_env.find("PATH") != extra_env.end())
- new_path += Strings::format(";%s", extra_env.find("PATH")->second);
- env_cstr.append(Strings::to_utf16(new_path));
- env_cstr.push_back(L'\0');
- env_cstr.append(L"VSLANG=1033");
- env_cstr.push_back(L'\0');
- env_cstr.append(L"VSCMD_SKIP_SENDTELEMETRY=1");
- env_cstr.push_back(L'\0');
-
- for (const auto& item : extra_env)
- {
- if (item.first == "PATH") continue;
- env_cstr.append(Strings::to_utf16(item.first));
- env_cstr.push_back(L'=');
- env_cstr.append(Strings::to_utf16(item.second));
- env_cstr.push_back(L'\0');
- }
-
- return {env_cstr};
- }
-#else
- Environment System::get_modified_clean_environment(const std::unordered_map<std::string, std::string>&,
- const std::string&)
- {
- return {};
- }
-#endif
- const Environment& System::get_clean_environment()
- {
- static const Environment clean_env = get_modified_clean_environment({});
- return clean_env;
- }
-
- int System::cmd_execute_clean(const Command& cmd_line, InWorkingDirectory wd)
- {
- return cmd_execute(cmd_line, wd, get_clean_environment());
- }
-
-#if defined(_WIN32)
- struct ProcessInfo
- {
- constexpr ProcessInfo() noexcept : proc_info{} { }
- ProcessInfo(ProcessInfo&& other) noexcept : proc_info(other.proc_info)
- {
- other.proc_info.hProcess = nullptr;
- other.proc_info.hThread = nullptr;
- }
- ~ProcessInfo()
- {
- if (proc_info.hThread)
- {
- CloseHandle(proc_info.hThread);
- }
- if (proc_info.hProcess)
- {
- CloseHandle(proc_info.hProcess);
- }
- }
-
- ProcessInfo& operator=(ProcessInfo&& other) noexcept
- {
- ProcessInfo{std::move(other)}.swap(*this);
- return *this;
- }
-
- void swap(ProcessInfo& other) noexcept
- {
- std::swap(proc_info.hProcess, other.proc_info.hProcess);
- std::swap(proc_info.hThread, other.proc_info.hThread);
- }
-
- friend void swap(ProcessInfo& lhs, ProcessInfo& rhs) noexcept { lhs.swap(rhs); }
-
- unsigned int wait()
- {
- const DWORD result = WaitForSingleObject(proc_info.hProcess, INFINITE);
- Checks::check_exit(VCPKG_LINE_INFO, result != WAIT_FAILED, "WaitForSingleObject failed");
- DWORD exit_code = 0;
- GetExitCodeProcess(proc_info.hProcess, &exit_code);
- return exit_code;
- }
-
- PROCESS_INFORMATION proc_info;
- };
-
- /// <param name="maybe_environment">If non-null, an environment block to use for the new process. If null, the
- /// new process will inherit the current environment.</param>
- static ExpectedT<ProcessInfo, unsigned long> windows_create_process(StringView cmd_line,
- InWorkingDirectory wd,
- const Environment& env,
- DWORD dwCreationFlags,
- STARTUPINFOW& startup_info) noexcept
- {
- ProcessInfo process_info;
- Debug::print("CreateProcessW(", cmd_line, ")\n");
-
- // Flush stdout before launching external process
- fflush(nullptr);
-
- std::wstring working_directory;
- if (!wd.working_directory.empty())
- {
- // this only fails if we can't get the current working directory of vcpkg, and we assume that we have that,
- // so it's fine anyways
- working_directory = Files::get_real_filesystem().absolute(VCPKG_LINE_INFO, wd.working_directory).native();
- }
-
- VCPKG_MSVC_WARNING(suppress : 6335) // Leaking process information handle 'process_info.proc_info.hProcess'
- // /analyze can't tell that we transferred ownership here
- bool succeeded =
- TRUE == CreateProcessW(nullptr,
- Strings::to_utf16(cmd_line).data(),
- nullptr,
- nullptr,
- TRUE,
- IDLE_PRIORITY_CLASS | CREATE_UNICODE_ENVIRONMENT | dwCreationFlags,
- env.m_env_data.empty()
- ? nullptr
- : const_cast<void*>(static_cast<const void*>(env.m_env_data.data())),
- working_directory.empty() ? nullptr : working_directory.data(),
- &startup_info,
- &process_info.proc_info);
-
- if (succeeded)
- return process_info;
- else
- return GetLastError();
- }
-
- static ExpectedT<ProcessInfo, unsigned long> windows_create_windowless_process(StringView cmd_line,
- InWorkingDirectory wd,
- const Environment& env,
- DWORD dwCreationFlags) noexcept
- {
- STARTUPINFOW startup_info;
- memset(&startup_info, 0, sizeof(STARTUPINFOW));
- startup_info.cb = sizeof(STARTUPINFOW);
- startup_info.dwFlags = STARTF_USESHOWWINDOW;
- startup_info.wShowWindow = SW_HIDE;
-
- return windows_create_process(cmd_line, wd, env, dwCreationFlags, startup_info);
- }
-
- struct ProcessInfoAndPipes
- {
- ProcessInfo proc_info;
- HANDLE child_stdin = 0;
- HANDLE child_stdout = 0;
-
- template<class Function>
- int wait_and_stream_output(Function&& f)
- {
- CloseHandle(child_stdin);
-
- unsigned long bytes_read = 0;
- static constexpr int buffer_size = 1024 * 32;
- auto buf = std::make_unique<char[]>(buffer_size);
- while (ReadFile(child_stdout, (void*)buf.get(), buffer_size, &bytes_read, nullptr) && bytes_read > 0)
- {
- f(StringView{buf.get(), static_cast<size_t>(bytes_read)});
- }
-
- CloseHandle(child_stdout);
-
- return proc_info.wait();
- }
- };
-
- static ExpectedT<ProcessInfoAndPipes, unsigned long> windows_create_process_redirect(StringView cmd_line,
- InWorkingDirectory wd,
- const Environment& env,
- DWORD dwCreationFlags) noexcept
- {
- ProcessInfoAndPipes ret;
-
- STARTUPINFOW startup_info;
- memset(&startup_info, 0, sizeof(STARTUPINFOW));
- startup_info.cb = sizeof(STARTUPINFOW);
- startup_info.dwFlags |= STARTF_USESTDHANDLES;
-
- SECURITY_ATTRIBUTES saAttr;
- memset(&saAttr, 0, sizeof(SECURITY_ATTRIBUTES));
- saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
- saAttr.bInheritHandle = TRUE;
- saAttr.lpSecurityDescriptor = NULL;
-
- // Create a pipe for the child process's STDOUT.
- if (!CreatePipe(&ret.child_stdout, &startup_info.hStdOutput, &saAttr, 0)) Checks::exit_fail(VCPKG_LINE_INFO);
- // Ensure the read handle to the pipe for STDOUT is not inherited.
- if (!SetHandleInformation(ret.child_stdout, HANDLE_FLAG_INHERIT, 0)) Checks::exit_fail(VCPKG_LINE_INFO);
- // Create a pipe for the child process's STDIN.
- if (!CreatePipe(&startup_info.hStdInput, &ret.child_stdin, &saAttr, 0)) Checks::exit_fail(VCPKG_LINE_INFO);
- // Ensure the write handle to the pipe for STDIN is not inherited.
- if (!SetHandleInformation(ret.child_stdin, HANDLE_FLAG_INHERIT, 0)) Checks::exit_fail(VCPKG_LINE_INFO);
- startup_info.hStdError = startup_info.hStdOutput;
-
- auto maybe_proc_info = windows_create_process(cmd_line, wd, env, dwCreationFlags, startup_info);
-
- CloseHandle(startup_info.hStdInput);
- CloseHandle(startup_info.hStdOutput);
-
- if (auto proc_info = maybe_proc_info.get())
- {
- ret.proc_info = std::move(*proc_info);
- return std::move(ret);
- }
- else
- {
- return maybe_proc_info.error();
- }
- }
-#endif
-
-#if defined(_WIN32)
- void System::cmd_execute_background(const Command& cmd_line)
- {
- auto timer = Chrono::ElapsedTimer::create_started();
-
- auto process_info =
- windows_create_windowless_process(cmd_line.command_line(),
- InWorkingDirectory{fs::path()},
- {},
- CREATE_NEW_CONSOLE | CREATE_NO_WINDOW | CREATE_BREAKAWAY_FROM_JOB);
- if (!process_info.get())
- {
- Debug::print("cmd_execute_background() failed with error code ", process_info.error(), "\n");
- }
-
- Debug::print("cmd_execute_background() took ", static_cast<int>(timer.microseconds()), " us\n");
- }
-
- Environment System::cmd_execute_modify_env(const Command& cmd_line, const Environment& env)
- {
- static StringLiteral magic_string = "cdARN4xjKueKScMy9C6H";
-
- auto actual_cmd_line = cmd_line;
- actual_cmd_line.raw_arg(Strings::concat(" & echo ", magic_string, " & set"));
-
- auto rc_output = cmd_execute_and_capture_output(actual_cmd_line, env);
- Checks::check_exit(VCPKG_LINE_INFO, rc_output.exit_code == 0);
- Debug::print("command line: ", actual_cmd_line.command_line(), "\n");
- Debug::print(rc_output.output, "\n");
-
- auto it = Strings::search(rc_output.output, magic_string);
- const char* const last = rc_output.output.data() + rc_output.output.size();
-
- Checks::check_exit(VCPKG_LINE_INFO, it != last);
- // find the first non-whitespace character after the magic string
- it = std::find_if_not(it + magic_string.size(), last, ::isspace);
- Checks::check_exit(VCPKG_LINE_INFO, it != last);
-
- std::wstring out_env;
-
- for (;;)
- {
- auto equal_it = std::find(it, last, '=');
- if (equal_it == last) break;
- StringView variable_name(it, equal_it);
- auto newline_it = std::find(equal_it + 1, last, '\r');
- if (newline_it == last) break;
- StringView value(equal_it + 1, newline_it);
-
- out_env.append(Strings::to_utf16(Strings::concat(variable_name, '=', value)));
- out_env.push_back(L'\0');
-
- it = newline_it + 1;
- if (it != last && *it == '\n') ++it;
- }
-
- return {std::move(out_env)};
- }
-#endif
-
- int System::cmd_execute(const Command& cmd_line, System::InWorkingDirectory wd, const Environment& env)
- {
- auto timer = Chrono::ElapsedTimer::create_started();
-#if defined(_WIN32)
- using vcpkg::g_ctrl_c_state;
- g_ctrl_c_state.transition_to_spawn_process();
- auto proc_info = windows_create_windowless_process(cmd_line.command_line(), wd, env, 0);
- auto long_exit_code = [&]() -> unsigned long {
- if (auto p = proc_info.get())
- return p->wait();
- else
- return proc_info.error();
- }();
- if (long_exit_code > INT_MAX) long_exit_code = INT_MAX;
- int exit_code = static_cast<int>(long_exit_code);
- g_ctrl_c_state.transition_from_spawn_process();
-
- Debug::print(
- "cmd_execute() returned ", exit_code, " after ", static_cast<unsigned int>(timer.microseconds()), " us\n");
-#else
- (void)env;
- std::string real_command_line;
- if (wd.working_directory.empty())
- {
- real_command_line = cmd_line.command_line().to_string();
- }
- else
- {
- real_command_line = System::Command("cd")
- .path_arg(wd.working_directory)
- .raw_arg("&&")
- .raw_arg(cmd_line.command_line())
- .extract();
- }
- Debug::print("system(", real_command_line, ")\n");
- fflush(nullptr);
-
- int exit_code = system(real_command_line.c_str());
- Debug::print(
- "system() returned ", exit_code, " after ", static_cast<unsigned int>(timer.microseconds()), " us\n");
-#endif
- return exit_code;
- }
-
- int System::cmd_execute_and_stream_lines(const Command& cmd_line,
- System::InWorkingDirectory wd,
- std::function<void(StringView)> per_line_cb,
- const Environment& env)
- {
- std::string buf;
-
- auto rc = cmd_execute_and_stream_data(
- cmd_line,
- wd,
- [&](StringView sv) {
- auto prev_size = buf.size();
- Strings::append(buf, sv);
-
- auto it = std::find(buf.begin() + prev_size, buf.end(), '\n');
- while (it != buf.end())
- {
- std::string s(buf.begin(), it);
- per_line_cb(s);
- buf.erase(buf.begin(), it + 1);
- it = std::find(buf.begin(), buf.end(), '\n');
- }
- },
- env);
-
- per_line_cb(buf);
- return rc;
- }
-
- int System::cmd_execute_and_stream_data(const Command& cmd_line,
- System::InWorkingDirectory wd,
- std::function<void(StringView)> data_cb,
- const Environment& env)
- {
- auto timer = Chrono::ElapsedTimer::create_started();
-
-#if defined(_WIN32)
- using vcpkg::g_ctrl_c_state;
-
- g_ctrl_c_state.transition_to_spawn_process();
- auto maybe_proc_info = windows_create_process_redirect(cmd_line.command_line(), wd, env, 0);
- auto exit_code = [&]() -> unsigned long {
- if (auto p = maybe_proc_info.get())
- return p->wait_and_stream_output(data_cb);
- else
- return maybe_proc_info.error();
- }();
- g_ctrl_c_state.transition_from_spawn_process();
-#else
- (void)env;
- std::string actual_cmd_line;
- if (wd.working_directory.empty())
- {
- actual_cmd_line = Strings::format(R"(%s 2>&1)", cmd_line.command_line());
- }
- else
- {
- actual_cmd_line = System::Command("cd")
- .path_arg(wd.working_directory)
- .raw_arg("&&")
- .raw_arg(cmd_line.command_line())
- .raw_arg("2>&1")
- .extract();
- }
-
- Debug::print("popen(", actual_cmd_line, ")\n");
- // Flush stdout before launching external process
- fflush(stdout);
-
- const auto pipe = popen(actual_cmd_line.c_str(), "r");
- if (pipe == nullptr)
- {
- return 1;
- }
- char buf[1024];
- while (fgets(buf, 1024, pipe))
- {
- data_cb(StringView{buf, strlen(buf)});
- }
-
- if (!feof(pipe))
- {
- return 1;
- }
-
- const auto exit_code = pclose(pipe);
-#endif
- Debug::print("cmd_execute_and_stream_data() returned ",
- exit_code,
- " after ",
- Strings::format("%8d", static_cast<int>(timer.microseconds())),
- " us\n");
-
- return exit_code;
- }
-
- ExitCodeAndOutput System::cmd_execute_and_capture_output(const Command& cmd_line,
- System::InWorkingDirectory wd,
- const Environment& env)
- {
- std::string output;
- auto rc = cmd_execute_and_stream_data(
- cmd_line, wd, [&](StringView sv) { Strings::append(output, sv); }, env);
- return {rc, std::move(output)};
- }
-
-#if defined(_WIN32)
- static BOOL ctrl_handler(DWORD fdw_ctrl_type)
- {
- switch (fdw_ctrl_type)
- {
- case CTRL_C_EVENT: g_ctrl_c_state.transition_handle_ctrl_c(); return TRUE;
- default: return FALSE;
- }
- }
-
- void System::register_console_ctrl_handler()
- {
- SetConsoleCtrlHandler(reinterpret_cast<PHANDLER_ROUTINE>(ctrl_handler), TRUE);
- }
-#else
- void System::register_console_ctrl_handler() { }
-#endif
-}
diff --git a/toolsrc/src/vcpkg/base/uint128.cpp b/toolsrc/src/vcpkg/base/uint128.cpp
deleted file mode 100644
index 900cbf9e6..000000000
--- a/toolsrc/src/vcpkg/base/uint128.cpp
+++ /dev/null
@@ -1,66 +0,0 @@
-#include <vcpkg/base/uint128.h>
-
-#include <limits>
-
-namespace vcpkg
-{
- UInt128& UInt128::operator<<=(int by) noexcept
- {
- if (by == 0)
- {
- return *this;
- }
-
- if (by < 64)
- {
- top <<= by;
- const auto shift_up = bottom >> (64 - by);
- top |= shift_up;
- bottom <<= by;
- }
- else
- {
- top = bottom;
- top <<= (by - 64);
- bottom = 0;
- }
-
- return *this;
- }
-
- UInt128& UInt128::operator>>=(int by) noexcept
- {
- if (by == 0)
- {
- return *this;
- }
-
- if (by < 64)
- {
- bottom >>= by;
- const auto shift_down = top << (64 - by);
- bottom |= shift_down;
- top >>= by;
- }
- else
- {
- bottom = top;
- bottom >>= (by - 64);
- top = 0;
- }
-
- return *this;
- }
-
- UInt128& UInt128::operator+=(uint64_t rhs) noexcept
- {
- // bottom + lhs > uint64::max
- if (bottom > std::numeric_limits<uint64_t>::max() - rhs)
- {
- top += 1;
- }
- bottom += rhs;
- return *this;
- }
-
-}
diff --git a/toolsrc/src/vcpkg/base/unicode.cpp b/toolsrc/src/vcpkg/base/unicode.cpp
deleted file mode 100644
index 92b964ed8..000000000
--- a/toolsrc/src/vcpkg/base/unicode.cpp
+++ /dev/null
@@ -1,282 +0,0 @@
-#include <vcpkg/base/checks.h>
-#include <vcpkg/base/unicode.h>
-
-namespace vcpkg::Unicode
-{
- Utf8CodeUnitKind utf8_code_unit_kind(unsigned char code_unit) noexcept
- {
- if (code_unit < 0b1000'0000)
- {
- return Utf8CodeUnitKind::StartOne;
- }
- else if (code_unit < 0b1100'0000)
- {
- return Utf8CodeUnitKind::Continue;
- }
- else if (code_unit < 0b1110'0000)
- {
- return Utf8CodeUnitKind::StartTwo;
- }
- else if (code_unit < 0b1111'0000)
- {
- return Utf8CodeUnitKind::StartThree;
- }
- else if (code_unit < 0b1111'1000)
- {
- return Utf8CodeUnitKind::StartFour;
- }
- else
- {
- return Utf8CodeUnitKind::Invalid;
- }
- }
-
- int utf8_code_unit_count(Utf8CodeUnitKind kind) noexcept { return static_cast<int>(kind); }
- int utf8_code_unit_count(char code_unit) noexcept { return utf8_code_unit_count(utf8_code_unit_kind(code_unit)); }
-
- static int utf8_encode_code_unit_count(char32_t code_point) noexcept
- {
- if (code_point < 0x80)
- {
- return 1;
- }
- else if (code_point < 0x800)
- {
- return 2;
- }
- else if (code_point < 0x10000)
- {
- return 3;
- }
- else if (code_point < 0x110000)
- {
- return 4;
- }
- else
- {
- vcpkg::Checks::exit_with_message(
- VCPKG_LINE_INFO, "Invalid code point passed to utf8_encoded_code_point_count (%x)", code_point);
- }
- }
-
- int utf8_encode_code_point(char (&array)[4], char32_t code_point) noexcept
- {
- // count \in {2, 3, 4}
- const auto start_code_point = [](char32_t code_point, int count) {
- const unsigned char and_mask = 0xFF >> (count + 1);
- const unsigned char or_mask = (0xFF << (8 - count)) & 0xFF;
- const int shift = 6 * (count - 1);
- return static_cast<char>(or_mask | ((code_point >> shift) & and_mask));
- };
- // count \in {2, 3, 4}, byte \in {1, 2, 3}
- const auto continue_code_point = [](char32_t code_point, int count, int byte) {
- constexpr unsigned char and_mask = 0xFF >> 2;
- constexpr unsigned char or_mask = (0xFF << 7) & 0xFF;
- const int shift = 6 * (count - byte - 1);
- return static_cast<char>(or_mask | ((code_point >> shift) & and_mask));
- };
-
- int count = utf8_encode_code_unit_count(code_point);
- if (count == 1)
- {
- array[0] = static_cast<char>(code_point);
- return 1;
- }
-
- array[0] = start_code_point(code_point, count);
- for (int i = 1; i < count; ++i)
- {
- array[i] = continue_code_point(code_point, count, i);
- }
-
- return count;
- }
-
- bool utf8_is_valid_string(const char* first, const char* last) noexcept
- {
- std::error_code ec;
- for (auto dec = Utf8Decoder(first, last); dec != dec.end(); dec.next(ec))
- {
- }
- return !ec;
- }
-
- char32_t utf16_surrogates_to_code_point(char32_t leading, char32_t trailing)
- {
- vcpkg::Checks::check_exit(VCPKG_LINE_INFO, utf16_is_leading_surrogate_code_point(leading));
- vcpkg::Checks::check_exit(VCPKG_LINE_INFO, utf16_is_trailing_surrogate_code_point(trailing));
-
- char32_t res = (leading & 0b11'1111'1111) << 10;
- res |= trailing & 0b11'1111'1111;
- res += 0x0001'0000;
-
- return res;
- }
-
- const char* utf8_category::name() const noexcept { return "utf8"; }
- std::string utf8_category::message(int condition) const
- {
- switch (static_cast<utf8_errc>(condition))
- {
- case utf8_errc::NoError: return "no error";
- case utf8_errc::InvalidCodeUnit: return "invalid code unit";
- case utf8_errc::InvalidCodePoint: return "invalid code point (>0x10FFFF)";
- case utf8_errc::PairedSurrogates:
- return "trailing surrogate following leading surrogate (paired surrogates are invalid)";
- case utf8_errc::UnexpectedContinue: return "found continue code unit in start position";
- case utf8_errc::UnexpectedStart: return "found start code unit in continue position";
- case utf8_errc::UnexpectedEof: return "found end of string in middle of code point";
- default: return "error code out of range";
- }
- }
-
- Utf8Decoder::Utf8Decoder() noexcept : current_(end_of_file), next_(nullptr), last_(nullptr) { }
- Utf8Decoder::Utf8Decoder(const char* first, const char* last) noexcept : current_(0), next_(first), last_(last)
- {
- if (next_ != last_)
- {
- ++*this;
- }
- else
- {
- current_ = end_of_file;
- }
- }
-
- char const* Utf8Decoder::pointer_to_current() const noexcept
- {
- if (is_eof())
- {
- return last_;
- }
-
- auto count = utf8_encode_code_unit_count(current_);
- return next_ - count;
- }
-
- bool Utf8Decoder::is_eof() const noexcept { return current_ == end_of_file; }
- char32_t Utf8Decoder::operator*() const noexcept
- {
- if (is_eof())
- {
- Checks::exit_with_message(VCPKG_LINE_INFO, "Dereferenced Utf8Decoder on the end of a string");
- }
- return current_;
- }
-
- void Utf8Decoder::next(std::error_code& ec)
- {
- ec.clear();
-
- if (is_eof())
- {
- vcpkg::Checks::exit_with_message(VCPKG_LINE_INFO, "Incremented Utf8Decoder at the end of the string");
- }
-
- if (next_ == last_)
- {
- current_ = end_of_file;
- return;
- }
-
- auto set_error = [&ec, this](utf8_errc err) {
- ec = err;
- *this = sentinel();
- };
-
- unsigned char code_unit = static_cast<unsigned char>(*next_++);
-
- auto kind = utf8_code_unit_kind(code_unit);
- if (kind == Utf8CodeUnitKind::Invalid)
- {
- return set_error(utf8_errc::InvalidCodeUnit);
- }
- else if (kind == Utf8CodeUnitKind::Continue)
- {
- return set_error(utf8_errc::UnexpectedContinue);
- }
-
- const int count = utf8_code_unit_count(kind);
- if (count == 1)
- {
- current_ = static_cast<char32_t>(code_unit);
- }
- else
- {
- // 2 -> 0b0001'1111, 6
- // 3 -> 0b0000'1111, 12
- // 4 -> 0b0000'0111, 18
- const auto start_mask = static_cast<unsigned char>(0xFF >> (count + 1));
- const int start_shift = 6 * (count - 1);
- auto code_point = static_cast<char32_t>(code_unit & start_mask) << start_shift;
-
- constexpr unsigned char continue_mask = 0b0011'1111;
- for (int byte = 1; byte < count; ++byte)
- {
- if (next_ == last_)
- {
- return set_error(utf8_errc::UnexpectedContinue);
- }
- code_unit = static_cast<unsigned char>(*next_++);
-
- kind = utf8_code_unit_kind(code_unit);
- if (kind == Utf8CodeUnitKind::Invalid)
- {
- return set_error(utf8_errc::InvalidCodeUnit);
- }
- else if (kind != Utf8CodeUnitKind::Continue)
- {
- return set_error(utf8_errc::UnexpectedStart);
- }
-
- const int shift = 6 * (count - byte - 1);
- code_point |= (code_unit & continue_mask) << shift;
- }
-
- if (code_point > 0x10'FFFF)
- {
- return set_error(utf8_errc::InvalidCodePoint);
- }
- else if (utf16_is_trailing_surrogate_code_point(code_point) &&
- utf16_is_leading_surrogate_code_point(current_))
- {
- return set_error(utf8_errc::PairedSurrogates);
- }
- else
- {
- current_ = code_point;
- }
- }
- }
-
- Utf8Decoder& Utf8Decoder::operator++() noexcept
- {
- std::error_code ec;
- next(ec);
- if (ec)
- {
- vcpkg::Checks::exit_with_message(VCPKG_LINE_INFO, ec.message());
- }
-
- return *this;
- }
-
- Utf8Decoder& Utf8Decoder::operator=(sentinel) noexcept
- {
- next_ = last_;
- current_ = end_of_file;
- return *this;
- }
-
- bool operator==(const Utf8Decoder& lhs, const Utf8Decoder& rhs) noexcept
- {
- if (lhs.last_ != rhs.last_)
- {
- Checks::exit_with_message(VCPKG_LINE_INFO,
- "Comparing Utf8Decoders with different provenance; this is always an error");
- }
-
- return lhs.next_ == rhs.next_;
- }
-
-}
diff --git a/toolsrc/src/vcpkg/base/xmlserializer.cpp b/toolsrc/src/vcpkg/base/xmlserializer.cpp
deleted file mode 100644
index 535a0a92b..000000000
--- a/toolsrc/src/vcpkg/base/xmlserializer.cpp
+++ /dev/null
@@ -1,113 +0,0 @@
-#include <vcpkg/base/strings.h>
-#include <vcpkg/base/xmlserializer.h>
-
-namespace vcpkg
-{
- XmlSerializer& XmlSerializer::emit_declaration()
- {
- buf.append(R"(<?xml version="1.0" encoding="utf-8"?>)");
- return *this;
- }
- XmlSerializer& XmlSerializer::open_tag(StringLiteral sl)
- {
- emit_pending_indent();
- Strings::append(buf, '<', sl, '>');
- m_indent += 2;
- return *this;
- }
- XmlSerializer& XmlSerializer::start_complex_open_tag(StringLiteral sl)
- {
- emit_pending_indent();
- Strings::append(buf, '<', sl);
- m_indent += 2;
- return *this;
- }
- XmlSerializer& XmlSerializer::text_attr(StringLiteral name, StringView content)
- {
- if (m_pending_indent)
- {
- m_pending_indent = false;
- buf.append(m_indent, ' ');
- }
- else
- {
- buf.push_back(' ');
- }
- Strings::append(buf, name, "=\"");
- text(content);
- Strings::append(buf, '"');
- return *this;
- }
- XmlSerializer& XmlSerializer::finish_complex_open_tag()
- {
- emit_pending_indent();
- Strings::append(buf, '>');
- return *this;
- }
- XmlSerializer& XmlSerializer::finish_self_closing_complex_tag()
- {
- emit_pending_indent();
- Strings::append(buf, "/>");
- m_indent -= 2;
- return *this;
- }
- XmlSerializer& XmlSerializer::close_tag(StringLiteral sl)
- {
- m_indent -= 2;
- emit_pending_indent();
- Strings::append(buf, "</", sl, '>');
- return *this;
- }
- XmlSerializer& XmlSerializer::text(StringView sv)
- {
- emit_pending_indent();
- for (auto ch : sv)
- {
- if (ch == '&')
- {
- buf.append("&amp;");
- }
- else if (ch == '<')
- {
- buf.append("&lt;");
- }
- else if (ch == '>')
- {
- buf.append("&gt;");
- }
- else if (ch == '"')
- {
- buf.append("&quot;");
- }
- else if (ch == '\'')
- {
- buf.append("&apos;");
- }
- else
- {
- buf.push_back(ch);
- }
- }
- return *this;
- }
- XmlSerializer& XmlSerializer::simple_tag(StringLiteral tag, StringView content)
- {
- return emit_pending_indent().open_tag(tag).text(content).close_tag(tag);
- }
- XmlSerializer& XmlSerializer::line_break()
- {
- buf.push_back('\n');
- m_pending_indent = true;
- return *this;
- }
- XmlSerializer& XmlSerializer::emit_pending_indent()
- {
- if (m_pending_indent)
- {
- m_pending_indent = false;
- buf.append(m_indent, ' ');
- }
- return *this;
- }
-
-}
diff --git a/toolsrc/src/vcpkg/binarycaching.cpp b/toolsrc/src/vcpkg/binarycaching.cpp
deleted file mode 100644
index 280a5be28..000000000
--- a/toolsrc/src/vcpkg/binarycaching.cpp
+++ /dev/null
@@ -1,1477 +0,0 @@
-#include <vcpkg/base/checks.h>
-#include <vcpkg/base/downloads.h>
-#include <vcpkg/base/files.h>
-#include <vcpkg/base/parse.h>
-#include <vcpkg/base/strings.h>
-#include <vcpkg/base/system.debug.h>
-#include <vcpkg/base/system.print.h>
-#include <vcpkg/base/system.process.h>
-#include <vcpkg/base/xmlserializer.h>
-
-#include <vcpkg/binarycaching.h>
-#include <vcpkg/binarycaching.private.h>
-#include <vcpkg/build.h>
-#include <vcpkg/dependencies.h>
-#include <vcpkg/metrics.h>
-#include <vcpkg/tools.h>
-
-using namespace vcpkg;
-
-namespace
-{
- struct NullBinaryProvider : IBinaryProvider
- {
- void prefetch(const VcpkgPaths&, std::vector<const Dependencies::InstallPlanAction*>&) { }
-
- void push_success(const VcpkgPaths&, const Dependencies::InstallPlanAction&) { }
-
- RestoreResult try_restore(const VcpkgPaths&, const Dependencies::InstallPlanAction&)
- {
- return RestoreResult::missing;
- }
-
- void precheck(const VcpkgPaths&, std::unordered_map<const Dependencies::InstallPlanAction*, RestoreResult>&) { }
- };
-}
-
-std::unordered_map<const Dependencies::InstallPlanAction*, RestoreResult> vcpkg::binary_provider_precheck(
- const VcpkgPaths& paths, const Dependencies::ActionPlan& plan, IBinaryProvider& provider)
-{
- std::unordered_map<const Dependencies::InstallPlanAction*, RestoreResult> checked;
- for (auto&& action : plan.install_actions)
- {
- checked.emplace(&action, RestoreResult::missing);
- }
-
- provider.precheck(paths, checked);
- return checked;
-}
-
-namespace
-{
- static void clean_prepare_dir(Files::Filesystem& fs, const fs::path& dir)
- {
- fs.remove_all(dir, VCPKG_LINE_INFO);
- bool created_last = fs.create_directories(dir, VCPKG_LINE_INFO);
- Checks::check_exit(VCPKG_LINE_INFO, created_last, "unable to clear path: %s", fs::u8string(dir));
- }
-
- static System::ExitCodeAndOutput decompress_archive(const VcpkgPaths& paths,
- const fs::path& dst,
- const fs::path& archive_path)
- {
- System::Command cmd;
-#if defined(_WIN32)
- auto&& seven_zip_exe = paths.get_tool_exe(Tools::SEVEN_ZIP);
- cmd.path_arg(seven_zip_exe)
- .string_arg("x")
- .path_arg(archive_path)
- .string_arg("-o" + fs::u8string(dst))
- .string_arg("-y");
-#else
- (void)paths;
- cmd.string_arg("unzip").string_arg("-qq").path_arg(archive_path).string_arg("-d" + fs::u8string(dst));
-#endif
- return System::cmd_execute_and_capture_output(cmd, System::get_clean_environment());
- }
-
- static System::ExitCodeAndOutput clean_decompress_archive(const VcpkgPaths& paths,
- const PackageSpec& spec,
- const fs::path& archive_path)
- {
- auto pkg_path = paths.package_dir(spec);
- clean_prepare_dir(paths.get_filesystem(), pkg_path);
- return decompress_archive(paths, pkg_path, archive_path);
- }
-
- // Compress the source directory into the destination file.
- static void compress_directory(const VcpkgPaths& paths, const fs::path& source, const fs::path& destination)
- {
- auto& fs = paths.get_filesystem();
-
- std::error_code ec;
-
- fs.remove(destination, ec);
- Checks::check_exit(
- VCPKG_LINE_INFO, !fs.exists(destination), "Could not remove file: %s", fs::u8string(destination));
-#if defined(_WIN32)
- auto&& seven_zip_exe = paths.get_tool_exe(Tools::SEVEN_ZIP);
-
- System::cmd_execute_and_capture_output(
- System::Command{seven_zip_exe}.string_arg("a").path_arg(destination).path_arg(source / fs::u8path("*")),
- System::get_clean_environment());
-#else
- System::cmd_execute_clean(System::Command{"zip"}
- .string_arg("--quiet")
- .string_arg("-y")
- .string_arg("-r")
- .path_arg(destination)
- .string_arg("*"),
- System::InWorkingDirectory{source});
-#endif
- }
-
- struct ArchivesBinaryProvider : IBinaryProvider
- {
- ArchivesBinaryProvider(std::vector<fs::path>&& read_dirs,
- std::vector<fs::path>&& write_dirs,
- std::vector<std::string>&& put_url_templates,
- std::vector<std::string>&& secrets)
- : m_read_dirs(std::move(read_dirs))
- , m_write_dirs(std::move(write_dirs))
- , m_put_url_templates(std::move(put_url_templates))
- , m_secrets(std::move(secrets))
- {
- }
-
- void prefetch(const VcpkgPaths& paths, std::vector<const Dependencies::InstallPlanAction*>& actions) override
- {
- auto& fs = paths.get_filesystem();
- Util::erase_remove_if(actions, [this, &fs, &paths](const Dependencies::InstallPlanAction* action) {
- auto& spec = action->spec;
- const auto& abi_tag = action->abi_info.value_or_exit(VCPKG_LINE_INFO).package_abi;
- const auto archive_name = fs::u8path(abi_tag + ".zip");
- for (const auto& archives_root_dir : m_read_dirs)
- {
- auto archive_path = archives_root_dir;
- archive_path /= fs::u8path(abi_tag.substr(0, 2));
- archive_path /= archive_name;
- if (fs.exists(archive_path))
- {
- System::print2("Using cached binary package: ", fs::u8string(archive_path), "\n");
-
- int archive_result = clean_decompress_archive(paths, spec, archive_path).exit_code;
-
- if (archive_result == 0)
- {
- m_restored.insert(spec);
- return true;
- }
- else
- {
- System::print2("Failed to decompress archive package\n");
- if (action->build_options.purge_decompress_failure == Build::PurgeDecompressFailure::YES)
- {
- System::print2("Purging bad archive\n");
- fs.remove(archive_path, ignore_errors);
- }
- }
- }
-
- System::printf("Could not locate cached archive: %s\n", fs::u8string(archive_path));
- }
- return false;
- });
- }
- RestoreResult try_restore(const VcpkgPaths&, const Dependencies::InstallPlanAction& action) override
- {
- if (Util::Sets::contains(m_restored, action.spec))
- return RestoreResult::success;
- else
- return RestoreResult::missing;
- }
- void push_success(const VcpkgPaths& paths, const Dependencies::InstallPlanAction& action) override
- {
- if (m_write_dirs.empty() && m_put_url_templates.empty()) return;
- const auto& abi_tag = action.abi_info.value_or_exit(VCPKG_LINE_INFO).package_abi;
- auto& spec = action.spec;
- auto& fs = paths.get_filesystem();
- const auto tmp_archive_path = paths.buildtrees / spec.name() / (spec.triplet().to_string() + ".zip");
- compress_directory(paths, paths.package_dir(spec), tmp_archive_path);
-
- size_t http_remotes_pushed = 0;
- for (auto&& put_url_template : m_put_url_templates)
- {
- auto url = Strings::replace_all(std::string(put_url_template), "<SHA>", abi_tag);
- auto code = Downloads::put_file(fs, url, tmp_archive_path);
- if (code >= 200 && code < 300)
- {
- http_remotes_pushed++;
- continue;
- }
-
- auto safe_url = url;
- if (!Debug::g_debugging.load(std::memory_order_relaxed))
- {
- for (const auto& secret : m_secrets)
- {
- Strings::inplace_replace_all(safe_url, secret, "*** SECRET ***");
- }
- }
-
- System::print2(System::Color::warning, "Failed to upload to ", safe_url, ": ", code, '\n');
- }
-
- if (!m_put_url_templates.empty())
- {
- System::print2("Uploaded binaries to ", http_remotes_pushed, " HTTP remotes.\n");
- }
-
- const auto archive_name = fs::u8path(abi_tag + ".zip");
- for (const auto& archives_root_dir : m_write_dirs)
- {
- auto archive_path = archives_root_dir;
- archive_path /= fs::u8path(abi_tag.substr(0, 2));
- archive_path /= archive_name;
- fs.create_directories(archive_path.parent_path(), ignore_errors);
- std::error_code ec;
- if (m_write_dirs.size() > 1)
- {
- fs.copy_file(tmp_archive_path, archive_path, fs::copy_options::overwrite_existing, ec);
- }
- else
- {
- fs.rename_or_copy(tmp_archive_path, archive_path, ".tmp", ec);
- }
-
- if (ec)
- {
- System::printf(System::Color::warning,
- "Failed to store binary cache %s: %s\n",
- fs::u8string(archive_path),
- ec.message());
- }
- else
- {
- System::printf("Stored binary cache: %s\n", fs::u8string(archive_path));
- }
- }
- // In the case of 1 write dir, the file will be moved instead of copied
- if (m_write_dirs.size() != 1)
- {
- fs.remove(tmp_archive_path, ignore_errors);
- }
- }
- void precheck(const VcpkgPaths& paths,
- std::unordered_map<const Dependencies::InstallPlanAction*, RestoreResult>& results_map) override
- {
- auto& fs = paths.get_filesystem();
-
- for (auto&& result_pair : results_map)
- {
- if (result_pair.second != RestoreResult::missing)
- {
- continue;
- }
-
- const auto& abi_tag = result_pair.first->abi_info.value_or_exit(VCPKG_LINE_INFO).package_abi;
- std::error_code ec;
- for (auto&& archives_root_dir : m_read_dirs)
- {
- const std::string archive_name = abi_tag + ".zip";
- const fs::path archive_subpath = fs::u8path(abi_tag.substr(0, 2)) / archive_name;
- const fs::path archive_path = archives_root_dir / archive_subpath;
-
- if (fs.exists(archive_path))
- {
- result_pair.second = RestoreResult::success;
- break;
- }
- }
- }
- }
-
- private:
- std::vector<fs::path> m_read_dirs;
- std::vector<fs::path> m_write_dirs;
- std::vector<std::string> m_put_url_templates;
- std::vector<std::string> m_secrets;
-
- std::set<PackageSpec> m_restored;
- };
- struct HttpGetBinaryProvider : NullBinaryProvider
- {
- HttpGetBinaryProvider(std::vector<std::string>&& url_templates) : m_url_templates(std::move(url_templates)) { }
- void prefetch(const VcpkgPaths& paths, std::vector<const Dependencies::InstallPlanAction*>& actions) override
- {
- auto& fs = paths.get_filesystem();
-
- const size_t current_restored = m_restored.size();
-
- for (auto&& url_template : m_url_templates)
- {
- std::vector<std::pair<std::string, fs::path>> url_paths;
- std::vector<PackageSpec> specs;
-
- for (auto&& action : actions)
- {
- auto abi = action->package_abi();
- if (!abi)
- {
- continue;
- }
-
- specs.push_back(action->spec);
- auto pkgdir = paths.package_dir(action->spec);
- clean_prepare_dir(fs, pkgdir);
- pkgdir /= fs::u8path(Strings::concat(*abi.get(), ".zip"));
- url_paths.emplace_back(Strings::replace_all(std::string(url_template), "<SHA>", *abi.get()),
- pkgdir);
- }
-
- if (url_paths.empty()) break;
-
- System::print2("Attempting to fetch ", url_paths.size(), " packages from HTTP servers.\n");
-
- auto codes = Downloads::download_files(fs, url_paths);
- for (size_t i = 0; i < codes.size(); ++i)
- {
- if (codes[i] == 200)
- {
- int archive_result =
- decompress_archive(paths, paths.package_dir(specs[i]), url_paths[i].second).exit_code;
- if (archive_result == 0)
- {
- // decompression success
- fs.remove(url_paths[i].second, VCPKG_LINE_INFO);
- m_restored.insert(specs[i]);
- }
- else
- {
- Debug::print("Failed to decompress ", fs::u8string(url_paths[i].second), '\n');
- }
- }
- }
-
- Util::erase_remove_if(actions, [this](const Dependencies::InstallPlanAction* action) {
- return Util::Sets::contains(m_restored, action->spec);
- });
- }
- System::print2("Restored ",
- m_restored.size() - current_restored,
- " packages from HTTP servers. Use --debug for more information.\n");
- }
- RestoreResult try_restore(const VcpkgPaths&, const Dependencies::InstallPlanAction& action) override
- {
- if (Util::Sets::contains(m_restored, action.spec))
- {
- return RestoreResult::success;
- }
-
- return RestoreResult::missing;
- }
- void precheck(const VcpkgPaths&,
- std::unordered_map<const Dependencies::InstallPlanAction*, RestoreResult>& results_map) override
- {
- std::vector<std::string> urls;
- std::vector<const Dependencies::InstallPlanAction*> url_actions;
- for (auto&& url_template : m_url_templates)
- {
- urls.clear();
- url_actions.clear();
- for (auto&& result_pair : results_map)
- {
- if (result_pair.second != RestoreResult::missing) continue;
- auto abi = result_pair.first->package_abi();
- if (!abi) continue;
- urls.push_back(Strings::replace_all(std::string(url_template), "<SHA>", *abi.get()));
- url_actions.push_back(result_pair.first);
- }
-
- if (urls.empty())
- {
- break;
- }
-
- auto codes = Downloads::url_heads(urls);
- Checks::check_exit(VCPKG_LINE_INFO, codes.size() == url_actions.size());
- for (size_t i = 0; i < codes.size(); ++i)
- {
- if (codes[i] == 200)
- {
- results_map[url_actions[i]] = RestoreResult::success;
- }
- }
- }
- }
-
- std::vector<std::string> m_url_templates;
- std::set<PackageSpec> m_restored;
- };
-
- static std::string trim_leading_zeroes(std::string v)
- {
- auto n = v.find_first_not_of('0');
- if (n == std::string::npos)
- {
- v = "0";
- }
- else if (n > 0)
- {
- v.erase(0, n);
- }
-
- return v;
- }
-
- struct NugetBinaryProvider : NullBinaryProvider
- {
- NugetBinaryProvider(std::vector<std::string>&& read_sources,
- std::vector<std::string>&& write_sources,
- std::vector<fs::path>&& read_configs,
- std::vector<fs::path>&& write_configs,
- bool interactive)
- : m_read_sources(std::move(read_sources))
- , m_write_sources(std::move(write_sources))
- , m_read_configs(std::move(read_configs))
- , m_write_configs(std::move(write_configs))
- , m_interactive(interactive)
- , m_use_nuget_cache(false)
- {
- const std::string use_nuget_cache = System::get_environment_variable("VCPKG_USE_NUGET_CACHE").value_or("");
- m_use_nuget_cache = Strings::case_insensitive_ascii_equals(use_nuget_cache, "true") ||
- Strings::case_insensitive_ascii_equals(use_nuget_cache, "1");
- }
-
- int run_nuget_commandline(const System::Command& cmdline)
- {
- if (m_interactive)
- {
- return System::cmd_execute(cmdline);
- }
-
- auto res = System::cmd_execute_and_capture_output(cmdline);
- if (Debug::g_debugging)
- {
- System::print2(res.output);
- }
-
- if (res.output.find("Authentication may require manual action.") != std::string::npos)
- {
- System::print2(System::Color::warning,
- "One or more NuGet credential providers requested manual action. Add the binary "
- "source 'interactive' to allow interactivity.\n");
- }
- else if (res.output.find("Response status code does not indicate success: 401 (Unauthorized)") !=
- std::string::npos &&
- res.exit_code != 0)
- {
- System::print2(System::Color::warning,
- "One or more NuGet credential providers failed to authenticate. See "
- "https://github.com/Microsoft/vcpkg/tree/master/docs/users/binarycaching.md for "
- "more details on how to provide credentials.\n");
- }
- else if (res.output.find("for example \"-ApiKey AzureDevOps\"") != std::string::npos)
- {
- auto real_cmdline = cmdline;
- real_cmdline.string_arg("-ApiKey").string_arg("AzureDevOps");
- auto res2 = System::cmd_execute_and_capture_output(real_cmdline);
- if (Debug::g_debugging)
- {
- System::print2(res2.output);
- }
-
- return res2.exit_code;
- }
-
- return res.exit_code;
- }
-
- void prefetch(const VcpkgPaths& paths, std::vector<const Dependencies::InstallPlanAction*>& actions) override
- {
- if (m_read_sources.empty() && m_read_configs.empty())
- {
- return;
- }
-
- auto& fs = paths.get_filesystem();
-
- std::vector<std::pair<PackageSpec, NugetReference>> nuget_refs;
-
- for (auto&& action : actions)
- {
- if (!action->has_package_abi())
- {
- continue;
- }
-
- auto& spec = action->spec;
- fs.remove_all(paths.package_dir(spec), VCPKG_LINE_INFO);
-
- nuget_refs.emplace_back(spec, NugetReference(*action));
- }
-
- if (nuget_refs.empty())
- {
- return;
- }
-
- System::print2("Attempting to fetch ", nuget_refs.size(), " packages from nuget.\n");
-
- auto packages_config = paths.buildtrees / fs::u8path("packages.config");
-
- auto generate_packages_config = [&] {
- XmlSerializer xml;
- xml.emit_declaration().line_break();
- xml.open_tag("packages").line_break();
-
- for (auto&& nuget_ref : nuget_refs)
- {
- xml.start_complex_open_tag("package")
- .text_attr("id", nuget_ref.second.id)
- .text_attr("version", nuget_ref.second.version)
- .finish_self_closing_complex_tag()
- .line_break();
- }
-
- xml.close_tag("packages").line_break();
- paths.get_filesystem().write_contents(packages_config, xml.buf, VCPKG_LINE_INFO);
- };
-
- const auto& nuget_exe = paths.get_tool_exe("nuget");
- std::vector<System::Command> cmdlines;
-
- if (!m_read_sources.empty())
- {
- // First check using all sources
- System::Command cmdline;
-#ifndef _WIN32
- cmdline.path_arg(paths.get_tool_exe(Tools::MONO));
-#endif
- cmdline.path_arg(nuget_exe)
- .string_arg("install")
- .path_arg(packages_config)
- .string_arg("-OutputDirectory")
- .path_arg(paths.packages)
- .string_arg("-Source")
- .string_arg(Strings::join(";", m_read_sources))
- .string_arg("-ExcludeVersion")
- .string_arg("-PreRelease")
- .string_arg("-PackageSaveMode")
- .string_arg("nupkg")
- .string_arg("-Verbosity")
- .string_arg("detailed")
- .string_arg("-ForceEnglishOutput");
- if (!m_interactive)
- {
- cmdline.string_arg("-NonInteractive");
- }
- if (!m_use_nuget_cache)
- {
- cmdline.string_arg("-DirectDownload").string_arg("-NoCache");
- }
-
- cmdlines.push_back(std::move(cmdline));
- }
- for (auto&& cfg : m_read_configs)
- {
- // Then check using each config
- System::Command cmdline;
-#ifndef _WIN32
- cmdline.path_arg(paths.get_tool_exe(Tools::MONO));
-#endif
- cmdline.path_arg(nuget_exe)
- .string_arg("install")
- .path_arg(packages_config)
- .string_arg("-OutputDirectory")
- .path_arg(paths.packages)
- .string_arg("-ConfigFile")
- .path_arg(cfg)
- .string_arg("-ExcludeVersion")
- .string_arg("-PreRelease")
- .string_arg("-PackageSaveMode")
- .string_arg("nupkg")
- .string_arg("-Verbosity")
- .string_arg("detailed")
- .string_arg("-ForceEnglishOutput");
- if (!m_interactive)
- {
- cmdline.string_arg("-NonInteractive");
- }
- if (!m_use_nuget_cache)
- {
- cmdline.string_arg("-DirectDownload").string_arg("-NoCache");
- }
-
- cmdlines.push_back(std::move(cmdline));
- }
-
- const size_t current_restored = m_restored.size();
-
- for (const auto& cmdline : cmdlines)
- {
- if (nuget_refs.empty())
- {
- break;
- }
-
- [&] {
- generate_packages_config();
- run_nuget_commandline(cmdline);
- }();
-
- Util::erase_remove_if(nuget_refs, [&](const std::pair<PackageSpec, NugetReference>& nuget_ref) -> bool {
- auto nupkg_path = paths.package_dir(nuget_ref.first) / fs::u8path(nuget_ref.second.id + ".nupkg");
- if (fs.exists(nupkg_path, ignore_errors))
- {
- fs.remove(nupkg_path, VCPKG_LINE_INFO);
- Checks::check_exit(VCPKG_LINE_INFO,
- !fs.exists(nupkg_path, ignore_errors),
- "Unable to remove nupkg after restoring: %s",
- fs::u8string(nupkg_path));
- m_restored.emplace(nuget_ref.first);
- return true;
- }
-
- return false;
- });
- }
-
- Util::erase_remove_if(actions, [this](const Dependencies::InstallPlanAction* action) {
- return Util::Sets::contains(m_restored, action->spec);
- });
-
- System::print2("Restored ",
- m_restored.size() - current_restored,
- " packages from NuGet. Use --debug for more information.\n");
- }
- RestoreResult try_restore(const VcpkgPaths&, const Dependencies::InstallPlanAction& action) override
- {
- if (Util::Sets::contains(m_restored, action.spec))
- {
- return RestoreResult::success;
- }
-
- return RestoreResult::missing;
- }
- void push_success(const VcpkgPaths& paths, const Dependencies::InstallPlanAction& action) override
- {
- if (m_write_sources.empty() && m_write_configs.empty())
- {
- return;
- }
-
- auto& spec = action.spec;
-
- NugetReference nuget_ref(action);
- auto nuspec_path = paths.buildtrees / spec.name() / (spec.triplet().to_string() + ".nuspec");
- paths.get_filesystem().write_contents(
- nuspec_path, generate_nuspec(paths, action, nuget_ref), VCPKG_LINE_INFO);
-
- const auto& nuget_exe = paths.get_tool_exe("nuget");
- System::Command cmdline;
-#ifndef _WIN32
- cmdline.path_arg(paths.get_tool_exe(Tools::MONO));
-#endif
- cmdline.path_arg(nuget_exe)
- .string_arg("pack")
- .path_arg(nuspec_path)
- .string_arg("-OutputDirectory")
- .path_arg(paths.buildtrees)
- .string_arg("-NoDefaultExcludes")
- .string_arg("-ForceEnglishOutput");
- if (!m_interactive) cmdline.string_arg("-NonInteractive");
-
- auto pack_rc = run_nuget_commandline(cmdline);
-
- if (pack_rc != 0)
- {
- System::print2(System::Color::error, "Packing NuGet failed. Use --debug for more information.\n");
- }
- else
- {
- auto nupkg_path = paths.buildtrees / nuget_ref.nupkg_filename();
- for (auto&& write_src : m_write_sources)
- {
- System::Command cmd;
-#ifndef _WIN32
- cmd.path_arg(paths.get_tool_exe(Tools::MONO));
-#endif
- cmd.path_arg(nuget_exe)
- .string_arg("push")
- .path_arg(nupkg_path)
- .string_arg("-ForceEnglishOutput")
- .string_arg("-Source")
- .string_arg(write_src);
-
- if (!m_interactive)
- {
- cmd.string_arg("-NonInteractive");
- }
-
- System::print2("Uploading binaries for ", spec, " to NuGet source ", write_src, ".\n");
-
- auto rc = run_nuget_commandline(cmd);
- if (rc != 0)
- {
- System::print2(System::Color::error,
- "Pushing NuGet to ",
- write_src,
- " failed. Use --debug for more information.\n");
- }
- }
- for (auto&& write_cfg : m_write_configs)
- {
- System::Command cmd;
-#ifndef _WIN32
- cmd.path_arg(paths.get_tool_exe(Tools::MONO));
-#endif
- cmd.path_arg(nuget_exe)
- .string_arg("push")
- .path_arg(nupkg_path)
- .string_arg("-ForceEnglishOutput")
- .string_arg("-ConfigFile")
- .path_arg(write_cfg);
- if (!m_interactive)
- {
- cmd.string_arg("-NonInteractive");
- }
-
- System::print2(
- "Uploading binaries for ", spec, " using NuGet config ", fs::u8string(write_cfg), ".\n");
-
- auto rc = run_nuget_commandline(cmd);
-
- if (rc != 0)
- {
- System::print2(System::Color::error,
- "Pushing NuGet with ",
- fs::u8string(write_cfg),
- " failed. Use --debug for more information.\n");
- }
- }
-
- paths.get_filesystem().remove(nupkg_path, ignore_errors);
- }
- }
-
- private:
- std::vector<std::string> m_read_sources;
- std::vector<std::string> m_write_sources;
-
- std::vector<fs::path> m_read_configs;
- std::vector<fs::path> m_write_configs;
-
- std::set<PackageSpec> m_restored;
- bool m_interactive;
- bool m_use_nuget_cache;
- };
-}
-
-namespace vcpkg
-{
- struct MergeBinaryProviders : NullBinaryProvider
- {
- explicit MergeBinaryProviders(std::vector<std::unique_ptr<IBinaryProvider>>&& providers)
- : m_providers(std::move(providers))
- {
- }
-
- void prefetch(const VcpkgPaths& paths, std::vector<const Dependencies::InstallPlanAction*>& actions) override
- {
- for (auto&& provider : m_providers)
- {
- provider->prefetch(paths, actions);
- }
- }
- RestoreResult try_restore(const VcpkgPaths& paths, const Dependencies::InstallPlanAction& action) override
- {
- for (auto&& provider : m_providers)
- {
- auto result = provider->try_restore(paths, action);
- switch (result)
- {
- case RestoreResult::build_failed:
- case RestoreResult::success: return result;
- case RestoreResult::missing: continue;
- default: Checks::unreachable(VCPKG_LINE_INFO);
- }
- }
- return RestoreResult::missing;
- }
- void push_success(const VcpkgPaths& paths, const Dependencies::InstallPlanAction& action) override
- {
- for (auto&& provider : m_providers)
- {
- provider->push_success(paths, action);
- }
- }
- void precheck(const VcpkgPaths& paths,
- std::unordered_map<const Dependencies::InstallPlanAction*, RestoreResult>& results_map) override
- {
- for (auto&& provider : m_providers)
- {
- provider->precheck(paths, results_map);
- }
- }
-
- private:
- std::vector<std::unique_ptr<IBinaryProvider>> m_providers;
- };
-}
-
-IBinaryProvider& vcpkg::null_binary_provider()
-{
- static NullBinaryProvider p;
- return p;
-}
-
-namespace
-{
- const ExpectedS<fs::path>& default_cache_path()
- {
- static auto cachepath = System::get_platform_cache_home().then([](fs::path p) -> ExpectedS<fs::path> {
- auto maybe_cachepath = System::get_environment_variable("VCPKG_DEFAULT_BINARY_CACHE");
- if (auto p_str = maybe_cachepath.get())
- {
- Metrics::g_metrics.lock()->track_property("VCPKG_DEFAULT_BINARY_CACHE", "defined");
- auto path = fs::u8path(*p_str);
- path.make_preferred();
- const auto status = fs::stdfs::status(path);
- if (!fs::stdfs::exists(status))
- {
- return {"Path to VCPKG_DEFAULT_BINARY_CACHE does not exist: " + fs::u8string(path),
- expected_right_tag};
- }
-
- if (!fs::stdfs::is_directory(status))
- {
- return {"Value of environment variable VCPKG_DEFAULT_BINARY_CACHE is not a directory: " +
- fs::u8string(path),
- expected_right_tag};
- }
-
- if (!path.is_absolute())
- {
- return {"Value of environment variable VCPKG_DEFAULT_BINARY_CACHE is not absolute: " +
- fs::u8string(path),
- expected_right_tag};
- }
-
- return {std::move(path), expected_left_tag};
- }
- p /= fs::u8path("vcpkg/archives");
- p.make_preferred();
- if (p.is_absolute())
- {
- return {std::move(p), expected_left_tag};
- }
- else
- {
- return {"default path was not absolute: " + fs::u8string(p), expected_right_tag};
- }
- });
- return cachepath;
- }
-
- struct State
- {
- bool m_cleared = false;
- bool interactive = false;
-
- std::vector<fs::path> archives_to_read;
- std::vector<fs::path> archives_to_write;
-
- std::vector<std::string> url_templates_to_get;
- std::vector<std::string> azblob_templates_to_put;
-
- std::vector<std::string> sources_to_read;
- std::vector<std::string> sources_to_write;
-
- std::vector<fs::path> configs_to_read;
- std::vector<fs::path> configs_to_write;
-
- std::vector<std::string> secrets;
-
- void clear()
- {
- m_cleared = true;
- interactive = false;
- archives_to_read.clear();
- archives_to_write.clear();
- url_templates_to_get.clear();
- azblob_templates_to_put.clear();
- sources_to_read.clear();
- sources_to_write.clear();
- configs_to_read.clear();
- configs_to_write.clear();
- secrets.clear();
- }
- };
-
- struct BinaryConfigParser : Parse::ParserBase
- {
- BinaryConfigParser(StringView text, StringView origin, State* state)
- : Parse::ParserBase(text, origin), state(state)
- {
- }
-
- State* state;
-
- void parse()
- {
- while (!at_eof())
- {
- std::vector<std::pair<SourceLoc, std::string>> segments;
-
- for (;;)
- {
- SourceLoc loc = cur_loc();
- std::string segment;
- for (;;)
- {
- auto n = match_until([](char32_t ch) { return ch == ',' || ch == '`' || ch == ';'; });
- Strings::append(segment, n);
- auto ch = cur();
- if (ch == Unicode::end_of_file || ch == ',' || ch == ';')
- {
- break;
- }
-
- if (ch == '`')
- {
- ch = next();
- if (ch == Unicode::end_of_file)
- {
- add_error("unexpected eof: trailing unescaped backticks (`) are not allowed");
- }
- else
- {
- Unicode::utf8_append_code_point(segment, ch);
- }
-
- next();
- }
- else
- {
- Checks::unreachable(VCPKG_LINE_INFO);
- }
- }
- segments.emplace_back(std::move(loc), std::move(segment));
-
- auto ch = cur();
- if (ch == Unicode::end_of_file || ch == ';')
- {
- break;
- }
-
- if (ch == ',')
- {
- next();
- continue;
- }
-
- Checks::unreachable(VCPKG_LINE_INFO);
- }
-
- if (segments.size() != 1 || !segments[0].second.empty())
- {
- handle_segments(std::move(segments));
- }
-
- segments.clear();
- if (get_error())
- {
- return;
- }
-
- if (cur() == ';')
- {
- next();
- }
- }
- }
-
- template<class T>
- void handle_readwrite(std::vector<T>& read,
- std::vector<T>& write,
- T&& t,
- const std::vector<std::pair<SourceLoc, std::string>>& segments,
- size_t segment_idx)
- {
- if (segment_idx >= segments.size())
- {
- read.push_back(std::move(t));
- return;
- }
-
- auto& mode = segments[segment_idx].second;
-
- if (mode == "read")
- {
- read.push_back(std::move(t));
- }
- else if (mode == "write")
- {
- write.push_back(std::move(t));
- }
- else if (mode == "readwrite")
- {
- read.push_back(t);
- write.push_back(std::move(t));
- }
- else
- {
- return add_error("unexpected argument: expected 'read', readwrite', or 'write'",
- segments[segment_idx].first);
- }
- }
-
- void handle_segments(std::vector<std::pair<SourceLoc, std::string>>&& segments)
- {
- if (segments.empty()) return;
- if (segments[0].second == "clear")
- {
- if (segments.size() != 1)
- {
- return add_error("unexpected arguments: binary config 'clear' does not take arguments",
- segments[1].first);
- }
-
- state->clear();
- }
- else if (segments[0].second == "files")
- {
- if (segments.size() < 2)
- {
- return add_error("expected arguments: binary config 'files' requires at least a path argument",
- segments[0].first);
- }
-
- auto p = fs::u8path(segments[1].second);
- if (!p.is_absolute())
- {
- return add_error("expected arguments: path arguments for binary config strings must be absolute",
- segments[1].first);
- }
-
- handle_readwrite(state->archives_to_read, state->archives_to_write, std::move(p), segments, 2);
- if (segments.size() > 3)
- {
- return add_error("unexpected arguments: binary config 'files' requires 1 or 2 arguments",
- segments[3].first);
- }
- }
- else if (segments[0].second == "interactive")
- {
- if (segments.size() > 1)
- {
- return add_error("unexpected arguments: binary config 'interactive' does not accept any arguments",
- segments[1].first);
- }
-
- state->interactive = true;
- }
- else if (segments[0].second == "nugetconfig")
- {
- if (segments.size() < 2)
- {
- return add_error(
- "expected arguments: binary config 'nugetconfig' requires at least a source argument",
- segments[0].first);
- }
-
- auto p = fs::u8path(segments[1].second);
- if (!p.is_absolute())
- {
- return add_error("expected arguments: path arguments for binary config strings must be absolute",
- segments[1].first);
- }
-
- handle_readwrite(state->configs_to_read, state->configs_to_write, std::move(p), segments, 2);
- if (segments.size() > 3)
- {
- return add_error("unexpected arguments: binary config 'nugetconfig' requires 1 or 2 arguments",
- segments[3].first);
- }
- }
- else if (segments[0].second == "nuget")
- {
- if (segments.size() < 2)
- {
- return add_error("expected arguments: binary config 'nuget' requires at least a source argument",
- segments[0].first);
- }
-
- auto&& p = segments[1].second;
- if (p.empty())
- {
- return add_error("unexpected arguments: binary config 'nuget' requires non-empty source");
- }
-
- handle_readwrite(state->sources_to_read, state->sources_to_write, std::move(p), segments, 2);
- if (segments.size() > 3)
- {
- return add_error("unexpected arguments: binary config 'nuget' requires 1 or 2 arguments",
- segments[3].first);
- }
- }
- else if (segments[0].second == "default")
- {
- if (segments.size() > 2)
- {
- return add_error("unexpected arguments: binary config 'default' does not take more than 1 argument",
- segments[0].first);
- }
-
- const auto& maybe_home = default_cache_path();
- if (!maybe_home.has_value())
- {
- return add_error(maybe_home.error(), segments[0].first);
- }
-
- handle_readwrite(
- state->archives_to_read, state->archives_to_write, fs::path(*maybe_home.get()), segments, 1);
- }
- else if (segments[0].second == "x-azblob")
- {
- // Scheme: x-azblob,<baseurl>,<sas>[,<readwrite>]
- if (segments.size() < 3)
- {
- return add_error(
- "expected arguments: binary config 'azblob' requires at least a base-url and a SAS token",
- segments[0].first);
- }
-
- if (!Strings::starts_with(segments[1].second, "https://"))
- {
- return add_error(
- "invalid argument: binary config 'azblob' requires an https base url as the first argument",
- segments[1].first);
- }
-
- if (Strings::starts_with(segments[2].second, "?"))
- {
- return add_error("invalid argument: binary config 'azblob' requires a SAS token without a "
- "preceeding '?' as the second argument",
- segments[2].first);
- }
-
- if (segments.size() > 4)
- {
- return add_error("unexpected arguments: binary config 'azblob' requires 2 or 3 arguments",
- segments[4].first);
- }
-
- auto p = segments[1].second;
- if (p.back() != '/')
- {
- p.push_back('/');
- }
-
- p.append("<SHA>.zip");
- if (!Strings::starts_with(segments[2].second, "?"))
- {
- p.push_back('?');
- }
-
- p.append(segments[2].second);
- state->secrets.push_back(segments[2].second);
- handle_readwrite(
- state->url_templates_to_get, state->azblob_templates_to_put, std::move(p), segments, 3);
- }
- else
- {
- return add_error(
- "unknown binary provider type: valid providers are 'clear', 'default', 'nuget', 'nugetconfig', "
- "'interactive', and 'files'",
- segments[0].first);
- }
- }
- };
-}
-
-ExpectedS<std::unique_ptr<IBinaryProvider>> vcpkg::create_binary_provider_from_configs(View<std::string> args)
-{
- std::string env_string = System::get_environment_variable("VCPKG_BINARY_SOURCES").value_or("");
- if (Debug::g_debugging)
- {
- const auto& cachepath = default_cache_path();
- if (cachepath.has_value())
- {
- Debug::print("Default binary cache path is: ", fs::u8string(*cachepath.get()), '\n');
- }
- else
- {
- Debug::print("No binary cache path. Reason: ", cachepath.error(), '\n');
- }
- }
-
- return create_binary_provider_from_configs_pure(env_string, args);
-}
-
-ExpectedS<std::unique_ptr<IBinaryProvider>> vcpkg::create_binary_provider_from_configs_pure(
- const std::string& env_string, View<std::string> args)
-{
- {
- auto metrics = Metrics::g_metrics.lock();
- if (!env_string.empty())
- {
- metrics->track_property("VCPKG_BINARY_SOURCES", "defined");
- }
-
- if (args.size() != 0)
- {
- metrics->track_property("binarycaching-source", "defined");
- }
- }
-
- State s;
-
- BinaryConfigParser default_parser("default,readwrite", "<defaults>", &s);
- default_parser.parse();
- if (auto err = default_parser.get_error())
- {
- return err->get_message();
- }
-
- BinaryConfigParser env_parser(env_string, "VCPKG_BINARY_SOURCES", &s);
- env_parser.parse();
- if (auto err = env_parser.get_error())
- {
- return err->format();
- }
-
- for (auto&& arg : args)
- {
- BinaryConfigParser arg_parser(arg, "<command>", &s);
- arg_parser.parse();
- if (auto err = arg_parser.get_error())
- {
- return err->format();
- }
- }
-
- if (s.m_cleared)
- {
- Metrics::g_metrics.lock()->track_property("binarycaching-clear", "defined");
- }
-
- std::vector<std::unique_ptr<IBinaryProvider>> providers;
- if (!s.archives_to_read.empty() || !s.archives_to_write.empty() || !s.azblob_templates_to_put.empty())
- {
- providers.push_back(std::make_unique<ArchivesBinaryProvider>(std::move(s.archives_to_read),
- std::move(s.archives_to_write),
- std::move(s.azblob_templates_to_put),
- std::move(s.secrets)));
- }
-
- if (!s.url_templates_to_get.empty())
- {
- Metrics::g_metrics.lock()->track_property("binarycaching-url-get", "defined");
- providers.push_back(std::make_unique<HttpGetBinaryProvider>(std::move(s.url_templates_to_get)));
- }
-
- if (!s.sources_to_read.empty() || !s.sources_to_write.empty() || !s.configs_to_read.empty() ||
- !s.configs_to_write.empty())
- {
- Metrics::g_metrics.lock()->track_property("binarycaching-nuget", "defined");
- providers.push_back(std::make_unique<NugetBinaryProvider>(std::move(s.sources_to_read),
- std::move(s.sources_to_write),
- std::move(s.configs_to_read),
- std::move(s.configs_to_write),
- s.interactive));
- }
-
- return {std::make_unique<MergeBinaryProviders>(std::move(providers))};
-}
-
-std::string vcpkg::reformat_version(const std::string& version, const std::string& abi_tag)
-{
- static const std::regex semver_matcher(R"(v?(\d+)(\.\d+|$)(\.\d+)?.*)");
-
- std::smatch sm;
- if (std::regex_match(version.cbegin(), version.cend(), sm, semver_matcher))
- {
- auto major = trim_leading_zeroes(sm.str(1));
- auto minor = sm.size() > 2 && !sm.str(2).empty() ? trim_leading_zeroes(sm.str(2).substr(1)) : "0";
- auto patch = sm.size() > 3 && !sm.str(3).empty() ? trim_leading_zeroes(sm.str(3).substr(1)) : "0";
- return Strings::concat(major, '.', minor, '.', patch, "-vcpkg", abi_tag);
- }
-
- static const std::regex date_matcher(R"((\d\d\d\d)-(\d\d)-(\d\d).*)");
- if (std::regex_match(version.cbegin(), version.cend(), sm, date_matcher))
- {
- return Strings::concat(trim_leading_zeroes(sm.str(1)),
- '.',
- trim_leading_zeroes(sm.str(2)),
- '.',
- trim_leading_zeroes(sm.str(3)),
- "-vcpkg",
- abi_tag);
- }
-
- return Strings::concat("0.0.0-vcpkg", abi_tag);
-}
-
-details::NuGetRepoInfo details::get_nuget_repo_info_from_env()
-{
- auto vcpkg_nuget_repository = System::get_environment_variable("VCPKG_NUGET_REPOSITORY");
- if (auto p = vcpkg_nuget_repository.get())
- {
- Metrics::g_metrics.lock()->track_property("VCPKG_NUGET_REPOSITORY", "defined");
- return {std::move(*p)};
- }
-
- auto gh_repo = System::get_environment_variable("GITHUB_REPOSITORY").value_or("");
- if (gh_repo.empty())
- {
- return {};
- }
-
- auto gh_server = System::get_environment_variable("GITHUB_SERVER_URL").value_or("");
- if (gh_server.empty())
- {
- return {};
- }
-
- Metrics::g_metrics.lock()->track_property("GITHUB_REPOSITORY", "defined");
- return {Strings::concat(gh_server, '/', gh_repo, ".git"),
- System::get_environment_variable("GITHUB_REF").value_or(""),
- System::get_environment_variable("GITHUB_SHA").value_or("")};
-}
-
-std::string vcpkg::generate_nuspec(const VcpkgPaths& paths,
- const Dependencies::InstallPlanAction& action,
- const vcpkg::NugetReference& ref,
- details::NuGetRepoInfo rinfo)
-{
- auto& spec = action.spec;
- auto& scf = *action.source_control_file_location.value_or_exit(VCPKG_LINE_INFO).source_control_file;
- auto& version = scf.core_paragraph->version;
- const auto& abi_info = action.abi_info.value_or_exit(VCPKG_LINE_INFO);
- const auto& compiler_info = abi_info.compiler_info.value_or_exit(VCPKG_LINE_INFO);
- std::string description =
- Strings::concat("NOT FOR DIRECT USE. Automatically generated cache package.\n\n",
- Strings::join("\n ", scf.core_paragraph->description),
- "\n\nVersion: ",
- version,
- "\nTriplet: ",
- spec.triplet().to_string(),
- "\nCXX Compiler id: ",
- compiler_info.id,
- "\nCXX Compiler version: ",
- compiler_info.version,
- "\nTriplet/Compiler hash: ",
- abi_info.triplet_abi.value_or_exit(VCPKG_LINE_INFO),
- "\nFeatures:",
- Strings::join(",", action.feature_list, [](const std::string& s) { return " " + s; }),
- "\nDependencies:\n");
-
- for (auto&& dep : action.package_dependencies)
- {
- Strings::append(description, " ", dep.name(), '\n');
- }
-
- XmlSerializer xml;
- xml.open_tag("package").line_break();
- xml.open_tag("metadata").line_break();
- xml.simple_tag("id", ref.id).line_break();
- xml.simple_tag("version", ref.version).line_break();
- if (!scf.core_paragraph->homepage.empty())
- {
- xml.simple_tag("projectUrl", scf.core_paragraph->homepage);
- }
-
- xml.simple_tag("authors", "vcpkg").line_break();
- xml.simple_tag("description", description).line_break();
- xml.open_tag("packageTypes");
- xml.start_complex_open_tag("packageType").text_attr("name", "vcpkg").finish_self_closing_complex_tag();
- xml.close_tag("packageTypes").line_break();
- if (!rinfo.repo.empty())
- {
- xml.start_complex_open_tag("repository").text_attr("type", "git").text_attr("url", rinfo.repo);
- if (!rinfo.branch.empty())
- {
- xml.text_attr("branch", rinfo.branch);
- }
-
- if (!rinfo.commit.empty())
- {
- xml.text_attr("commit", rinfo.commit);
- }
-
- xml.finish_self_closing_complex_tag().line_break();
- }
-
- xml.close_tag("metadata").line_break();
- xml.open_tag("files");
- xml.start_complex_open_tag("file")
- .text_attr("src", fs::u8string(paths.package_dir(spec) / fs::u8path("**")))
- .text_attr("target", "")
- .finish_self_closing_complex_tag();
- xml.close_tag("files").line_break();
- xml.close_tag("package").line_break();
- return std::move(xml.buf);
-}
-
-void vcpkg::help_topic_binary_caching(const VcpkgPaths&)
-{
- HelpTableFormatter tbl;
- tbl.text("Vcpkg can cache compiled packages to accelerate restoration on a single machine or across the network."
- " By default, vcpkg will save builds to a local machine cache. This can be disabled by passing "
- "`--binarysource=clear` as the last option on the command line.");
- tbl.blank();
- tbl.blank();
- tbl.text(
- "Binary caching can be further configured by either passing `--binarysource=<source>` options "
- "to every command line or setting the `VCPKG_BINARY_SOURCES` environment variable to a set of sources (Ex: "
- "\"<source>;<source>;...\"). Command line sources are interpreted after environment sources.");
- tbl.blank();
- tbl.blank();
- tbl.header("Valid source strings");
- tbl.format("clear", "Removes all previous sources");
- tbl.format("default[,<rw>]", "Adds the default file-based location.");
- tbl.format("files,<path>[,<rw>]", "Adds a custom file-based location.");
- tbl.format("nuget,<uri>[,<rw>]",
- "Adds a NuGet-based source; equivalent to the `-Source` parameter of the NuGet CLI.");
- tbl.format("nugetconfig,<path>[,<rw>]",
- "Adds a NuGet-config-file-based source; equivalent to the `-Config` parameter of the NuGet CLI. This "
- "config should specify `defaultPushSource` for uploads.");
- tbl.format("x-azblob,<url>,<sas>[,<rw>]",
- "**Experimental: will change or be removed without warning** Adds an Azure Blob Storage source. Uses "
- "Shared Access Signature validation. URL should include the container path.");
- tbl.format("interactive", "Enables interactive credential management for some source types");
- tbl.blank();
- tbl.text("The `<rw>` optional parameter for certain strings controls whether they will be consulted for "
- "downloading binaries and whether on-demand builds will be uploaded to that remote. It can be specified "
- "as 'read', 'write', or 'readwrite'.");
- tbl.blank();
- tbl.text("The `nuget` and `nugetconfig` source providers additionally respect certain environment variables while "
- "generating nuget packages. The `metadata.repository` field will be optionally generated like:\n"
- "\n"
- " <repository type=\"git\" url=\"$VCPKG_NUGET_REPOSITORY\"/>\n"
- "or\n"
- " <repository type=\"git\"\n"
- " url=\"${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}.git\"\n"
- " branch=\"${GITHUB_REF}\"\n"
- " commit=\"${GITHUB_SHA}\"/>\n"
- "\n"
- "if the appropriate environment variables are defined and non-empty.\n");
- tbl.blank();
- tbl.text("NuGet's cache is not used by default. To use it for every nuget-based source, set the environment "
- "variable `VCPKG_USE_NUGET_CACHE` to `true` (case-insensitive) or `1`.\n");
- tbl.blank();
- System::print2(tbl.m_str);
- const auto& maybe_cachepath = default_cache_path();
- if (auto p = maybe_cachepath.get())
- {
- System::print2(
- "\nBased on your system settings, the default path to store binaries is\n ",
- fs::u8string(*p),
- "\nThis consults %LOCALAPPDATA%/%APPDATA% on Windows and $XDG_CACHE_HOME or $HOME on other platforms.\n");
- }
-
- System::print2("\nExtended documentation is available at "
- "https://github.com/Microsoft/vcpkg/tree/master/docs/users/binarycaching.md \n");
-}
-
-std::string vcpkg::generate_nuget_packages_config(const Dependencies::ActionPlan& action)
-{
- auto refs = Util::fmap(action.install_actions,
- [&](const Dependencies::InstallPlanAction& ipa) { return NugetReference(ipa); });
- XmlSerializer xml;
- xml.emit_declaration().line_break();
- xml.open_tag("packages").line_break();
- for (auto&& ref : refs)
- {
- xml.start_complex_open_tag("package")
- .text_attr("id", ref.id)
- .text_attr("version", ref.version)
- .finish_self_closing_complex_tag()
- .line_break();
- }
-
- xml.close_tag("packages").line_break();
- return std::move(xml.buf);
-}
diff --git a/toolsrc/src/vcpkg/binaryparagraph.cpp b/toolsrc/src/vcpkg/binaryparagraph.cpp
deleted file mode 100644
index f86081223..000000000
--- a/toolsrc/src/vcpkg/binaryparagraph.cpp
+++ /dev/null
@@ -1,312 +0,0 @@
-#include <vcpkg/base/checks.h>
-#include <vcpkg/base/system.print.h>
-#include <vcpkg/base/util.h>
-
-#include <vcpkg/binaryparagraph.h>
-#include <vcpkg/paragraphparser.h>
-#include <vcpkg/paragraphs.h>
-
-namespace vcpkg
-{
- namespace Fields
- {
- static const std::string PACKAGE = "Package";
- static const std::string VERSION = "Version";
- static const std::string PORT_VERSION = "Port-Version";
- static const std::string ARCHITECTURE = "Architecture";
- static const std::string MULTI_ARCH = "Multi-Arch";
- }
-
- namespace Fields
- {
- static const std::string ABI = "Abi";
- static const std::string FEATURE = "Feature";
- static const std::string DESCRIPTION = "Description";
- static const std::string MAINTAINER = "Maintainer";
- static const std::string DEPENDS = "Depends";
- static const std::string DEFAULT_FEATURES = "Default-Features";
- static const std::string TYPE = "Type";
- }
-
- BinaryParagraph::BinaryParagraph() = default;
-
- BinaryParagraph::BinaryParagraph(Parse::Paragraph fields)
- {
- using namespace vcpkg::Parse;
-
- ParagraphParser parser(std::move(fields));
-
- {
- std::string name;
- parser.required_field(Fields::PACKAGE, name);
- std::string architecture;
- parser.required_field(Fields::ARCHITECTURE, architecture);
- this->spec = PackageSpec(std::move(name), Triplet::from_canonical_name(std::move(architecture)));
- }
-
- // one or the other
- this->version = parser.optional_field(Fields::VERSION);
- this->feature = parser.optional_field(Fields::FEATURE);
-
- auto pv_str = parser.optional_field(Fields::PORT_VERSION);
- this->port_version = 0;
- if (!pv_str.empty())
- {
- auto pv_opt = Strings::strto<int>(pv_str);
- if (auto pv = pv_opt.get())
- {
- this->port_version = *pv;
- }
- else
- {
- parser.add_type_error(Fields::PORT_VERSION, "a non-negative integer");
- }
- }
-
- this->description = Strings::split(parser.optional_field(Fields::DESCRIPTION), '\n');
- for (auto& desc : this->description)
- {
- desc = Strings::trim(std::move(desc));
- }
- this->maintainers = Strings::split(parser.optional_field(Fields::MAINTAINER), '\n');
- for (auto& maintainer : this->maintainers)
- {
- maintainer = Strings::trim(std::move(maintainer));
- }
-
- this->abi = parser.optional_field(Fields::ABI);
-
- std::string multi_arch;
- parser.required_field(Fields::MULTI_ARCH, multi_arch);
-
- this->dependencies = Util::fmap(
- parse_qualified_specifier_list(parser.optional_field(Fields::DEPENDS)).value_or_exit(VCPKG_LINE_INFO),
- [](const ParsedQualifiedSpecifier& dep) {
- // for compatibility with previous vcpkg versions, we discard all irrelevant information
- return dep.name;
- });
- if (!this->is_feature())
- {
- this->default_features = parse_default_features_list(parser.optional_field(Fields::DEFAULT_FEATURES))
- .value_or_exit(VCPKG_LINE_INFO);
- }
-
- this->type = Type::from_string(parser.optional_field(Fields::TYPE));
-
- if (const auto err = parser.error_info(this->spec.to_string()))
- {
- System::print2(System::Color::error, "Error: while parsing the Binary Paragraph for ", this->spec, '\n');
- print_error_message(err);
- Checks::exit_fail(VCPKG_LINE_INFO);
- }
-
- // prefer failing above when possible because it gives better information
- Checks::check_exit(VCPKG_LINE_INFO, multi_arch == "same", "Multi-Arch must be 'same' but was %s", multi_arch);
- }
-
- BinaryParagraph::BinaryParagraph(const SourceParagraph& spgh,
- Triplet triplet,
- const std::string& abi_tag,
- const std::vector<FeatureSpec>& deps)
- : spec(spgh.name, triplet)
- , version(spgh.version)
- , port_version(spgh.port_version)
- , description(spgh.description)
- , maintainers(spgh.maintainers)
- , feature()
- , default_features(spgh.default_features)
- , dependencies()
- , abi(abi_tag)
- , type(spgh.type)
- {
- this->dependencies = Util::fmap(deps, [](const FeatureSpec& spec) { return spec.spec().name(); });
- Util::sort_unique_erase(this->dependencies);
- }
-
- BinaryParagraph::BinaryParagraph(const SourceParagraph& spgh,
- const FeatureParagraph& fpgh,
- Triplet triplet,
- const std ::vector<FeatureSpec>& deps)
- : spec(spgh.name, triplet)
- , version()
- , port_version()
- , description(fpgh.description)
- , maintainers()
- , feature(fpgh.name)
- , default_features()
- , dependencies()
- , abi()
- , type(spgh.type)
- {
- this->dependencies = Util::fmap(deps, [](const FeatureSpec& spec) { return spec.spec().name(); });
- Util::sort_unique_erase(this->dependencies);
- }
-
- std::string BinaryParagraph::displayname() const
- {
- if (!this->is_feature() || this->feature == "core")
- return Strings::format("%s:%s", this->spec.name(), this->spec.triplet());
- return Strings::format("%s[%s]:%s", this->spec.name(), this->feature, this->spec.triplet());
- }
-
- std::string BinaryParagraph::dir() const { return this->spec.dir(); }
-
- std::string BinaryParagraph::fullstem() const
- {
- return Strings::format("%s_%s_%s", this->spec.name(), this->version, this->spec.triplet());
- }
-
- bool operator==(const BinaryParagraph& lhs, const BinaryParagraph& rhs)
- {
- if (lhs.spec != rhs.spec) return false;
- if (lhs.version != rhs.version) return false;
- if (lhs.port_version != rhs.port_version) return false;
- if (lhs.description != rhs.description) return false;
- if (lhs.maintainers != rhs.maintainers) return false;
- if (lhs.feature != rhs.feature) return false;
- if (lhs.default_features != rhs.default_features) return false;
- if (lhs.dependencies != rhs.dependencies) return false;
- if (lhs.abi != rhs.abi) return false;
- if (lhs.type != rhs.type) return false;
-
- return true;
- }
-
- bool operator!=(const BinaryParagraph& lhs, const BinaryParagraph& rhs) { return !(lhs == rhs); }
-
- static void serialize_string(StringView name, const std::string& field, std::string& out_str)
- {
- if (field.empty())
- {
- return;
- }
-
- out_str.append(name.begin(), name.end()).append(": ").append(field).push_back('\n');
- }
- static void serialize_array(StringView name,
- const std::vector<std::string>& array,
- std::string& out_str,
- const char* joiner = ", ")
- {
- if (array.empty())
- {
- return;
- }
-
- out_str.append(name.begin(), name.end()).append(": ");
- out_str.append(Strings::join(joiner, array));
- out_str.push_back('\n');
- }
- static void serialize_paragraph(StringView name, const std::vector<std::string>& array, std::string& out_str)
- {
- serialize_array(name, array, out_str, "\n ");
- }
-
- void serialize(const BinaryParagraph& pgh, std::string& out_str)
- {
- const size_t initial_end = out_str.size();
-
- serialize_string(Fields::PACKAGE, pgh.spec.name(), out_str);
-
- serialize_string(Fields::VERSION, pgh.version, out_str);
- if (pgh.port_version != 0)
- {
- out_str.append(Fields::PORT_VERSION).append(": ").append(std::to_string(pgh.port_version)).push_back('\n');
- }
-
- if (pgh.is_feature())
- {
- serialize_string(Fields::FEATURE, pgh.feature, out_str);
- }
-
- if (!pgh.dependencies.empty())
- {
- serialize_array(Fields::DEPENDS, pgh.dependencies, out_str);
- }
-
- serialize_string(Fields::ARCHITECTURE, pgh.spec.triplet().to_string(), out_str);
- serialize_string(Fields::MULTI_ARCH, "same", out_str);
-
- serialize_paragraph(Fields::MAINTAINER, pgh.maintainers, out_str);
-
- serialize_string(Fields::ABI, pgh.abi, out_str);
-
- serialize_paragraph(Fields::DESCRIPTION, pgh.description, out_str);
-
- serialize_string(Fields::TYPE, Type::to_string(pgh.type), out_str);
- serialize_array(Fields::DEFAULT_FEATURES, pgh.default_features, out_str);
-
- // sanity check the serialized data
- const auto my_paragraph = out_str.substr(initial_end);
- auto parsed_paragraph = Paragraphs::parse_single_paragraph(
- out_str.substr(initial_end), "vcpkg::serialize(const BinaryParagraph&, std::string&)");
- if (!parsed_paragraph.has_value())
- {
- Checks::exit_maybe_upgrade(VCPKG_LINE_INFO,
- R"([sanity check] Failed to parse a serialized binary paragraph.
-Please open an issue at https://github.com/microsoft/vcpkg, with the following output:
- Error: %s
-
-=== Serialized BinaryParagraph ===
-%s
- )",
- parsed_paragraph.error(),
- my_paragraph);
- }
-
- auto binary_paragraph = BinaryParagraph(*parsed_paragraph.get());
- if (binary_paragraph != pgh)
- {
- const auto& join_str = R"(", ")";
- Checks::exit_maybe_upgrade(
- VCPKG_LINE_INFO,
- R"([sanity check] The serialized binary paragraph was different from the original binary paragraph.
-Please open an issue at https://github.com/microsoft/vcpkg, with the following output:
-
-=== Original BinaryParagraph ===
-spec: "%s"
-version: "%s"
-port_version: %d
-description: ["%s"]
-maintainers: ["%s"]
-feature: "%s"
-default_features: ["%s"]
-dependencies: ["%s"]
-abi: "%s"
-type: %s
-
-=== Serialized BinaryParagraph ===
-spec: "%s"
-version: "%s"
-port_version: %d
-description: ["%s"]
-maintainers: ["%s"]
-feature: "%s"
-default_features: ["%s"]
-dependencies: ["%s"]
-abi: "%s"
-type: %s
-)",
- pgh.spec.to_string(),
- pgh.version,
- pgh.port_version,
- Strings::join(join_str, pgh.description),
- Strings::join(join_str, pgh.maintainers),
- pgh.feature,
- Strings::join(join_str, pgh.default_features),
- Strings::join(join_str, pgh.dependencies),
- pgh.abi,
- Type::to_string(pgh.type),
- binary_paragraph.spec.to_string(),
- binary_paragraph.version,
- binary_paragraph.port_version,
- Strings::join(join_str, binary_paragraph.description),
- Strings::join(join_str, binary_paragraph.maintainers),
- binary_paragraph.feature,
- Strings::join(join_str, binary_paragraph.default_features),
- Strings::join(join_str, binary_paragraph.dependencies),
- binary_paragraph.abi,
- Type::to_string(binary_paragraph.type));
- }
- }
-}
diff --git a/toolsrc/src/vcpkg/build.cpp b/toolsrc/src/vcpkg/build.cpp
deleted file mode 100644
index b38062f0c..000000000
--- a/toolsrc/src/vcpkg/build.cpp
+++ /dev/null
@@ -1,1491 +0,0 @@
-#include <vcpkg/base/cache.h>
-#include <vcpkg/base/checks.h>
-#include <vcpkg/base/chrono.h>
-#include <vcpkg/base/enums.h>
-#include <vcpkg/base/hash.h>
-#include <vcpkg/base/optional.h>
-#include <vcpkg/base/stringliteral.h>
-#include <vcpkg/base/system.debug.h>
-#include <vcpkg/base/system.print.h>
-#include <vcpkg/base/system.process.h>
-#include <vcpkg/base/util.h>
-
-#include <vcpkg/binarycaching.h>
-#include <vcpkg/build.h>
-#include <vcpkg/buildenvironment.h>
-#include <vcpkg/cmakevars.h>
-#include <vcpkg/commands.h>
-#include <vcpkg/commands.version.h>
-#include <vcpkg/dependencies.h>
-#include <vcpkg/globalstate.h>
-#include <vcpkg/help.h>
-#include <vcpkg/input.h>
-#include <vcpkg/metrics.h>
-#include <vcpkg/paragraphs.h>
-#include <vcpkg/portfileprovider.h>
-#include <vcpkg/postbuildlint.h>
-#include <vcpkg/statusparagraphs.h>
-#include <vcpkg/tools.h>
-#include <vcpkg/vcpkglib.h>
-
-using namespace vcpkg;
-using vcpkg::Build::BuildResult;
-using vcpkg::Parse::ParseControlErrorInfo;
-using vcpkg::Parse::ParseExpected;
-using vcpkg::PortFileProvider::PathsPortFileProvider;
-
-namespace
-{
- using vcpkg::PackageSpec;
- using vcpkg::VcpkgPaths;
- using vcpkg::Build::IBuildLogsRecorder;
- struct NullBuildLogsRecorder final : IBuildLogsRecorder
- {
- void record_build_result(const VcpkgPaths& paths, const PackageSpec& spec, BuildResult result) const override
- {
- (void)paths;
- (void)spec;
- (void)result;
- }
- };
-
- static const NullBuildLogsRecorder null_build_logs_recorder_instance;
-}
-
-namespace vcpkg::Build
-{
- using Dependencies::InstallPlanAction;
- using Dependencies::InstallPlanType;
-
- void Command::perform_and_exit_ex(const VcpkgCmdArguments& args,
- const FullPackageSpec& full_spec,
- const SourceControlFileLocation& scfl,
- const PathsPortFileProvider& provider,
- IBinaryProvider& binaryprovider,
- const IBuildLogsRecorder& build_logs_recorder,
- const VcpkgPaths& paths)
- {
- Checks::exit_with_code(VCPKG_LINE_INFO,
- perform_ex(args, full_spec, scfl, provider, binaryprovider, build_logs_recorder, paths));
- }
-
- const CommandStructure COMMAND_STRUCTURE = {
- create_example_string("build zlib:x64-windows"),
- 1,
- 1,
- {{}, {}},
- nullptr,
- };
-
- void Command::perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, Triplet default_triplet)
- {
- Checks::exit_with_code(VCPKG_LINE_INFO, perform(args, paths, default_triplet));
- }
-
- int Command::perform_ex(const VcpkgCmdArguments& args,
- const FullPackageSpec& full_spec,
- const SourceControlFileLocation& scfl,
- const PathsPortFileProvider& provider,
- IBinaryProvider& binaryprovider,
- const IBuildLogsRecorder& build_logs_recorder,
- const VcpkgPaths& paths)
- {
- auto var_provider_storage = CMakeVars::make_triplet_cmake_var_provider(paths);
- auto& var_provider = *var_provider_storage;
- var_provider.load_dep_info_vars({{full_spec.package_spec}});
-
- StatusParagraphs status_db = database_load_check(paths);
-
- auto action_plan = Dependencies::create_feature_install_plan(
- provider, var_provider, std::vector<FullPackageSpec>{full_spec}, status_db);
-
- var_provider.load_tag_vars(action_plan, provider);
-
- const PackageSpec& spec = full_spec.package_spec;
- const SourceControlFile& scf = *scfl.source_control_file;
-
- Checks::check_maybe_upgrade(
- VCPKG_LINE_INFO,
- spec.name() == scf.core_paragraph->name,
- Strings::format("The Source field inside the CONTROL file does not match the port directory: '%s' != '%s'",
- scf.core_paragraph->name,
- spec.name()));
-
- compute_all_abis(paths, action_plan, var_provider, status_db);
-
- InstallPlanAction* action = nullptr;
- for (auto& install_action : action_plan.already_installed)
- {
- if (install_action.spec == full_spec.package_spec)
- {
- action = &install_action;
- }
- }
- for (auto& install_action : action_plan.install_actions)
- {
- if (install_action.spec == full_spec.package_spec)
- {
- action = &install_action;
- }
- }
-
- Checks::check_exit(VCPKG_LINE_INFO, action != nullptr);
- ASSUME(action != nullptr);
- action->build_options = default_build_package_options;
- action->build_options.editable = Editable::YES;
- action->build_options.clean_buildtrees = CleanBuildtrees::NO;
- action->build_options.clean_packages = CleanPackages::NO;
-
- const auto build_timer = Chrono::ElapsedTimer::create_started();
- const auto result = Build::build_package(args, paths, *action, binaryprovider, build_logs_recorder, status_db);
- System::print2("Elapsed time for package ", spec, ": ", build_timer, '\n');
-
- if (result.code == BuildResult::CASCADED_DUE_TO_MISSING_DEPENDENCIES)
- {
- System::print2(System::Color::error,
- "The build command requires all dependencies to be already installed.\n");
- System::print2("The following dependencies are missing:\n\n");
- for (const auto& p : result.unmet_dependencies)
- {
- System::print2(" ", p, '\n');
- }
- System::print2('\n');
- Checks::exit_fail(VCPKG_LINE_INFO);
- }
-
- Checks::check_exit(VCPKG_LINE_INFO, result.code != BuildResult::EXCLUDED);
-
- if (result.code != BuildResult::SUCCEEDED)
- {
- System::print2(System::Color::error, Build::create_error_message(result.code, spec), '\n');
- System::print2(Build::create_user_troubleshooting_message(spec), '\n');
- return 1;
- }
-
- return 0;
- }
-
- int Command::perform(const VcpkgCmdArguments& args, const VcpkgPaths& paths, Triplet default_triplet)
- {
- // Build only takes a single package and all dependencies must already be installed
- const ParsedArguments options = args.parse_arguments(COMMAND_STRUCTURE);
- std::string first_arg = args.command_arguments.at(0);
-
- auto binaryprovider = create_binary_provider_from_configs(args.binary_sources).value_or_exit(VCPKG_LINE_INFO);
-
- const FullPackageSpec spec = Input::check_and_get_full_package_spec(
- std::move(first_arg), default_triplet, COMMAND_STRUCTURE.example_text);
-
- Input::check_triplet(spec.package_spec.triplet(), paths);
-
- PathsPortFileProvider provider(paths, args.overlay_ports);
- const auto port_name = spec.package_spec.name();
- const auto* scfl = provider.get_control_file(port_name).get();
-
- Checks::check_maybe_upgrade(VCPKG_LINE_INFO, scfl != nullptr, "Error: Couldn't find port '%s'", port_name);
- ASSUME(scfl != nullptr);
-
- return perform_ex(args,
- spec,
- *scfl,
- provider,
- args.binary_caching_enabled() ? *binaryprovider : null_binary_provider(),
- Build::null_build_logs_recorder(),
- paths);
- }
-
- void BuildCommand::perform_and_exit(const VcpkgCmdArguments& args,
- const VcpkgPaths& paths,
- Triplet default_triplet) const
- {
- Build::Command::perform_and_exit(args, paths, default_triplet);
- }
-}
-
-namespace vcpkg::Build
-{
- static const std::string NAME_EMPTY_PACKAGE = "PolicyEmptyPackage";
- static const std::string NAME_DLLS_WITHOUT_LIBS = "PolicyDLLsWithoutLIBs";
- static const std::string NAME_DLLS_WITHOUT_EXPORTS = "PolicyDLLsWithoutExports";
- static const std::string NAME_DLLS_IN_STATIC_LIBRARY = "PolicyDLLsInStaticLibrary";
- static const std::string NAME_MISMATCHED_NUMBER_OF_BINARIES = "PolicyMismatchedNumberOfBinaries";
- static const std::string NAME_ONLY_RELEASE_CRT = "PolicyOnlyReleaseCRT";
- static const std::string NAME_EMPTY_INCLUDE_FOLDER = "PolicyEmptyIncludeFolder";
- static const std::string NAME_ALLOW_OBSOLETE_MSVCRT = "PolicyAllowObsoleteMsvcrt";
- static const std::string NAME_ALLOW_RESTRICTED_HEADERS = "PolicyAllowRestrictedHeaders";
- static const std::string NAME_SKIP_DUMPBIN_CHECKS = "PolicySkipDumpbinChecks";
- static const std::string NAME_SKIP_ARCHITECTURE_CHECK = "PolicySkipArchitectureCheck";
-
- static std::remove_const_t<decltype(ALL_POLICIES)> generate_all_policies()
- {
- std::remove_const_t<decltype(ALL_POLICIES)> res{};
- for (size_t i = 0; i < res.size(); ++i)
- {
- res[i] = static_cast<BuildPolicy>(i);
- }
-
- return res;
- }
-
- decltype(ALL_POLICIES) ALL_POLICIES = generate_all_policies();
-
- const std::string& to_string(BuildPolicy policy)
- {
- switch (policy)
- {
- case BuildPolicy::EMPTY_PACKAGE: return NAME_EMPTY_PACKAGE;
- case BuildPolicy::DLLS_WITHOUT_LIBS: return NAME_DLLS_WITHOUT_LIBS;
- case BuildPolicy::DLLS_WITHOUT_EXPORTS: return NAME_DLLS_WITHOUT_EXPORTS;
- case BuildPolicy::DLLS_IN_STATIC_LIBRARY: return NAME_DLLS_IN_STATIC_LIBRARY;
- case BuildPolicy::MISMATCHED_NUMBER_OF_BINARIES: return NAME_MISMATCHED_NUMBER_OF_BINARIES;
- case BuildPolicy::ONLY_RELEASE_CRT: return NAME_ONLY_RELEASE_CRT;
- case BuildPolicy::EMPTY_INCLUDE_FOLDER: return NAME_EMPTY_INCLUDE_FOLDER;
- case BuildPolicy::ALLOW_OBSOLETE_MSVCRT: return NAME_ALLOW_OBSOLETE_MSVCRT;
- case BuildPolicy::ALLOW_RESTRICTED_HEADERS: return NAME_ALLOW_RESTRICTED_HEADERS;
- case BuildPolicy::SKIP_DUMPBIN_CHECKS: return NAME_SKIP_DUMPBIN_CHECKS;
- case BuildPolicy::SKIP_ARCHITECTURE_CHECK: return NAME_SKIP_ARCHITECTURE_CHECK;
- default: Checks::unreachable(VCPKG_LINE_INFO);
- }
- }
-
- CStringView to_cmake_variable(BuildPolicy policy)
- {
- switch (policy)
- {
- case BuildPolicy::EMPTY_PACKAGE: return "VCPKG_POLICY_EMPTY_PACKAGE";
- case BuildPolicy::DLLS_WITHOUT_LIBS: return "VCPKG_POLICY_DLLS_WITHOUT_LIBS";
- case BuildPolicy::DLLS_WITHOUT_EXPORTS: return "VCPKG_POLICY_DLLS_WITHOUT_EXPORTS";
- case BuildPolicy::DLLS_IN_STATIC_LIBRARY: return "VCPKG_POLICY_DLLS_IN_STATIC_LIBRARY";
- case BuildPolicy::MISMATCHED_NUMBER_OF_BINARIES: return "VCPKG_POLICY_MISMATCHED_NUMBER_OF_BINARIES";
- case BuildPolicy::ONLY_RELEASE_CRT: return "VCPKG_POLICY_ONLY_RELEASE_CRT";
- case BuildPolicy::EMPTY_INCLUDE_FOLDER: return "VCPKG_POLICY_EMPTY_INCLUDE_FOLDER";
- case BuildPolicy::ALLOW_OBSOLETE_MSVCRT: return "VCPKG_POLICY_ALLOW_OBSOLETE_MSVCRT";
- case BuildPolicy::ALLOW_RESTRICTED_HEADERS: return "VCPKG_POLICY_ALLOW_RESTRICTED_HEADERS";
- case BuildPolicy::SKIP_DUMPBIN_CHECKS: return "VCPKG_POLICY_SKIP_DUMPBIN_CHECKS";
- case BuildPolicy::SKIP_ARCHITECTURE_CHECK: return "VCPKG_POLICY_SKIP_ARCHITECTURE_CHECK";
- default: Checks::unreachable(VCPKG_LINE_INFO);
- }
- }
-
- static const std::string NAME_BUILD_IN_DOWNLOAD = "BUILT_IN";
- static const std::string NAME_ARIA2_DOWNLOAD = "ARIA2";
-
- const std::string& to_string(DownloadTool tool)
- {
- switch (tool)
- {
- case DownloadTool::BUILT_IN: return NAME_BUILD_IN_DOWNLOAD;
- case DownloadTool::ARIA2: return NAME_ARIA2_DOWNLOAD;
- default: Checks::unreachable(VCPKG_LINE_INFO);
- }
- }
-
- Optional<LinkageType> to_linkage_type(const std::string& str)
- {
- if (str == "dynamic") return LinkageType::DYNAMIC;
- if (str == "static") return LinkageType::STATIC;
- return nullopt;
- }
-
- namespace BuildInfoRequiredField
- {
- static const std::string CRT_LINKAGE = "CRTLinkage";
- static const std::string LIBRARY_LINKAGE = "LibraryLinkage";
- }
-
- static CStringView to_vcvarsall_target(const std::string& cmake_system_name)
- {
- if (cmake_system_name.empty()) return "";
- if (cmake_system_name == "Windows") return "";
- if (cmake_system_name == "WindowsStore") return "store";
-
- Checks::exit_maybe_upgrade(VCPKG_LINE_INFO,
- "Error: Could not map VCPKG_CMAKE_SYSTEM_NAME '%s' to a vcvarsall platform. "
- "Supported systems are '', 'Windows' and 'WindowsStore'.",
- cmake_system_name);
- }
-
- static CStringView to_vcvarsall_toolchain(const std::string& target_architecture,
- const Toolset& toolset,
- View<Toolset> all_toolsets)
- {
-#if defined(_WIN32)
- auto maybe_target_arch = System::to_cpu_architecture(target_architecture);
- Checks::check_maybe_upgrade(
- VCPKG_LINE_INFO, maybe_target_arch.has_value(), "Invalid architecture string: %s", target_architecture);
- auto target_arch = maybe_target_arch.value_or_exit(VCPKG_LINE_INFO);
- auto host_architectures = System::get_supported_host_architectures();
-
- for (auto&& host : host_architectures)
- {
- const auto it = Util::find_if(toolset.supported_architectures, [&](const ToolsetArchOption& opt) {
- return host == opt.host_arch && target_arch == opt.target_arch;
- });
- if (it != toolset.supported_architectures.end()) return it->name;
- }
-
- System::print2("Error: Unsupported toolchain combination.\n");
- System::print2("Target was ",
- target_architecture,
- " but the chosen Visual Studio instance supports:\n ",
- Strings::join(", ",
- toolset.supported_architectures,
- [](const ToolsetArchOption& t) { return t.name.c_str(); }),
- "\nVcpkg selected ",
- fs::u8string(toolset.visual_studio_root_path),
- " as the Visual Studio instance.\nDetected instances:\n",
- Strings::join("",
- all_toolsets,
- [](const Toolset& t) {
- return Strings::concat(" ", fs::u8string(t.visual_studio_root_path), '\n');
- }),
- "\nSee "
- "https://github.com/microsoft/vcpkg/blob/master/docs/users/triplets.md#VCPKG_VISUAL_STUDIO_PATH "
- "for more information.\n");
- Checks::exit_maybe_upgrade(VCPKG_LINE_INFO);
-#else
- (void)target_architecture;
- (void)toolset;
- (void)all_toolsets;
- Checks::exit_with_message(VCPKG_LINE_INFO,
- "Error: vcvars-based toolchains are only usable on Windows platforms.");
-#endif
- }
-
-#if defined(_WIN32)
- const System::Environment& EnvCache::get_action_env(const VcpkgPaths& paths, const AbiInfo& abi_info)
- {
- auto build_env_cmd = make_build_env_cmd(
- *abi_info.pre_build_info, abi_info.toolset.value_or_exit(VCPKG_LINE_INFO), paths.get_all_toolsets());
-
- const auto& base_env = envs.get_lazy(abi_info.pre_build_info->passthrough_env_vars, [&]() -> EnvMapEntry {
- std::unordered_map<std::string, std::string> env;
-
- for (auto&& env_var : abi_info.pre_build_info->passthrough_env_vars)
- {
- auto env_val = System::get_environment_variable(env_var);
-
- if (env_val)
- {
- env[env_var] = env_val.value_or_exit(VCPKG_LINE_INFO);
- }
- }
- static constexpr StringLiteral s_extra_vars[] = {
- "VCPKG_COMMAND",
- "VCPKG_FORCE_SYSTEM_BINARIES",
- VcpkgCmdArguments::RECURSIVE_DATA_ENV,
- };
-
- for (auto var : s_extra_vars)
- {
- auto val = System::get_environment_variable(var);
- if (auto p_val = val.get()) env.emplace(var, *p_val);
- }
-
- return {env};
- });
-
- return base_env.cmd_cache.get_lazy(build_env_cmd, [&]() {
- const fs::path& powershell_exe_path = paths.get_tool_exe("powershell-core");
- auto clean_env = System::get_modified_clean_environment(
- base_env.env_map, fs::u8string(powershell_exe_path.parent_path()) + ";");
- if (build_env_cmd.empty())
- return clean_env;
- else
- return System::cmd_execute_modify_env(build_env_cmd, clean_env);
- });
- }
-#else
- const System::Environment& EnvCache::get_action_env(const VcpkgPaths&, const AbiInfo&)
- {
- return System::get_clean_environment();
- }
-#endif
-
- static CompilerInfo load_compiler_info(const VcpkgPaths& paths, const AbiInfo& abi_info);
-
- const CompilerInfo& EnvCache::get_compiler_info(const VcpkgPaths& paths, const AbiInfo& abi_info)
- {
- const auto& fs = paths.get_filesystem();
- Checks::check_exit(VCPKG_LINE_INFO, abi_info.pre_build_info != nullptr);
- const fs::path triplet_file_path = paths.get_triplet_file_path(abi_info.pre_build_info->triplet);
-
- auto tcfile = abi_info.pre_build_info->toolchain_file();
- auto&& toolchain_hash = m_toolchain_cache.get_lazy(
- tcfile, [&]() { return Hash::get_file_hash(VCPKG_LINE_INFO, fs, tcfile, Hash::Algorithm::Sha1); });
-
- auto&& triplet_entry = m_triplet_cache.get_lazy(triplet_file_path, [&]() -> TripletMapEntry {
- return TripletMapEntry{Hash::get_file_hash(VCPKG_LINE_INFO, fs, triplet_file_path, Hash::Algorithm::Sha1)};
- });
-
- return triplet_entry.compiler_info.get_lazy(toolchain_hash, [&]() -> CompilerInfo {
- if (m_compiler_tracking)
- {
- return load_compiler_info(paths, abi_info);
- }
- else
- {
- return CompilerInfo{};
- }
- });
- }
-
- const std::string& EnvCache::get_triplet_info(const VcpkgPaths& paths, const AbiInfo& abi_info)
- {
- const auto& fs = paths.get_filesystem();
- Checks::check_exit(VCPKG_LINE_INFO, abi_info.pre_build_info != nullptr);
- const fs::path triplet_file_path = paths.get_triplet_file_path(abi_info.pre_build_info->triplet);
-
- auto tcfile = abi_info.pre_build_info->toolchain_file();
- auto&& toolchain_hash = m_toolchain_cache.get_lazy(
- tcfile, [&]() { return Hash::get_file_hash(VCPKG_LINE_INFO, fs, tcfile, Hash::Algorithm::Sha1); });
-
- auto&& triplet_entry = m_triplet_cache.get_lazy(triplet_file_path, [&]() -> TripletMapEntry {
- return TripletMapEntry{Hash::get_file_hash(VCPKG_LINE_INFO, fs, triplet_file_path, Hash::Algorithm::Sha1)};
- });
-
- return triplet_entry.compiler_hashes.get_lazy(toolchain_hash, [&]() -> std::string {
- if (m_compiler_tracking)
- {
- auto& compiler_info = triplet_entry.compiler_info.get_lazy(toolchain_hash, [&]() -> CompilerInfo {
- if (m_compiler_tracking)
- {
- return load_compiler_info(paths, abi_info);
- }
- else
- {
- return CompilerInfo{};
- }
- });
- return Strings::concat(triplet_entry.hash, '-', toolchain_hash, '-', compiler_info.hash);
- }
- else
- {
- return triplet_entry.hash + "-" + toolchain_hash;
- }
- });
- }
-
- System::Command make_build_env_cmd(const PreBuildInfo& pre_build_info,
- const Toolset& toolset,
- View<Toolset> all_toolsets)
- {
- if (!pre_build_info.using_vcvars()) return {};
-
- const char* tonull = " >nul";
- if (Debug::g_debugging)
- {
- tonull = "";
- }
-
- const auto arch = to_vcvarsall_toolchain(pre_build_info.target_architecture, toolset, all_toolsets);
- const auto target = to_vcvarsall_target(pre_build_info.cmake_system_name);
-
- return System::Command{"cmd"}.string_arg("/c").raw_arg(
- Strings::format(R"("%s" %s %s %s %s 2>&1 <NUL)",
- fs::u8string(toolset.vcvarsall),
- Strings::join(" ", toolset.vcvarsall_options),
- arch,
- target,
- tonull));
- }
-
- static std::unique_ptr<BinaryControlFile> create_binary_control_file(
- const SourceParagraph& source_paragraph,
- Triplet triplet,
- const BuildInfo& build_info,
- const std::string& abi_tag,
- const std::vector<FeatureSpec>& core_dependencies)
- {
- auto bcf = std::make_unique<BinaryControlFile>();
- BinaryParagraph bpgh(source_paragraph, triplet, abi_tag, core_dependencies);
- if (const auto p_ver = build_info.version.get())
- {
- bpgh.version = *p_ver;
- }
-
- bcf->core_paragraph = std::move(bpgh);
- return bcf;
- }
-
- static void write_binary_control_file(const VcpkgPaths& paths, const BinaryControlFile& bcf)
- {
- std::string start = Strings::serialize(bcf.core_paragraph);
- for (auto&& feature : bcf.features)
- {
- start += "\n" + Strings::serialize(feature);
- }
- const fs::path binary_control_file = paths.packages / bcf.core_paragraph.dir() / fs::u8path("CONTROL");
- paths.get_filesystem().write_contents(binary_control_file, start, VCPKG_LINE_INFO);
- }
-
- static int get_concurrency()
- {
- static int concurrency = [] {
- auto user_defined_concurrency = System::get_environment_variable("VCPKG_MAX_CONCURRENCY");
- if (user_defined_concurrency)
- {
- return std::stoi(user_defined_concurrency.value_or_exit(VCPKG_LINE_INFO));
- }
- else
- {
- return System::get_num_logical_cores() + 1;
- }
- }();
-
- return concurrency;
- }
-
- static void get_generic_cmake_build_args(const VcpkgPaths& paths,
- Triplet triplet,
- const Toolset& toolset,
- std::vector<System::CMakeVariable>& out_vars)
- {
- Util::Vectors::append(&out_vars,
- std::initializer_list<System::CMakeVariable>{
- {"CMD", "BUILD"},
- {"DOWNLOADS", paths.downloads},
- {"TARGET_TRIPLET", triplet.canonical_name()},
- {"TARGET_TRIPLET_FILE", fs::u8string(paths.get_triplet_file_path(triplet))},
- {"VCPKG_BASE_VERSION", Commands::Version::base_version()},
- {"VCPKG_CONCURRENCY", std::to_string(get_concurrency())},
- {"VCPKG_PLATFORM_TOOLSET", toolset.version.c_str()},
- });
- if (!System::get_environment_variable("VCPKG_FORCE_SYSTEM_BINARIES").has_value())
- {
- const fs::path& git_exe_path = paths.get_tool_exe(Tools::GIT);
- out_vars.push_back({"GIT", git_exe_path});
- }
- }
-
- static CompilerInfo load_compiler_info(const VcpkgPaths& paths, const AbiInfo& abi_info)
- {
- auto triplet = abi_info.pre_build_info->triplet;
- System::print2("Detecting compiler hash for triplet ", triplet, "...\n");
- auto buildpath = paths.buildtrees / "detect_compiler";
-
-#if !defined(_WIN32)
- // TODO: remove when vcpkg.exe is in charge for acquiring tools. Change introduced in vcpkg v0.0.107.
- // bootstrap should have already downloaded ninja, but making sure it is present in case it was deleted.
- (void)(paths.get_tool_exe(Tools::NINJA));
-#endif
- std::vector<System::CMakeVariable> cmake_args{
- {"CURRENT_PORT_DIR", paths.scripts / "detect_compiler"},
- {"CURRENT_BUILDTREES_DIR", buildpath},
- {"CURRENT_PACKAGES_DIR", paths.packages / ("detect_compiler_" + triplet.canonical_name())},
- };
- get_generic_cmake_build_args(paths, triplet, abi_info.toolset.value_or_exit(VCPKG_LINE_INFO), cmake_args);
-
- auto command = vcpkg::make_cmake_cmd(paths, paths.ports_cmake, std::move(cmake_args));
-
- const auto& env = paths.get_action_env(abi_info);
- auto& fs = paths.get_filesystem();
- if (!fs.exists(buildpath))
- {
- std::error_code err;
- fs.create_directory(buildpath, err);
- Checks::check_exit(VCPKG_LINE_INFO,
- !err.value(),
- "Failed to create directory '%s', code: %d",
- fs::u8string(buildpath),
- err.value());
- }
- auto stdoutlog = buildpath / ("stdout-" + triplet.canonical_name() + ".log");
- std::ofstream out_file(stdoutlog.native().c_str(), std::ios::out | std::ios::binary | std::ios::trunc);
- Checks::check_exit(VCPKG_LINE_INFO, out_file, "Failed to open '%s' for writing", fs::u8string(stdoutlog));
- CompilerInfo compiler_info;
- std::string buf;
- int rc = System::cmd_execute_and_stream_lines(
- command,
- [&](StringView s) {
- static const StringLiteral s_hash_marker = "#COMPILER_HASH#";
- if (Strings::starts_with(s, s_hash_marker))
- {
- compiler_info.hash = s.data() + s_hash_marker.size();
- }
- static const StringLiteral s_version_marker = "#COMPILER_CXX_VERSION#";
- if (Strings::starts_with(s, s_version_marker))
- {
- compiler_info.version = s.data() + s_version_marker.size();
- }
- static const StringLiteral s_id_marker = "#COMPILER_CXX_ID#";
- if (Strings::starts_with(s, s_id_marker))
- {
- compiler_info.id = s.data() + s_id_marker.size();
- }
- Debug::print(s, '\n');
- Strings::append(buf, s, '\n');
- out_file.write(s.data(), s.size()).put('\n');
- Checks::check_exit(
- VCPKG_LINE_INFO, out_file, "Error occurred while writing '%s'", fs::u8string(stdoutlog));
- },
- env);
- out_file.close();
-
- if (compiler_info.hash.empty() || rc != 0)
- {
- Debug::print("Compiler information tracking can be disabled by passing --",
- VcpkgCmdArguments::FEATURE_FLAGS_ARG,
- "=-",
- VcpkgCmdArguments::COMPILER_TRACKING_FEATURE,
- "\n");
-
- System::print2("Error: while detecting compiler information:\nThe log content at ",
- fs::u8string(stdoutlog),
- " is:\n",
- buf);
- Checks::exit_with_message(VCPKG_LINE_INFO,
- "Error: vcpkg was unable to detect the active compiler's information. See above "
- "for the CMake failure output.");
- }
-
- Debug::print("Detected compiler hash for triplet ", triplet, ": ", compiler_info.hash, "\n");
- return compiler_info;
- }
-
- static std::vector<System::CMakeVariable> get_cmake_build_args(const VcpkgCmdArguments& args,
- const VcpkgPaths& paths,
- const Dependencies::InstallPlanAction& action,
- Triplet triplet)
- {
-#if !defined(_WIN32)
- // TODO: remove when vcpkg.exe is in charge for acquiring tools. Change introduced in vcpkg v0.0.107.
- // bootstrap should have already downloaded ninja, but making sure it is present in case it was deleted.
- (void)(paths.get_tool_exe(Tools::NINJA));
-#endif
- auto& scfl = action.source_control_file_location.value_or_exit(VCPKG_LINE_INFO);
- auto& scf = *scfl.source_control_file;
-
- std::string all_features;
- for (auto& feature : scf.feature_paragraphs)
- {
- all_features.append(feature->name + ";");
- }
-
- std::vector<System::CMakeVariable> variables{
- {"ALL_FEATURES", all_features},
- {"CURRENT_PORT_DIR", scfl.source_location},
- {"FEATURES", Strings::join(";", action.feature_list)},
- {"PORT", scf.core_paragraph->name},
- {"VCPKG_USE_HEAD_VERSION", Util::Enum::to_bool(action.build_options.use_head_version) ? "1" : "0"},
- {"_VCPKG_DOWNLOAD_TOOL", to_string(action.build_options.download_tool)},
- {"_VCPKG_EDITABLE", Util::Enum::to_bool(action.build_options.editable) ? "1" : "0"},
- {"_VCPKG_NO_DOWNLOADS", !Util::Enum::to_bool(action.build_options.allow_downloads) ? "1" : "0"},
- };
-
- for (auto cmake_arg : args.cmake_args)
- {
- variables.push_back(System::CMakeVariable{cmake_arg});
- }
-
- if (action.build_options.backcompat_features == BackcompatFeatures::PROHIBIT)
- {
- variables.emplace_back("_VCPKG_PROHIBIT_BACKCOMPAT_FEATURES", "1");
- }
-
- get_generic_cmake_build_args(
- paths,
- triplet,
- action.abi_info.value_or_exit(VCPKG_LINE_INFO).toolset.value_or_exit(VCPKG_LINE_INFO),
- variables);
-
- if (Util::Enum::to_bool(action.build_options.only_downloads))
- {
- variables.push_back({"VCPKG_DOWNLOAD_MODE", "true"});
- }
-
- const Files::Filesystem& fs = paths.get_filesystem();
-
- std::vector<std::string> port_configs;
- for (const PackageSpec& dependency : action.package_dependencies)
- {
- const fs::path port_config_path = paths.installed / fs::u8path(dependency.triplet().canonical_name()) /
- fs::u8path("share") / fs::u8path(dependency.name()) /
- fs::u8path("vcpkg-port-config.cmake");
-
- if (fs.is_regular_file(port_config_path))
- {
- port_configs.emplace_back(fs::u8string(port_config_path));
- }
- }
-
- if (!port_configs.empty())
- {
- variables.emplace_back("VCPKG_PORT_CONFIGS", Strings::join(";", port_configs));
- }
-
- return variables;
- }
-
- bool PreBuildInfo::using_vcvars() const
- {
- return (!external_toolchain_file.has_value() || load_vcvars_env) &&
- (cmake_system_name.empty() || cmake_system_name == "WindowsStore");
- }
-
- fs::path PreBuildInfo::toolchain_file() const
- {
- if (auto p = external_toolchain_file.get())
- {
- return fs::u8path(*p);
- }
- else if (cmake_system_name == "Linux")
- {
- return m_paths.scripts / fs::u8path("toolchains/linux.cmake");
- }
- else if (cmake_system_name == "Darwin")
- {
- return m_paths.scripts / fs::u8path("toolchains/osx.cmake");
- }
- else if (cmake_system_name == "FreeBSD")
- {
- return m_paths.scripts / fs::u8path("toolchains/freebsd.cmake");
- }
- else if (cmake_system_name == "OpenBSD")
- {
- return m_paths.scripts / fs::u8path("toolchains/openbsd.cmake");
- }
- else if (cmake_system_name == "Android")
- {
- return m_paths.scripts / fs::u8path("toolchains/android.cmake");
- }
- else if (cmake_system_name == "iOS")
- {
- return m_paths.scripts / fs::u8path("toolchains/ios.cmake");
- }
- else if (cmake_system_name == "MinGW")
- {
- return m_paths.scripts / fs::u8path("toolchains/mingw.cmake");
- }
- else if (cmake_system_name.empty() || cmake_system_name == "Windows" || cmake_system_name == "WindowsStore")
- {
- return m_paths.scripts / fs::u8path("toolchains/windows.cmake");
- }
- else
- {
- Checks::exit_maybe_upgrade(VCPKG_LINE_INFO,
- "Unable to determine toolchain to use for triplet %s with CMAKE_SYSTEM_NAME %s; "
- "maybe you meant to use VCPKG_CHAINLOAD_TOOLCHAIN_FILE?",
- triplet,
- cmake_system_name);
- }
- }
-
- static ExtendedBuildResult do_build_package(const VcpkgCmdArguments& args,
- const VcpkgPaths& paths,
- const Dependencies::InstallPlanAction& action)
- {
- const auto& pre_build_info = action.pre_build_info(VCPKG_LINE_INFO);
-
- auto& fs = paths.get_filesystem();
- auto&& scfl = action.source_control_file_location.value_or_exit(VCPKG_LINE_INFO);
-
- Triplet triplet = action.spec.triplet();
- const auto& triplet_file_path = fs::u8string(paths.get_triplet_file_path(triplet));
-
- if (Strings::case_insensitive_ascii_starts_with(triplet_file_path, fs::u8string(paths.community_triplets)))
- {
- System::printf(vcpkg::System::Color::warning,
- "-- Using community triplet %s. This triplet configuration is not guaranteed to succeed.\n",
- triplet.canonical_name());
- System::printf("-- [COMMUNITY] Loading triplet configuration from: %s\n", triplet_file_path);
- }
- else if (!Strings::case_insensitive_ascii_starts_with(triplet_file_path, fs::u8string(paths.triplets)))
- {
- System::printf("-- [OVERLAY] Loading triplet configuration from: %s\n", triplet_file_path);
- }
-
- auto u8portdir = fs::u8string(scfl.source_location);
- if (!Strings::case_insensitive_ascii_starts_with(u8portdir, fs::u8string(paths.builtin_ports_directory())))
- {
- System::printf("-- Installing port from location: %s\n", u8portdir);
- }
-
- const auto timer = Chrono::ElapsedTimer::create_started();
-
- auto command =
- vcpkg::make_cmake_cmd(paths, paths.ports_cmake, get_cmake_build_args(args, paths, action, triplet));
-
- const auto& env = paths.get_action_env(action.abi_info.value_or_exit(VCPKG_LINE_INFO));
-
- auto buildpath = paths.buildtrees / action.spec.name();
- if (!fs.exists(buildpath))
- {
- std::error_code err;
- fs.create_directory(buildpath, err);
- Checks::check_exit(VCPKG_LINE_INFO,
- !err.value(),
- "Failed to create directory '%s', code: %d",
- fs::u8string(buildpath),
- err.value());
- }
- auto stdoutlog = buildpath / ("stdout-" + action.spec.triplet().canonical_name() + ".log");
- std::ofstream out_file(stdoutlog.native().c_str(), std::ios::out | std::ios::binary | std::ios::trunc);
- Checks::check_exit(VCPKG_LINE_INFO, out_file, "Failed to open '%s' for writing", fs::u8string(stdoutlog));
- const int return_code = System::cmd_execute_and_stream_data(
- command,
- [&](StringView sv) {
- System::print2(sv);
- out_file.write(sv.data(), sv.size());
- Checks::check_exit(
- VCPKG_LINE_INFO, out_file, "Error occurred while writing '%s'", fs::u8string(stdoutlog));
- },
- env);
- out_file.close();
-
- // With the exception of empty packages, builds in "Download Mode" always result in failure.
- if (action.build_options.only_downloads == Build::OnlyDownloads::YES)
- {
- // TODO: Capture executed command output and evaluate whether the failure was intended.
- // If an unintended error occurs then return a BuildResult::DOWNLOAD_FAILURE status.
- return BuildResult::DOWNLOADED;
- }
-
- const auto buildtimeus = timer.microseconds();
- const auto spec_string = action.spec.to_string();
-
- {
- auto locked_metrics = Metrics::g_metrics.lock();
-
- locked_metrics->track_buildtime(Hash::get_string_hash(spec_string, Hash::Algorithm::Sha256) + ":[" +
- Strings::join(",",
- action.feature_list,
- [](const std::string& feature) {
- return Hash::get_string_hash(feature,
- Hash::Algorithm::Sha256);
- }) +
- "]",
- buildtimeus);
- if (return_code != 0)
- {
- locked_metrics->track_property("error", "build failed");
- locked_metrics->track_property("build_error", spec_string);
- return BuildResult::BUILD_FAILED;
- }
- }
-
- const BuildInfo build_info = read_build_info(fs, paths.build_info_file_path(action.spec));
- const size_t error_count =
- PostBuildLint::perform_all_checks(action.spec, paths, pre_build_info, build_info, scfl.source_location);
-
- auto find_itr = action.feature_dependencies.find("core");
- Checks::check_exit(VCPKG_LINE_INFO, find_itr != action.feature_dependencies.end());
-
- std::unique_ptr<BinaryControlFile> bcf = create_binary_control_file(*scfl.source_control_file->core_paragraph,
- triplet,
- build_info,
- action.public_abi(),
- std::move(find_itr->second));
-
- if (error_count != 0)
- {
- return BuildResult::POST_BUILD_CHECKS_FAILED;
- }
- for (auto&& feature : action.feature_list)
- {
- for (auto&& f_pgh : scfl.source_control_file->feature_paragraphs)
- {
- if (f_pgh->name == feature)
- {
- find_itr = action.feature_dependencies.find(feature);
- Checks::check_exit(VCPKG_LINE_INFO, find_itr != action.feature_dependencies.end());
-
- bcf->features.emplace_back(
- *scfl.source_control_file->core_paragraph, *f_pgh, triplet, std::move(find_itr->second));
- }
- }
- }
-
- write_binary_control_file(paths, *bcf);
- return {BuildResult::SUCCEEDED, std::move(bcf)};
- }
-
- static ExtendedBuildResult do_build_package_and_clean_buildtrees(const VcpkgCmdArguments& args,
- const VcpkgPaths& paths,
- const Dependencies::InstallPlanAction& action)
- {
- auto result = do_build_package(args, paths, action);
-
- if (action.build_options.clean_buildtrees == CleanBuildtrees::YES)
- {
- auto& fs = paths.get_filesystem();
- auto buildtree_files = fs.get_files_non_recursive(paths.build_dir(action.spec));
- for (auto&& file : buildtree_files)
- {
- if (fs.is_directory(file)) // Will only keep the logs
- {
- std::error_code ec;
- fs::path failure_point;
- fs.remove_all(file, ec, failure_point);
- }
- }
- }
-
- return result;
- }
-
- static void abi_entries_from_abi_info(const AbiInfo& abi_info, std::vector<AbiEntry>& abi_tag_entries)
- {
- const auto& pre_build_info = *abi_info.pre_build_info;
- if (pre_build_info.public_abi_override)
- {
- abi_tag_entries.emplace_back(
- "public_abi_override",
- Hash::get_string_hash(pre_build_info.public_abi_override.value_or_exit(VCPKG_LINE_INFO),
- Hash::Algorithm::Sha1));
- }
-
- for (const auto& env_var : pre_build_info.passthrough_env_vars_tracked)
- {
- if (auto e = System::get_environment_variable(env_var))
- {
- abi_tag_entries.emplace_back(
- "ENV:" + env_var, Hash::get_string_hash(e.value_or_exit(VCPKG_LINE_INFO), Hash::Algorithm::Sha1));
- }
- }
- }
-
- struct AbiTagAndFile
- {
- const std::string* triplet_abi;
- std::string tag;
- fs::path tag_file;
- };
-
- static Optional<AbiTagAndFile> compute_abi_tag(const VcpkgPaths& paths,
- const Dependencies::InstallPlanAction& action,
- Span<const AbiEntry> dependency_abis)
- {
- auto& fs = paths.get_filesystem();
- Triplet triplet = action.spec.triplet();
-
- if (action.build_options.use_head_version == UseHeadVersion::YES)
- {
- Debug::print("Binary caching for package ", action.spec, " is disabled due to --head\n");
- return nullopt;
- }
- if (action.build_options.editable == Editable::YES)
- {
- Debug::print("Binary caching for package ", action.spec, " is disabled due to --editable\n");
- return nullopt;
- }
- for (auto&& dep_abi : dependency_abis)
- {
- if (dep_abi.value.empty())
- {
- Debug::print("Binary caching for package ",
- action.spec,
- " is disabled due to missing abi info for ",
- dep_abi.key,
- '\n');
- return nullopt;
- }
- }
-
- std::vector<AbiEntry> abi_tag_entries(dependency_abis.begin(), dependency_abis.end());
-
- const auto& abi_info = action.abi_info.value_or_exit(VCPKG_LINE_INFO);
- const auto& triplet_abi = paths.get_triplet_info(abi_info);
- abi_tag_entries.emplace_back("triplet", triplet.canonical_name());
- abi_tag_entries.emplace_back("triplet_abi", triplet_abi);
- abi_entries_from_abi_info(abi_info, abi_tag_entries);
-
- // If there is an unusually large number of files in the port then
- // something suspicious is going on. Rather than hash all of them
- // just mark the port as no-hash
- const int max_port_file_count = 100;
-
- auto&& port_dir = action.source_control_file_location.value_or_exit(VCPKG_LINE_INFO).source_location;
- size_t port_file_count = 0;
- for (auto& port_file : fs::stdfs::recursive_directory_iterator(port_dir))
- {
- if (fs::is_regular_file(fs.status(VCPKG_LINE_INFO, port_file)))
- {
- abi_tag_entries.emplace_back(
- fs::u8string(port_file.path().filename()),
- vcpkg::Hash::get_file_hash(VCPKG_LINE_INFO, fs, port_file, Hash::Algorithm::Sha1));
-
- ++port_file_count;
- if (port_file_count > max_port_file_count)
- {
- abi_tag_entries.emplace_back("no_hash_max_portfile", "");
- break;
- }
- }
- }
-
- abi_tag_entries.emplace_back("cmake", paths.get_tool_version(Tools::CMAKE));
-
-#if defined(_WIN32)
- abi_tag_entries.emplace_back("powershell", paths.get_tool_version("powershell-core"));
-#endif
-
- auto& helpers = paths.get_cmake_script_hashes();
- auto portfile_contents =
- fs.read_contents(port_dir / fs::u8path("portfile.cmake")).value_or_exit(VCPKG_LINE_INFO);
- for (auto&& helper : helpers)
- {
- if (Strings::case_insensitive_ascii_contains(portfile_contents, helper.first))
- {
- abi_tag_entries.emplace_back(helper.first, helper.second);
- }
- }
-
- abi_tag_entries.emplace_back("post_build_checks", "2");
- std::vector<std::string> sorted_feature_list = action.feature_list;
- Util::sort(sorted_feature_list);
- abi_tag_entries.emplace_back("features", Strings::join(";", sorted_feature_list));
-
- Util::sort(abi_tag_entries);
-
- const std::string full_abi_info =
- Strings::join("", abi_tag_entries, [](const AbiEntry& p) { return p.key + " " + p.value + "\n"; });
-
- if (Debug::g_debugging)
- {
- std::string message = Strings::concat("[DEBUG] <abientries for ", action.spec, ">\n");
- for (auto&& entry : abi_tag_entries)
- {
- Strings::append(message, "[DEBUG] ", entry.key, "|", entry.value, "\n");
- }
- Strings::append(message, "[DEBUG] </abientries>\n");
- System::print2(message);
- }
-
- auto abi_tag_entries_missing = Util::filter(abi_tag_entries, [](const AbiEntry& p) { return p.value.empty(); });
-
- if (abi_tag_entries_missing.empty())
- {
- auto current_build_tree = paths.build_dir(action.spec);
- fs.create_directory(current_build_tree, VCPKG_LINE_INFO);
- const auto abi_file_path = current_build_tree / (triplet.canonical_name() + ".vcpkg_abi_info.txt");
- fs.write_contents(abi_file_path, full_abi_info, VCPKG_LINE_INFO);
-
- return AbiTagAndFile{&triplet_abi,
- Hash::get_file_hash(VCPKG_LINE_INFO, fs, abi_file_path, Hash::Algorithm::Sha1),
- abi_file_path};
- }
-
- Debug::print(
- "Warning: abi keys are missing values:\n",
- Strings::join("", abi_tag_entries_missing, [](const AbiEntry& e) { return " " + e.key + "\n"; }),
- "\n");
-
- return nullopt;
- }
-
- void compute_all_abis(const VcpkgPaths& paths,
- Dependencies::ActionPlan& action_plan,
- const CMakeVars::CMakeVarProvider& var_provider,
- const StatusParagraphs& status_db)
- {
- using Dependencies::InstallPlanAction;
- for (auto it = action_plan.install_actions.begin(); it != action_plan.install_actions.end(); ++it)
- {
- auto& action = *it;
- if (action.abi_info.has_value()) continue;
-
- std::vector<AbiEntry> dependency_abis;
- if (!Util::Enum::to_bool(action.build_options.only_downloads))
- {
- for (auto&& pspec : action.package_dependencies)
- {
- if (pspec == action.spec) continue;
-
- auto pred = [&](const InstallPlanAction& ipa) { return ipa.spec == pspec; };
- auto it2 = std::find_if(action_plan.install_actions.begin(), it, pred);
- if (it2 == it)
- {
- // Finally, look in current installed
- auto status_it = status_db.find(pspec);
- if (status_it == status_db.end())
- {
- Checks::exit_maybe_upgrade(
- VCPKG_LINE_INFO, "Failed to find dependency abi for %s -> %s", action.spec, pspec);
- }
-
- dependency_abis.emplace_back(AbiEntry{pspec.name(), status_it->get()->package.abi});
- }
- else
- {
- dependency_abis.emplace_back(AbiEntry{pspec.name(), it2->public_abi()});
- }
- }
- }
-
- action.abi_info = AbiInfo();
- auto& abi_info = action.abi_info.value_or_exit(VCPKG_LINE_INFO);
-
- abi_info.pre_build_info = std::make_unique<PreBuildInfo>(
- paths, action.spec.triplet(), var_provider.get_tag_vars(action.spec).value_or_exit(VCPKG_LINE_INFO));
- abi_info.toolset = paths.get_toolset(*abi_info.pre_build_info);
-
- auto maybe_abi_tag_and_file = compute_abi_tag(paths, action, dependency_abis);
- if (auto p = maybe_abi_tag_and_file.get())
- {
- abi_info.compiler_info = paths.get_compiler_info(abi_info);
- abi_info.triplet_abi = *p->triplet_abi;
- abi_info.package_abi = std::move(p->tag);
- abi_info.abi_tag_file = std::move(p->tag_file);
- }
- }
- }
-
- ExtendedBuildResult build_package(const VcpkgCmdArguments& args,
- const VcpkgPaths& paths,
- const Dependencies::InstallPlanAction& action,
- IBinaryProvider& binaries_provider,
- const IBuildLogsRecorder& build_logs_recorder,
- const StatusParagraphs& status_db)
- {
- auto& filesystem = paths.get_filesystem();
- auto& spec = action.spec;
- const std::string& name = action.source_control_file_location.value_or_exit(VCPKG_LINE_INFO)
- .source_control_file->core_paragraph->name;
-
- std::vector<FeatureSpec> missing_fspecs;
- for (const auto& kv : action.feature_dependencies)
- {
- for (const FeatureSpec& fspec : kv.second)
- {
- if (!(status_db.is_installed(fspec) || fspec.name() == name))
- {
- missing_fspecs.emplace_back(fspec);
- }
- }
- }
-
- if (!missing_fspecs.empty() && !Util::Enum::to_bool(action.build_options.only_downloads))
- {
- return {BuildResult::CASCADED_DUE_TO_MISSING_DEPENDENCIES, std::move(missing_fspecs)};
- }
-
- std::vector<AbiEntry> dependency_abis;
- for (auto&& pspec : action.package_dependencies)
- {
- if (pspec == spec || Util::Enum::to_bool(action.build_options.only_downloads))
- {
- continue;
- }
- const auto status_it = status_db.find_installed(pspec);
- Checks::check_exit(VCPKG_LINE_INFO, status_it != status_db.end());
- dependency_abis.emplace_back(
- AbiEntry{status_it->get()->package.spec.name(), status_it->get()->package.abi});
- }
-
- auto& abi_info = action.abi_info.value_or_exit(VCPKG_LINE_INFO);
- if (!abi_info.abi_tag_file)
- {
- return do_build_package_and_clean_buildtrees(args, paths, action);
- }
-
- auto& abi_file = *abi_info.abi_tag_file.get();
-
- const fs::path abi_package_dir = paths.package_dir(spec) / "share" / spec.name();
- const fs::path abi_file_in_package = paths.package_dir(spec) / "share" / spec.name() / "vcpkg_abi_info.txt";
- if (action.has_package_abi())
- {
- auto restore = binaries_provider.try_restore(paths, action);
- if (restore == RestoreResult::build_failed)
- {
- return BuildResult::BUILD_FAILED;
- }
- else if (restore == RestoreResult::success)
- {
- auto maybe_bcf = Paragraphs::try_load_cached_package(paths, spec);
- auto bcf = std::make_unique<BinaryControlFile>(std::move(maybe_bcf).value_or_exit(VCPKG_LINE_INFO));
- return {BuildResult::SUCCEEDED, std::move(bcf)};
- }
- else
- {
- // missing package, proceed to build.
- }
- }
- if (action.build_options.build_missing == BuildMissing::NO)
- {
- return BuildResult::CACHE_MISSING;
- }
-
- ExtendedBuildResult result = do_build_package_and_clean_buildtrees(args, paths, action);
- build_logs_recorder.record_build_result(paths, spec, result.code);
-
- std::error_code ec;
- filesystem.create_directories(abi_package_dir, ec);
- if (ec)
- {
- Checks::exit_with_message(VCPKG_LINE_INFO,
- Strings::format("Could not create %s: %s (%d)",
- fs::u8string(abi_package_dir).c_str(),
- ec.message().c_str(),
- ec.value()));
- }
-
- filesystem.copy_file(abi_file, abi_file_in_package, fs::copy_options::none, ec);
- if (ec)
- {
- Checks::exit_with_message(VCPKG_LINE_INFO,
- Strings::format("Could not copy %s -> %s: %s (%d)",
- fs::u8string(abi_file).c_str(),
- fs::u8string(abi_file_in_package).c_str(),
- ec.message().c_str(),
- ec.value()));
- }
-
- if (action.has_package_abi() && result.code == BuildResult::SUCCEEDED)
- {
- binaries_provider.push_success(paths, action);
- }
-
- return result;
- }
-
- const std::string& to_string(const BuildResult build_result)
- {
- static const std::string NULLVALUE_STRING = Enums::nullvalue_to_string("vcpkg::Commands::Build::BuildResult");
- static const std::string SUCCEEDED_STRING = "SUCCEEDED";
- static const std::string BUILD_FAILED_STRING = "BUILD_FAILED";
- static const std::string FILE_CONFLICTS_STRING = "FILE_CONFLICTS";
- static const std::string POST_BUILD_CHECKS_FAILED_STRING = "POST_BUILD_CHECKS_FAILED";
- static const std::string CASCADED_DUE_TO_MISSING_DEPENDENCIES_STRING = "CASCADED_DUE_TO_MISSING_DEPENDENCIES";
- static const std::string EXCLUDED_STRING = "EXCLUDED";
- static const std::string CACHE_MISSING_STRING = "CACHE_MISSING";
- static const std::string DOWNLOADED_STRING = "DOWNLOADED";
-
- switch (build_result)
- {
- case BuildResult::NULLVALUE: return NULLVALUE_STRING;
- case BuildResult::SUCCEEDED: return SUCCEEDED_STRING;
- case BuildResult::BUILD_FAILED: return BUILD_FAILED_STRING;
- case BuildResult::POST_BUILD_CHECKS_FAILED: return POST_BUILD_CHECKS_FAILED_STRING;
- case BuildResult::FILE_CONFLICTS: return FILE_CONFLICTS_STRING;
- case BuildResult::CASCADED_DUE_TO_MISSING_DEPENDENCIES: return CASCADED_DUE_TO_MISSING_DEPENDENCIES_STRING;
- case BuildResult::EXCLUDED: return EXCLUDED_STRING;
- case BuildResult::CACHE_MISSING: return CACHE_MISSING_STRING;
- case BuildResult::DOWNLOADED: return DOWNLOADED_STRING;
- default: Checks::unreachable(VCPKG_LINE_INFO);
- }
- }
-
- std::string create_error_message(const BuildResult build_result, const PackageSpec& spec)
- {
- return Strings::format("Error: Building package %s failed with: %s", spec, Build::to_string(build_result));
- }
-
- std::string create_user_troubleshooting_message(const PackageSpec& spec)
- {
-#if defined(_WIN32)
- auto vcpkg_update_cmd = ".\\vcpkg";
-#else
- auto vcpkg_update_cmd = "./vcpkg";
-#endif
- return Strings::format("Please ensure you're using the latest portfiles with `%s update`, then\n"
- "submit an issue at https://github.com/Microsoft/vcpkg/issues including:\n"
- " Package: %s\n"
- " Vcpkg version: %s\n"
- "\n"
- "Additionally, attach any relevant sections from the log files above.",
- vcpkg_update_cmd,
- spec,
- Commands::Version::version());
- }
-
- static BuildInfo inner_create_buildinfo(Parse::Paragraph pgh)
- {
- Parse::ParagraphParser parser(std::move(pgh));
-
- BuildInfo build_info;
-
- {
- std::string crt_linkage_as_string;
- parser.required_field(BuildInfoRequiredField::CRT_LINKAGE, crt_linkage_as_string);
-
- auto crtlinkage = to_linkage_type(crt_linkage_as_string);
- if (const auto p = crtlinkage.get())
- {
- build_info.crt_linkage = *p;
- }
- else
- {
- Checks::exit_with_message(VCPKG_LINE_INFO, "Invalid crt linkage type: [%s]", crt_linkage_as_string);
- }
- }
-
- {
- std::string library_linkage_as_string;
- parser.required_field(BuildInfoRequiredField::LIBRARY_LINKAGE, library_linkage_as_string);
- auto liblinkage = to_linkage_type(library_linkage_as_string);
- if (const auto p = liblinkage.get())
- {
- build_info.library_linkage = *p;
- }
- else
- {
- Checks::exit_with_message(
- VCPKG_LINE_INFO, "Invalid library linkage type: [%s]", library_linkage_as_string);
- }
- }
-
- std::string version = parser.optional_field("Version");
- if (!version.empty()) build_info.version = std::move(version);
-
- std::map<BuildPolicy, bool> policies;
- for (auto policy : ALL_POLICIES)
- {
- const auto setting = parser.optional_field(to_string(policy));
- if (setting.empty()) continue;
- if (setting == "enabled")
- policies.emplace(policy, true);
- else if (setting == "disabled")
- policies.emplace(policy, false);
- else
- Checks::exit_maybe_upgrade(
- VCPKG_LINE_INFO, "Unknown setting for policy '%s': %s", to_string(policy), setting);
- }
-
- if (const auto err = parser.error_info("PostBuildInformation"))
- {
- print_error_message(err);
- Checks::exit_fail(VCPKG_LINE_INFO);
- }
-
- build_info.policies = BuildPolicies(std::move(policies));
-
- return build_info;
- }
-
- BuildInfo read_build_info(const Files::Filesystem& fs, const fs::path& filepath)
- {
- const ExpectedS<Parse::Paragraph> pghs = Paragraphs::get_single_paragraph(fs, filepath);
- Checks::check_maybe_upgrade(
- VCPKG_LINE_INFO, pghs.get() != nullptr, "Invalid BUILD_INFO file for package: %s", pghs.error());
- return inner_create_buildinfo(*pghs.get());
- }
-
- PreBuildInfo::PreBuildInfo(const VcpkgPaths& paths,
- Triplet triplet,
- const std::unordered_map<std::string, std::string>& cmakevars)
- : triplet(triplet), m_paths(paths)
- {
- enum class VcpkgTripletVar
- {
- TARGET_ARCHITECTURE = 0,
- CMAKE_SYSTEM_NAME,
- CMAKE_SYSTEM_VERSION,
- PLATFORM_TOOLSET,
- VISUAL_STUDIO_PATH,
- CHAINLOAD_TOOLCHAIN_FILE,
- BUILD_TYPE,
- ENV_PASSTHROUGH,
- ENV_PASSTHROUGH_UNTRACKED,
- PUBLIC_ABI_OVERRIDE,
- LOAD_VCVARS_ENV,
- };
-
- static const std::vector<std::pair<std::string, VcpkgTripletVar>> VCPKG_OPTIONS = {
- {"VCPKG_TARGET_ARCHITECTURE", VcpkgTripletVar::TARGET_ARCHITECTURE},
- {"VCPKG_CMAKE_SYSTEM_NAME", VcpkgTripletVar::CMAKE_SYSTEM_NAME},
- {"VCPKG_CMAKE_SYSTEM_VERSION", VcpkgTripletVar::CMAKE_SYSTEM_VERSION},
- {"VCPKG_PLATFORM_TOOLSET", VcpkgTripletVar::PLATFORM_TOOLSET},
- {"VCPKG_VISUAL_STUDIO_PATH", VcpkgTripletVar::VISUAL_STUDIO_PATH},
- {"VCPKG_CHAINLOAD_TOOLCHAIN_FILE", VcpkgTripletVar::CHAINLOAD_TOOLCHAIN_FILE},
- {"VCPKG_BUILD_TYPE", VcpkgTripletVar::BUILD_TYPE},
- {"VCPKG_ENV_PASSTHROUGH", VcpkgTripletVar::ENV_PASSTHROUGH},
- {"VCPKG_ENV_PASSTHROUGH_UNTRACKED", VcpkgTripletVar::ENV_PASSTHROUGH_UNTRACKED},
- {"VCPKG_PUBLIC_ABI_OVERRIDE", VcpkgTripletVar::PUBLIC_ABI_OVERRIDE},
- {"VCPKG_LOAD_VCVARS_ENV", VcpkgTripletVar::LOAD_VCVARS_ENV},
- };
-
- std::string empty;
- for (auto&& kv : VCPKG_OPTIONS)
- {
- const std::string& variable_value = [&]() -> const std::string& {
- auto find_itr = cmakevars.find(kv.first);
- if (find_itr == cmakevars.end())
- {
- return empty;
- }
- else
- {
- return find_itr->second;
- }
- }();
-
- switch (kv.second)
- {
- case VcpkgTripletVar::TARGET_ARCHITECTURE: target_architecture = variable_value; break;
- case VcpkgTripletVar::CMAKE_SYSTEM_NAME: cmake_system_name = variable_value; break;
- case VcpkgTripletVar::CMAKE_SYSTEM_VERSION: cmake_system_version = variable_value; break;
- case VcpkgTripletVar::PLATFORM_TOOLSET:
- platform_toolset = variable_value.empty() ? nullopt : Optional<std::string>{variable_value};
- break;
- case VcpkgTripletVar::VISUAL_STUDIO_PATH:
- visual_studio_path = variable_value.empty() ? nullopt : Optional<fs::path>{variable_value};
- break;
- case VcpkgTripletVar::CHAINLOAD_TOOLCHAIN_FILE:
- external_toolchain_file = variable_value.empty() ? nullopt : Optional<std::string>{variable_value};
- break;
- case VcpkgTripletVar::BUILD_TYPE:
- if (variable_value.empty())
- build_type = nullopt;
- else if (Strings::case_insensitive_ascii_equals(variable_value, "debug"))
- build_type = ConfigurationType::DEBUG;
- else if (Strings::case_insensitive_ascii_equals(variable_value, "release"))
- build_type = ConfigurationType::RELEASE;
- else
- Checks::exit_with_message(
- VCPKG_LINE_INFO,
- "Unknown setting for VCPKG_BUILD_TYPE: %s. Valid settings are '', 'debug' and 'release'.",
- variable_value);
- break;
- case VcpkgTripletVar::ENV_PASSTHROUGH:
- passthrough_env_vars_tracked = Strings::split(variable_value, ';');
- Util::Vectors::append(&passthrough_env_vars, passthrough_env_vars_tracked);
- break;
- case VcpkgTripletVar::ENV_PASSTHROUGH_UNTRACKED:
- Util::Vectors::append(&passthrough_env_vars, Strings::split(variable_value, ';'));
- break;
- case VcpkgTripletVar::PUBLIC_ABI_OVERRIDE:
- public_abi_override = variable_value.empty() ? nullopt : Optional<std::string>{variable_value};
- break;
- case VcpkgTripletVar::LOAD_VCVARS_ENV:
- if (variable_value.empty())
- {
- load_vcvars_env = true;
- if (external_toolchain_file) load_vcvars_env = false;
- }
- else if (Strings::case_insensitive_ascii_equals(variable_value, "1") ||
- Strings::case_insensitive_ascii_equals(variable_value, "on") ||
- Strings::case_insensitive_ascii_equals(variable_value, "true"))
- {
- load_vcvars_env = true;
- }
- else if (Strings::case_insensitive_ascii_equals(variable_value, "0") ||
- Strings::case_insensitive_ascii_equals(variable_value, "off") ||
- Strings::case_insensitive_ascii_equals(variable_value, "false"))
- {
- load_vcvars_env = false;
- }
- else
- {
- Checks::exit_with_message(VCPKG_LINE_INFO,
- "Unknown boolean setting for VCPKG_LOAD_VCVARS_ENV: %s. Valid "
- "settings are '', '1', '0', 'ON', 'OFF', 'TRUE', and 'FALSE'.",
- variable_value);
- }
- break;
- }
- }
- }
-
- ExtendedBuildResult::ExtendedBuildResult(BuildResult code) : code(code) { }
- ExtendedBuildResult::ExtendedBuildResult(BuildResult code, std::unique_ptr<BinaryControlFile>&& bcf)
- : code(code), binary_control_file(std::move(bcf))
- {
- }
- ExtendedBuildResult::ExtendedBuildResult(BuildResult code, std::vector<FeatureSpec>&& unmet_deps)
- : code(code), unmet_dependencies(std::move(unmet_deps))
- {
- }
-
- const IBuildLogsRecorder& null_build_logs_recorder() noexcept { return null_build_logs_recorder_instance; }
-}
diff --git a/toolsrc/src/vcpkg/buildenvironment.cpp b/toolsrc/src/vcpkg/buildenvironment.cpp
deleted file mode 100644
index bc116f4f3..000000000
--- a/toolsrc/src/vcpkg/buildenvironment.cpp
+++ /dev/null
@@ -1,20 +0,0 @@
-#include <vcpkg/buildenvironment.h>
-#include <vcpkg/tools.h>
-#include <vcpkg/vcpkgpaths.h>
-
-namespace vcpkg
-{
- System::Command make_cmake_cmd(const VcpkgPaths& paths,
- const fs::path& cmake_script,
- std::vector<System::CMakeVariable>&& pass_variables)
- {
- auto local_variables = std::move(pass_variables);
- local_variables.emplace_back("VCPKG_ROOT_DIR", paths.root);
- local_variables.emplace_back("PACKAGES_DIR", paths.packages);
- local_variables.emplace_back("BUILDTREES_DIR", paths.buildtrees);
- local_variables.emplace_back("_VCPKG_INSTALLED_DIR", paths.installed);
- local_variables.emplace_back("DOWNLOADS", paths.downloads);
- local_variables.emplace_back("VCPKG_MANIFEST_INSTALL", "OFF");
- return System::make_basic_cmake_cmd(paths.get_tool_exe(Tools::CMAKE), cmake_script, local_variables);
- }
-}
diff --git a/toolsrc/src/vcpkg/cmakevars.cpp b/toolsrc/src/vcpkg/cmakevars.cpp
deleted file mode 100644
index 8a90e574b..000000000
--- a/toolsrc/src/vcpkg/cmakevars.cpp
+++ /dev/null
@@ -1,323 +0,0 @@
-#include <vcpkg/base/hash.h>
-#include <vcpkg/base/optional.h>
-#include <vcpkg/base/span.h>
-#include <vcpkg/base/system.process.h>
-#include <vcpkg/base/util.h>
-
-#include <vcpkg/buildenvironment.h>
-#include <vcpkg/cmakevars.h>
-#include <vcpkg/dependencies.h>
-#include <vcpkg/portfileprovider.h>
-
-using namespace vcpkg;
-using vcpkg::Optional;
-
-namespace vcpkg::CMakeVars
-{
- void CMakeVarProvider::load_tag_vars(const vcpkg::Dependencies::ActionPlan& action_plan,
- const PortFileProvider::PortFileProvider& port_provider) const
- {
- std::vector<FullPackageSpec> install_package_specs;
- for (auto&& action : action_plan.install_actions)
- {
- install_package_specs.emplace_back(FullPackageSpec{action.spec, action.feature_list});
- }
-
- load_tag_vars(install_package_specs, port_provider);
- }
-
- namespace
- {
- struct TripletCMakeVarProvider : Util::ResourceBase, CMakeVarProvider
- {
- explicit TripletCMakeVarProvider(const vcpkg::VcpkgPaths& paths) : paths(paths) { }
-
- void load_generic_triplet_vars(Triplet triplet) const override;
-
- void load_dep_info_vars(View<PackageSpec> specs) const override;
-
- void load_tag_vars(View<FullPackageSpec> specs,
- const PortFileProvider::PortFileProvider& port_provider) const override;
-
- Optional<const std::unordered_map<std::string, std::string>&> get_generic_triplet_vars(
- Triplet triplet) const override;
-
- Optional<const std::unordered_map<std::string, std::string>&> get_dep_info_vars(
- const PackageSpec& spec) const override;
-
- Optional<const std::unordered_map<std::string, std::string>&> get_tag_vars(
- const PackageSpec& spec) const override;
-
- public:
- fs::path create_tag_extraction_file(
- const View<std::pair<const FullPackageSpec*, std::string>> spec_abi_settings) const;
-
- fs::path create_dep_info_extraction_file(const View<PackageSpec> specs) const;
-
- void launch_and_split(const fs::path& script_path,
- std::vector<std::vector<std::pair<std::string, std::string>>>& vars) const;
-
- const VcpkgPaths& paths;
- const fs::path get_tags_path = paths.scripts / "vcpkg_get_tags.cmake";
- const fs::path get_dep_info_path = paths.scripts / "vcpkg_get_dep_info.cmake";
- mutable std::unordered_map<PackageSpec, std::unordered_map<std::string, std::string>> dep_resolution_vars;
- mutable std::unordered_map<PackageSpec, std::unordered_map<std::string, std::string>> tag_vars;
- mutable std::unordered_map<Triplet, std::unordered_map<std::string, std::string>> generic_triplet_vars;
- };
- }
-
- std::unique_ptr<CMakeVarProvider> make_triplet_cmake_var_provider(const vcpkg::VcpkgPaths& paths)
- {
- return std::make_unique<TripletCMakeVarProvider>(paths);
- }
-
- static std::string create_extraction_file_prelude(const VcpkgPaths& paths,
- const std::map<Triplet, int>& emitted_triplets)
- {
- const auto& fs = paths.get_filesystem();
- std::string extraction_file("macro(vcpkg_triplet_file VCPKG_TRIPLET_ID)\n");
-
- Strings::append(extraction_file,
- "set(_vcpkg_triplet_file_BACKUP_CURRENT_LIST_FILE \"${CMAKE_CURRENT_LIST_FILE}\")\n");
-
- for (auto&& p : emitted_triplets)
- {
- auto path_to_triplet = paths.get_triplet_file_path(p.first);
- Strings::append(extraction_file, "if(VCPKG_TRIPLET_ID EQUAL ", p.second, ")\n");
- Strings::append(
- extraction_file, "set(CMAKE_CURRENT_LIST_FILE \"", fs::generic_u8string(path_to_triplet), "\")\n");
- Strings::append(
- extraction_file,
- "get_filename_component(CMAKE_CURRENT_LIST_DIR \"${CMAKE_CURRENT_LIST_FILE}\" DIRECTORY)\n");
- Strings::append(extraction_file, fs.read_contents(path_to_triplet, VCPKG_LINE_INFO));
- Strings::append(extraction_file, "\nendif()\n");
- }
- Strings::append(extraction_file,
- R"(
-set(CMAKE_CURRENT_LIST_FILE "${_vcpkg_triplet_file_BACKUP_CURRENT_LIST_FILE}")
-get_filename_component(CMAKE_CURRENT_LIST_DIR "${CMAKE_CURRENT_LIST_FILE}" DIRECTORY)
-endmacro()
-)");
- return extraction_file;
- }
-
- fs::path TripletCMakeVarProvider::create_tag_extraction_file(
- const View<std::pair<const FullPackageSpec*, std::string>> spec_abi_settings) const
- {
- Files::Filesystem& fs = paths.get_filesystem();
- static int tag_extract_id = 0;
-
- std::map<Triplet, int> emitted_triplets;
- int emitted_triplet_id = 0;
- for (const auto& spec_abi_setting : spec_abi_settings)
- {
- emitted_triplets[spec_abi_setting.first->package_spec.triplet()] = emitted_triplet_id++;
- }
- std::string extraction_file = create_extraction_file_prelude(paths, emitted_triplets);
-
- Strings::append(extraction_file, "\ninclude(\"" + fs::generic_u8string(get_tags_path) + "\")\n\n");
-
- for (const auto& spec_abi_setting : spec_abi_settings)
- {
- const FullPackageSpec& spec = *spec_abi_setting.first;
-
- Strings::append(extraction_file,
- "vcpkg_get_tags(\"",
- spec.package_spec.name(),
- "\" \"",
- Strings::join(";", spec.features),
- "\" \"",
- emitted_triplets[spec.package_spec.triplet()],
- "\" \"",
- spec_abi_setting.second,
- "\")\n");
- }
-
- fs::path path = paths.buildtrees / Strings::concat(tag_extract_id++, ".vcpkg_tags.cmake");
- fs.write_contents_and_dirs(path, extraction_file, VCPKG_LINE_INFO);
- return path;
- }
-
- fs::path TripletCMakeVarProvider::create_dep_info_extraction_file(const View<PackageSpec> specs) const
- {
- static int dep_info_id = 0;
- Files::Filesystem& fs = paths.get_filesystem();
-
- std::map<Triplet, int> emitted_triplets;
- int emitted_triplet_id = 0;
- for (const auto& spec : specs)
- {
- emitted_triplets[spec.triplet()] = emitted_triplet_id++;
- }
-
- std::string extraction_file = create_extraction_file_prelude(paths, emitted_triplets);
-
- Strings::append(extraction_file, "\ninclude(\"" + fs::generic_u8string(get_dep_info_path) + "\")\n\n");
-
- for (const PackageSpec& spec : specs)
- {
- Strings::append(
- extraction_file, "vcpkg_get_dep_info(", spec.name(), " ", emitted_triplets[spec.triplet()], ")\n");
- }
-
- fs::path path = paths.buildtrees / Strings::concat(dep_info_id++, ".vcpkg_dep_info.cmake");
- fs.write_contents_and_dirs(path, extraction_file, VCPKG_LINE_INFO);
- return path;
- }
-
- void TripletCMakeVarProvider::launch_and_split(
- const fs::path& script_path, std::vector<std::vector<std::pair<std::string, std::string>>>& vars) const
- {
- static constexpr CStringView PORT_START_GUID = "d8187afd-ea4a-4fc3-9aa4-a6782e1ed9af";
- static constexpr CStringView PORT_END_GUID = "8c504940-be29-4cba-9f8f-6cd83e9d87b7";
- static constexpr CStringView BLOCK_START_GUID = "c35112b6-d1ba-415b-aa5d-81de856ef8eb";
- static constexpr CStringView BLOCK_END_GUID = "e1e74b5c-18cb-4474-a6bd-5c1c8bc81f3f";
-
- const auto cmd_launch_cmake = vcpkg::make_cmake_cmd(paths, script_path, {});
- const auto ec_data = System::cmd_execute_and_capture_output(cmd_launch_cmake);
- Checks::check_exit(VCPKG_LINE_INFO, ec_data.exit_code == 0, ec_data.output);
-
- const std::vector<std::string> lines = Strings::split(ec_data.output, '\n');
-
- const auto end = lines.cend();
-
- auto port_start = std::find(lines.cbegin(), end, PORT_START_GUID);
- auto port_end = std::find(port_start, end, PORT_END_GUID);
-
- for (auto var_itr = vars.begin(); port_start != end && var_itr != vars.end(); ++var_itr)
- {
- auto block_start = std::find(port_start, port_end, BLOCK_START_GUID);
- auto block_end = std::find(++block_start, port_end, BLOCK_END_GUID);
-
- while (block_start != port_end)
- {
- while (block_start != block_end)
- {
- const std::string& line = *block_start;
-
- std::vector<std::string> s = Strings::split(line, '=');
- Checks::check_exit(VCPKG_LINE_INFO,
- s.size() == 1 || s.size() == 2,
- "Expected format is [VARIABLE_NAME=VARIABLE_VALUE], but was [%s]",
- line);
-
- var_itr->emplace_back(std::move(s[0]), s.size() == 1 ? "" : std::move(s[1]));
-
- ++block_start;
- }
-
- block_start = std::find(block_end, port_end, BLOCK_START_GUID);
- block_end = std::find(block_start, port_end, BLOCK_END_GUID);
- }
-
- port_start = std::find(port_end, end, PORT_START_GUID);
- port_end = std::find(port_start, end, PORT_END_GUID);
- }
- }
-
- void TripletCMakeVarProvider::load_generic_triplet_vars(Triplet triplet) const
- {
- std::vector<std::vector<std::pair<std::string, std::string>>> vars(1);
- // Hack: PackageSpecs should never have .name==""
- FullPackageSpec full_spec({"", triplet});
- const fs::path file_path =
- create_tag_extraction_file(std::array<std::pair<const FullPackageSpec*, std::string>, 1>{
- std::pair<const FullPackageSpec*, std::string>{&full_spec, ""}});
- launch_and_split(file_path, vars);
- paths.get_filesystem().remove(file_path, VCPKG_LINE_INFO);
-
- generic_triplet_vars[triplet].insert(std::make_move_iterator(vars.front().begin()),
- std::make_move_iterator(vars.front().end()));
- }
-
- void TripletCMakeVarProvider::load_dep_info_vars(View<PackageSpec> specs) const
- {
- if (specs.size() == 0) return;
- std::vector<std::vector<std::pair<std::string, std::string>>> vars(specs.size());
- const fs::path file_path = create_dep_info_extraction_file(specs);
- if (specs.size() > 100)
- {
- System::print2("Loading dependency information for ", specs.size(), " packages...\n");
- }
- launch_and_split(file_path, vars);
- paths.get_filesystem().remove(file_path, VCPKG_LINE_INFO);
-
- auto var_list_itr = vars.begin();
- for (const PackageSpec& spec : specs)
- {
- dep_resolution_vars.emplace(std::piecewise_construct,
- std::forward_as_tuple(spec),
- std::forward_as_tuple(std::make_move_iterator(var_list_itr->begin()),
- std::make_move_iterator(var_list_itr->end())));
- ++var_list_itr;
- }
- }
-
- void TripletCMakeVarProvider::load_tag_vars(View<FullPackageSpec> specs,
- const PortFileProvider::PortFileProvider& port_provider) const
- {
- if (specs.size() == 0) return;
- std::vector<std::pair<const FullPackageSpec*, std::string>> spec_abi_settings;
- spec_abi_settings.reserve(specs.size());
-
- for (const FullPackageSpec& spec : specs)
- {
- auto& scfl = port_provider.get_control_file(spec.package_spec.name()).value_or_exit(VCPKG_LINE_INFO);
- const fs::path override_path = scfl.source_location / "vcpkg-abi-settings.cmake";
- spec_abi_settings.emplace_back(&spec, fs::generic_u8string(override_path));
- }
-
- std::vector<std::vector<std::pair<std::string, std::string>>> vars(spec_abi_settings.size());
- const fs::path file_path = create_tag_extraction_file(spec_abi_settings);
- launch_and_split(file_path, vars);
- paths.get_filesystem().remove(file_path, VCPKG_LINE_INFO);
-
- auto var_list_itr = vars.begin();
- for (const auto& spec_abi_setting : spec_abi_settings)
- {
- const FullPackageSpec& spec = *spec_abi_setting.first;
-
- tag_vars.emplace(std::piecewise_construct,
- std::forward_as_tuple(spec.package_spec),
- std::forward_as_tuple(std::make_move_iterator(var_list_itr->begin()),
- std::make_move_iterator(var_list_itr->end())));
- ++var_list_itr;
- }
- }
-
- Optional<const std::unordered_map<std::string, std::string>&> TripletCMakeVarProvider::get_generic_triplet_vars(
- Triplet triplet) const
- {
- auto find_itr = generic_triplet_vars.find(triplet);
- if (find_itr != generic_triplet_vars.end())
- {
- return find_itr->second;
- }
-
- return nullopt;
- }
-
- Optional<const std::unordered_map<std::string, std::string>&> TripletCMakeVarProvider::get_dep_info_vars(
- const PackageSpec& spec) const
- {
- auto find_itr = dep_resolution_vars.find(spec);
- if (find_itr != dep_resolution_vars.end())
- {
- return find_itr->second;
- }
-
- return nullopt;
- }
-
- Optional<const std::unordered_map<std::string, std::string>&> TripletCMakeVarProvider::get_tag_vars(
- const PackageSpec& spec) const
- {
- auto find_itr = tag_vars.find(spec);
- if (find_itr != tag_vars.end())
- {
- return find_itr->second;
- }
-
- return nullopt;
- }
-}
diff --git a/toolsrc/src/vcpkg/commands.add-version.cpp b/toolsrc/src/vcpkg/commands.add-version.cpp
deleted file mode 100644
index bb4cc213b..000000000
--- a/toolsrc/src/vcpkg/commands.add-version.cpp
+++ /dev/null
@@ -1,416 +0,0 @@
-
-#include <vcpkg/base/checks.h>
-#include <vcpkg/base/files.h>
-#include <vcpkg/base/json.h>
-
-#include <vcpkg/commands.add-version.h>
-#include <vcpkg/configuration.h>
-#include <vcpkg/paragraphs.h>
-#include <vcpkg/portfileprovider.h>
-#include <vcpkg/registries.h>
-#include <vcpkg/vcpkgcmdarguments.h>
-#include <vcpkg/vcpkgpaths.h>
-#include <vcpkg/versions.h>
-
-using namespace vcpkg;
-
-namespace
-{
- constexpr StringLiteral BASELINE = "baseline";
- constexpr StringLiteral VERSION_RELAXED = "version";
- constexpr StringLiteral VERSION_SEMVER = "version-semver";
- constexpr StringLiteral VERSION_DATE = "version-date";
- constexpr StringLiteral VERSION_STRING = "version-string";
-
- using VersionGitTree = std::pair<SchemedVersion, std::string>;
-
- void insert_version_to_json_object(Json::Object& obj, const VersionT& version, StringLiteral version_field)
- {
- obj.insert(version_field, Json::Value::string(version.text()));
- obj.insert("port-version", Json::Value::integer(version.port_version()));
- }
-
- void insert_schemed_version_to_json_object(Json::Object& obj, const SchemedVersion& version)
- {
- if (version.scheme == Versions::Scheme::Relaxed)
- {
- return insert_version_to_json_object(obj, version.versiont, VERSION_RELAXED);
- }
-
- if (version.scheme == Versions::Scheme::Semver)
- {
- return insert_version_to_json_object(obj, version.versiont, VERSION_SEMVER);
- }
-
- if (version.scheme == Versions::Scheme::Date)
- {
- return insert_version_to_json_object(obj, version.versiont, VERSION_DATE);
- }
-
- if (version.scheme == Versions::Scheme::String)
- {
- return insert_version_to_json_object(obj, version.versiont, VERSION_STRING);
- }
- Checks::unreachable(VCPKG_LINE_INFO);
- }
-
- static Json::Object serialize_baseline(const std::map<std::string, VersionT, std::less<>>& baseline)
- {
- Json::Object port_entries_obj;
- for (auto&& kv_pair : baseline)
- {
- Json::Object baseline_version_obj;
- insert_version_to_json_object(baseline_version_obj, kv_pair.second, BASELINE);
- port_entries_obj.insert(kv_pair.first, baseline_version_obj);
- }
-
- Json::Object baseline_obj;
- baseline_obj.insert("default", port_entries_obj);
- return baseline_obj;
- }
-
- static Json::Object serialize_versions(const std::vector<VersionGitTree>& versions)
- {
- Json::Array versions_array;
- for (auto&& version : versions)
- {
- Json::Object version_obj;
- version_obj.insert("git-tree", Json::Value::string(version.second));
- insert_schemed_version_to_json_object(version_obj, version.first);
- versions_array.push_back(std::move(version_obj));
- }
-
- Json::Object output_object;
- output_object.insert("versions", versions_array);
- return output_object;
- }
-
- static void write_baseline_file(Files::Filesystem& fs,
- const std::map<std::string, VersionT, std::less<>>& baseline_map,
- const fs::path& output_path)
- {
- auto backup_path = fs::u8path(Strings::concat(fs::u8string(output_path), ".backup"));
- if (fs.exists(output_path))
- {
- fs.rename(output_path, backup_path, VCPKG_LINE_INFO);
- fs.remove(output_path, VCPKG_LINE_INFO);
- }
-
- std::error_code ec;
- fs.write_contents(
- output_path, Json::stringify(serialize_baseline(baseline_map), Json::JsonStyle::with_spaces(2)), ec);
- if (ec)
- {
- System::printf(
- System::Color::error, "Error: Couldn't write baseline file to %s.", fs::u8string(output_path));
- if (fs.exists(backup_path))
- {
- fs.rename(backup_path, output_path, VCPKG_LINE_INFO);
- }
- Checks::exit_fail(VCPKG_LINE_INFO);
- }
- if (fs.exists(backup_path))
- {
- fs.remove(backup_path, VCPKG_LINE_INFO);
- }
- }
-
- static void write_versions_file(Files::Filesystem& fs,
- const std::vector<VersionGitTree>& versions,
- const fs::path& output_path)
- {
- auto backup_path = fs::u8path(Strings::concat(fs::u8string(output_path), ".backup"));
- if (fs.exists(output_path))
- {
- fs.rename(output_path, backup_path, VCPKG_LINE_INFO);
- fs.remove(output_path, VCPKG_LINE_INFO);
- }
-
- std::error_code ec;
- fs.create_directories(output_path.parent_path(), VCPKG_LINE_INFO);
- fs.write_contents(
- output_path, Json::stringify(serialize_versions(versions), Json::JsonStyle::with_spaces(2)), ec);
- if (ec)
- {
- System::printf(
- System::Color::error, "Error: Couldn't write versions file to %s.", fs::u8string(output_path));
- if (fs.exists(backup_path))
- {
- fs.rename(backup_path, output_path, VCPKG_LINE_INFO);
- }
- Checks::exit_fail(VCPKG_LINE_INFO);
- }
- if (fs.exists(backup_path))
- {
- fs.remove(backup_path, VCPKG_LINE_INFO);
- }
- }
-
- static void update_baseline_version(const VcpkgPaths& paths,
- const std::string& port_name,
- const VersionT& version,
- const fs::path& baseline_path,
- bool print_success)
- {
- bool is_new_file = false;
- auto& fs = paths.get_filesystem();
- auto baseline_map = [&]() -> std::map<std::string, vcpkg::VersionT, std::less<>> {
- if (!fs.exists(VCPKG_LINE_INFO, baseline_path))
- {
- is_new_file = true;
- std::map<std::string, vcpkg::VersionT, std::less<>> ret;
- return ret;
- }
- auto maybe_baseline_map = vcpkg::get_builtin_baseline(paths);
- return maybe_baseline_map.value_or_exit(VCPKG_LINE_INFO);
- }();
-
- auto it = baseline_map.find(port_name);
- if (it != baseline_map.end())
- {
- auto& baseline_version = it->second;
- if (baseline_version == version)
- {
- if (print_success)
- {
- System::printf(System::Color::success,
- "Version `%s` is already in `%s`\n",
- version,
- fs::u8string(baseline_path));
- }
- return;
- }
- baseline_version = version;
- }
- else
- {
- baseline_map.emplace(port_name, version);
- }
-
- write_baseline_file(fs, baseline_map, baseline_path);
- if (print_success)
- {
- System::printf(System::Color::success,
- "Added version `%s` to `%s`%s.\n",
- version.to_string(),
- fs::u8string(baseline_path),
- is_new_file ? " (new file)" : "");
- }
- return;
- }
-
- static void update_version_db_file(const VcpkgPaths& paths,
- const std::string& port_name,
- const SchemedVersion& version,
- const std::string& git_tree,
- const fs::path& version_db_file_path,
- bool overwrite_version,
- bool print_success,
- bool keep_going)
- {
- auto& fs = paths.get_filesystem();
- if (!fs.exists(VCPKG_LINE_INFO, version_db_file_path))
- {
- std::vector<VersionGitTree> new_entry{{version, git_tree}};
- write_versions_file(fs, new_entry, version_db_file_path);
- if (print_success)
- {
- System::printf(System::Color::success,
- "Added version `%s` to `%s` (new file).\n",
- version.versiont,
- fs::u8string(version_db_file_path));
- }
- return;
- }
-
- auto maybe_versions = get_builtin_versions(paths, port_name);
- if (auto versions = maybe_versions.get())
- {
- const auto& versions_end = versions->end();
-
- auto found_same_sha = std::find_if(
- versions->begin(), versions_end, [&](auto&& entry) -> bool { return entry.second == git_tree; });
- if (found_same_sha != versions_end)
- {
- if (found_same_sha->first.versiont == version.versiont)
- {
- if (print_success)
- {
- System::printf(System::Color::success,
- "Version `%s` is already in `%s`\n",
- version.versiont,
- fs::u8string(version_db_file_path));
- }
- return;
- }
- System::printf(System::Color::warning,
- "Warning: Local port files SHA is the same as version `%s` in `%s`.\n"
- "-- SHA: %s\n"
- "-- Did you remember to commit your changes?\n"
- "***No files were updated.***\n",
- found_same_sha->first.versiont,
- fs::u8string(version_db_file_path),
- git_tree);
- if (keep_going) return;
- Checks::exit_fail(VCPKG_LINE_INFO);
- }
-
- auto it = std::find_if(versions->begin(), versions_end, [&](auto&& entry) -> bool {
- return entry.first.versiont == version.versiont;
- });
-
- if (it != versions_end)
- {
- if (!overwrite_version)
- {
- System::printf(System::Color::error,
- "Error: Local changes detected for %s but no changes to version or port version.\n"
- "-- Version: %s\n"
- "-- Old SHA: %s\n"
- "-- New SHA: %s\n"
- "-- Did you remember to update the version or port version?\n"
- "-- Pass `--overwrite-version` to bypass this check.\n"
- "***No files were updated.***\n",
- port_name,
- version.versiont,
- it->second,
- git_tree);
- if (keep_going) return;
- Checks::exit_fail(VCPKG_LINE_INFO);
- }
-
- it->first = version;
- it->second = git_tree;
- }
- else
- {
- versions->insert(versions->begin(), std::make_pair(version, git_tree));
- }
-
- write_versions_file(fs, *versions, version_db_file_path);
- if (print_success)
- {
- System::printf(System::Color::success,
- "Added version `%s` to `%s`.\n",
- version.versiont,
- fs::u8string(version_db_file_path));
- }
- return;
- }
-
- System::printf(System::Color::error,
- "Error: Unable to parse versions file %s.\n%s\n",
- fs::u8string(version_db_file_path),
- maybe_versions.error());
- Checks::exit_fail(VCPKG_LINE_INFO);
- }
-}
-
-namespace vcpkg::Commands::AddVersion
-{
- static constexpr StringLiteral OPTION_ALL = "all";
- static constexpr StringLiteral OPTION_OVERWRITE_VERSION = "overwrite-version";
- static constexpr StringLiteral OPTION_VERBOSE = "verbose";
-
- const CommandSwitch COMMAND_SWITCHES[] = {
- {OPTION_ALL, "Process versions for all ports."},
- {OPTION_OVERWRITE_VERSION, "Overwrite `git-tree` of an existing version."},
- {OPTION_VERBOSE, "Print success messages instead of just errors."},
- };
-
- const CommandStructure COMMAND_STRUCTURE{
- create_example_string(R"###(x-add-version <port name>)###"),
- 0,
- 1,
- {{COMMAND_SWITCHES}, {}, {}},
- nullptr,
- };
-
- void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths)
- {
- auto parsed_args = args.parse_arguments(COMMAND_STRUCTURE);
- const bool add_all = Util::Sets::contains(parsed_args.switches, OPTION_ALL);
- const bool overwrite_version = Util::Sets::contains(parsed_args.switches, OPTION_OVERWRITE_VERSION);
- const bool verbose = Util::Sets::contains(parsed_args.switches, OPTION_VERBOSE);
-
- auto& fs = paths.get_filesystem();
- auto baseline_path = paths.builtin_registry_versions / fs::u8path("baseline.json");
- if (!fs.exists(VCPKG_LINE_INFO, baseline_path))
- {
- System::printf(
- System::Color::error, "Error: Couldn't find required file `%s`\n.", fs::u8string(baseline_path));
- Checks::exit_fail(VCPKG_LINE_INFO);
- }
-
- std::vector<std::string> port_names;
- if (!args.command_arguments.empty())
- {
- if (add_all)
- {
- System::printf(System::Color::warning,
- "Warning: Ignoring option `--%s` since a port name argument was provided.\n",
- OPTION_ALL);
- }
- port_names.emplace_back(args.command_arguments[0]);
- }
- else
- {
- if (!add_all)
- {
- System::printf(System::Color::error,
- "Error: Use option `--%s` to update version files for all ports at once.\n",
- OPTION_ALL);
- Checks::exit_fail(VCPKG_LINE_INFO);
- }
-
- for (auto&& port_dir : fs::directory_iterator(paths.builtin_ports_directory()))
- {
- port_names.emplace_back(fs::u8string(port_dir.path().stem()));
- }
- }
-
- // Get tree-ish from local repository state.
- auto maybe_git_tree_map = paths.git_get_local_port_treeish_map();
- auto git_tree_map = maybe_git_tree_map.value_or_exit(VCPKG_LINE_INFO);
-
- for (auto&& port_name : port_names)
- {
- // Get version information of the local port
- auto maybe_scf = Paragraphs::try_load_port(fs, paths.builtin_ports_directory() / fs::u8path(port_name));
- if (!maybe_scf.has_value())
- {
- if (add_all) continue;
- System::printf(System::Color::error, "Error: Couldn't load port `%s`.", port_name);
- Checks::exit_fail(VCPKG_LINE_INFO);
- }
-
- const auto& scf = maybe_scf.value_or_exit(VCPKG_LINE_INFO);
- const auto& schemed_version = scf->to_schemed_version();
-
- auto git_tree_it = git_tree_map.find(port_name);
- if (git_tree_it == git_tree_map.end())
- {
- System::printf(System::Color::warning,
- "Warning: No local Git SHA was found for port `%s`.\n"
- "-- Did you remember to commit your changes?\n"
- "***No files were updated.***\n",
- port_name);
- if (add_all) continue;
- Checks::exit_fail(VCPKG_LINE_INFO);
- }
- const auto& git_tree = git_tree_it->second;
-
- auto port_versions_path = paths.builtin_registry_versions / fs::u8path({port_name[0], '-'}) /
- fs::u8path(Strings::concat(port_name, ".json"));
- update_version_db_file(
- paths, port_name, schemed_version, git_tree, port_versions_path, overwrite_version, verbose, add_all);
- update_baseline_version(paths, port_name, schemed_version.versiont, baseline_path, verbose);
- }
- Checks::exit_success(VCPKG_LINE_INFO);
- }
-
- void AddVersionCommand::perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) const
- {
- AddVersion::perform_and_exit(args, paths);
- }
-}
diff --git a/toolsrc/src/vcpkg/commands.autocomplete.cpp b/toolsrc/src/vcpkg/commands.autocomplete.cpp
deleted file mode 100644
index d61e9119e..000000000
--- a/toolsrc/src/vcpkg/commands.autocomplete.cpp
+++ /dev/null
@@ -1,185 +0,0 @@
-#include <vcpkg/base/system.print.h>
-
-#include <vcpkg/commands.autocomplete.h>
-#include <vcpkg/commands.edit.h>
-#include <vcpkg/commands.integrate.h>
-#include <vcpkg/commands.upgrade.h>
-#include <vcpkg/install.h>
-#include <vcpkg/metrics.h>
-#include <vcpkg/paragraphs.h>
-#include <vcpkg/remove.h>
-#include <vcpkg/vcpkgcmdarguments.h>
-#include <vcpkg/vcpkglib.h>
-
-namespace vcpkg::Commands::Autocomplete
-{
- [[noreturn]] static void output_sorted_results_and_exit(const LineInfo& line_info,
- std::vector<std::string>&& results)
- {
- const SortedVector<std::string> sorted_results(results);
- System::print2(Strings::join("\n", sorted_results), '\n');
-
- Checks::exit_success(line_info);
- }
-
- static std::vector<std::string> combine_port_with_triplets(const std::string& port,
- const std::vector<std::string>& triplets)
- {
- return Util::fmap(triplets,
- [&](const std::string& triplet) { return Strings::format("%s:%s", port, triplet); });
- }
-
- void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths)
- {
- Metrics::g_metrics.lock()->set_send_metrics(false);
- const std::string to_autocomplete = Strings::join(" ", args.command_arguments);
- const std::vector<std::string> tokens = Strings::split(to_autocomplete, ' ');
-
- std::smatch match;
-
- // Handles vcpkg <command>
- if (std::regex_match(to_autocomplete, match, std::regex{R"###(^(\S*)$)###"}))
- {
- const std::string requested_command = match[1].str();
-
- // First try public commands
- std::vector<std::string> public_commands = {"install",
- "search",
- "remove",
- "list",
- "update",
- "hash",
- "help",
- "integrate",
- "export",
- "edit",
- "create",
- "owns",
- "cache",
- "version",
- "contact",
- "upgrade"};
-
- Util::erase_remove_if(public_commands, [&](const std::string& s) {
- return !Strings::case_insensitive_ascii_starts_with(s, requested_command);
- });
-
- if (!public_commands.empty())
- {
- output_sorted_results_and_exit(VCPKG_LINE_INFO, std::move(public_commands));
- }
-
- // If no public commands match, try private commands
- std::vector<std::string> private_commands = {
- "build",
- "buildexternal",
- "ci",
- "depend-info",
- "env",
- "portsdiff",
- };
-
- Util::erase_remove_if(private_commands, [&](const std::string& s) {
- return !Strings::case_insensitive_ascii_starts_with(s, requested_command);
- });
-
- output_sorted_results_and_exit(VCPKG_LINE_INFO, std::move(private_commands));
- }
-
- // Handles vcpkg install package:<triplet>
- if (std::regex_match(to_autocomplete, match, std::regex{R"###(^install(.*|)\s([^:]+):(\S*)$)###"}))
- {
- const auto port_name = match[2].str();
- const auto triplet_prefix = match[3].str();
-
- // TODO: Support autocomplete for ports in --overlay-ports
- auto maybe_port =
- Paragraphs::try_load_port(paths.get_filesystem(), paths.builtin_ports_directory() / port_name);
- if (maybe_port.error())
- {
- Checks::exit_success(VCPKG_LINE_INFO);
- }
-
- std::vector<std::string> triplets = paths.get_available_triplets_names();
- Util::erase_remove_if(triplets, [&](const std::string& s) {
- return !Strings::case_insensitive_ascii_starts_with(s, triplet_prefix);
- });
-
- auto result = combine_port_with_triplets(port_name, triplets);
-
- output_sorted_results_and_exit(VCPKG_LINE_INFO, std::move(result));
- }
-
- struct CommandEntry
- {
- constexpr CommandEntry(const CStringView& name, const CStringView& regex, const CommandStructure& structure)
- : name(name), regex(regex), structure(structure)
- {
- }
-
- CStringView name;
- CStringView regex;
- const CommandStructure& structure;
- };
-
- static constexpr CommandEntry COMMANDS[] = {
- CommandEntry{"install", R"###(^install\s(.*\s|)(\S*)$)###", Install::COMMAND_STRUCTURE},
- CommandEntry{"edit", R"###(^edit\s(.*\s|)(\S*)$)###", Edit::COMMAND_STRUCTURE},
- CommandEntry{"remove", R"###(^remove\s(.*\s|)(\S*)$)###", Remove::COMMAND_STRUCTURE},
- CommandEntry{"integrate", R"###(^integrate(\s+)(\S*)$)###", Integrate::COMMAND_STRUCTURE},
- CommandEntry{"upgrade", R"###(^upgrade(\s+)(\S*)$)###", Upgrade::COMMAND_STRUCTURE},
- };
-
- for (auto&& command : COMMANDS)
- {
- if (std::regex_match(to_autocomplete, match, std::regex{command.regex.c_str()}))
- {
- const auto prefix = match[2].str();
- std::vector<std::string> results;
-
- const bool is_option = Strings::case_insensitive_ascii_starts_with(prefix, "-");
- if (is_option)
- {
- results = Util::fmap(command.structure.options.switches, [](const CommandSwitch& s) -> std::string {
- return Strings::format("--%s", s.name.to_string());
- });
-
- auto settings = Util::fmap(command.structure.options.settings,
- [](auto&& s) { return Strings::format("--%s", s.name); });
- results.insert(results.end(), settings.begin(), settings.end());
-
- auto multisettings = Util::fmap(command.structure.options.multisettings,
- [](auto&& s) { return Strings::format("--%s", s.name); });
- results.insert(results.end(), multisettings.begin(), multisettings.end());
- }
- else
- {
- if (command.structure.valid_arguments != nullptr)
- {
- results = command.structure.valid_arguments(paths);
- }
- }
-
- Util::erase_remove_if(results, [&](const std::string& s) {
- return !Strings::case_insensitive_ascii_starts_with(s, prefix);
- });
-
- if (command.name == "install" && results.size() == 1 && !is_option)
- {
- const auto port_at_each_triplet =
- combine_port_with_triplets(results[0], paths.get_available_triplets_names());
- Util::Vectors::append(&results, port_at_each_triplet);
- }
-
- output_sorted_results_and_exit(VCPKG_LINE_INFO, std::move(results));
- }
- }
-
- Checks::exit_success(VCPKG_LINE_INFO);
- }
-
- void AutocompleteCommand::perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) const
- {
- Autocomplete::perform_and_exit(args, paths);
- }
-}
diff --git a/toolsrc/src/vcpkg/commands.buildexternal.cpp b/toolsrc/src/vcpkg/commands.buildexternal.cpp
deleted file mode 100644
index 65b1ec823..000000000
--- a/toolsrc/src/vcpkg/commands.buildexternal.cpp
+++ /dev/null
@@ -1,54 +0,0 @@
-#include <vcpkg/binarycaching.h>
-#include <vcpkg/build.h>
-#include <vcpkg/cmakevars.h>
-#include <vcpkg/commands.buildexternal.h>
-#include <vcpkg/help.h>
-#include <vcpkg/input.h>
-#include <vcpkg/portfileprovider.h>
-#include <vcpkg/vcpkgcmdarguments.h>
-
-namespace vcpkg::Commands::BuildExternal
-{
- const CommandStructure COMMAND_STRUCTURE = {
- create_example_string(R"(build_external zlib2 C:\path\to\dir\with\controlfile\)"),
- 2,
- 2,
- {},
- nullptr,
- };
-
- void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, Triplet default_triplet)
- {
- const ParsedArguments options = args.parse_arguments(COMMAND_STRUCTURE);
-
- auto binaryprovider = create_binary_provider_from_configs(args.binary_sources).value_or_exit(VCPKG_LINE_INFO);
-
- const FullPackageSpec spec = Input::check_and_get_full_package_spec(
- std::string(args.command_arguments.at(0)), default_triplet, COMMAND_STRUCTURE.example_text);
- Input::check_triplet(spec.package_spec.triplet(), paths);
-
- auto overlays = args.overlay_ports;
- overlays.insert(overlays.begin(), args.command_arguments.at(1));
-
- PortFileProvider::PathsPortFileProvider provider(paths, overlays);
- auto maybe_scfl = provider.get_control_file(spec.package_spec.name());
-
- Checks::check_maybe_upgrade(
- VCPKG_LINE_INFO, maybe_scfl.has_value(), "could not load control file for %s", spec.package_spec.name());
-
- Build::Command::perform_and_exit_ex(args,
- spec,
- maybe_scfl.value_or_exit(VCPKG_LINE_INFO),
- provider,
- args.binary_caching_enabled() ? *binaryprovider : null_binary_provider(),
- Build::null_build_logs_recorder(),
- paths);
- }
-
- void BuildExternalCommand::perform_and_exit(const VcpkgCmdArguments& args,
- const VcpkgPaths& paths,
- Triplet default_triplet) const
- {
- BuildExternal::perform_and_exit(args, paths, default_triplet);
- }
-}
diff --git a/toolsrc/src/vcpkg/commands.cache.cpp b/toolsrc/src/vcpkg/commands.cache.cpp
deleted file mode 100644
index af851bc98..000000000
--- a/toolsrc/src/vcpkg/commands.cache.cpp
+++ /dev/null
@@ -1,79 +0,0 @@
-#include <vcpkg/base/files.h>
-#include <vcpkg/base/system.print.h>
-
-#include <vcpkg/binaryparagraph.h>
-#include <vcpkg/commands.cache.h>
-#include <vcpkg/help.h>
-#include <vcpkg/paragraphs.h>
-#include <vcpkg/vcpkgcmdarguments.h>
-#include <vcpkg/vcpkgpaths.h>
-
-namespace vcpkg::Commands::Cache
-{
- static std::vector<BinaryParagraph> read_all_binary_paragraphs(const VcpkgPaths& paths)
- {
- std::vector<BinaryParagraph> output;
- for (auto&& path : paths.get_filesystem().get_files_non_recursive(paths.packages))
- {
- const auto pghs = Paragraphs::get_single_paragraph(paths.get_filesystem(), path / fs::u8path("CONTROL"));
- if (const auto p = pghs.get())
- {
- const BinaryParagraph binary_paragraph = BinaryParagraph(*p);
- output.push_back(binary_paragraph);
- }
- }
-
- return output;
- }
-
- const CommandStructure COMMAND_STRUCTURE = {
- Strings::format(
- "The argument should be a substring to search for, or no argument to display all cached libraries.\n%s",
- create_example_string("cache png")),
- 0,
- 1,
- {},
- nullptr,
- };
-
- void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths)
- {
- (void)(args.parse_arguments(COMMAND_STRUCTURE));
-
- const std::vector<BinaryParagraph> binary_paragraphs = read_all_binary_paragraphs(paths);
- if (binary_paragraphs.empty())
- {
- System::print2("No packages are cached.\n");
- Checks::exit_success(VCPKG_LINE_INFO);
- }
-
- if (args.command_arguments.empty())
- {
- for (const BinaryParagraph& binary_paragraph : binary_paragraphs)
- {
- System::print2(binary_paragraph.displayname(), '\n');
- }
- }
- else
- {
- // At this point there is 1 argument
- for (const BinaryParagraph& binary_paragraph : binary_paragraphs)
- {
- const std::string displayname = binary_paragraph.displayname();
- if (!Strings::case_insensitive_ascii_contains(displayname, args.command_arguments[0]))
- {
- continue;
- }
-
- System::print2(displayname, '\n');
- }
- }
-
- Checks::exit_success(VCPKG_LINE_INFO);
- }
-
- void CacheCommand::perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) const
- {
- Cache::perform_and_exit(args, paths);
- }
-}
diff --git a/toolsrc/src/vcpkg/commands.ci.cpp b/toolsrc/src/vcpkg/commands.ci.cpp
deleted file mode 100644
index 26ae058ad..000000000
--- a/toolsrc/src/vcpkg/commands.ci.cpp
+++ /dev/null
@@ -1,606 +0,0 @@
-#include <vcpkg/base/cache.h>
-#include <vcpkg/base/files.h>
-#include <vcpkg/base/graphs.h>
-#include <vcpkg/base/stringliteral.h>
-#include <vcpkg/base/system.h>
-#include <vcpkg/base/util.h>
-
-#include <vcpkg/binarycaching.h>
-#include <vcpkg/build.h>
-#include <vcpkg/cmakevars.h>
-#include <vcpkg/commands.ci.h>
-#include <vcpkg/dependencies.h>
-#include <vcpkg/globalstate.h>
-#include <vcpkg/help.h>
-#include <vcpkg/input.h>
-#include <vcpkg/install.h>
-#include <vcpkg/packagespec.h>
-#include <vcpkg/paragraphs.h>
-#include <vcpkg/platform-expression.h>
-#include <vcpkg/portfileprovider.h>
-#include <vcpkg/vcpkgcmdarguments.h>
-#include <vcpkg/vcpkglib.h>
-
-using namespace vcpkg;
-
-namespace
-{
- using namespace vcpkg::Build;
-
- const fs::path dot_log = fs::u8path(".log");
- const fs::path readme_dot_log = fs::u8path("readme.log");
-
- class CiBuildLogsRecorder final : public IBuildLogsRecorder
- {
- fs::path base_path;
-
- public:
- CiBuildLogsRecorder(const fs::path& base_path_) : base_path(base_path_) { }
-
- virtual void record_build_result(const VcpkgPaths& paths,
- const PackageSpec& spec,
- BuildResult result) const override
- {
- if (result == BuildResult::SUCCEEDED)
- {
- return;
- }
-
- auto& filesystem = paths.get_filesystem();
- const auto source_path = paths.build_dir(spec);
- auto children = filesystem.get_files_non_recursive(source_path);
- Util::erase_remove_if(children, [](const fs::path& p) { return p.extension() != dot_log; });
- const auto target_path = base_path / fs::u8path(spec.name());
- (void)filesystem.create_directory(target_path, VCPKG_LINE_INFO);
- if (children.empty())
- {
- std::string message =
- "There are no build logs for " + spec.to_string() +
- " build.\n"
- "This is usually because the build failed early and outside of a task that is logged.\n"
- "See the console output logs from vcpkg for more information on the failure.\n";
- filesystem.write_contents(target_path / readme_dot_log, message, VCPKG_LINE_INFO);
- }
- else
- {
- for (const fs::path& p : children)
- {
- filesystem.copy_file(p, target_path / p.filename(), fs::copy_options::none, VCPKG_LINE_INFO);
- }
- }
- }
- };
-}
-
-namespace vcpkg::Commands::CI
-{
- using Build::BuildResult;
- using Dependencies::InstallPlanAction;
- using Dependencies::InstallPlanType;
-
- struct TripletAndSummary
- {
- Triplet triplet;
- Install::InstallSummary summary;
- };
-
- static constexpr StringLiteral OPTION_DRY_RUN = "dry-run";
- static constexpr StringLiteral OPTION_EXCLUDE = "exclude";
- static constexpr StringLiteral OPTION_FAILURE_LOGS = "failure-logs";
- static constexpr StringLiteral OPTION_XUNIT = "x-xunit";
- static constexpr StringLiteral OPTION_RANDOMIZE = "x-randomize";
-
- static constexpr std::array<CommandSetting, 3> CI_SETTINGS = {
- {{OPTION_EXCLUDE, "Comma separated list of ports to skip"},
- {OPTION_XUNIT, "File to output results in XUnit format (internal)"},
- {OPTION_FAILURE_LOGS, "Directory to which failure logs will be copied"}}};
-
- static constexpr std::array<CommandSwitch, 2> CI_SWITCHES = {{
- {OPTION_DRY_RUN, "Print out plan without execution"},
- {OPTION_RANDOMIZE, "Randomize the install order"},
- }};
-
- const CommandStructure COMMAND_STRUCTURE = {
- create_example_string("ci x64-windows"),
- 1,
- SIZE_MAX,
- {CI_SWITCHES, CI_SETTINGS},
- nullptr,
- };
-
- struct XunitTestResults
- {
- public:
- XunitTestResults() { m_assembly_run_datetime = Chrono::CTime::get_current_date_time(); }
-
- void add_test_results(const std::string& spec,
- const Build::BuildResult& build_result,
- const Chrono::ElapsedTime& elapsed_time,
- const std::string& abi_tag,
- const std::vector<std::string>& features)
- {
- m_collections.back().tests.push_back({spec, build_result, elapsed_time, abi_tag, features});
- }
-
- // Starting a new test collection
- void push_collection(const std::string& name) { m_collections.push_back({name}); }
-
- void collection_time(const vcpkg::Chrono::ElapsedTime& time) { m_collections.back().time = time; }
-
- const std::string& build_xml()
- {
- m_xml.clear();
- xml_start_assembly();
-
- for (const auto& collection : m_collections)
- {
- xml_start_collection(collection);
- for (const auto& test : collection.tests)
- {
- xml_test(test);
- }
- xml_finish_collection();
- }
-
- xml_finish_assembly();
- return m_xml;
- }
-
- void assembly_time(const vcpkg::Chrono::ElapsedTime& assembly_time) { m_assembly_time = assembly_time; }
-
- private:
- struct XunitTest
- {
- std::string name;
- vcpkg::Build::BuildResult result;
- vcpkg::Chrono::ElapsedTime time;
- std::string abi_tag;
- std::vector<std::string> features;
- };
-
- struct XunitCollection
- {
- std::string name;
- vcpkg::Chrono::ElapsedTime time;
- std::vector<XunitTest> tests;
- };
-
- void xml_start_assembly()
- {
- std::string datetime;
- if (m_assembly_run_datetime)
- {
- auto rawDateTime = m_assembly_run_datetime.get()->to_string();
- // The expected format is "yyyy-mm-ddThh:mm:ss.0Z"
- // 0123456789012345678901
- datetime = Strings::format(
- R"(run-date="%s" run-time="%s")", rawDateTime.substr(0, 10), rawDateTime.substr(11, 8));
- }
-
- std::string time = Strings::format(R"(time="%lld")", m_assembly_time.as<std::chrono::seconds>().count());
-
- m_xml += Strings::format(R"(<assemblies>)"
- "\n"
- R"( <assembly name="vcpkg" %s %s>)"
- "\n",
- datetime,
- time);
- }
- void xml_finish_assembly()
- {
- m_xml += " </assembly>\n"
- "</assemblies>\n";
- }
-
- void xml_start_collection(const XunitCollection& collection)
- {
- m_xml += Strings::format(R"( <collection name="%s" time="%lld">)"
- "\n",
- collection.name,
- collection.time.as<std::chrono::seconds>().count());
- }
- void xml_finish_collection() { m_xml += " </collection>\n"; }
-
- void xml_test(const XunitTest& test)
- {
- std::string message_block;
- const char* result_string = "";
- switch (test.result)
- {
- case BuildResult::POST_BUILD_CHECKS_FAILED:
- case BuildResult::FILE_CONFLICTS:
- case BuildResult::BUILD_FAILED:
- result_string = "Fail";
- message_block =
- Strings::format("<failure><message><![CDATA[%s]]></message></failure>", to_string(test.result));
- break;
- case BuildResult::EXCLUDED:
- case BuildResult::CASCADED_DUE_TO_MISSING_DEPENDENCIES:
- result_string = "Skip";
- message_block = Strings::format("<reason><![CDATA[%s]]></reason>", to_string(test.result));
- break;
- case BuildResult::SUCCEEDED: result_string = "Pass"; break;
- default: Checks::unreachable(VCPKG_LINE_INFO);
- }
-
- std::string traits_block;
- if (!test.abi_tag.empty())
- {
- traits_block += Strings::format(R"(<trait name="abi_tag" value="%s" />)", test.abi_tag);
- }
-
- if (!test.features.empty())
- {
- std::string feature_list;
- for (const auto& feature : test.features)
- {
- if (!feature_list.empty())
- {
- feature_list += ", ";
- }
- feature_list += feature;
- }
-
- traits_block += Strings::format(R"(<trait name="features" value="%s" />)", feature_list);
- }
-
- if (!traits_block.empty())
- {
- traits_block = "<traits>" + traits_block + "</traits>";
- }
-
- m_xml += Strings::format(R"( <test name="%s" method="%s" time="%lld" result="%s">%s%s</test>)"
- "\n",
- test.name,
- test.name,
- test.time.as<std::chrono::seconds>().count(),
- result_string,
- traits_block,
- message_block);
- }
-
- Optional<vcpkg::Chrono::CTime> m_assembly_run_datetime;
- vcpkg::Chrono::ElapsedTime m_assembly_time;
- std::vector<XunitCollection> m_collections;
-
- std::string m_xml;
- };
-
- struct UnknownCIPortsResults
- {
- std::vector<FullPackageSpec> unknown;
- std::map<PackageSpec, Build::BuildResult> known;
- std::map<PackageSpec, std::vector<std::string>> features;
- Dependencies::ActionPlan plan;
- std::map<PackageSpec, std::string> abi_map;
- };
-
- static bool supported_for_triplet(const CMakeVars::CMakeVarProvider& var_provider,
- const InstallPlanAction* install_plan)
- {
- auto&& scfl = install_plan->source_control_file_location.value_or_exit(VCPKG_LINE_INFO);
- const auto& supports_expression = scfl.source_control_file->core_paragraph->supports_expression;
- PlatformExpression::Context context =
- var_provider.get_tag_vars(install_plan->spec).value_or_exit(VCPKG_LINE_INFO);
-
- return supports_expression.evaluate(context);
- }
-
- static std::unique_ptr<UnknownCIPortsResults> find_unknown_ports_for_ci(
- const VcpkgPaths& paths,
- const std::set<std::string>& exclusions,
- const PortFileProvider::PortFileProvider& provider,
- const CMakeVars::CMakeVarProvider& var_provider,
- const std::vector<FullPackageSpec>& specs,
- IBinaryProvider& binaryprovider)
- {
- auto ret = std::make_unique<UnknownCIPortsResults>();
-
- std::set<PackageSpec> will_fail;
-
- std::vector<PackageSpec> packages_with_qualified_deps;
- auto has_qualifier = [](Dependency const& dep) { return !dep.platform.is_empty(); };
- for (auto&& spec : specs)
- {
- auto&& scfl = provider.get_control_file(spec.package_spec.name()).value_or_exit(VCPKG_LINE_INFO);
- if (Util::any_of(scfl.source_control_file->core_paragraph->dependencies, has_qualifier) ||
- Util::any_of(scfl.source_control_file->feature_paragraphs,
- [&](auto&& pgh) { return Util::any_of(pgh->dependencies, has_qualifier); }))
- {
- packages_with_qualified_deps.push_back(spec.package_spec);
- }
- }
-
- var_provider.load_dep_info_vars(packages_with_qualified_deps);
- auto action_plan = Dependencies::create_feature_install_plan(provider, var_provider, specs, {}, {});
-
- std::vector<FullPackageSpec> install_specs;
- for (auto&& install_action : action_plan.install_actions)
- {
- install_specs.emplace_back(install_action.spec, install_action.feature_list);
- }
-
- var_provider.load_tag_vars(install_specs, provider);
-
- auto timer = Chrono::ElapsedTimer::create_started();
-
- Checks::check_exit(VCPKG_LINE_INFO, action_plan.already_installed.empty());
- Checks::check_exit(VCPKG_LINE_INFO, action_plan.remove_actions.empty());
-
- Build::compute_all_abis(paths, action_plan, var_provider, {});
-
- auto precheck_results = binary_provider_precheck(paths, action_plan, binaryprovider);
- {
- vcpkg::System::BufferedPrint stdout_print;
-
- for (auto&& action : action_plan.install_actions)
- {
- auto p = &action;
- ret->abi_map.emplace(action.spec, action.abi_info.value_or_exit(VCPKG_LINE_INFO).package_abi);
- ret->features.emplace(action.spec, action.feature_list);
-
- auto precheck_result = precheck_results.at(&action);
- bool b_will_build = false;
-
- std::string state;
-
- if (Util::Sets::contains(exclusions, p->spec.name()))
- {
- state = "skip";
- ret->known.emplace(p->spec, BuildResult::EXCLUDED);
- will_fail.emplace(p->spec);
- }
- else if (!supported_for_triplet(var_provider, p))
- {
- // This treats unsupported ports as if they are excluded
- // which means the ports dependent on it will be cascaded due to missing dependencies
- // Should this be changed so instead it is a failure to depend on a unsupported port?
- state = "n/a";
- ret->known.emplace(p->spec, BuildResult::EXCLUDED);
- will_fail.emplace(p->spec);
- }
- else if (Util::any_of(p->package_dependencies,
- [&](const PackageSpec& spec) { return Util::Sets::contains(will_fail, spec); }))
- {
- state = "cascade";
- ret->known.emplace(p->spec, BuildResult::CASCADED_DUE_TO_MISSING_DEPENDENCIES);
- will_fail.emplace(p->spec);
- }
- else if (precheck_result == RestoreResult::success)
- {
- state = "pass";
- ret->known.emplace(p->spec, BuildResult::SUCCEEDED);
- }
- else if (precheck_result == RestoreResult::build_failed)
- {
- state = "fail";
- ret->known.emplace(p->spec, BuildResult::BUILD_FAILED);
- will_fail.emplace(p->spec);
- }
- else
- {
- ret->unknown.emplace_back(p->spec, p->feature_list);
- b_will_build = true;
- }
-
- stdout_print.append(Strings::format("%40s: %1s %8s: %s\n",
- p->spec,
- (b_will_build ? "*" : " "),
- state,
- action.abi_info.value_or_exit(VCPKG_LINE_INFO).package_abi));
- }
- } // flush stdout_print
-
- // This algorithm consumes the previous action plan to build and return a reduced one.
- std::vector<InstallPlanAction>&& input_install_actions = std::move(action_plan.install_actions);
- std::vector<InstallPlanAction*> rev_install_actions;
- rev_install_actions.reserve(input_install_actions.size());
- std::set<PackageSpec> to_keep;
- for (auto it = input_install_actions.rbegin(); it != input_install_actions.rend(); ++it)
- {
- if (!Util::Sets::contains(ret->known, it->spec))
- {
- to_keep.insert(it->spec);
- }
-
- if (Util::Sets::contains(to_keep, it->spec))
- {
- rev_install_actions.push_back(&*it);
- to_keep.insert(it->package_dependencies.begin(), it->package_dependencies.end());
- }
- }
-
- for (auto it = rev_install_actions.rbegin(); it != rev_install_actions.rend(); ++it)
- {
- ret->plan.install_actions.push_back(std::move(**it));
- }
-
- System::printf("Time to determine pass/fail: %s\n", timer.elapsed());
- return ret;
- }
-
- void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, Triplet default_triplet)
- {
- std::unique_ptr<IBinaryProvider> binaryproviderStorage;
- if (args.binary_caching_enabled())
- {
- binaryproviderStorage =
- create_binary_provider_from_configs(args.binary_sources).value_or_exit(VCPKG_LINE_INFO);
- }
-
- IBinaryProvider& binaryprovider = binaryproviderStorage ? *binaryproviderStorage : null_binary_provider();
-
- const ParsedArguments options = args.parse_arguments(COMMAND_STRUCTURE);
- auto& settings = options.settings;
-
- std::set<std::string> exclusions_set;
- auto it_exclusions = settings.find(OPTION_EXCLUDE);
- if (it_exclusions != settings.end())
- {
- auto exclusions = Strings::split(it_exclusions->second, ',');
- exclusions_set.insert(exclusions.begin(), exclusions.end());
- }
-
- const auto is_dry_run = Util::Sets::contains(options.switches, OPTION_DRY_RUN);
-
- std::vector<Triplet> triplets = Util::fmap(
- args.command_arguments, [](std::string s) { return Triplet::from_canonical_name(std::move(s)); });
-
- if (triplets.empty())
- {
- triplets.push_back(default_triplet);
- }
-
- auto& filesystem = paths.get_filesystem();
- Optional<CiBuildLogsRecorder> build_logs_recorder_storage;
- {
- auto it_failure_logs = settings.find(OPTION_FAILURE_LOGS);
- if (it_failure_logs != settings.end())
- {
- auto raw_path = fs::u8path(it_failure_logs->second);
- System::printf("Creating failure logs output directory %s\n", it_failure_logs->second);
- filesystem.create_directories(raw_path, VCPKG_LINE_INFO);
- build_logs_recorder_storage = filesystem.canonical(VCPKG_LINE_INFO, raw_path);
- }
- }
-
- const IBuildLogsRecorder& build_logs_recorder =
- build_logs_recorder_storage ? *(build_logs_recorder_storage.get()) : null_build_logs_recorder();
-
- StatusParagraphs status_db = database_load_check(paths);
-
- PortFileProvider::PathsPortFileProvider provider(paths, args.overlay_ports);
- auto var_provider_storage = CMakeVars::make_triplet_cmake_var_provider(paths);
- auto& var_provider = *var_provider_storage;
-
- std::vector<std::map<PackageSpec, BuildResult>> all_known_results;
-
- XunitTestResults xunitTestResults;
-
- std::vector<std::string> all_ports =
- Util::fmap(provider.load_all_control_files(), Paragraphs::get_name_of_control_file);
- std::vector<TripletAndSummary> results;
- auto timer = Chrono::ElapsedTimer::create_started();
- for (Triplet triplet : triplets)
- {
- Input::check_triplet(triplet, paths);
-
- xunitTestResults.push_collection(triplet.canonical_name());
-
- std::vector<PackageSpec> specs = PackageSpec::to_package_specs(all_ports, triplet);
- // Install the default features for every package
- auto all_default_full_specs = Util::fmap(specs, [&](auto& spec) {
- std::vector<std::string> default_features =
- provider.get_control_file(spec.name()).get()->source_control_file->core_paragraph->default_features;
- default_features.emplace_back("core");
- return FullPackageSpec{spec, std::move(default_features)};
- });
-
- Dependencies::CreateInstallPlanOptions serialize_options;
-
- struct RandomizerInstance : Graphs::Randomizer
- {
- virtual int random(int i) override
- {
- if (i <= 1) return 0;
- std::uniform_int_distribution<int> d(0, i - 1);
- return d(e);
- }
-
- std::random_device e;
- } randomizer_instance;
-
- if (Util::Sets::contains(options.switches, OPTION_RANDOMIZE))
- {
- serialize_options.randomizer = &randomizer_instance;
- }
-
- auto split_specs = find_unknown_ports_for_ci(
- paths, exclusions_set, provider, var_provider, all_default_full_specs, binaryprovider);
-
- auto& action_plan = split_specs->plan;
-
- for (auto&& action : action_plan.install_actions)
- {
- if (Util::Sets::contains(exclusions_set, action.spec.name()))
- {
- action.plan_type = InstallPlanType::EXCLUDED;
- }
- else
- {
- action.build_options = vcpkg::Build::backcompat_prohibiting_package_options;
- }
- }
-
- if (is_dry_run)
- {
- Dependencies::print_plan(action_plan, true, paths.builtin_ports_directory());
- }
- else
- {
- auto collection_timer = Chrono::ElapsedTimer::create_started();
- auto summary = Install::perform(args,
- action_plan,
- Install::KeepGoing::YES,
- paths,
- status_db,
- binaryprovider,
- build_logs_recorder,
- var_provider);
- auto collection_time_elapsed = collection_timer.elapsed();
-
- // Adding results for ports that were built or pulled from an archive
- for (auto&& result : summary.results)
- {
- auto& port_features = split_specs->features.at(result.spec);
- split_specs->known.erase(result.spec);
- xunitTestResults.add_test_results(result.spec.to_string(),
- result.build_result.code,
- result.timing,
- split_specs->abi_map.at(result.spec),
- port_features);
- }
-
- // Adding results for ports that were not built because they have known states
- for (auto&& port : split_specs->known)
- {
- auto& port_features = split_specs->features.at(port.first);
- xunitTestResults.add_test_results(port.first.to_string(),
- port.second,
- Chrono::ElapsedTime{},
- split_specs->abi_map.at(port.first),
- port_features);
- }
-
- all_known_results.emplace_back(std::move(split_specs->known));
-
- results.push_back({triplet, std::move(summary)});
-
- xunitTestResults.collection_time(collection_time_elapsed);
- }
- }
- xunitTestResults.assembly_time(timer.elapsed());
-
- for (auto&& result : results)
- {
- System::print2("\nTriplet: ", result.triplet, "\n");
- System::print2("Total elapsed time: ", result.summary.total_elapsed_time, "\n");
- result.summary.print();
- }
-
- auto it_xunit = settings.find(OPTION_XUNIT);
- if (it_xunit != settings.end())
- {
- filesystem.write_contents(fs::u8path(it_xunit->second), xunitTestResults.build_xml(), VCPKG_LINE_INFO);
- }
-
- Checks::exit_success(VCPKG_LINE_INFO);
- }
-
- void CICommand::perform_and_exit(const VcpkgCmdArguments& args,
- const VcpkgPaths& paths,
- Triplet default_triplet) const
- {
- CI::perform_and_exit(args, paths, default_triplet);
- }
-}
diff --git a/toolsrc/src/vcpkg/commands.ciclean.cpp b/toolsrc/src/vcpkg/commands.ciclean.cpp
deleted file mode 100644
index a92b918c8..000000000
--- a/toolsrc/src/vcpkg/commands.ciclean.cpp
+++ /dev/null
@@ -1,46 +0,0 @@
-#include <vcpkg/base/checks.h>
-#include <vcpkg/base/files.h>
-#include <vcpkg/base/system.print.h>
-
-#include <vcpkg/commands.ciclean.h>
-#include <vcpkg/vcpkgcmdarguments.h>
-#include <vcpkg/vcpkgpaths.h>
-
-using namespace vcpkg;
-
-namespace
-{
- void clear_directory(Files::Filesystem& fs, const fs::path& target)
- {
- using vcpkg::System::print2;
- if (fs.is_directory(target))
- {
- print2("Clearing contents of ", fs::u8string(target), "\n");
- fs.remove_all_inside(target, VCPKG_LINE_INFO);
- }
- else
- {
- print2("Skipping clearing contents of ", fs::u8string(target), " because it was not a directory\n");
- }
- }
-}
-
-namespace vcpkg::Commands::CIClean
-{
- void perform_and_exit(const VcpkgCmdArguments&, const VcpkgPaths& paths)
- {
- using vcpkg::System::print2;
- auto& fs = paths.get_filesystem();
- print2("Starting vcpkg CI clean\n");
- clear_directory(fs, paths.buildtrees);
- clear_directory(fs, paths.installed);
- clear_directory(fs, paths.packages);
- print2("Completed vcpkg CI clean\n");
- Checks::exit_success(VCPKG_LINE_INFO);
- }
-
- void CICleanCommand::perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) const
- {
- CIClean::perform_and_exit(args, paths);
- }
-}
diff --git a/toolsrc/src/vcpkg/commands.civerifyversions.cpp b/toolsrc/src/vcpkg/commands.civerifyversions.cpp
deleted file mode 100644
index 78269646c..000000000
--- a/toolsrc/src/vcpkg/commands.civerifyversions.cpp
+++ /dev/null
@@ -1,418 +0,0 @@
-#include <vcpkg/base/checks.h>
-#include <vcpkg/base/files.h>
-#include <vcpkg/base/json.h>
-#include <vcpkg/base/system.debug.h>
-
-#include <vcpkg/commands.civerifyversions.h>
-#include <vcpkg/paragraphs.h>
-#include <vcpkg/registries.h>
-#include <vcpkg/sourceparagraph.h>
-#include <vcpkg/vcpkgcmdarguments.h>
-#include <vcpkg/vcpkgpaths.h>
-#include <vcpkg/versiondeserializers.h>
-
-namespace
-{
- using namespace vcpkg;
-
- std::string get_scheme_name(Versions::Scheme scheme)
- {
- switch (scheme)
- {
- case Versions::Scheme::Relaxed: return "version";
- case Versions::Scheme::Semver: return "version-semver";
- case Versions::Scheme::String: return "version-string";
- case Versions::Scheme::Date: return "version-date";
- default: Checks::unreachable(VCPKG_LINE_INFO);
- }
- }
-}
-
-namespace vcpkg::Commands::CIVerifyVersions
-{
- static constexpr StringLiteral OPTION_EXCLUDE = "exclude";
- static constexpr StringLiteral OPTION_VERBOSE = "verbose";
- static constexpr StringLiteral OPTION_VERIFY_GIT_TREES = "verify-git-trees";
-
- static constexpr CommandSwitch VERIFY_VERSIONS_SWITCHES[]{
- {OPTION_VERBOSE, "Print result for each port instead of just errors."},
- {OPTION_VERIFY_GIT_TREES, "Verify that each git tree object matches its declared version (this is very slow)"},
- };
-
- static constexpr CommandSetting VERIFY_VERSIONS_SETTINGS[] = {
- {OPTION_EXCLUDE, "Comma-separated list of ports to skip"},
- };
-
- const CommandStructure COMMAND_STRUCTURE{
- create_example_string(R"###(x-ci-verify-versions)###"),
- 0,
- SIZE_MAX,
- {{VERIFY_VERSIONS_SWITCHES}, {VERIFY_VERSIONS_SETTINGS}, {}},
- nullptr,
- };
-
- static ExpectedS<std::string> verify_version_in_db(const VcpkgPaths& paths,
- const std::map<std::string, VersionT, std::less<>> baseline,
- const std::string& port_name,
- const fs::path& port_path,
- const fs::path& versions_file_path,
- const std::string& local_git_tree,
- bool verify_git_trees)
- {
- auto maybe_versions = vcpkg::get_builtin_versions(paths, port_name);
- if (!maybe_versions.has_value())
- {
- return {
- Strings::format("Error: While attempting to parse versions for port %s from file: %s\n"
- " Found the following error(s):\n%s",
- port_name,
- fs::u8string(versions_file_path),
- maybe_versions.error()),
- expected_right_tag,
- };
- }
-
- const auto& versions = maybe_versions.value_or_exit(VCPKG_LINE_INFO);
- if (versions.empty())
- {
- return {
- Strings::format("Error: While reading versions for port %s from file: %s\n"
- " File contains no versions.",
- port_name,
- fs::u8string(versions_file_path)),
- expected_right_tag,
- };
- }
-
- if (verify_git_trees)
- {
- for (auto&& version_entry : versions)
- {
- bool version_ok = false;
- for (const std::string& control_file : {"CONTROL", "vcpkg.json"})
- {
- auto treeish = Strings::concat(version_entry.second, ':', control_file);
- auto maybe_file = paths.git_show(Strings::concat(treeish), paths.root / fs::u8path(".git"));
- if (!maybe_file.has_value()) continue;
-
- const auto& file = maybe_file.value_or_exit(VCPKG_LINE_INFO);
- auto maybe_scf = Paragraphs::try_load_port_text(file, treeish, control_file == "vcpkg.json");
- if (!maybe_scf.has_value())
- {
- return {
- Strings::format("Error: While reading versions for port %s from file: %s\n"
- " While validating version: %s.\n"
- " While trying to load port from: %s\n"
- " Found the following error(s):\n%s",
- port_name,
- fs::u8string(versions_file_path),
- version_entry.first.versiont,
- treeish,
- maybe_scf.error()->error),
- expected_right_tag,
- };
- }
-
- const auto& scf = maybe_scf.value_or_exit(VCPKG_LINE_INFO);
- auto&& git_tree_version = scf.get()->to_schemed_version();
- if (version_entry.first.versiont != git_tree_version.versiont)
- {
- return {
- Strings::format(
- "Error: While reading versions for port %s from file: %s\n"
- " While validating version: %s.\n"
- " The version declared in file does not match checked-out version: %s\n"
- " Checked out Git SHA: %s",
- port_name,
- fs::u8string(versions_file_path),
- version_entry.first.versiont,
- git_tree_version.versiont,
- version_entry.second),
- expected_right_tag,
- };
- }
- version_ok = true;
- break;
- }
-
- if (!version_ok)
- {
- return {
- Strings::format(
- "Error: While reading versions for port %s from file: %s\n"
- " While validating version: %s.\n"
- " The checked-out object does not contain a CONTROL file or vcpkg.json file.\n"
- " Checked out Git SHA: %s",
- port_name,
- fs::u8string(versions_file_path),
- version_entry.first.versiont,
- version_entry.second),
- expected_right_tag,
- };
- }
- }
- }
-
- const auto& top_entry = versions.front();
-
- auto maybe_scf = Paragraphs::try_load_port(paths.get_filesystem(), port_path);
- if (!maybe_scf.has_value())
- {
- return {
- Strings::format("Error: While attempting to load local port %s.\n"
- " Found the following error(s):\n%s",
- port_name,
- maybe_scf.error()->error),
- expected_right_tag,
- };
- }
-
- const auto local_port_version = maybe_scf.value_or_exit(VCPKG_LINE_INFO)->to_schemed_version();
-
- if (top_entry.first.versiont != local_port_version.versiont)
- {
- auto versions_end = versions.end();
- auto it = std::find_if(versions.begin(), versions_end, [&](auto&& entry) {
- return entry.first.versiont == local_port_version.versiont;
- });
- if (it != versions_end)
- {
- return {
- Strings::format("Error: While reading versions for port %s from file: %s\n"
- " Local port version `%s` exists in version file but it's not the first "
- "entry in the \"versions\" array.",
- port_name,
- fs::u8string(versions_file_path),
- local_port_version.versiont),
- expected_right_tag,
- };
- }
- else
- {
- return {
- Strings::format("Error: While reading versions for port %s from file: %s\n"
- " Version `%s` was not found in versions file.\n"
- " Run:\n\n"
- " vcpkg x-add-version %s\n\n"
- " to add the new port version.",
- port_name,
- fs::u8string(versions_file_path),
- local_port_version.versiont,
- port_name),
- expected_right_tag,
- };
- }
- }
-
- if (top_entry.first.scheme != local_port_version.scheme)
- {
- return {
- Strings::format("Error: While reading versions for port %s from file: %s\n"
- " File declares version `%s` with scheme: `%s`.\n"
- " But local port declares the same version with a different scheme: `%s`.\n"
- " Version must be unique even between different schemes.\n"
- " Run:\n\n"
- " vcpkg x-add-version %s --overwrite-version\n\n"
- " to overwrite the declared version's scheme.",
- port_name,
- fs::u8string(versions_file_path),
- top_entry.first.versiont,
- get_scheme_name(top_entry.first.scheme),
- get_scheme_name(local_port_version.scheme),
- port_name),
- expected_right_tag,
- };
- }
-
- if (local_git_tree != top_entry.second)
- {
- return {
- Strings::format("Error: While reading versions for port %s from file: %s\n"
- " File declares version `%s` with SHA: %s\n"
- " But local port with the same verion has a different SHA: %s\n"
- " Please update the port's version fields and then run:\n\n"
- " vcpkg x-add-version %s\n\n"
- " to add a new version.",
- port_name,
- fs::u8string(versions_file_path),
- top_entry.first.versiont,
- local_git_tree,
- top_entry.second,
- port_name),
- expected_right_tag,
- };
- }
-
- auto maybe_baseline = baseline.find(port_name);
- if (maybe_baseline == baseline.end())
- {
- return {
- Strings::format("Error: While reading baseline version for port %s.\n"
- " Baseline version not found.\n"
- " Run:\n\n"
- " vcpkg x-add-version %s\n\n"
- " to set version %s as the baseline version.",
- port_name,
- port_name,
- local_port_version.versiont),
- expected_right_tag,
- };
- }
-
- auto&& baseline_version = maybe_baseline->second;
- if (baseline_version != top_entry.first.versiont)
- {
- return {
- Strings::format("Error: While reading baseline version for port %s.\n"
- " While validating latest version from file: %s\n"
- " Baseline file declares version: %s.\n"
- " But the latest version in version files is: %s.\n"
- " Run:\n\n"
- " vcpkg x-add-version %s\n\n"
- " to update the baseline version.",
- port_name,
- fs::u8string(versions_file_path),
- baseline_version,
- top_entry.first.versiont,
- port_name),
- expected_right_tag,
- };
- }
-
- return {
- Strings::format("OK: %s\t%s -> %s\n", top_entry.second, port_name, top_entry.first.versiont),
- expected_left_tag,
- };
- }
-
- void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths)
- {
- auto parsed_args = args.parse_arguments(COMMAND_STRUCTURE);
-
- bool verbose = Util::Sets::contains(parsed_args.switches, OPTION_VERBOSE);
- bool verify_git_trees = Util::Sets::contains(parsed_args.switches, OPTION_VERIFY_GIT_TREES);
-
- std::set<std::string> exclusion_set;
- auto settings = parsed_args.settings;
- auto it_exclusions = settings.find(OPTION_EXCLUDE);
- if (it_exclusions != settings.end())
- {
- auto exclusions = Strings::split(it_exclusions->second, ',');
- exclusion_set.insert(exclusions.begin(), exclusions.end());
- }
-
- auto maybe_port_git_tree_map = paths.git_get_local_port_treeish_map();
- Checks::check_exit(VCPKG_LINE_INFO,
- maybe_port_git_tree_map.has_value(),
- "Fatal error: Failed to obtain git SHAs for local ports.\n%s",
- maybe_port_git_tree_map.error());
- auto port_git_tree_map = maybe_port_git_tree_map.value_or_exit(VCPKG_LINE_INFO);
-
- // Baseline is required.
- auto baseline = get_builtin_baseline(paths).value_or_exit(VCPKG_LINE_INFO);
- auto& fs = paths.get_filesystem();
- std::set<std::string> errors;
- for (const auto& dir : fs::directory_iterator(paths.builtin_ports_directory()))
- {
- const auto& port_path = dir.path();
-
- auto&& port_name = fs::u8string(port_path.stem());
- if (Util::Sets::contains(exclusion_set, port_name))
- {
- if (verbose) System::printf("SKIP: %s\n", port_name);
- continue;
- }
- auto git_tree_it = port_git_tree_map.find(port_name);
- if (git_tree_it == port_git_tree_map.end())
- {
- System::printf(System::Color::error, "FAIL: %s\n", port_name);
- errors.emplace(Strings::format("Error: While validating port %s.\n"
- " Missing Git SHA.\n"
- " Run:\n\n"
- " git add %s.\n"
- " git commit -m \"[%s] Add new port\"\n"
- " vcpkg x-add-version %s\n\n"
- " to commit the new port and create its version file.",
- port_name,
- fs::u8string(port_path),
- port_name,
- port_name));
- continue;
- }
- auto git_tree = git_tree_it->second;
-
- auto control_path = port_path / fs::u8path("CONTROL");
- auto manifest_path = port_path / fs::u8path("vcpkg.json");
- auto manifest_exists = fs.exists(manifest_path);
- auto control_exists = fs.exists(control_path);
-
- if (manifest_exists && control_exists)
- {
- System::printf(System::Color::error, "FAIL: %s\n", port_name);
- errors.emplace(
- Strings::format("Error: While validating port %s.\n"
- " Both a manifest file and a CONTROL file exist in port directory: %s",
- port_name,
- fs::u8string(port_path)));
- continue;
- }
-
- if (!manifest_exists && !control_exists)
- {
- System::printf(System::Color::error, "FAIL: %s\n", port_name);
- errors.emplace(Strings::format("Error: While validating port %s.\n"
- " No manifest file or CONTROL file exist in port directory: %s",
- port_name,
- fs::u8string(port_path)));
- continue;
- }
-
- auto versions_file_path = paths.builtin_registry_versions / fs::u8path({port_name[0], '-'}) /
- fs::u8path(Strings::concat(port_name, ".json"));
- if (!fs.exists(versions_file_path))
- {
- System::printf(System::Color::error, "FAIL: %s\n", port_name);
- errors.emplace(Strings::format("Error: While validating port %s.\n"
- " Missing expected versions file at: %s\n"
- " Run:\n\n"
- " vcpkg x-add-version %s\n\n"
- " to create the versions file.",
- port_name,
- fs::u8string(versions_file_path),
- port_name));
- continue;
- }
-
- auto maybe_ok = verify_version_in_db(
- paths, baseline, port_name, port_path, versions_file_path, git_tree, verify_git_trees);
-
- if (!maybe_ok.has_value())
- {
- System::printf(System::Color::error, "FAIL: %s\n", port_name);
- errors.emplace(maybe_ok.error());
- continue;
- }
-
- if (verbose) System::printf("%s", maybe_ok.value_or_exit(VCPKG_LINE_INFO));
- }
-
- if (!errors.empty())
- {
- System::print2(System::Color::error, "Found the following errors:\n");
- for (auto&& error : errors)
- {
- System::printf(System::Color::error, "%s\n", error);
- }
- System::print2(System::Color::error,
- "\nTo attempt to resolve all errors at once, run:\n\n"
- " vcpkg x-add-version --all\n\n");
- Checks::exit_fail(VCPKG_LINE_INFO);
- }
- Checks::exit_success(VCPKG_LINE_INFO);
- }
-
- void CIVerifyVersionsCommand::perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) const
- {
- CIVerifyVersions::perform_and_exit(args, paths);
- }
-}
diff --git a/toolsrc/src/vcpkg/commands.contact.cpp b/toolsrc/src/vcpkg/commands.contact.cpp
deleted file mode 100644
index 830dba908..000000000
--- a/toolsrc/src/vcpkg/commands.contact.cpp
+++ /dev/null
@@ -1,66 +0,0 @@
-#include <vcpkg/base/chrono.h>
-#include <vcpkg/base/system.print.h>
-#include <vcpkg/base/system.process.h>
-#include <vcpkg/base/util.h>
-
-#include <vcpkg/commands.contact.h>
-#include <vcpkg/help.h>
-#include <vcpkg/userconfig.h>
-#include <vcpkg/vcpkgcmdarguments.h>
-
-namespace vcpkg::Commands::Contact
-{
- const std::string& email()
- {
- static const std::string S_EMAIL = R"(vcpkg@microsoft.com)";
- return S_EMAIL;
- }
-
- static constexpr StringLiteral OPTION_SURVEY = "survey";
-
- static constexpr std::array<CommandSwitch, 1> SWITCHES = {{
- {OPTION_SURVEY, "Launch default browser to the current vcpkg survey"},
- }};
-
- const CommandStructure COMMAND_STRUCTURE = {
- create_example_string("contact"),
- 0,
- 0,
- {SWITCHES, {}},
- nullptr,
- };
-
- void perform_and_exit(const VcpkgCmdArguments& args, Files::Filesystem& fs)
- {
- const ParsedArguments parsed_args = args.parse_arguments(COMMAND_STRUCTURE);
-
- if (Util::Sets::contains(parsed_args.switches, SWITCHES[0].name))
- {
- auto maybe_now = Chrono::CTime::get_current_date_time();
- if (const auto p_now = maybe_now.get())
- {
- auto config = UserConfig::try_read_data(fs);
- config.last_completed_survey = p_now->to_string();
- config.try_write_data(fs);
- }
-
-#if defined(_WIN32)
- System::cmd_execute(System::Command("start").string_arg("https://aka.ms/NPS_vcpkg"));
- System::print2("Default browser launched to https://aka.ms/NPS_vcpkg; thank you for your feedback!\n");
-#else
- System::print2("Please navigate to https://aka.ms/NPS_vcpkg in your preferred browser. Thank you for your "
- "feedback!\n");
-#endif
- }
- else
- {
- System::print2("Send an email to ", email(), " with any feedback.\n");
- }
- Checks::exit_success(VCPKG_LINE_INFO);
- }
-
- void ContactCommand::perform_and_exit(const VcpkgCmdArguments& args, Files::Filesystem& fs) const
- {
- Contact::perform_and_exit(args, fs);
- }
-}
diff --git a/toolsrc/src/vcpkg/commands.cpp b/toolsrc/src/vcpkg/commands.cpp
deleted file mode 100644
index 386aedf58..000000000
--- a/toolsrc/src/vcpkg/commands.cpp
+++ /dev/null
@@ -1,134 +0,0 @@
-#include <vcpkg/base/system.print.h>
-
-#include <vcpkg/build.h>
-#include <vcpkg/commands.add-version.h>
-#include <vcpkg/commands.autocomplete.h>
-#include <vcpkg/commands.buildexternal.h>
-#include <vcpkg/commands.cache.h>
-#include <vcpkg/commands.ci.h>
-#include <vcpkg/commands.ciclean.h>
-#include <vcpkg/commands.civerifyversions.h>
-#include <vcpkg/commands.contact.h>
-#include <vcpkg/commands.create.h>
-#include <vcpkg/commands.dependinfo.h>
-#include <vcpkg/commands.edit.h>
-#include <vcpkg/commands.env.h>
-#include <vcpkg/commands.fetch.h>
-#include <vcpkg/commands.format-manifest.h>
-#include <vcpkg/commands.h>
-#include <vcpkg/commands.hash.h>
-#include <vcpkg/commands.info.h>
-#include <vcpkg/commands.integrate.h>
-#include <vcpkg/commands.list.h>
-#include <vcpkg/commands.owns.h>
-#include <vcpkg/commands.porthistory.h>
-#include <vcpkg/commands.portsdiff.h>
-#include <vcpkg/commands.search.h>
-#include <vcpkg/commands.setinstalled.h>
-#include <vcpkg/commands.upgrade.h>
-#include <vcpkg/commands.upload-metrics.h>
-#include <vcpkg/commands.version.h>
-#include <vcpkg/commands.xvsinstances.h>
-#include <vcpkg/export.h>
-#include <vcpkg/help.h>
-#include <vcpkg/install.h>
-#include <vcpkg/remove.h>
-#include <vcpkg/update.h>
-
-namespace vcpkg::Commands
-{
- Span<const PackageNameAndFunction<const BasicCommand*>> get_available_basic_commands()
- {
- static const Version::VersionCommand version{};
- static const Contact::ContactCommand contact{};
-#if defined(_WIN32)
- static const UploadMetrics::UploadMetricsCommand upload_metrics{};
-#endif // defined(_WIN32)
-
- static std::vector<PackageNameAndFunction<const BasicCommand*>> t = {
- {"version", &version},
- {"contact", &contact},
-#if defined(_WIN32)
- {"x-upload-metrics", &upload_metrics},
-#endif // defined(_WIN32)
- };
- return t;
- }
-
- Span<const PackageNameAndFunction<const PathsCommand*>> get_available_paths_commands()
- {
- static const Help::HelpCommand help{};
- static const Search::SearchCommand search{};
- static const List::ListCommand list{};
- static const Info::InfoCommand info{};
- static const Integrate::IntegrateCommand integrate{};
- static const Owns::OwnsCommand owns{};
- static const Update::UpdateCommand update{};
- static const Edit::EditCommand edit{};
- static const Create::CreateCommand create{};
- static const Cache::CacheCommand cache{};
- static const PortsDiff::PortsDiffCommand portsdiff{};
- static const Autocomplete::AutocompleteCommand autocomplete{};
- static const Hash::HashCommand hash{};
- static const Fetch::FetchCommand fetch{};
- static const CIClean::CICleanCommand ciclean{};
- static const PortHistory::PortHistoryCommand porthistory{};
- static const X_VSInstances::VSInstancesCommand vsinstances{};
- static const FormatManifest::FormatManifestCommand format_manifest{};
- static const CIVerifyVersions::CIVerifyVersionsCommand ci_verify_versions{};
- static const AddVersion::AddVersionCommand add_version{};
-
- static std::vector<PackageNameAndFunction<const PathsCommand*>> t = {
- {"/?", &help},
- {"help", &help},
- {"search", &search},
- {"list", &list},
- {"integrate", &integrate},
- {"owns", &owns},
- {"update", &update},
- {"edit", &edit},
- {"create", &create},
- {"cache", &cache},
- {"portsdiff", &portsdiff},
- {"autocomplete", &autocomplete},
- {"hash", &hash},
- {"fetch", &fetch},
- {"x-ci-clean", &ciclean},
- {"x-package-info", &info},
- {"x-history", &porthistory},
- {"x-vsinstances", &vsinstances},
- {"format-manifest", &format_manifest},
- {"x-ci-verify-versions", &ci_verify_versions},
- {"x-add-version", &add_version},
- };
- return t;
- }
-
- Span<const PackageNameAndFunction<const TripletCommand*>> get_available_triplet_commands()
- {
- static const Install::InstallCommand install{};
- static const SetInstalled::SetInstalledCommand set_installed{};
- static const CI::CICommand ci{};
- static const Remove::RemoveCommand remove{};
- static const Upgrade::UpgradeCommand upgrade{};
- static const Build::BuildCommand build{};
- static const Env::EnvCommand env{};
- static const BuildExternal::BuildExternalCommand build_external{};
- static const Export::ExportCommand export_command{};
- static const DependInfo::DependInfoCommand depend_info{};
-
- static std::vector<PackageNameAndFunction<const TripletCommand*>> t = {
- {"install", &install},
- {"x-set-installed", &set_installed},
- {"ci", &ci},
- {"remove", &remove},
- {"upgrade", &upgrade},
- {"build", &build},
- {"env", &env},
- {"build-external", &build_external},
- {"export", &export_command},
- {"depend-info", &depend_info},
- };
- return t;
- }
-}
diff --git a/toolsrc/src/vcpkg/commands.create.cpp b/toolsrc/src/vcpkg/commands.create.cpp
deleted file mode 100644
index 6ef5163cb..000000000
--- a/toolsrc/src/vcpkg/commands.create.cpp
+++ /dev/null
@@ -1,70 +0,0 @@
-#include <vcpkg/base/checks.h>
-#include <vcpkg/base/files.h>
-#include <vcpkg/base/util.h>
-
-#include <vcpkg/buildenvironment.h>
-#include <vcpkg/commands.create.h>
-#include <vcpkg/commands.version.h>
-#include <vcpkg/help.h>
-#include <vcpkg/vcpkgcmdarguments.h>
-#include <vcpkg/vcpkgpaths.h>
-
-namespace
-{
- std::string remove_trailing_slashes(std::string argument)
- {
- using fs::is_slash;
- argument.erase(std::find_if_not(argument.rbegin(), argument.rend(), is_slash).base(), argument.end());
- return argument;
- }
-}
-
-namespace vcpkg::Commands::Create
-{
- const CommandStructure COMMAND_STRUCTURE = {
- create_example_string(R"###(create zlib2 http://zlib.net/zlib1211.zip "zlib1211-2.zip")###"),
- 2,
- 3,
- {},
- nullptr,
- };
-
- int perform(const VcpkgCmdArguments& args, const VcpkgPaths& paths)
- {
- (void)args.parse_arguments(COMMAND_STRUCTURE);
- const std::string port_name = args.command_arguments.at(0);
- const std::string url = remove_trailing_slashes(args.command_arguments.at(1));
-
- std::vector<System::CMakeVariable> cmake_args{
- {"CMD", "CREATE"},
- {"PORT", port_name},
- {"PORT_PATH", fs::generic_u8string(paths.builtin_ports_directory() / fs::u8path(port_name))},
- {"URL", url},
- {"VCPKG_BASE_VERSION", Commands::Version::base_version()},
- };
-
- if (args.command_arguments.size() >= 3)
- {
- const std::string& zip_file_name = args.command_arguments.at(2);
- Checks::check_exit(VCPKG_LINE_INFO,
- !Files::has_invalid_chars_for_filesystem(zip_file_name),
- R"(Filename cannot contain invalid chars %s, but was %s)",
- Files::FILESYSTEM_INVALID_CHARACTERS,
- zip_file_name);
- cmake_args.emplace_back("FILENAME", zip_file_name);
- }
-
- auto cmd_launch_cmake = make_cmake_cmd(paths, paths.ports_cmake, std::move(cmake_args));
- return System::cmd_execute_clean(cmd_launch_cmake);
- }
-
- void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths)
- {
- Checks::exit_with_code(VCPKG_LINE_INFO, perform(args, paths));
- }
-
- void CreateCommand::perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) const
- {
- Create::perform_and_exit(args, paths);
- }
-}
diff --git a/toolsrc/src/vcpkg/commands.dependinfo.cpp b/toolsrc/src/vcpkg/commands.dependinfo.cpp
deleted file mode 100644
index bfd719df0..000000000
--- a/toolsrc/src/vcpkg/commands.dependinfo.cpp
+++ /dev/null
@@ -1,339 +0,0 @@
-#include <vcpkg/base/strings.h>
-#include <vcpkg/base/system.print.h>
-#include <vcpkg/base/util.h>
-
-#include <vcpkg/cmakevars.h>
-#include <vcpkg/commands.dependinfo.h>
-#include <vcpkg/dependencies.h>
-#include <vcpkg/help.h>
-#include <vcpkg/input.h>
-#include <vcpkg/install.h>
-#include <vcpkg/packagespec.h>
-#include <vcpkg/portfileprovider.h>
-#include <vcpkg/vcpkgcmdarguments.h>
-
-#include <vector>
-
-using vcpkg::Dependencies::ActionPlan;
-using vcpkg::Dependencies::InstallPlanAction;
-using vcpkg::PortFileProvider::PathsPortFileProvider;
-
-namespace vcpkg::Commands::DependInfo
-{
- namespace
- {
- constexpr StringLiteral OPTION_DOT = "dot";
- constexpr StringLiteral OPTION_DGML = "dgml";
- constexpr StringLiteral OPTION_SHOW_DEPTH = "show-depth";
- constexpr StringLiteral OPTION_MAX_RECURSE = "max-recurse";
- constexpr StringLiteral OPTION_SORT = "sort";
-
- constexpr int NO_RECURSE_LIMIT_VALUE = -1;
-
- constexpr std::array<CommandSwitch, 3> DEPEND_SWITCHES = {
- {{OPTION_DOT, "Creates graph on basis of dot"},
- {OPTION_DGML, "Creates graph on basis of dgml"},
- {OPTION_SHOW_DEPTH, "Show recursion depth in output"}}};
-
- constexpr std::array<CommandSetting, 2> DEPEND_SETTINGS = {
- {{OPTION_MAX_RECURSE, "Set max recursion depth, a value of -1 indicates no limit"},
- {OPTION_SORT,
- "Set sort order for the list of dependencies, accepted values are: lexicographical, topological "
- "(default), "
- "reverse"}}};
-
- struct PackageDependInfo
- {
- std::string package;
- int depth;
- std::unordered_set<std::string> features;
- std::vector<std::string> dependencies;
- };
-
- enum SortMode
- {
- Lexicographical = 0,
- Topological,
- ReverseTopological,
- Default = Topological
- };
-
- int get_max_depth(const ParsedArguments& options)
- {
- auto iter = options.settings.find(OPTION_MAX_RECURSE);
- if (iter != options.settings.end())
- {
- std::string value = iter->second;
- try
- {
- return std::stoi(value);
- }
- catch (std::exception&)
- {
- Checks::exit_with_message(VCPKG_LINE_INFO, "Value of --max-depth must be an integer");
- }
- }
- // No --max-depth set, default to no limit.
- return NO_RECURSE_LIMIT_VALUE;
- }
-
- SortMode get_sort_mode(const ParsedArguments& options)
- {
- constexpr StringLiteral OPTION_SORT_LEXICOGRAPHICAL = "lexicographical";
- constexpr StringLiteral OPTION_SORT_TOPOLOGICAL = "topological";
- constexpr StringLiteral OPTION_SORT_REVERSE = "reverse";
-
- static const std::map<std::string, SortMode> sortModesMap{{OPTION_SORT_LEXICOGRAPHICAL, Lexicographical},
- {OPTION_SORT_TOPOLOGICAL, Topological},
- {OPTION_SORT_REVERSE, ReverseTopological}};
-
- auto iter = options.settings.find(OPTION_SORT);
- if (iter != options.settings.end())
- {
- const std::string value = Strings::ascii_to_lowercase(std::string{iter->second});
- auto it = sortModesMap.find(value);
- if (it != sortModesMap.end())
- {
- return it->second;
- }
- Checks::exit_with_message(VCPKG_LINE_INFO,
- "Value of --sort must be one of `%s`, `%s`, or `%s`",
- OPTION_SORT_LEXICOGRAPHICAL,
- OPTION_SORT_TOPOLOGICAL,
- OPTION_SORT_REVERSE);
- }
- return Default;
- }
-
- std::string create_dot_as_string(const std::vector<PackageDependInfo>& depend_info)
- {
- int empty_node_count = 0;
-
- std::string s;
- s.append("digraph G{ rankdir=LR; edge [minlen=3]; overlap=false;");
-
- for (const auto& package : depend_info)
- {
- if (package.dependencies.empty())
- {
- empty_node_count++;
- continue;
- }
-
- const std::string name = Strings::replace_all(std::string{package.package}, "-", "_");
- s.append(Strings::format("%s;", name));
- for (const auto& d : package.dependencies)
- {
- const std::string dependency_name = Strings::replace_all(std::string{d}, "-", "_");
- s.append(Strings::format("%s -> %s;", name, dependency_name));
- }
- }
-
- s.append(Strings::format("empty [label=\"%d singletons...\"]; }", empty_node_count));
- return s;
- }
-
- std::string create_dgml_as_string(const std::vector<PackageDependInfo>& depend_info)
- {
- std::string s;
- s.append("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
- s.append("<DirectedGraph xmlns=\"http://schemas.microsoft.com/vs/2009/dgml\">");
-
- std::string nodes, links;
- for (const auto& package : depend_info)
- {
- const std::string name = package.package;
- nodes.append(Strings::format("<Node Id=\"%s\" />", name));
-
- // Iterate over dependencies.
- for (const auto& d : package.dependencies)
- {
- links.append(Strings::format("<Link Source=\"%s\" Target=\"%s\" />", name, d));
- }
- }
-
- s.append(Strings::format("<Nodes>%s</Nodes>", nodes));
-
- s.append(Strings::format("<Links>%s</Links>", links));
-
- s.append("</DirectedGraph>");
- return s;
- }
-
- std::string create_graph_as_string(const std::unordered_set<std::string>& switches,
- const std::vector<PackageDependInfo>& depend_info)
- {
- if (Util::Sets::contains(switches, OPTION_DOT))
- {
- return create_dot_as_string(depend_info);
- }
- else if (Util::Sets::contains(switches, OPTION_DGML))
- {
- return create_dgml_as_string(depend_info);
- }
- return "";
- }
-
- void assign_depth_to_dependencies(const std::string& package,
- const int depth,
- const int max_depth,
- std::map<std::string, PackageDependInfo>& dependencies_map)
- {
- auto iter = dependencies_map.find(package);
- Checks::check_exit(
- VCPKG_LINE_INFO, iter != dependencies_map.end(), "Package not found in dependency graph");
-
- PackageDependInfo& info = iter->second;
-
- if (depth > info.depth)
- {
- info.depth = depth;
- if (depth < max_depth || max_depth == NO_RECURSE_LIMIT_VALUE)
- {
- for (auto&& dependency : info.dependencies)
- {
- assign_depth_to_dependencies(dependency, depth + 1, max_depth, dependencies_map);
- }
- }
- }
- }
-
- std::vector<PackageDependInfo> extract_depend_info(const std::vector<const InstallPlanAction*>& install_actions,
- const int max_depth)
- {
- std::map<std::string, PackageDependInfo> package_dependencies;
- for (const InstallPlanAction* pia : install_actions)
- {
- const InstallPlanAction& install_action = *pia;
-
- const std::vector<std::string> dependencies = Util::fmap(
- install_action.package_dependencies, [](const PackageSpec& spec) { return spec.name(); });
-
- std::unordered_set<std::string> features{install_action.feature_list.begin(),
- install_action.feature_list.end()};
- features.erase("core");
-
- std::string port_name = install_action.spec.name();
-
- PackageDependInfo info{port_name, -1, features, dependencies};
- package_dependencies.emplace(port_name, std::move(info));
- }
-
- const InstallPlanAction& init = *install_actions.back();
- assign_depth_to_dependencies(init.spec.name(), 0, max_depth, package_dependencies);
-
- std::vector<PackageDependInfo> out =
- Util::fmap(package_dependencies, [](auto&& kvpair) -> PackageDependInfo { return kvpair.second; });
- Util::erase_remove_if(out, [](auto&& info) { return info.depth < 0; });
- return out;
- }
- }
-
- const CommandStructure COMMAND_STRUCTURE = {
- create_example_string("depend-info sqlite3"),
- 1,
- 1,
- {DEPEND_SWITCHES, DEPEND_SETTINGS},
- nullptr,
- };
-
- void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, Triplet default_triplet)
- {
- const ParsedArguments options = args.parse_arguments(COMMAND_STRUCTURE);
- const int max_depth = get_max_depth(options);
- const SortMode sort_mode = get_sort_mode(options);
- const bool show_depth = Util::Sets::contains(options.switches, OPTION_SHOW_DEPTH);
-
- const std::vector<FullPackageSpec> specs = Util::fmap(args.command_arguments, [&](auto&& arg) {
- return Input::check_and_get_full_package_spec(
- std::string{arg}, default_triplet, COMMAND_STRUCTURE.example_text);
- });
-
- for (auto&& spec : specs)
- {
- Input::check_triplet(spec.package_spec.triplet(), paths);
- }
-
- PathsPortFileProvider provider(paths, args.overlay_ports);
- auto var_provider_storage = CMakeVars::make_triplet_cmake_var_provider(paths);
- auto& var_provider = *var_provider_storage;
-
- // By passing an empty status_db, we should get a plan containing all dependencies.
- // All actions in the plan should be install actions, as there's no installed packages to remove.
- StatusParagraphs status_db;
- auto action_plan = Dependencies::create_feature_install_plan(provider, var_provider, specs, status_db);
- Checks::check_exit(
- VCPKG_LINE_INFO, action_plan.remove_actions.empty(), "Only install actions should exist in the plan");
- std::vector<const InstallPlanAction*> install_actions =
- Util::fmap(action_plan.already_installed, [&](const auto& action) { return &action; });
- for (auto&& action : action_plan.install_actions)
- install_actions.push_back(&action);
-
- std::vector<PackageDependInfo> depend_info = extract_depend_info(install_actions, max_depth);
-
- if (Util::Sets::contains(options.switches, OPTION_DOT) || Util::Sets::contains(options.switches, OPTION_DGML))
- {
- const std::vector<const SourceControlFile*> source_control_files =
- Util::fmap(install_actions, [](const InstallPlanAction* install_action) {
- const SourceControlFileLocation& scfl =
- install_action->source_control_file_location.value_or_exit(VCPKG_LINE_INFO);
- return const_cast<const SourceControlFile*>(scfl.source_control_file.get());
- });
-
- const std::string graph_as_string = create_graph_as_string(options.switches, depend_info);
- System::print2(graph_as_string, '\n');
- Checks::exit_success(VCPKG_LINE_INFO);
- }
-
- // TODO: Improve this code
- auto lex = [](const PackageDependInfo& lhs, const PackageDependInfo& rhs) -> bool {
- return lhs.package < rhs.package;
- };
- auto topo = [](const PackageDependInfo& lhs, const PackageDependInfo& rhs) -> bool {
- return lhs.depth > rhs.depth;
- };
- auto reverse = [](const PackageDependInfo& lhs, const PackageDependInfo& rhs) -> bool {
- return lhs.depth < rhs.depth;
- };
-
- switch (sort_mode)
- {
- case SortMode::Lexicographical: std::sort(std::begin(depend_info), std::end(depend_info), lex); break;
- case SortMode::ReverseTopological:
- std::sort(std::begin(depend_info), std::end(depend_info), reverse);
- break;
- case SortMode::Topological: std::sort(std::begin(depend_info), std::end(depend_info), topo); break;
- default: Checks::unreachable(VCPKG_LINE_INFO);
- }
-
- for (auto&& info : depend_info)
- {
- if (info.depth >= 0)
- {
- std::string features = Strings::join(", ", info.features);
- const std::string dependencies = Strings::join(", ", info.dependencies);
-
- if (show_depth)
- {
- System::print2(System::Color::error, "(", info.depth, ") ");
- }
- System::print2(System::Color::success, info.package);
- if (!features.empty())
- {
- System::print2("[");
- System::print2(System::Color::warning, features);
- System::print2("]");
- }
- System::print2(": ", dependencies, "\n");
- }
- }
- Checks::exit_success(VCPKG_LINE_INFO);
- }
-
- void DependInfoCommand::perform_and_exit(const VcpkgCmdArguments& args,
- const VcpkgPaths& paths,
- Triplet default_triplet) const
- {
- DependInfo::perform_and_exit(args, paths, default_triplet);
- }
-}
diff --git a/toolsrc/src/vcpkg/commands.edit.cpp b/toolsrc/src/vcpkg/commands.edit.cpp
deleted file mode 100644
index e761b3cf4..000000000
--- a/toolsrc/src/vcpkg/commands.edit.cpp
+++ /dev/null
@@ -1,278 +0,0 @@
-#include <vcpkg/base/strings.h>
-#include <vcpkg/base/system.print.h>
-#include <vcpkg/base/system.process.h>
-#include <vcpkg/base/util.h>
-
-#include <vcpkg/commands.edit.h>
-#include <vcpkg/help.h>
-#include <vcpkg/paragraphs.h>
-#include <vcpkg/vcpkgcmdarguments.h>
-#include <vcpkg/vcpkgpaths.h>
-
-#include <limits.h>
-
-#if defined(_WIN32)
-namespace
-{
- std::vector<fs::path> find_from_registry()
- {
- std::vector<fs::path> output;
-
- struct RegKey
- {
- HKEY root;
- vcpkg::StringLiteral subkey;
- } REGKEYS[] = {
- {HKEY_LOCAL_MACHINE,
- R"(SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{C26E74D1-022E-4238-8B9D-1E7564A36CC9}_is1)"},
- {HKEY_LOCAL_MACHINE,
- R"(SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{1287CAD5-7C8D-410D-88B9-0D1EE4A83FF2}_is1)"},
- {HKEY_LOCAL_MACHINE,
- R"(SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{F8A2A208-72B3-4D61-95FC-8A65D340689B}_is1)"},
- {HKEY_CURRENT_USER,
- R"(Software\Microsoft\Windows\CurrentVersion\Uninstall\{771FD6B0-FA20-440A-A002-3B3BAC16DC50}_is1)"},
- {HKEY_LOCAL_MACHINE,
- R"(SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{EA457B21-F73E-494C-ACAB-524FDE069978}_is1)"},
- };
-
- for (auto&& keypath : REGKEYS)
- {
- const vcpkg::Optional<std::string> code_installpath =
- vcpkg::System::get_registry_string(keypath.root, keypath.subkey, "InstallLocation");
- if (const auto c = code_installpath.get())
- {
- const fs::path install_path = fs::u8path(*c);
- output.push_back(install_path / "Code - Insiders.exe");
- output.push_back(install_path / "Code.exe");
- }
- }
- return output;
- }
-
- std::string expand_environment_strings(const std::string& input)
- {
- const auto widened = vcpkg::Strings::to_utf16(input);
- std::wstring result;
- result.resize(result.capacity());
- bool done;
- do
- {
- if (result.size() == ULONG_MAX)
- {
- vcpkg::Checks::exit_fail(VCPKG_LINE_INFO); // integer overflow
- }
-
- const auto required_size =
- ExpandEnvironmentStringsW(widened.c_str(), &result[0], static_cast<unsigned long>(result.size() + 1));
- if (required_size == 0)
- {
- vcpkg::System::print2(vcpkg::System::Color::error, "Error: could not expand the environment string:\n");
- vcpkg::System::print2(vcpkg::System::Color::error, input);
- vcpkg::Checks::exit_fail(VCPKG_LINE_INFO);
- }
-
- done = required_size <= result.size() + 1;
- result.resize(required_size - 1);
- } while (!done);
- return vcpkg::Strings::to_utf8(result);
- }
-}
-#endif
-
-namespace vcpkg::Commands::Edit
-{
- static constexpr StringLiteral OPTION_BUILDTREES = "buildtrees";
-
- static constexpr StringLiteral OPTION_ALL = "all";
-
- static std::vector<std::string> valid_arguments(const VcpkgPaths& paths)
- {
- auto sources_and_errors = Paragraphs::try_load_all_registry_ports(paths);
-
- return Util::fmap(sources_and_errors.paragraphs, Paragraphs::get_name_of_control_file);
- }
-
- static constexpr std::array<CommandSwitch, 2> EDIT_SWITCHES = {
- {{OPTION_BUILDTREES, "Open editor into the port-specific buildtree subfolder"},
- {OPTION_ALL, "Open editor into the port as well as the port-specific buildtree subfolder"}}};
-
- const CommandStructure COMMAND_STRUCTURE = {
- create_example_string("edit zlib"),
- 1,
- 10,
- {EDIT_SWITCHES, {}},
- &valid_arguments,
- };
-
- static std::vector<std::string> create_editor_arguments(const VcpkgPaths& paths,
- const ParsedArguments& options,
- const std::vector<std::string>& ports)
- {
- if (Util::Sets::contains(options.switches, OPTION_ALL))
- {
- const auto& fs = paths.get_filesystem();
- auto packages = fs.get_files_non_recursive(paths.packages);
-
- // TODO: Support edit for --overlay-ports
- return Util::fmap(ports, [&](const std::string& port_name) -> std::string {
- const auto portpath = paths.builtin_ports_directory() / port_name;
- const auto portfile = portpath / "portfile.cmake";
- const auto buildtrees_current_dir = paths.build_dir(port_name);
- const auto pattern = port_name + "_";
-
- std::string package_paths;
- for (auto&& package : packages)
- {
- if (Strings::case_insensitive_ascii_starts_with(fs::u8string(package.filename()), pattern))
- {
- package_paths.append(Strings::format(" \"%s\"", fs::u8string(package)));
- }
- }
-
- return Strings::format(R"###("%s" "%s" "%s"%s)###",
- fs::u8string(portpath),
- fs::u8string(portfile),
- fs::u8string(buildtrees_current_dir),
- package_paths);
- });
- }
-
- if (Util::Sets::contains(options.switches, OPTION_BUILDTREES))
- {
- return Util::fmap(ports, [&](const std::string& port_name) -> std::string {
- return Strings::format(R"###("%s")###", fs::u8string(paths.build_dir(port_name)));
- });
- }
-
- return Util::fmap(ports, [&](const std::string& port_name) -> std::string {
- const auto portpath = paths.builtin_ports_directory() / port_name;
- const auto portfile = portpath / "portfile.cmake";
- return Strings::format(R"###("%s" "%s")###", fs::u8string(portpath), fs::u8string(portfile));
- });
- }
-
- void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths)
- {
- auto& fs = paths.get_filesystem();
-
- const ParsedArguments options = args.parse_arguments(COMMAND_STRUCTURE);
-
- const std::vector<std::string>& ports = args.command_arguments;
- for (auto&& port_name : ports)
- {
- const fs::path portpath = paths.builtin_ports_directory() / port_name;
- Checks::check_maybe_upgrade(
- VCPKG_LINE_INFO, fs.is_directory(portpath), R"(Could not find port named "%s")", port_name);
- }
-
- std::vector<fs::path> candidate_paths;
- auto maybe_editor_path = System::get_environment_variable("EDITOR");
- if (const std::string* editor_path = maybe_editor_path.get())
- {
- candidate_paths.emplace_back(*editor_path);
- }
-
-#ifdef _WIN32
- static const fs::path VS_CODE_INSIDERS = fs::path{"Microsoft VS Code Insiders"} / "Code - Insiders.exe";
- static const fs::path VS_CODE = fs::path{"Microsoft VS Code"} / "Code.exe";
-
- const auto& program_files = System::get_program_files_platform_bitness();
- if (const fs::path* pf = program_files.get())
- {
- candidate_paths.push_back(*pf / VS_CODE_INSIDERS);
- candidate_paths.push_back(*pf / VS_CODE);
- }
-
- const auto& program_files_32_bit = System::get_program_files_32_bit();
- if (const fs::path* pf = program_files_32_bit.get())
- {
- candidate_paths.push_back(*pf / VS_CODE_INSIDERS);
- candidate_paths.push_back(*pf / VS_CODE);
- }
-
- const auto& app_data = System::get_environment_variable("APPDATA");
- if (const auto* ad = app_data.get())
- {
- const fs::path default_base = fs::path{*ad}.parent_path() / "Local" / "Programs";
- candidate_paths.push_back(default_base / VS_CODE_INSIDERS);
- candidate_paths.push_back(default_base / VS_CODE);
- }
-
- const std::vector<fs::path> from_registry = find_from_registry();
- candidate_paths.insert(candidate_paths.end(), from_registry.cbegin(), from_registry.cend());
-
- const auto txt_default = System::get_registry_string(HKEY_CLASSES_ROOT, R"(.txt\ShellNew)", "ItemName");
- if (const auto entry = txt_default.get())
- {
- auto full_path = expand_environment_strings(*entry);
- auto first = full_path.begin();
- const auto last = full_path.end();
- first = std::find_if_not(first, last, [](const char c) { return c == '@'; });
- const auto comma = std::find(first, last, ',');
- candidate_paths.push_back(fs::u8path(first, comma));
- }
-#elif defined(__APPLE__)
- candidate_paths.push_back(
- fs::path{"/Applications/Visual Studio Code - Insiders.app/Contents/Resources/app/bin/code"});
- candidate_paths.push_back(fs::path{"/Applications/Visual Studio Code.app/Contents/Resources/app/bin/code"});
-#elif defined(__linux__)
- candidate_paths.push_back(fs::path{"/usr/share/code/bin/code"});
- candidate_paths.push_back(fs::path{"/usr/bin/code"});
-
- if (System::cmd_execute(System::Command("command").string_arg("-v").string_arg("xdg-mime")) == 0)
- {
- auto mime_qry =
- System::Command("xdg-mime").string_arg("query").string_arg("default").string_arg("text/plain");
- auto execute_result = System::cmd_execute_and_capture_output(mime_qry);
- if (execute_result.exit_code == 0 && !execute_result.output.empty())
- {
- mime_qry = System::Command("command").string_arg("-v").string_arg(
- execute_result.output.substr(0, execute_result.output.find('.')));
- execute_result = System::cmd_execute_and_capture_output(mime_qry);
- if (execute_result.exit_code == 0 && !execute_result.output.empty())
- {
- execute_result.output.erase(
- std::remove(std::begin(execute_result.output), std::end(execute_result.output), '\n'),
- std::end(execute_result.output));
- candidate_paths.push_back(fs::path{execute_result.output});
- }
- }
- }
-#endif
-
- const auto it = Util::find_if(candidate_paths, [&](const fs::path& p) { return fs.exists(p); });
- if (it == candidate_paths.cend())
- {
- System::print2(
- System::Color::error,
- "Error: Visual Studio Code was not found and the environment variable EDITOR is not set or invalid.\n");
- System::print2("The following paths were examined:\n");
- Files::print_paths(candidate_paths);
- System::print2("You can also set the environmental variable EDITOR to your editor of choice.\n");
- Checks::exit_fail(VCPKG_LINE_INFO);
- }
-
- const fs::path env_editor = *it;
- const std::vector<std::string> arguments = create_editor_arguments(paths, options, ports);
- const auto args_as_string = Strings::join(" ", arguments);
- auto cmd_line = System::Command(env_editor).raw_arg(args_as_string).string_arg("-n");
-
- auto editor_exe = fs::u8string(env_editor.filename());
-
-#ifdef _WIN32
- if (editor_exe == "Code.exe" || editor_exe == "Code - Insiders.exe")
- {
- // note that we are invoking cmd silently but Code.exe is relaunched from there
- System::cmd_execute_background(System::Command("cmd").string_arg("/c").raw_arg(
- Strings::concat('"', cmd_line.command_line(), R"( <NUL")")));
- Checks::exit_success(VCPKG_LINE_INFO);
- }
-#endif
- Checks::exit_with_code(VCPKG_LINE_INFO, System::cmd_execute(cmd_line));
- }
-
- void EditCommand::perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) const
- {
- Edit::perform_and_exit(args, paths);
- }
-}
diff --git a/toolsrc/src/vcpkg/commands.env.cpp b/toolsrc/src/vcpkg/commands.env.cpp
deleted file mode 100644
index f129f0262..000000000
--- a/toolsrc/src/vcpkg/commands.env.cpp
+++ /dev/null
@@ -1,122 +0,0 @@
-#include <vcpkg/base/strings.h>
-#include <vcpkg/base/system.process.h>
-
-#include <vcpkg/build.h>
-#include <vcpkg/cmakevars.h>
-#include <vcpkg/commands.env.h>
-#include <vcpkg/help.h>
-#include <vcpkg/portfileprovider.h>
-#include <vcpkg/vcpkgcmdarguments.h>
-
-namespace vcpkg::Commands::Env
-{
- static constexpr StringLiteral OPTION_BIN = "bin";
- static constexpr StringLiteral OPTION_INCLUDE = "include";
- static constexpr StringLiteral OPTION_DEBUG_BIN = "debug-bin";
- static constexpr StringLiteral OPTION_TOOLS = "tools";
- static constexpr StringLiteral OPTION_PYTHON = "python";
-
- static constexpr std::array<CommandSwitch, 5> SWITCHES = {{
- {OPTION_BIN, "Add installed bin/ to PATH"},
- {OPTION_INCLUDE, "Add installed include/ to INCLUDE"},
- {OPTION_DEBUG_BIN, "Add installed debug/bin/ to PATH"},
- {OPTION_TOOLS, "Add installed tools/*/ to PATH"},
- {OPTION_PYTHON, "Add installed python/ to PYTHONPATH"},
- }};
-
- const CommandStructure COMMAND_STRUCTURE = {
- create_example_string("env <optional command> --triplet x64-windows"),
- 0,
- 1,
- {SWITCHES, {}},
- nullptr,
- };
-
- // This command should probably optionally take a port
- void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, Triplet triplet)
- {
- const auto& fs = paths.get_filesystem();
-
- const ParsedArguments options = args.parse_arguments(COMMAND_STRUCTURE);
-
- PortFileProvider::PathsPortFileProvider provider(paths, args.overlay_ports);
- auto var_provider_storage = CMakeVars::make_triplet_cmake_var_provider(paths);
- auto& var_provider = *var_provider_storage;
-
- var_provider.load_generic_triplet_vars(triplet);
-
- const Build::PreBuildInfo pre_build_info(
- paths, triplet, var_provider.get_generic_triplet_vars(triplet).value_or_exit(VCPKG_LINE_INFO));
- const Toolset& toolset = paths.get_toolset(pre_build_info);
- auto build_env_cmd = Build::make_build_env_cmd(pre_build_info, toolset, paths.get_all_toolsets());
-
- std::unordered_map<std::string, std::string> extra_env = {};
- const bool add_bin = Util::Sets::contains(options.switches, OPTION_BIN);
- const bool add_include = Util::Sets::contains(options.switches, OPTION_INCLUDE);
- const bool add_debug_bin = Util::Sets::contains(options.switches, OPTION_DEBUG_BIN);
- const bool add_tools = Util::Sets::contains(options.switches, OPTION_TOOLS);
- const bool add_python = Util::Sets::contains(options.switches, OPTION_PYTHON);
-
- std::vector<std::string> path_vars;
- if (add_bin) path_vars.push_back(fs::u8string(paths.installed / triplet.to_string() / "bin"));
- if (add_debug_bin) path_vars.push_back(fs::u8string(paths.installed / triplet.to_string() / "debug" / "bin"));
- if (add_include) extra_env.emplace("INCLUDE", fs::u8string(paths.installed / triplet.to_string() / "include"));
- if (add_tools)
- {
- auto tools_dir = paths.installed / triplet.to_string() / "tools";
- auto tool_files = fs.get_files_non_recursive(tools_dir);
- path_vars.push_back(fs::u8string(tools_dir));
- for (auto&& tool_dir : tool_files)
- {
- if (fs.is_directory(tool_dir)) path_vars.push_back(fs::u8string(tool_dir));
- }
- }
- if (add_python)
- extra_env.emplace("PYTHONPATH",
- fs::u8string(paths.installed / fs::u8path(triplet.to_string()) / fs::u8path("python")));
- if (path_vars.size() > 0) extra_env.emplace("PATH", Strings::join(";", path_vars));
- for (auto&& passthrough : pre_build_info.passthrough_env_vars)
- {
- if (auto e = System::get_environment_variable(passthrough))
- {
- extra_env.emplace(passthrough, e.value_or_exit(VCPKG_LINE_INFO));
- }
- }
-
- auto env = [&] {
- auto clean_env = System::get_modified_clean_environment(extra_env);
- if (build_env_cmd.empty())
- return clean_env;
- else
- {
-#ifdef _WIN32
- return System::cmd_execute_modify_env(build_env_cmd, clean_env);
-#else
- Checks::exit_with_message(VCPKG_LINE_INFO,
- "Build environment commands are not supported on this platform");
-#endif
- }
- }();
-
- System::Command cmd("cmd");
- if (!args.command_arguments.empty())
- {
- cmd.string_arg("/c").raw_arg(args.command_arguments.at(0));
- }
-#ifdef _WIN32
- System::enter_interactive_subprocess();
-#endif
- auto rc = System::cmd_execute(cmd, env);
-#ifdef _WIN32
- System::exit_interactive_subprocess();
-#endif
- Checks::exit_with_code(VCPKG_LINE_INFO, rc);
- }
-
- void EnvCommand::perform_and_exit(const VcpkgCmdArguments& args,
- const VcpkgPaths& paths,
- Triplet default_triplet) const
- {
- Env::perform_and_exit(args, paths, default_triplet);
- }
-}
diff --git a/toolsrc/src/vcpkg/commands.fetch.cpp b/toolsrc/src/vcpkg/commands.fetch.cpp
deleted file mode 100644
index 68df98700..000000000
--- a/toolsrc/src/vcpkg/commands.fetch.cpp
+++ /dev/null
@@ -1,30 +0,0 @@
-#include <vcpkg/base/system.print.h>
-
-#include <vcpkg/commands.fetch.h>
-#include <vcpkg/vcpkgcmdarguments.h>
-#include <vcpkg/vcpkgpaths.h>
-
-namespace vcpkg::Commands::Fetch
-{
- const CommandStructure COMMAND_STRUCTURE = {
- Strings::format("The argument should be tool name\n%s", create_example_string("fetch cmake")),
- 1,
- 1,
- {},
- nullptr,
- };
-
- void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths)
- {
- (void)args.parse_arguments(COMMAND_STRUCTURE);
- const std::string tool = args.command_arguments[0];
- const fs::path tool_path = paths.get_tool_exe(tool);
- System::print2(fs::u8string(tool_path), '\n');
- Checks::exit_success(VCPKG_LINE_INFO);
- }
-
- void FetchCommand::perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) const
- {
- Fetch::perform_and_exit(args, paths);
- }
-}
diff --git a/toolsrc/src/vcpkg/commands.format-manifest.cpp b/toolsrc/src/vcpkg/commands.format-manifest.cpp
deleted file mode 100644
index 0e7394c25..000000000
--- a/toolsrc/src/vcpkg/commands.format-manifest.cpp
+++ /dev/null
@@ -1,291 +0,0 @@
-#include <vcpkg/base/checks.h>
-#include <vcpkg/base/files.h>
-#include <vcpkg/base/json.h>
-#include <vcpkg/base/system.debug.h>
-
-#include <vcpkg/commands.format-manifest.h>
-#include <vcpkg/paragraphs.h>
-#include <vcpkg/portfileprovider.h>
-#include <vcpkg/sourceparagraph.h>
-#include <vcpkg/vcpkgcmdarguments.h>
-#include <vcpkg/vcpkgpaths.h>
-
-namespace
-{
- using namespace vcpkg;
-
- struct ToWrite
- {
- SourceControlFile scf;
- fs::path file_to_write;
- fs::path original_path;
- std::string original_source;
- };
-
- Optional<ToWrite> read_manifest(Files::Filesystem& fs, fs::path&& manifest_path)
- {
- auto path_string = fs::u8string(manifest_path);
- Debug::print("Reading ", path_string, "\n");
- auto contents = fs.read_contents(manifest_path, VCPKG_LINE_INFO);
- auto parsed_json_opt = Json::parse(contents, manifest_path);
- if (!parsed_json_opt.has_value())
- {
- System::printf(
- System::Color::error, "Failed to parse %s: %s\n", path_string, parsed_json_opt.error()->format());
- return nullopt;
- }
-
- const auto& parsed_json = parsed_json_opt.value_or_exit(VCPKG_LINE_INFO).first;
- if (!parsed_json.is_object())
- {
- System::printf(System::Color::error, "The file %s is not an object\n", path_string);
- return nullopt;
- }
-
- auto parsed_json_obj = parsed_json.object();
-
- auto scf = SourceControlFile::parse_manifest_file(manifest_path, parsed_json_obj);
- if (!scf.has_value())
- {
- System::printf(System::Color::error, "Failed to parse manifest file: %s\n", path_string);
- print_error_message(scf.error());
- return nullopt;
- }
-
- return ToWrite{
- std::move(*scf.value_or_exit(VCPKG_LINE_INFO)),
- manifest_path,
- manifest_path,
- std::move(contents),
- };
- }
-
- Optional<ToWrite> read_control_file(Files::Filesystem& fs, fs::path&& control_path)
- {
- std::error_code ec;
- auto control_path_string = fs::u8string(control_path);
- Debug::print("Reading ", control_path_string, "\n");
-
- auto manifest_path = control_path.parent_path();
- manifest_path /= fs::u8path("vcpkg.json");
-
- auto contents = fs.read_contents(control_path, VCPKG_LINE_INFO);
- auto paragraphs = Paragraphs::parse_paragraphs(contents, control_path_string);
-
- if (!paragraphs)
- {
- System::printf(System::Color::error,
- "Failed to read paragraphs from %s: %s\n",
- control_path_string,
- paragraphs.error());
- return {};
- }
- auto scf_res = SourceControlFile::parse_control_file(fs::u8string(control_path),
- std::move(paragraphs).value_or_exit(VCPKG_LINE_INFO));
- if (!scf_res)
- {
- System::printf(System::Color::error, "Failed to parse control file: %s\n", control_path_string);
- print_error_message(scf_res.error());
- return {};
- }
-
- return ToWrite{
- std::move(*scf_res.value_or_exit(VCPKG_LINE_INFO)),
- manifest_path,
- control_path,
- std::move(contents),
- };
- }
-
- void write_file(Files::Filesystem& fs, const ToWrite& data)
- {
- auto original_path_string = fs::u8string(data.original_path);
- auto file_to_write_string = fs::u8string(data.file_to_write);
- if (data.file_to_write == data.original_path)
- {
- Debug::print("Formatting ", file_to_write_string, "\n");
- }
- else
- {
- Debug::print("Converting ", file_to_write_string, " -> ", original_path_string, "\n");
- }
- auto res = serialize_manifest(data.scf);
-
- auto check = SourceControlFile::parse_manifest_file(fs::path{}, res);
- if (!check)
- {
- System::printf(System::Color::error,
- R"([correctness check] Failed to parse serialized manifest file of %s
-Please open an issue at https://github.com/microsoft/vcpkg, with the following output:
-Error:)",
- data.scf.core_paragraph->name);
- print_error_message(check.error());
- Checks::exit_maybe_upgrade(VCPKG_LINE_INFO,
- R"(
-=== Serialized manifest file ===
-%s
-)",
- Json::stringify(res, {}));
- }
-
- auto check_scf = std::move(check).value_or_exit(VCPKG_LINE_INFO);
- if (*check_scf != data.scf)
- {
- Checks::exit_maybe_upgrade(
- VCPKG_LINE_INFO,
- R"([correctness check] The serialized manifest SCF was different from the original SCF.
-Please open an issue at https://github.com/microsoft/vcpkg, with the following output:
-
-=== Original File ===
-%s
-
-=== Serialized File ===
-%s
-
-=== Original SCF ===
-%s
-
-=== Serialized SCF ===
-%s
-)",
- data.original_source,
- Json::stringify(res, {}),
- Json::stringify(serialize_debug_manifest(data.scf), {}),
- Json::stringify(serialize_debug_manifest(*check_scf), {}));
- }
-
- // the manifest scf is correct
- std::error_code ec;
- fs.write_contents(data.file_to_write, Json::stringify(res, {}), ec);
- if (ec)
- {
- Checks::exit_with_message(
- VCPKG_LINE_INFO, "Failed to write manifest file %s: %s\n", file_to_write_string, ec.message());
- }
- if (data.original_path != data.file_to_write)
- {
- fs.remove(data.original_path, ec);
- if (ec)
- {
- Checks::exit_with_message(
- VCPKG_LINE_INFO, "Failed to remove control file %s: %s\n", original_path_string, ec.message());
- }
- }
- }
-}
-
-namespace vcpkg::Commands::FormatManifest
-{
- static constexpr StringLiteral OPTION_ALL = "all";
- static constexpr StringLiteral OPTION_CONVERT_CONTROL = "convert-control";
-
- const CommandSwitch FORMAT_SWITCHES[] = {
- {OPTION_ALL, "Format all ports' manifest files."},
- {OPTION_CONVERT_CONTROL, "Convert CONTROL files to manifest files."},
- };
-
- const CommandStructure COMMAND_STRUCTURE = {
- create_example_string(R"###(format-manifest --all)###"),
- 0,
- SIZE_MAX,
- {FORMAT_SWITCHES, {}, {}},
- nullptr,
- };
-
- void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths)
- {
- auto parsed_args = args.parse_arguments(COMMAND_STRUCTURE);
-
- auto& fs = paths.get_filesystem();
- bool has_error = false;
-
- const bool format_all = Util::Sets::contains(parsed_args.switches, OPTION_ALL);
- const bool convert_control = Util::Sets::contains(parsed_args.switches, OPTION_CONVERT_CONTROL);
-
- if (!format_all && convert_control)
- {
- System::print2(System::Color::warning, R"(format-manifest was passed '--convert-control' without '--all'.
- This doesn't do anything:
- we will automatically convert all control files passed explicitly.)");
- }
-
- if (!format_all && args.command_arguments.empty())
- {
- Checks::exit_with_message(
- VCPKG_LINE_INFO,
- "No files to format; please pass either --all, or the explicit files to format or convert.");
- }
-
- std::vector<ToWrite> to_write;
-
- const auto add_file = [&to_write, &has_error](Optional<ToWrite>&& opt) {
- if (auto t = opt.get())
- to_write.push_back(std::move(*t));
- else
- has_error = true;
- };
-
- for (const auto& arg : args.command_arguments)
- {
- auto path = fs::u8path(arg);
- if (path.is_relative())
- {
- path = paths.original_cwd / path;
- }
-
- if (path.filename() == fs::u8path("CONTROL"))
- {
- add_file(read_control_file(fs, std::move(path)));
- }
- else
- {
- add_file(read_manifest(fs, std::move(path)));
- }
- }
-
- if (format_all)
- {
- for (const auto& dir : fs::directory_iterator(paths.builtin_ports_directory()))
- {
- auto control_path = dir.path() / fs::u8path("CONTROL");
- auto manifest_path = dir.path() / fs::u8path("vcpkg.json");
- auto manifest_exists = fs.exists(manifest_path);
- auto control_exists = fs.exists(control_path);
-
- Checks::check_exit(VCPKG_LINE_INFO,
- !manifest_exists || !control_exists,
- "Both a manifest file and a CONTROL file exist in port directory: %s",
- fs::u8string(dir.path()));
-
- if (manifest_exists)
- {
- add_file(read_manifest(fs, std::move(manifest_path)));
- }
- if (convert_control && control_exists)
- {
- add_file(read_control_file(fs, std::move(control_path)));
- }
- }
- }
-
- for (auto const& el : to_write)
- {
- write_file(fs, el);
- }
-
- if (has_error)
- {
- Checks::exit_fail(VCPKG_LINE_INFO);
- }
- else
- {
- System::print2("Succeeded in formatting the manifest files.\n");
- Checks::exit_success(VCPKG_LINE_INFO);
- }
- }
-
- void FormatManifestCommand::perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) const
- {
- FormatManifest::perform_and_exit(args, paths);
- }
-}
diff --git a/toolsrc/src/vcpkg/commands.hash.cpp b/toolsrc/src/vcpkg/commands.hash.cpp
deleted file mode 100644
index 6b2e81c12..000000000
--- a/toolsrc/src/vcpkg/commands.hash.cpp
+++ /dev/null
@@ -1,41 +0,0 @@
-#include <vcpkg/base/hash.h>
-#include <vcpkg/base/system.print.h>
-#include <vcpkg/base/util.h>
-
-#include <vcpkg/commands.hash.h>
-#include <vcpkg/vcpkgcmdarguments.h>
-#include <vcpkg/vcpkgpaths.h>
-
-namespace vcpkg::Commands::Hash
-{
- const CommandStructure COMMAND_STRUCTURE = {
- Strings::format("The argument should be a file path\n%s", create_example_string("hash boost_1_62_0.tar.bz2")),
- 1,
- 2,
- {},
- nullptr,
- };
-
- void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths)
- {
- (void)args.parse_arguments(COMMAND_STRUCTURE);
-
- const fs::path file_to_hash = args.command_arguments[0];
-
- auto algorithm = vcpkg::Hash::Algorithm::Sha512;
- if (args.command_arguments.size() == 2)
- {
- algorithm = vcpkg::Hash::algorithm_from_string(args.command_arguments[1]).value_or_exit(VCPKG_LINE_INFO);
- }
-
- const std::string hash =
- vcpkg::Hash::get_file_hash(VCPKG_LINE_INFO, paths.get_filesystem(), file_to_hash, algorithm);
- System::print2(hash, '\n');
- Checks::exit_success(VCPKG_LINE_INFO);
- }
-
- void HashCommand::perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) const
- {
- Hash::perform_and_exit(args, paths);
- }
-}
diff --git a/toolsrc/src/vcpkg/commands.info.cpp b/toolsrc/src/vcpkg/commands.info.cpp
deleted file mode 100644
index dbf089534..000000000
--- a/toolsrc/src/vcpkg/commands.info.cpp
+++ /dev/null
@@ -1,147 +0,0 @@
-#include "pch.h"
-
-#include <vcpkg/base/json.h>
-#include <vcpkg/base/parse.h>
-#include <vcpkg/base/stringliteral.h>
-
-#include <vcpkg/commands.info.h>
-#include <vcpkg/input.h>
-#include <vcpkg/install.h>
-#include <vcpkg/portfileprovider.h>
-#include <vcpkg/statusparagraphs.h>
-#include <vcpkg/vcpkgcmdarguments.h>
-#include <vcpkg/vcpkglib.h>
-#include <vcpkg/versiont.h>
-
-namespace vcpkg::Commands::Info
-{
- static constexpr StringLiteral OPTION_TRANSITIVE = "x-transitive";
- static constexpr StringLiteral OPTION_INSTALLED = "x-installed";
-
- static constexpr CommandSwitch INFO_SWITCHES[] = {
- {OPTION_INSTALLED, "(experimental) Report on installed packages instead of available"},
- {OPTION_TRANSITIVE, "(experimental) Also report on dependencies of installed packages"},
- };
-
- const CommandStructure COMMAND_STRUCTURE = {
- Strings::format("Display detailed information on packages.\n%s",
- create_example_string("x-package-info zlib openssl:x64-windows")),
- 1,
- SIZE_MAX,
- {INFO_SWITCHES, {}},
- nullptr,
- };
-
- void InfoCommand::perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) const
- {
- const ParsedArguments options = args.parse_arguments(COMMAND_STRUCTURE);
- if (!args.output_json())
- {
- Checks::exit_maybe_upgrade(
- VCPKG_LINE_INFO, "This command currently requires --%s", VcpkgCmdArguments::JSON_SWITCH);
- }
-
- const bool installed = Util::Sets::contains(options.switches, OPTION_INSTALLED);
- const bool transitive = Util::Sets::contains(options.switches, OPTION_TRANSITIVE);
-
- if (transitive && !installed)
- {
- Checks::exit_with_message(VCPKG_LINE_INFO, "--%s requires --%s", OPTION_TRANSITIVE, OPTION_INSTALLED);
- }
-
- if (installed)
- {
- const StatusParagraphs status_paragraphs = database_load_check(paths);
- std::set<PackageSpec> specs_written;
- std::vector<PackageSpec> specs_to_write;
- for (auto&& arg : args.command_arguments)
- {
- Parse::ParserBase parser(arg, "<command>");
- auto maybe_qpkg = parse_qualified_specifier(parser);
- if (!parser.at_eof() || !maybe_qpkg)
- {
- parser.add_error("expected a package specifier");
- }
- else if (!maybe_qpkg.get()->triplet)
- {
- parser.add_error("expected an explicit triplet");
- }
- else if (maybe_qpkg.get()->features)
- {
- parser.add_error("unexpected list of features");
- }
- else if (maybe_qpkg.get()->platform)
- {
- parser.add_error("unexpected qualifier");
- }
- if (auto err = parser.get_error())
- {
- System::print2(err->format(), "\n");
- Checks::exit_fail(VCPKG_LINE_INFO);
- }
-
- auto& qpkg = *maybe_qpkg.get();
- auto t = Triplet::from_canonical_name(std::string(*qpkg.triplet.get()));
- Input::check_triplet(t, paths);
- specs_to_write.emplace_back(qpkg.name, t);
- }
- Json::Object response;
- Json::Object results;
- while (!specs_to_write.empty())
- {
- auto spec = std::move(specs_to_write.back());
- specs_to_write.pop_back();
- if (!specs_written.insert(spec).second) continue;
- auto maybe_ipv = status_paragraphs.get_installed_package_view(spec);
- if (auto ipv = maybe_ipv.get())
- {
- results.insert(spec.to_string(), serialize_ipv(*ipv, paths));
- if (transitive)
- {
- auto deps = ipv->dependencies();
- specs_to_write.insert(specs_to_write.end(),
- std::make_move_iterator(deps.begin()),
- std::make_move_iterator(deps.end()));
- }
- }
- }
- response.insert("results", std::move(results));
- System::print2(Json::stringify(response, {}));
- }
- else
- {
- Json::Object response;
- Json::Object results;
- PortFileProvider::PathsPortFileProvider provider(paths, args.overlay_ports);
-
- for (auto&& arg : args.command_arguments)
- {
- Parse::ParserBase parser(arg, "<command>");
- auto maybe_pkg = parse_package_name(parser);
- if (!parser.at_eof() || !maybe_pkg)
- {
- parser.add_error("expected only a package identifier");
- }
- if (auto err = parser.get_error())
- {
- System::print2(err->format(), "\n");
- Checks::exit_fail(VCPKG_LINE_INFO);
- }
-
- auto& pkg = *maybe_pkg.get();
-
- if (results.contains(pkg)) continue;
-
- auto maybe_scfl = provider.get_control_file(pkg);
-
- Json::Object obj;
- if (auto pscfl = maybe_scfl.get())
- {
- results.insert(pkg, serialize_manifest(*pscfl->source_control_file));
- }
- }
- response.insert("results", std::move(results));
- System::print2(Json::stringify(response, {}));
- }
- }
-}
diff --git a/toolsrc/src/vcpkg/commands.integrate.cpp b/toolsrc/src/vcpkg/commands.integrate.cpp
deleted file mode 100644
index 8258de1fe..000000000
--- a/toolsrc/src/vcpkg/commands.integrate.cpp
+++ /dev/null
@@ -1,607 +0,0 @@
-#include <vcpkg/base/checks.h>
-#include <vcpkg/base/expected.h>
-#include <vcpkg/base/files.h>
-#include <vcpkg/base/system.print.h>
-#include <vcpkg/base/system.process.h>
-#include <vcpkg/base/util.h>
-
-#include <vcpkg/commands.integrate.h>
-#include <vcpkg/metrics.h>
-#include <vcpkg/tools.h>
-#include <vcpkg/userconfig.h>
-#include <vcpkg/vcpkgcmdarguments.h>
-#include <vcpkg/vcpkgpaths.h>
-
-namespace vcpkg::Commands::Integrate
-{
-#if defined(_WIN32)
- static std::string create_appdata_shortcut(const std::string& target_path) noexcept
- {
- return Strings::format(R"###(
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Condition="Exists('%s') and '$(VCPkgLocalAppDataDisabled)' == ''" Project="%s" />
-</Project>
-)###",
- target_path,
- target_path);
- }
-#endif
-
-#if defined(_WIN32)
- static std::string create_system_targets_shortcut() noexcept
- {
- return R"###(
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <!-- version 1 -->
- <PropertyGroup>
- <VCLibPackagePath Condition="'$(VCLibPackagePath)' == ''">$(LOCALAPPDATA)\vcpkg\vcpkg.user</VCLibPackagePath>
- </PropertyGroup>
- <Import Condition="'$(VCLibPackagePath)' != '' and Exists('$(VCLibPackagePath).props')" Project="$(VCLibPackagePath).props" />
- <Import Condition="'$(VCLibPackagePath)' != '' and Exists('$(VCLibPackagePath).targets')" Project="$(VCLibPackagePath).targets" />
-</Project>
-)###";
- }
-#endif
-
-#if defined(_WIN32)
- static std::string create_nuget_targets_file_contents(const fs::path& msbuild_vcpkg_targets_file) noexcept
- {
- const std::string as_string = msbuild_vcpkg_targets_file.string();
-
- return Strings::format(R"###(
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="%s" Condition="Exists('%s')" />
- <Target Name="CheckValidPlatform" BeforeTargets="Build">
- <Error Text="Unsupported architecture combination. Remove the 'vcpkg' nuget package." Condition="'$(VCPkgEnabled)' != 'true' and '$(VCPkgDisableError)' == ''"/>
- </Target>
-</Project>
-)###",
- as_string,
- as_string);
- }
-#endif
-
-#if defined(_WIN32)
- static std::string create_nuget_props_file_contents() noexcept
- {
- return R"###(
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <PropertyGroup>
- <VCPkgLocalAppDataDisabled>true</VCPkgLocalAppDataDisabled>
- </PropertyGroup>
-</Project>
-)###";
- }
-#endif
-
-#if defined(_WIN32)
- static std::string get_nuget_id(const fs::path& vcpkg_root_dir)
- {
- std::string dir_id = fs::generic_u8string(vcpkg_root_dir);
- std::replace(dir_id.begin(), dir_id.end(), '/', '.');
- dir_id.erase(1, 1); // Erasing the ":"
-
- // NuGet id cannot have invalid characters. We will only use alphanumeric and dot.
- Util::erase_remove_if(dir_id, [](char c) { return !isalnum(static_cast<unsigned char>(c)) && (c != '.'); });
-
- const std::string nuget_id = "vcpkg." + dir_id;
- return nuget_id;
- }
-#endif
-
-#if defined(_WIN32)
- static std::string create_nuspec_file_contents(const fs::path& vcpkg_root_dir,
- const std::string& nuget_id,
- const std::string& nupkg_version)
- {
- static constexpr auto CONTENT_TEMPLATE = R"(
-<package>
- <metadata>
- <id>@NUGET_ID@</id>
- <version>@VERSION@</version>
- <authors>vcpkg</authors>
- <description>
- This package imports all libraries currently installed in @VCPKG_DIR@. This package does not contain any libraries and instead refers to the folder directly (like a symlink).
- </description>
- </metadata>
- <files>
- <file src="vcpkg.nuget.props" target="build\native\@NUGET_ID@.props" />
- <file src="vcpkg.nuget.targets" target="build\native\@NUGET_ID@.targets" />
- </files>
-</package>
-)";
-
- std::string content = Strings::replace_all(CONTENT_TEMPLATE, "@NUGET_ID@", nuget_id);
- Strings::inplace_replace_all(content, "@VCPKG_DIR@", vcpkg_root_dir.string());
- Strings::inplace_replace_all(content, "@VERSION@", nupkg_version);
- return content;
- }
-#endif
-
-#if defined(_WIN32)
- enum class ElevationPromptChoice
- {
- YES,
- NO
- };
-
- static ElevationPromptChoice elevated_cmd_execute(const std::string& param)
- {
- SHELLEXECUTEINFOW sh_ex_info{};
- sh_ex_info.cbSize = sizeof(sh_ex_info);
- sh_ex_info.fMask = SEE_MASK_NOCLOSEPROCESS;
- sh_ex_info.hwnd = nullptr;
- sh_ex_info.lpVerb = L"runas";
- sh_ex_info.lpFile = L"cmd"; // Application to start
-
- auto wparam = Strings::to_utf16(param);
- sh_ex_info.lpParameters = wparam.c_str(); // Additional parameters
- sh_ex_info.lpDirectory = nullptr;
- sh_ex_info.nShow = SW_HIDE;
- sh_ex_info.hInstApp = nullptr;
-
- if (!ShellExecuteExW(&sh_ex_info))
- {
- return ElevationPromptChoice::NO;
- }
- if (sh_ex_info.hProcess == nullptr)
- {
- return ElevationPromptChoice::NO;
- }
- WaitForSingleObject(sh_ex_info.hProcess, INFINITE);
- CloseHandle(sh_ex_info.hProcess);
- return ElevationPromptChoice::YES;
- }
-#endif
-
-#if defined(_WIN32)
- static fs::path get_appdata_targets_path()
- {
- return System::get_appdata_local().value_or_exit(VCPKG_LINE_INFO) / fs::u8path("vcpkg/vcpkg.user.targets");
- }
-#endif
-#if defined(_WIN32)
- static fs::path get_appdata_props_path()
- {
- return System::get_appdata_local().value_or_exit(VCPKG_LINE_INFO) / fs::u8path("vcpkg/vcpkg.user.props");
- }
-#endif
-
- static fs::path get_path_txt_path() { return get_user_dir() / "vcpkg.path.txt"; }
-
-#if defined(_WIN32)
- static void integrate_install_msbuild14(Files::Filesystem& fs, const fs::path& tmp_dir)
- {
- static const std::array<fs::path, 2> OLD_SYSTEM_TARGET_FILES = {
- System::get_program_files_32_bit().value_or_exit(VCPKG_LINE_INFO) /
- "MSBuild/14.0/Microsoft.Common.Targets/ImportBefore/vcpkg.nuget.targets",
- System::get_program_files_32_bit().value_or_exit(VCPKG_LINE_INFO) /
- "MSBuild/14.0/Microsoft.Common.Targets/ImportBefore/vcpkg.system.targets"};
- static const fs::path SYSTEM_WIDE_TARGETS_FILE =
- System::get_program_files_32_bit().value_or_exit(VCPKG_LINE_INFO) /
- "MSBuild/Microsoft.Cpp/v4.0/V140/ImportBefore/Default/vcpkg.system.props";
-
- // TODO: This block of code should eventually be removed
- for (auto&& old_system_wide_targets_file : OLD_SYSTEM_TARGET_FILES)
- {
- if (fs.exists(old_system_wide_targets_file))
- {
- const std::string param =
- Strings::format(R"(/c "DEL "%s" /Q > nul")", old_system_wide_targets_file.string());
- const ElevationPromptChoice user_choice = elevated_cmd_execute(param);
- switch (user_choice)
- {
- case ElevationPromptChoice::YES: break;
- case ElevationPromptChoice::NO:
- System::print2(System::Color::warning, "Warning: Previous integration file was not removed\n");
- Checks::exit_fail(VCPKG_LINE_INFO);
- default: Checks::unreachable(VCPKG_LINE_INFO);
- }
- }
- }
- bool should_install_system = true;
- const Expected<std::string> system_wide_file_contents = fs.read_contents(SYSTEM_WIDE_TARGETS_FILE);
- static const std::regex RE(R"###(<!-- version (\d+) -->)###");
- if (const auto contents_data = system_wide_file_contents.get())
- {
- std::match_results<std::string::const_iterator> match;
- const auto found = std::regex_search(*contents_data, match, RE);
- if (found)
- {
- const int ver = atoi(match[1].str().c_str());
- if (ver >= 1) should_install_system = false;
- }
- }
-
- if (should_install_system)
- {
- const fs::path sys_src_path = tmp_dir / "vcpkg.system.targets";
- fs.write_contents(sys_src_path, create_system_targets_shortcut(), VCPKG_LINE_INFO);
-
- const std::string param = Strings::format(R"(/c "mkdir "%s" & copy "%s" "%s" /Y > nul")",
- SYSTEM_WIDE_TARGETS_FILE.parent_path().string(),
- sys_src_path.string(),
- SYSTEM_WIDE_TARGETS_FILE.string());
- const ElevationPromptChoice user_choice = elevated_cmd_execute(param);
- switch (user_choice)
- {
- case ElevationPromptChoice::YES: break;
- case ElevationPromptChoice::NO:
- System::print2(System::Color::warning, "Warning: integration was not applied\n");
- Checks::exit_fail(VCPKG_LINE_INFO);
- default: Checks::unreachable(VCPKG_LINE_INFO);
- }
-
- Checks::check_exit(VCPKG_LINE_INFO,
- fs.exists(SYSTEM_WIDE_TARGETS_FILE),
- "Error: failed to copy targets file to %s",
- SYSTEM_WIDE_TARGETS_FILE.string());
- }
- }
-#endif
-
- static void integrate_install(const VcpkgPaths& paths)
- {
- auto& fs = paths.get_filesystem();
-
-#if defined(_WIN32)
- {
- std::error_code ec;
- const fs::path tmp_dir = paths.buildsystems / "tmp";
- fs.create_directory(paths.buildsystems, ec);
- fs.create_directory(tmp_dir, ec);
-
- integrate_install_msbuild14(fs, tmp_dir);
-
- const fs::path appdata_src_path = tmp_dir / "vcpkg.user.targets";
- fs.write_contents(appdata_src_path,
- create_appdata_shortcut(fs::u8string(paths.buildsystems_msbuild_targets)),
- VCPKG_LINE_INFO);
- auto appdata_dst_path = get_appdata_targets_path();
-
- const auto rc = fs.copy_file(appdata_src_path, appdata_dst_path, fs::copy_options::overwrite_existing, ec);
-
- if (!rc || ec)
- {
- System::print2(System::Color::error,
- "Error: Failed to copy file: ",
- fs::u8string(appdata_src_path),
- " -> ",
- fs::u8string(appdata_dst_path),
- "\n");
- Checks::exit_fail(VCPKG_LINE_INFO);
- }
-
- const fs::path appdata_src_path2 = tmp_dir / "vcpkg.user.props";
- fs.write_contents(appdata_src_path2,
- create_appdata_shortcut(fs::u8string(paths.buildsystems_msbuild_props)),
- VCPKG_LINE_INFO);
- auto appdata_dst_path2 = get_appdata_props_path();
-
- const auto rc2 =
- fs.copy_file(appdata_src_path2, appdata_dst_path2, fs::copy_options::overwrite_existing, ec);
-
- if (!rc2 || ec)
- {
- System::print2(System::Color::error,
- "Error: Failed to copy file: ",
- fs::u8string(appdata_src_path2),
- " -> ",
- fs::u8string(appdata_dst_path2),
- "\n");
- Checks::exit_fail(VCPKG_LINE_INFO);
- }
- }
-#endif
-
- const auto pathtxt = get_path_txt_path();
- std::error_code ec;
- fs.write_contents(pathtxt, fs::generic_u8string(paths.root), VCPKG_LINE_INFO);
-
- System::print2(System::Color::success, "Applied user-wide integration for this vcpkg root.\n");
- const fs::path cmake_toolchain = paths.buildsystems / "vcpkg.cmake";
-#if defined(_WIN32)
- System::printf(
- R"(
-All MSBuild C++ projects can now #include any installed libraries.
-Linking will be handled automatically.
-Installing new libraries will make them instantly available.
-
-CMake projects should use: "-DCMAKE_TOOLCHAIN_FILE=%s"
-)",
- fs::generic_u8string(cmake_toolchain));
-#else
- System::printf(
- R"(
-CMake projects should use: "-DCMAKE_TOOLCHAIN_FILE=%s"
-)",
- fs::generic_u8string(cmake_toolchain));
-#endif
-
- Checks::exit_success(VCPKG_LINE_INFO);
- }
-
- static void integrate_remove(Files::Filesystem& fs)
- {
- std::error_code ec;
- bool was_deleted = false;
-
-#if defined(_WIN32)
- const fs::path path = get_appdata_targets_path();
-
- was_deleted |= fs.remove(path, ec);
- Checks::check_exit(VCPKG_LINE_INFO, !ec, "Error: Unable to remove user-wide integration: %s", ec.message());
-
- const fs::path path2 = get_appdata_props_path();
-
- was_deleted |= fs.remove(path2, ec);
- Checks::check_exit(VCPKG_LINE_INFO, !ec, "Error: Unable to remove user-wide integration: %s", ec.message());
-#endif
-
- was_deleted |= fs.remove(get_path_txt_path(), ec);
- Checks::check_exit(VCPKG_LINE_INFO, !ec, "Error: Unable to remove user-wide integration: %s", ec.message());
-
- if (was_deleted)
- {
- System::print2(System::Color::success, "User-wide integration was removed\n");
- }
- else
- {
- System::print2(System::Color::success, "User-wide integration is not installed\n");
- }
-
- Checks::exit_success(VCPKG_LINE_INFO);
- }
-
-#if defined(WIN32)
- static void integrate_project(const VcpkgPaths& paths)
- {
- auto& fs = paths.get_filesystem();
-
- const fs::path& nuget_exe = paths.get_tool_exe(Tools::NUGET);
-
- const fs::path& buildsystems_dir = paths.buildsystems;
- const fs::path tmp_dir = buildsystems_dir / "tmp";
- std::error_code ec;
- fs.create_directory(buildsystems_dir, ec);
- fs.create_directory(tmp_dir, ec);
-
- const fs::path targets_file_path = tmp_dir / "vcpkg.nuget.targets";
- const fs::path props_file_path = tmp_dir / "vcpkg.nuget.props";
- const fs::path nuspec_file_path = tmp_dir / "vcpkg.nuget.nuspec";
- const std::string nuget_id = get_nuget_id(paths.root);
- const std::string nupkg_version = "1.0.0";
-
- fs.write_contents(
- targets_file_path, create_nuget_targets_file_contents(paths.buildsystems_msbuild_targets), VCPKG_LINE_INFO);
- fs.write_contents(props_file_path, create_nuget_props_file_contents(), VCPKG_LINE_INFO);
- fs.write_contents(
- nuspec_file_path, create_nuspec_file_contents(paths.root, nuget_id, nupkg_version), VCPKG_LINE_INFO);
-
- // Using all forward slashes for the command line
- auto cmd_line = System::Command(nuget_exe)
- .string_arg("pack")
- .string_arg("-OutputDirectory")
- .path_arg(buildsystems_dir)
- .path_arg(nuspec_file_path);
-
- const int exit_code =
- System::cmd_execute_and_capture_output(cmd_line, System::get_clean_environment()).exit_code;
-
- const fs::path nuget_package = buildsystems_dir / Strings::format("%s.%s.nupkg", nuget_id, nupkg_version);
- Checks::check_exit(
- VCPKG_LINE_INFO, exit_code == 0 && fs.exists(nuget_package), "Error: NuGet package creation failed");
- System::print2(System::Color::success, "Created nupkg: ", fs::u8string(nuget_package), '\n');
-
- auto source_path = fs::u8string(buildsystems_dir);
- Strings::inplace_replace_all(source_path, "`", "``");
-
- System::printf(R"(
-With a project open, go to Tools->NuGet Package Manager->Package Manager Console and paste:
- Install-Package %s -Source "%s"
-
-)",
- nuget_id,
- source_path);
-
- Checks::exit_success(VCPKG_LINE_INFO);
- }
-#endif
-
-#if defined(_WIN32)
- static void integrate_powershell(const VcpkgPaths& paths)
- {
- static constexpr StringLiteral TITLE = "PowerShell Tab-Completion";
- const fs::path script_path = paths.scripts / "addPoshVcpkgToPowershellProfile.ps1";
-
- const auto& ps = paths.get_tool_exe("powershell-core");
- auto cmd = System::Command(ps)
- .string_arg("-NoProfile")
- .string_arg("-ExecutionPolicy")
- .string_arg("Bypass")
- .string_arg("-Command")
- .string_arg(Strings::format("& {& '%s' }", fs::u8string(script_path)));
- const int rc = System::cmd_execute(cmd);
- if (rc)
- {
- System::printf(System::Color::error,
- "%s\n"
- "Could not run:\n"
- " '%s'\n",
- TITLE,
- fs::generic_u8string(script_path));
-
- {
- auto locked_metrics = Metrics::g_metrics.lock();
- locked_metrics->track_property("error", "powershell script failed");
- locked_metrics->track_property("title", TITLE);
- }
- }
-
- Checks::exit_with_code(VCPKG_LINE_INFO, rc);
- }
-#else
- static void integrate_bash(const VcpkgPaths& paths)
- {
- const auto home_path = System::get_environment_variable("HOME").value_or_exit(VCPKG_LINE_INFO);
- const fs::path bashrc_path = fs::path{home_path} / ".bashrc";
-
- auto& fs = paths.get_filesystem();
- const fs::path completion_script_path = paths.scripts / "vcpkg_completion.bash";
-
- Expected<std::vector<std::string>> maybe_bashrc_content = fs.read_lines(bashrc_path);
- Checks::check_exit(
- VCPKG_LINE_INFO, maybe_bashrc_content.has_value(), "Unable to read %s", fs::u8string(bashrc_path));
-
- std::vector<std::string> bashrc_content = maybe_bashrc_content.value_or_exit(VCPKG_LINE_INFO);
-
- std::vector<std::string> matches;
- for (auto&& line : bashrc_content)
- {
- std::smatch match;
- if (std::regex_match(line, match, std::regex{R"###(^source.*scripts/vcpkg_completion.bash$)###"}))
- {
- matches.push_back(line);
- }
- }
-
- if (!matches.empty())
- {
- System::printf("vcpkg bash completion is already imported to your %s file.\n"
- "The following entries were found:\n"
- " %s\n"
- "Please make sure you have started a new bash shell for the changes to take effect.\n",
- fs::u8string(bashrc_path),
- Strings::join("\n ", matches));
- Checks::exit_success(VCPKG_LINE_INFO);
- }
-
- System::printf("Adding vcpkg completion entry to %s\n", fs::u8string(bashrc_path));
- bashrc_content.push_back(Strings::format("source %s", fs::u8string(completion_script_path)));
- fs.write_contents(bashrc_path, Strings::join("\n", bashrc_content) + '\n', VCPKG_LINE_INFO);
- Checks::exit_success(VCPKG_LINE_INFO);
- }
-
- static void integrate_fish(const VcpkgPaths& paths)
- {
- fs::path fish_completions_path;
- const auto config_path = System::get_environment_variable("XDG_CONFIG_HOME");
- if (config_path.has_value())
- {
- fish_completions_path = fs::path{config_path.value_or_exit(VCPKG_LINE_INFO)};
- }
- else
- {
- const auto home_path = System::get_environment_variable("HOME").value_or_exit(VCPKG_LINE_INFO);
- fish_completions_path = fs::path{home_path} / ".config";
- }
- fish_completions_path = fish_completions_path / "fish" / "completions" / "vcpkg.fish";
-
- if (fs::stdfs::exists(fish_completions_path))
- {
- System::printf("vcpkg fish completion is already added at %s.\n", fs::u8string(fish_completions_path));
- Checks::exit_success(VCPKG_LINE_INFO);
- }
-
- const fs::path completion_script_path = paths.scripts / "vcpkg_completion.fish";
-
- System::printf("Adding vcpkg completion entry at %s.\n", fs::u8string(fish_completions_path));
- fs::stdfs::create_symlink(completion_script_path, fish_completions_path);
- Checks::exit_success(VCPKG_LINE_INFO);
- }
-#endif
-
- void append_helpstring(HelpTableFormatter& table)
- {
-#if defined(_WIN32)
- table.format("vcpkg integrate install",
- "Make installed packages available user-wide. Requires admin privileges on first use");
- table.format("vcpkg integrate remove", "Remove user-wide integration");
- table.format("vcpkg integrate project", "Generate a referencing nuget package for individual VS project use");
- table.format("vcpkg integrate powershell", "Enable PowerShell tab-completion");
-#else // ^^^ defined(_WIN32) // !defined(_WIN32) vvv
- table.format("vcpkg integrate install", "Make installed packages available user-wide");
- table.format("vcpkg integrate remove", "Remove user-wide integration");
- table.format("vcpkg integrate bash", "Enable bash tab-completion");
- table.format("vcpkg integrate fish", "Enable fish tab-completion");
-#endif // ^^^ !defined(_WIN32)
- }
-
- std::string get_helpstring()
- {
- HelpTableFormatter table;
- append_helpstring(table);
- return std::move(table.m_str);
- }
-
- namespace Subcommand
- {
- static const std::string INSTALL = "install";
- static const std::string REMOVE = "remove";
- static const std::string PROJECT = "project";
- static const std::string POWERSHELL = "powershell";
- static const std::string BASH = "bash";
- static const std::string FISH = "x-fish";
- }
-
- static std::vector<std::string> valid_arguments(const VcpkgPaths&)
- {
- return
- {
- Subcommand::INSTALL, Subcommand::REMOVE,
-#if defined(_WIN32)
- Subcommand::PROJECT, Subcommand::POWERSHELL,
-#else
- Subcommand::BASH, Subcommand::FISH,
-#endif
- };
- }
-
- const CommandStructure COMMAND_STRUCTURE = {
- "Commands:\n" + get_helpstring(),
- 1,
- 1,
- {},
- &valid_arguments,
- };
-
- void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths)
- {
- (void)args.parse_arguments(COMMAND_STRUCTURE);
-
- if (args.command_arguments[0] == Subcommand::INSTALL)
- {
- return integrate_install(paths);
- }
- if (args.command_arguments[0] == Subcommand::REMOVE)
- {
- return integrate_remove(paths.get_filesystem());
- }
-#if defined(_WIN32)
- if (args.command_arguments[0] == Subcommand::PROJECT)
- {
- return integrate_project(paths);
- }
- if (args.command_arguments[0] == Subcommand::POWERSHELL)
- {
- return integrate_powershell(paths);
- }
-#else
- if (args.command_arguments[0] == Subcommand::BASH)
- {
- return integrate_bash(paths);
- }
- if (args.command_arguments[0] == Subcommand::FISH)
- {
- return integrate_fish(paths);
- }
-#endif
-
- Checks::exit_maybe_upgrade(VCPKG_LINE_INFO, "Unknown parameter %s for integrate", args.command_arguments[0]);
- }
-
- void IntegrateCommand::perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) const
- {
- Integrate::perform_and_exit(args, paths);
- }
-}
diff --git a/toolsrc/src/vcpkg/commands.list.cpp b/toolsrc/src/vcpkg/commands.list.cpp
deleted file mode 100644
index 0af7c1f6c..000000000
--- a/toolsrc/src/vcpkg/commands.list.cpp
+++ /dev/null
@@ -1,147 +0,0 @@
-#include <vcpkg/base/system.print.h>
-#include <vcpkg/base/util.h>
-
-#include <vcpkg/commands.list.h>
-#include <vcpkg/help.h>
-#include <vcpkg/vcpkgcmdarguments.h>
-#include <vcpkg/vcpkglib.h>
-#include <vcpkg/versiont.h>
-
-namespace vcpkg::Commands::List
-{
- static constexpr StringLiteral OPTION_FULLDESC = "x-full-desc"; // TODO: This should find a better home, eventually
-
- static void do_print_json(std::vector<const vcpkg::StatusParagraph*> installed_packages)
- {
- Json::Object obj;
- for (const StatusParagraph* status_paragraph : installed_packages)
- {
- auto current_spec = status_paragraph->package.spec;
- if (obj.contains(current_spec.to_string()))
- {
- if (status_paragraph->package.is_feature())
- {
- Json::Value* value_obj = obj.get(current_spec.to_string());
- auto& feature_list = value_obj->object()["features"].array();
- feature_list.push_back(Json::Value::string(status_paragraph->package.feature));
- }
- }
- else
- {
- Json::Object& library_obj = obj.insert(current_spec.to_string(), Json::Object());
- library_obj.insert("package_name", Json::Value::string(current_spec.name()));
- library_obj.insert("triplet", Json::Value::string(current_spec.triplet().to_string()));
- library_obj.insert("version", Json::Value::string(status_paragraph->package.version));
- library_obj.insert("port_version", Json::Value::integer(status_paragraph->package.port_version));
- Json::Array& features_array = library_obj.insert("features", Json::Array());
- if (status_paragraph->package.is_feature())
- {
- features_array.push_back(Json::Value::string(status_paragraph->package.feature));
- }
- Json::Array& desc = library_obj.insert("desc", Json::Array());
- for (const auto& line : status_paragraph->package.description)
- {
- desc.push_back(Json::Value::string(line));
- }
- }
- }
-
- System::print2(Json::stringify(obj, Json::JsonStyle{}));
- }
-
- static void do_print(const StatusParagraph& pgh, const bool full_desc)
- {
- auto full_version = VersionT(pgh.package.version, pgh.package.port_version).to_string();
- if (full_desc)
- {
- System::printf("%-50s %-16s %s\n",
- pgh.package.displayname(),
- full_version,
- Strings::join("\n ", pgh.package.description));
- }
- else
- {
- std::string description;
- if (!pgh.package.description.empty())
- {
- description = pgh.package.description[0];
- }
- System::printf("%-50s %-16s %s\n",
- vcpkg::shorten_text(pgh.package.displayname(), 50),
- vcpkg::shorten_text(full_version, 16),
- vcpkg::shorten_text(description, 51));
- }
- }
-
- static constexpr std::array<CommandSwitch, 1> LIST_SWITCHES = {{
- {OPTION_FULLDESC, "Do not truncate long text"},
- }};
-
- const CommandStructure COMMAND_STRUCTURE = {
- Strings::format(
- "The argument should be a substring to search for, or no argument to display all installed libraries.\n%s",
- create_example_string("list png")),
- 0,
- 1,
- {LIST_SWITCHES, {}},
- nullptr,
- };
-
- void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths)
- {
- const ParsedArguments options = args.parse_arguments(COMMAND_STRUCTURE);
-
- const StatusParagraphs status_paragraphs = database_load_check(paths);
- auto installed_ipv = get_installed_ports(status_paragraphs);
-
- if (installed_ipv.empty())
- {
- if (args.output_json())
- System::print2(Json::stringify(Json::Object(), {}));
- else
- System::print2("No packages are installed. Did you mean `search`?\n");
- Checks::exit_success(VCPKG_LINE_INFO);
- }
-
- auto installed_packages = Util::fmap(installed_ipv, [](const InstalledPackageView& ipv) { return ipv.core; });
- auto installed_features =
- Util::fmap_flatten(installed_ipv, [](const InstalledPackageView& ipv) { return ipv.features; });
- installed_packages.insert(installed_packages.end(), installed_features.begin(), installed_features.end());
-
- std::sort(installed_packages.begin(),
- installed_packages.end(),
- [](const StatusParagraph* lhs, const StatusParagraph* rhs) -> bool {
- return lhs->package.displayname() < rhs->package.displayname();
- });
-
- const auto enable_fulldesc = Util::Sets::contains(options.switches, OPTION_FULLDESC.to_string());
-
- if (!args.command_arguments.empty())
- {
- auto& query = args.command_arguments[0];
- auto pghs = Util::filter(installed_packages, [query](const StatusParagraph* status_paragraph) {
- return Strings::case_insensitive_ascii_contains(status_paragraph->package.displayname(), query);
- });
- installed_packages = pghs;
- }
-
- if (args.output_json())
- {
- do_print_json(installed_packages);
- }
- else
- {
- for (const StatusParagraph* status_paragraph : installed_packages)
- {
- do_print(*status_paragraph, enable_fulldesc);
- }
- }
-
- Checks::exit_success(VCPKG_LINE_INFO);
- }
-
- void ListCommand::perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) const
- {
- List::perform_and_exit(args, paths);
- }
-}
diff --git a/toolsrc/src/vcpkg/commands.owns.cpp b/toolsrc/src/vcpkg/commands.owns.cpp
deleted file mode 100644
index 8bd020108..000000000
--- a/toolsrc/src/vcpkg/commands.owns.cpp
+++ /dev/null
@@ -1,47 +0,0 @@
-#include <vcpkg/base/system.print.h>
-
-#include <vcpkg/commands.owns.h>
-#include <vcpkg/help.h>
-#include <vcpkg/vcpkgcmdarguments.h>
-#include <vcpkg/vcpkglib.h>
-
-namespace vcpkg::Commands::Owns
-{
- static void search_file(const VcpkgPaths& paths, const std::string& file_substr, const StatusParagraphs& status_db)
- {
- const std::vector<StatusParagraphAndAssociatedFiles> installed_files = get_installed_files(paths, status_db);
- for (const StatusParagraphAndAssociatedFiles& pgh_and_file : installed_files)
- {
- const StatusParagraph& pgh = pgh_and_file.pgh;
-
- for (const std::string& file : pgh_and_file.files)
- {
- if (file.find(file_substr) != std::string::npos)
- {
- System::print2(pgh.package.displayname(), ": ", file, '\n');
- }
- }
- }
- }
- const CommandStructure COMMAND_STRUCTURE = {
- Strings::format("The argument should be a pattern to search for. %s", create_example_string("owns zlib.dll")),
- 1,
- 1,
- {},
- nullptr,
- };
-
- void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths)
- {
- (void)args.parse_arguments(COMMAND_STRUCTURE);
-
- const StatusParagraphs status_db = database_load_check(paths);
- search_file(paths, args.command_arguments[0], status_db);
- Checks::exit_success(VCPKG_LINE_INFO);
- }
-
- void OwnsCommand::perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) const
- {
- Owns::perform_and_exit(args, paths);
- }
-}
diff --git a/toolsrc/src/vcpkg/commands.porthistory.cpp b/toolsrc/src/vcpkg/commands.porthistory.cpp
deleted file mode 100644
index 7d7fcf3d5..000000000
--- a/toolsrc/src/vcpkg/commands.porthistory.cpp
+++ /dev/null
@@ -1,240 +0,0 @@
-#include <vcpkg/base/json.h>
-#include <vcpkg/base/system.print.h>
-#include <vcpkg/base/system.process.h>
-#include <vcpkg/base/util.h>
-
-#include <vcpkg/commands.porthistory.h>
-#include <vcpkg/help.h>
-#include <vcpkg/paragraphs.h>
-#include <vcpkg/tools.h>
-#include <vcpkg/vcpkgcmdarguments.h>
-#include <vcpkg/vcpkgpaths.h>
-#include <vcpkg/versiondeserializers.h>
-#include <vcpkg/versions.h>
-
-namespace vcpkg::Commands::PortHistory
-{
- namespace
- {
- struct HistoryVersion
- {
- std::string port_name;
- std::string git_tree;
- std::string commit_id;
- std::string commit_date;
- std::string version_string;
- std::string version;
- int port_version;
- Versions::Scheme scheme;
- };
-
- const System::ExitCodeAndOutput run_git_command_inner(const VcpkgPaths& paths,
- const fs::path& dot_git_directory,
- const fs::path& working_directory,
- const System::Command& cmd)
- {
- const fs::path& git_exe = paths.get_tool_exe(Tools::GIT);
-
- auto full_cmd = System::Command(git_exe)
- .string_arg(Strings::concat("--git-dir=", fs::u8string(dot_git_directory)))
- .string_arg(Strings::concat("--work-tree=", fs::u8string(working_directory)))
- .raw_arg(cmd.command_line());
-
- auto output = System::cmd_execute_and_capture_output(full_cmd);
- return output;
- }
-
- const System::ExitCodeAndOutput run_git_command(const VcpkgPaths& paths, const System::Command& cmd)
- {
- const fs::path& work_dir = paths.root;
- const fs::path dot_git_dir = paths.root / ".git";
-
- return run_git_command_inner(paths, dot_git_dir, work_dir, cmd);
- }
-
- vcpkg::Optional<HistoryVersion> get_version_from_text(const std::string& text,
- const std::string& git_tree,
- const std::string& commit_id,
- const std::string& commit_date,
- const std::string& port_name,
- bool is_manifest)
- {
- auto res = Paragraphs::try_load_port_text(text, Strings::concat(commit_id, ":", port_name), is_manifest);
- if (const auto& maybe_scf = res.get())
- {
- if (const auto& scf = maybe_scf->get())
- {
- auto version = scf->core_paragraph->version;
- auto port_version = scf->core_paragraph->port_version;
- auto scheme = scf->core_paragraph->version_scheme;
- return HistoryVersion{
- port_name,
- git_tree,
- commit_id,
- commit_date,
- Strings::concat(version, "#", port_version),
- version,
- port_version,
- scheme,
- };
- }
- }
-
- return nullopt;
- }
-
- vcpkg::Optional<HistoryVersion> get_version_from_commit(const VcpkgPaths& paths,
- const std::string& commit_id,
- const std::string& commit_date,
- const std::string& port_name)
- {
- auto rev_parse_cmd =
- System::Command("rev-parse").string_arg(Strings::concat(commit_id, ":ports/", port_name));
- auto rev_parse_output = run_git_command(paths, rev_parse_cmd);
- if (rev_parse_output.exit_code == 0)
- {
- // Remove newline character
- const auto git_tree = Strings::trim(std::move(rev_parse_output.output));
-
- // Do we have a manifest file?
- auto manifest_cmd = System::Command("show").string_arg(Strings::concat(git_tree, ":vcpkg.json"));
- auto manifest_output = run_git_command(paths, manifest_cmd);
- if (manifest_output.exit_code == 0)
- {
- return get_version_from_text(
- manifest_output.output, git_tree, commit_id, commit_date, port_name, true);
- }
-
- auto cmd = System::Command("show").string_arg(Strings::concat(git_tree, ":CONTROL"));
- auto control_output = run_git_command(paths, cmd);
-
- if (control_output.exit_code == 0)
- {
- return get_version_from_text(
- control_output.output, git_tree, commit_id, commit_date, port_name, false);
- }
- }
-
- return nullopt;
- }
-
- std::vector<HistoryVersion> read_versions_from_log(const VcpkgPaths& paths, const std::string& port_name)
- {
- // log --format="%H %cd" --date=short --left-only -- ports/{port_name}/.
- System::Command builder;
- builder.string_arg("log");
- builder.string_arg("--format=%H %cd");
- builder.string_arg("--date=short");
- builder.string_arg("--left-only");
- builder.string_arg("--"); // Begin pathspec
- builder.string_arg(Strings::format("ports/%s/.", port_name));
- const auto output = run_git_command(paths, builder);
-
- auto commits = Util::fmap(
- Strings::split(output.output, '\n'), [](const std::string& line) -> auto {
- auto parts = Strings::split(line, ' ');
- return std::make_pair(parts[0], parts[1]);
- });
-
- std::vector<HistoryVersion> ret;
- std::string last_version;
- for (auto&& commit_date_pair : commits)
- {
- auto maybe_version =
- get_version_from_commit(paths, commit_date_pair.first, commit_date_pair.second, port_name);
- if (maybe_version.has_value())
- {
- const auto version = maybe_version.value_or_exit(VCPKG_LINE_INFO);
-
- // Keep latest port with the current version string
- if (last_version != version.version_string)
- {
- last_version = version.version_string;
- ret.emplace_back(version);
- }
- }
- }
- return ret;
- }
- }
-
- static constexpr StringLiteral OPTION_OUTPUT_FILE = "output";
-
- static const CommandSetting HISTORY_SETTINGS[] = {
- {OPTION_OUTPUT_FILE, "Write output to a file"},
- };
-
- const CommandStructure COMMAND_STRUCTURE = {
- create_example_string("history <port>"),
- 1,
- 1,
- {{}, {HISTORY_SETTINGS}, {}},
- nullptr,
- };
-
- static Optional<std::string> maybe_lookup(std::unordered_map<std::string, std::string> const& m,
- std::string const& key)
- {
- const auto it = m.find(key);
- if (it != m.end()) return it->second;
- return nullopt;
- }
-
- void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths)
- {
- const ParsedArguments parsed_args = args.parse_arguments(COMMAND_STRUCTURE);
- auto maybe_output_file = maybe_lookup(parsed_args.settings, OPTION_OUTPUT_FILE);
-
- std::string port_name = args.command_arguments.at(0);
- std::vector<HistoryVersion> versions = read_versions_from_log(paths, port_name);
-
- if (args.output_json())
- {
- Json::Array versions_json;
- for (auto&& version : versions)
- {
- Json::Object object;
- object.insert("git-tree", Json::Value::string(version.git_tree));
-
- serialize_schemed_version(object, version.scheme, version.version, version.port_version, true);
- versions_json.push_back(std::move(object));
- }
-
- Json::Object root;
- root.insert("versions", versions_json);
-
- auto json_string = Json::stringify(root, vcpkg::Json::JsonStyle::with_spaces(2));
-
- if (maybe_output_file.has_value())
- {
- auto output_file_path = fs::u8path(maybe_output_file.value_or_exit(VCPKG_LINE_INFO));
- auto& fs = paths.get_filesystem();
- fs.write_contents(output_file_path, json_string, VCPKG_LINE_INFO);
- }
- else
- {
- System::printf("%s\n", json_string);
- }
- }
- else
- {
- if (maybe_output_file.has_value())
- {
- System::printf(
- System::Color::warning, "Warning: Option `--$s` requires `--x-json` switch.", OPTION_OUTPUT_FILE);
- }
-
- System::print2(" version date vcpkg commit\n");
- for (auto&& version : versions)
- {
- System::printf("%20.20s %s %s\n", version.version_string, version.commit_date, version.commit_id);
- }
- }
- Checks::exit_success(VCPKG_LINE_INFO);
- }
-
- void PortHistoryCommand::perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) const
- {
- PortHistory::perform_and_exit(args, paths);
- }
-}
diff --git a/toolsrc/src/vcpkg/commands.portsdiff.cpp b/toolsrc/src/vcpkg/commands.portsdiff.cpp
deleted file mode 100644
index 18e3a9d91..000000000
--- a/toolsrc/src/vcpkg/commands.portsdiff.cpp
+++ /dev/null
@@ -1,200 +0,0 @@
-#include <vcpkg/base/sortedvector.h>
-#include <vcpkg/base/system.print.h>
-#include <vcpkg/base/system.process.h>
-#include <vcpkg/base/util.h>
-
-#include <vcpkg/commands.portsdiff.h>
-#include <vcpkg/help.h>
-#include <vcpkg/paragraphs.h>
-#include <vcpkg/tools.h>
-#include <vcpkg/vcpkgcmdarguments.h>
-#include <vcpkg/vcpkgpaths.h>
-#include <vcpkg/versiont.h>
-
-namespace vcpkg::Commands::PortsDiff
-{
- struct UpdatedPort
- {
- static bool compare_by_name(const UpdatedPort& left, const UpdatedPort& right)
- {
- return left.port < right.port;
- }
-
- std::string port;
- VersionDiff version_diff;
- };
-
- template<class T>
- struct SetElementPresence
- {
- static SetElementPresence create(std::vector<T> left, std::vector<T> right)
- {
- // TODO: This can be done with one pass instead of three passes
- SetElementPresence output;
- std::set_difference(
- left.cbegin(), left.cend(), right.cbegin(), right.cend(), std::back_inserter(output.only_left));
- std::set_intersection(
- left.cbegin(), left.cend(), right.cbegin(), right.cend(), std::back_inserter(output.both));
- std::set_difference(
- right.cbegin(), right.cend(), left.cbegin(), left.cend(), std::back_inserter(output.only_right));
-
- return output;
- }
-
- std::vector<T> only_left;
- std::vector<T> both;
- std::vector<T> only_right;
- };
-
- static std::vector<UpdatedPort> find_updated_ports(
- const std::vector<std::string>& ports,
- const std::map<std::string, VersionT>& previous_names_and_versions,
- const std::map<std::string, VersionT>& current_names_and_versions)
- {
- std::vector<UpdatedPort> output;
- for (const std::string& name : ports)
- {
- const VersionT& previous_version = previous_names_and_versions.at(name);
- const VersionT& current_version = current_names_and_versions.at(name);
- if (previous_version == current_version)
- {
- continue;
- }
-
- output.push_back({name, VersionDiff(previous_version, current_version)});
- }
-
- return output;
- }
-
- static void do_print_name_and_version(const std::vector<std::string>& ports_to_print,
- const std::map<std::string, VersionT>& names_and_versions)
- {
- for (const std::string& name : ports_to_print)
- {
- const VersionT& version = names_and_versions.at(name);
- System::printf(" - %-14s %-16s\n", name, version);
- }
- }
-
- static std::map<std::string, VersionT> read_ports_from_commit(const VcpkgPaths& paths,
- const std::string& git_commit_id)
- {
- std::error_code ec;
- auto& fs = paths.get_filesystem();
- const fs::path& git_exe = paths.get_tool_exe(Tools::GIT);
- const fs::path dot_git_dir = paths.root / ".git";
- const std::string ports_dir_name_as_string = fs::u8string(paths.builtin_ports_directory().filename());
- const fs::path temp_checkout_path =
- paths.root / Strings::format("%s-%s", ports_dir_name_as_string, git_commit_id);
- fs.create_directory(temp_checkout_path, ec);
- const auto checkout_this_dir =
- Strings::format(R"(.\%s)", ports_dir_name_as_string); // Must be relative to the root of the repository
-
- auto cmd = System::Command(git_exe)
- .string_arg(Strings::format("--git-dir=%s", fs::u8string(dot_git_dir)))
- .string_arg(Strings::format("--work-tree=%s", fs::u8string(temp_checkout_path)))
- .string_arg("checkout")
- .string_arg(git_commit_id)
- .string_arg("-f")
- .string_arg("-q")
- .string_arg("--")
- .string_arg(checkout_this_dir)
- .string_arg(".vcpkg-root");
- System::cmd_execute_and_capture_output(cmd, System::get_clean_environment());
- System::cmd_execute_and_capture_output(System::Command(git_exe).string_arg("reset"),
- System::get_clean_environment());
- const auto ports_at_commit = Paragraphs::load_overlay_ports(fs, temp_checkout_path / ports_dir_name_as_string);
- std::map<std::string, VersionT> names_and_versions;
- for (auto&& port : ports_at_commit)
- {
- const auto& core_pgh = *port.source_control_file->core_paragraph;
- names_and_versions.emplace(core_pgh.name, VersionT(core_pgh.version, core_pgh.port_version));
- }
- fs.remove_all(temp_checkout_path, VCPKG_LINE_INFO);
- return names_and_versions;
- }
-
- static void check_commit_exists(const fs::path& git_exe, const std::string& git_commit_id)
- {
- static const std::string VALID_COMMIT_OUTPUT = "commit\n";
-
- auto cmd = System::Command(git_exe).string_arg("cat-file").string_arg("-t").string_arg(git_commit_id);
- const System::ExitCodeAndOutput output = System::cmd_execute_and_capture_output(cmd);
- Checks::check_exit(
- VCPKG_LINE_INFO, output.output == VALID_COMMIT_OUTPUT, "Invalid commit id %s", git_commit_id);
- }
-
- const CommandStructure COMMAND_STRUCTURE = {
- Strings::format("The argument should be a branch/tag/hash to checkout.\n%s",
- create_example_string("portsdiff mybranchname")),
- 1,
- 2,
- {},
- nullptr,
- };
-
- void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths)
- {
- (void)args.parse_arguments(COMMAND_STRUCTURE);
- const fs::path& git_exe = paths.get_tool_exe(Tools::GIT);
-
- const std::string git_commit_id_for_previous_snapshot = args.command_arguments.at(0);
- const std::string git_commit_id_for_current_snapshot =
- args.command_arguments.size() < 2 ? "HEAD" : args.command_arguments.at(1);
-
- check_commit_exists(git_exe, git_commit_id_for_current_snapshot);
- check_commit_exists(git_exe, git_commit_id_for_previous_snapshot);
-
- const std::map<std::string, VersionT> current_names_and_versions =
- read_ports_from_commit(paths, git_commit_id_for_current_snapshot);
- const std::map<std::string, VersionT> previous_names_and_versions =
- read_ports_from_commit(paths, git_commit_id_for_previous_snapshot);
-
- // Already sorted, so set_difference can work on std::vector too
- const std::vector<std::string> current_ports = Util::extract_keys(current_names_and_versions);
- const std::vector<std::string> previous_ports = Util::extract_keys(previous_names_and_versions);
-
- const SetElementPresence<std::string> setp =
- SetElementPresence<std::string>::create(current_ports, previous_ports);
-
- const std::vector<std::string>& added_ports = setp.only_left;
- if (!added_ports.empty())
- {
- System::printf("\nThe following %zd ports were added:\n", added_ports.size());
- do_print_name_and_version(added_ports, current_names_and_versions);
- }
-
- const std::vector<std::string>& removed_ports = setp.only_right;
- if (!removed_ports.empty())
- {
- System::printf("\nThe following %zd ports were removed:\n", removed_ports.size());
- do_print_name_and_version(removed_ports, previous_names_and_versions);
- }
-
- const std::vector<std::string>& common_ports = setp.both;
- const std::vector<UpdatedPort> updated_ports =
- find_updated_ports(common_ports, previous_names_and_versions, current_names_and_versions);
-
- if (!updated_ports.empty())
- {
- System::printf("\nThe following %zd ports were updated:\n", updated_ports.size());
- for (const UpdatedPort& p : updated_ports)
- {
- System::printf(" - %-14s %-16s\n", p.port, p.version_diff.to_string());
- }
- }
-
- if (added_ports.empty() && removed_ports.empty() && updated_ports.empty())
- {
- System::print2("There were no changes in the ports between the two commits.\n");
- }
-
- Checks::exit_success(VCPKG_LINE_INFO);
- }
-
- void PortsDiffCommand::perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) const
- {
- PortsDiff::perform_and_exit(args, paths);
- }
-}
diff --git a/toolsrc/src/vcpkg/commands.search.cpp b/toolsrc/src/vcpkg/commands.search.cpp
deleted file mode 100644
index 69d31a249..000000000
--- a/toolsrc/src/vcpkg/commands.search.cpp
+++ /dev/null
@@ -1,184 +0,0 @@
-#include <vcpkg/base/system.print.h>
-
-#include <vcpkg/commands.search.h>
-#include <vcpkg/dependencies.h>
-#include <vcpkg/globalstate.h>
-#include <vcpkg/help.h>
-#include <vcpkg/paragraphs.h>
-#include <vcpkg/portfileprovider.h>
-#include <vcpkg/sourceparagraph.h>
-#include <vcpkg/vcpkgcmdarguments.h>
-#include <vcpkg/vcpkglib.h>
-#include <vcpkg/versiont.h>
-
-using vcpkg::PortFileProvider::PathsPortFileProvider;
-
-namespace vcpkg::Commands::Search
-{
- static constexpr StringLiteral OPTION_FULLDESC = "x-full-desc"; // TODO: This should find a better home, eventually
- static constexpr StringLiteral OPTION_JSON = "x-json";
-
- static void do_print_json(std::vector<const vcpkg::SourceControlFile*> source_control_files)
- {
- Json::Object obj;
- for (const SourceControlFile* scf : source_control_files)
- {
- auto& source_paragraph = scf->core_paragraph;
- Json::Object& library_obj = obj.insert(source_paragraph->name, Json::Object());
- library_obj.insert("package_name", Json::Value::string(source_paragraph->name));
- library_obj.insert("version", Json::Value::string(source_paragraph->version));
- library_obj.insert("port_version", Json::Value::integer(source_paragraph->port_version));
- Json::Array& desc = library_obj.insert("description", Json::Array());
- for (const auto& line : source_paragraph->description)
- {
- desc.push_back(Json::Value::string(line));
- }
- }
-
- System::print2(Json::stringify(obj, Json::JsonStyle{}));
- }
- static void do_print(const SourceParagraph& source_paragraph, bool full_desc)
- {
- auto full_version = VersionT(source_paragraph.version, source_paragraph.port_version).to_string();
- if (full_desc)
- {
- System::printf("%-20s %-16s %s\n",
- source_paragraph.name,
- full_version,
- Strings::join("\n ", source_paragraph.description));
- }
- else
- {
- std::string description;
- if (!source_paragraph.description.empty())
- {
- description = source_paragraph.description[0];
- }
- System::printf("%-20s %-16s %s\n",
- vcpkg::shorten_text(source_paragraph.name, 20),
- vcpkg::shorten_text(full_version, 16),
- vcpkg::shorten_text(description, 81));
- }
- }
-
- static void do_print(const std::string& name, const FeatureParagraph& feature_paragraph, bool full_desc)
- {
- auto full_feature_name = Strings::concat(name, "[", feature_paragraph.name, "]");
- if (full_desc)
- {
- System::printf("%-37s %s\n", full_feature_name, Strings::join("\n ", feature_paragraph.description));
- }
- else
- {
- std::string description;
- if (!feature_paragraph.description.empty())
- {
- description = feature_paragraph.description[0];
- }
- System::printf(
- "%-37s %s\n", vcpkg::shorten_text(full_feature_name, 37), vcpkg::shorten_text(description, 81));
- }
- }
-
- static constexpr std::array<CommandSwitch, 2> SEARCH_SWITCHES = {{
- {OPTION_FULLDESC, "Do not truncate long text"},
- {OPTION_JSON, "(experimental) List libraries in JSON format"},
- }};
-
- const CommandStructure COMMAND_STRUCTURE = {
- Strings::format(
- "The argument should be a substring to search for, or no argument to display all libraries.\n%s",
- create_example_string("search png")),
- 0,
- 1,
- {SEARCH_SWITCHES, {}},
- nullptr,
- };
-
- void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths)
- {
- const ParsedArguments options = args.parse_arguments(COMMAND_STRUCTURE);
- const bool full_description = Util::Sets::contains(options.switches, OPTION_FULLDESC);
- const bool enable_json = Util::Sets::contains(options.switches, OPTION_JSON);
-
- PathsPortFileProvider provider(paths, args.overlay_ports);
- auto source_paragraphs =
- Util::fmap(provider.load_all_control_files(),
- [](auto&& port) -> const SourceControlFile* { return port->source_control_file.get(); });
-
- if (args.command_arguments.empty())
- {
- if (enable_json)
- {
- do_print_json(source_paragraphs);
- }
- else
- {
- for (const auto& source_control_file : source_paragraphs)
- {
- do_print(*source_control_file->core_paragraph, full_description);
- for (auto&& feature_paragraph : source_control_file->feature_paragraphs)
- {
- do_print(source_control_file->core_paragraph->name, *feature_paragraph, full_description);
- }
- }
- }
- }
- else
- {
- // At this point there is 1 argument
- auto&& args_zero = args.command_arguments[0];
- const auto contained_in = [&args_zero](const auto& s) {
- return Strings::case_insensitive_ascii_contains(s, args_zero);
- };
- for (const auto& source_control_file : source_paragraphs)
- {
- auto&& sp = *source_control_file->core_paragraph;
-
- bool found_match = contained_in(sp.name);
- if (!found_match)
- {
- found_match = std::any_of(sp.description.begin(), sp.description.end(), contained_in);
- }
-
- if (found_match)
- {
- do_print(sp, full_description);
- }
-
- for (auto&& feature_paragraph : source_control_file->feature_paragraphs)
- {
- bool found_match_for_feature = found_match;
- if (!found_match_for_feature)
- {
- found_match_for_feature = contained_in(feature_paragraph->name);
- }
- if (!found_match_for_feature)
- {
- found_match_for_feature = std::any_of(
- feature_paragraph->description.begin(), feature_paragraph->description.end(), contained_in);
- }
-
- if (found_match_for_feature)
- {
- do_print(sp.name, *feature_paragraph, full_description);
- }
- }
- }
- }
-
- if (!enable_json)
- {
- System::print2(
- "\nIf your library is not listed, please open an issue at and/or consider making a pull request:\n"
- " https://github.com/Microsoft/vcpkg/issues\n");
- }
-
- Checks::exit_success(VCPKG_LINE_INFO);
- }
-
- void SearchCommand::perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) const
- {
- Search::perform_and_exit(args, paths);
- }
-}
diff --git a/toolsrc/src/vcpkg/commands.setinstalled.cpp b/toolsrc/src/vcpkg/commands.setinstalled.cpp
deleted file mode 100644
index 28eee6992..000000000
--- a/toolsrc/src/vcpkg/commands.setinstalled.cpp
+++ /dev/null
@@ -1,176 +0,0 @@
-#include <vcpkg/base/system.print.h>
-
-#include <vcpkg/binarycaching.h>
-#include <vcpkg/commands.setinstalled.h>
-#include <vcpkg/globalstate.h>
-#include <vcpkg/help.h>
-#include <vcpkg/input.h>
-#include <vcpkg/install.h>
-#include <vcpkg/metrics.h>
-#include <vcpkg/portfileprovider.h>
-#include <vcpkg/remove.h>
-#include <vcpkg/vcpkgcmdarguments.h>
-#include <vcpkg/vcpkglib.h>
-
-namespace vcpkg::Commands::SetInstalled
-{
- static constexpr StringLiteral OPTION_DRY_RUN = "dry-run";
- static constexpr StringLiteral OPTION_WRITE_PACKAGES_CONFIG = "x-write-nuget-packages-config";
-
- static constexpr CommandSwitch INSTALL_SWITCHES[] = {
- {OPTION_DRY_RUN, "Do not actually build or install"},
- };
- static constexpr CommandSetting INSTALL_SETTINGS[] = {
- {OPTION_WRITE_PACKAGES_CONFIG,
- "Writes out a NuGet packages.config-formatted file for use with external binary caching.\n"
- "See `vcpkg help binarycaching` for more information."},
- };
-
- const CommandStructure COMMAND_STRUCTURE = {
- create_example_string(R"(x-set-installed <package>...)"),
- 0,
- SIZE_MAX,
- {INSTALL_SWITCHES, INSTALL_SETTINGS},
- nullptr,
- };
-
- void perform_and_exit_ex(const VcpkgCmdArguments& args,
- const VcpkgPaths& paths,
- const PortFileProvider::PathsPortFileProvider& provider,
- IBinaryProvider& binary_provider,
- const CMakeVars::CMakeVarProvider& cmake_vars,
- Dependencies::ActionPlan action_plan,
- DryRun dry_run,
- const Optional<fs::path>& maybe_pkgsconfig)
- {
- cmake_vars.load_tag_vars(action_plan, provider);
- Build::compute_all_abis(paths, action_plan, cmake_vars, {});
-
- std::set<std::string> all_abis;
-
- for (const auto& action : action_plan.install_actions)
- {
- all_abis.insert(action.abi_info.value_or_exit(VCPKG_LINE_INFO).package_abi);
- }
-
- // currently (or once) installed specifications
- auto status_db = database_load_check(paths);
- std::vector<PackageSpec> specs_to_remove;
- std::set<PackageSpec> specs_installed;
- for (auto&& status_pgh : status_db)
- {
- if (!status_pgh->is_installed()) continue;
- if (status_pgh->package.is_feature()) continue;
-
- const auto& abi = status_pgh->package.abi;
- if (abi.empty() || !Util::Sets::contains(all_abis, abi))
- {
- specs_to_remove.push_back(status_pgh->package.spec);
- }
- else
- {
- specs_installed.emplace(status_pgh->package.spec);
- }
- }
-
- action_plan.remove_actions = Dependencies::create_remove_plan(specs_to_remove, status_db);
-
- for (const auto& action : action_plan.remove_actions)
- {
- // This should not technically be needed, however ensuring that all specs to be removed are not included in
- // `specs_installed` acts as a sanity check
- specs_installed.erase(action.spec);
- }
-
- Util::erase_remove_if(action_plan.install_actions, [&](const Dependencies::InstallPlanAction& ipa) {
- return Util::Sets::contains(specs_installed, ipa.spec);
- });
-
- Dependencies::print_plan(action_plan, true, paths.builtin_ports_directory());
-
- if (auto p_pkgsconfig = maybe_pkgsconfig.get())
- {
- Build::compute_all_abis(paths, action_plan, cmake_vars, status_db);
- auto& fs = paths.get_filesystem();
- auto pkgsconfig_path = Files::combine(paths.original_cwd, *p_pkgsconfig);
- auto pkgsconfig_contents = generate_nuget_packages_config(action_plan);
- fs.write_contents(pkgsconfig_path, pkgsconfig_contents, VCPKG_LINE_INFO);
- System::print2("Wrote NuGet packages config information to ", fs::u8string(pkgsconfig_path), "\n");
- }
-
- if (dry_run == DryRun::Yes)
- {
- Checks::exit_success(VCPKG_LINE_INFO);
- }
-
- const auto summary = Install::perform(args,
- action_plan,
- Install::KeepGoing::NO,
- paths,
- status_db,
- args.binary_caching_enabled() ? binary_provider : null_binary_provider(),
- Build::null_build_logs_recorder(),
- cmake_vars);
-
- System::print2("\nTotal elapsed time: ", summary.total_elapsed_time, "\n\n");
-
- Checks::exit_success(VCPKG_LINE_INFO);
- }
-
- void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, Triplet default_triplet)
- {
- // input sanitization
- const ParsedArguments options = args.parse_arguments(COMMAND_STRUCTURE);
-
- const std::vector<FullPackageSpec> specs = Util::fmap(args.command_arguments, [&](auto&& arg) {
- return Input::check_and_get_full_package_spec(
- std::string(arg), default_triplet, COMMAND_STRUCTURE.example_text);
- });
-
- for (auto&& spec : specs)
- {
- Input::check_triplet(spec.package_spec.triplet(), paths);
- }
-
- auto binary_provider = create_binary_provider_from_configs(args.binary_sources).value_or_exit(VCPKG_LINE_INFO);
-
- const bool dry_run = Util::Sets::contains(options.switches, OPTION_DRY_RUN);
-
- PortFileProvider::PathsPortFileProvider provider(paths, args.overlay_ports);
- auto cmake_vars = CMakeVars::make_triplet_cmake_var_provider(paths);
-
- Optional<fs::path> pkgsconfig;
- auto it_pkgsconfig = options.settings.find(OPTION_WRITE_PACKAGES_CONFIG);
- if (it_pkgsconfig != options.settings.end())
- {
- Metrics::g_metrics.lock()->track_property("x-write-nuget-packages-config", "defined");
- pkgsconfig = it_pkgsconfig->second;
- }
-
- // We have a set of user-requested specs.
- // We need to know all the specs which are required to fulfill dependencies for those specs.
- // Therefore, we see what we would install into an empty installed tree, so we can use the existing code.
- auto action_plan = Dependencies::create_feature_install_plan(provider, *cmake_vars, specs, {});
-
- for (auto&& action : action_plan.install_actions)
- {
- action.build_options = Build::default_build_package_options;
- }
-
- perform_and_exit_ex(args,
- paths,
- provider,
- *binary_provider,
- *cmake_vars,
- std::move(action_plan),
- dry_run ? DryRun::Yes : DryRun::No,
- pkgsconfig);
- }
-
- void SetInstalledCommand::perform_and_exit(const VcpkgCmdArguments& args,
- const VcpkgPaths& paths,
- Triplet default_triplet) const
- {
- SetInstalled::perform_and_exit(args, paths, default_triplet);
- }
-}
diff --git a/toolsrc/src/vcpkg/commands.upgrade.cpp b/toolsrc/src/vcpkg/commands.upgrade.cpp
deleted file mode 100644
index 2d25be455..000000000
--- a/toolsrc/src/vcpkg/commands.upgrade.cpp
+++ /dev/null
@@ -1,210 +0,0 @@
-#include <vcpkg/base/system.print.h>
-#include <vcpkg/base/util.h>
-
-#include <vcpkg/binarycaching.h>
-#include <vcpkg/cmakevars.h>
-#include <vcpkg/commands.upgrade.h>
-#include <vcpkg/dependencies.h>
-#include <vcpkg/globalstate.h>
-#include <vcpkg/help.h>
-#include <vcpkg/input.h>
-#include <vcpkg/install.h>
-#include <vcpkg/portfileprovider.h>
-#include <vcpkg/statusparagraphs.h>
-#include <vcpkg/update.h>
-#include <vcpkg/vcpkgcmdarguments.h>
-#include <vcpkg/vcpkglib.h>
-
-namespace vcpkg::Commands::Upgrade
-{
- using Install::KeepGoing;
- using Install::to_keep_going;
-
- static constexpr StringLiteral OPTION_NO_DRY_RUN = "no-dry-run";
- static constexpr StringLiteral OPTION_KEEP_GOING = "keep-going";
-
- static constexpr std::array<CommandSwitch, 2> INSTALL_SWITCHES = {{
- {OPTION_NO_DRY_RUN, "Actually upgrade"},
- {OPTION_KEEP_GOING, "Continue installing packages on failure"},
- }};
-
- const CommandStructure COMMAND_STRUCTURE = {
- create_example_string("upgrade --no-dry-run"),
- 0,
- SIZE_MAX,
- {INSTALL_SWITCHES, {}},
- nullptr,
- };
-
- void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, Triplet default_triplet)
- {
- const ParsedArguments options = args.parse_arguments(COMMAND_STRUCTURE);
-
- const bool no_dry_run = Util::Sets::contains(options.switches, OPTION_NO_DRY_RUN);
- const KeepGoing keep_going = to_keep_going(Util::Sets::contains(options.switches, OPTION_KEEP_GOING));
-
- auto binaryprovider = create_binary_provider_from_configs(args.binary_sources).value_or_exit(VCPKG_LINE_INFO);
-
- StatusParagraphs status_db = database_load_check(paths);
-
- // Load ports from ports dirs
- PortFileProvider::PathsPortFileProvider provider(paths, args.overlay_ports);
- auto var_provider_storage = CMakeVars::make_triplet_cmake_var_provider(paths);
- auto& var_provider = *var_provider_storage;
-
- // input sanitization
- const std::vector<PackageSpec> specs = Util::fmap(args.command_arguments, [&](auto&& arg) {
- return Input::check_and_get_package_spec(std::string(arg), default_triplet, COMMAND_STRUCTURE.example_text);
- });
-
- for (auto&& spec : specs)
- {
- Input::check_triplet(spec.triplet(), paths);
- }
-
- Dependencies::ActionPlan action_plan;
- if (specs.empty())
- {
- // If no packages specified, upgrade all outdated packages.
- auto outdated_packages = Update::find_outdated_packages(provider, status_db);
-
- if (outdated_packages.empty())
- {
- System::print2("All installed packages are up-to-date with the local portfiles.\n");
- Checks::exit_success(VCPKG_LINE_INFO);
- }
-
- action_plan = Dependencies::create_upgrade_plan(
- provider,
- var_provider,
- Util::fmap(outdated_packages, [](const Update::OutdatedPackage& package) { return package.spec; }),
- status_db);
- }
- else
- {
- std::vector<PackageSpec> not_installed;
- std::vector<PackageSpec> no_control_file;
- std::vector<PackageSpec> to_upgrade;
- std::vector<PackageSpec> up_to_date;
-
- for (auto&& spec : specs)
- {
- bool skip_version_check = false;
- auto installed_status = status_db.find_installed(spec);
- if (installed_status == status_db.end())
- {
- not_installed.push_back(spec);
- skip_version_check = true;
- }
-
- auto maybe_control_file = provider.get_control_file(spec.name());
- if (!maybe_control_file.has_value())
- {
- no_control_file.push_back(spec);
- skip_version_check = true;
- }
-
- if (skip_version_check) continue;
-
- const auto& control_file = maybe_control_file.value_or_exit(VCPKG_LINE_INFO);
- const auto& control_paragraph = *control_file.source_control_file->core_paragraph;
- auto control_version = VersionT(control_paragraph.version, control_paragraph.port_version);
- const auto& installed_paragraph = (*installed_status)->package;
- auto installed_version = VersionT(installed_paragraph.version, installed_paragraph.port_version);
- if (control_version == installed_version)
- {
- up_to_date.push_back(spec);
- }
- else
- {
- to_upgrade.push_back(spec);
- }
- }
-
- Util::sort(not_installed);
- Util::sort(no_control_file);
- Util::sort(up_to_date);
- Util::sort(to_upgrade);
-
- if (!up_to_date.empty())
- {
- System::print2(System::Color::success, "The following packages are up-to-date:\n");
- System::print2(Strings::join("",
- up_to_date,
- [](const PackageSpec& spec) { return " " + spec.to_string() + "\n"; }),
- '\n');
- }
-
- if (!not_installed.empty())
- {
- System::print2(System::Color::error, "The following packages are not installed:\n");
- System::print2(Strings::join("",
- not_installed,
- [](const PackageSpec& spec) { return " " + spec.to_string() + "\n"; }),
- '\n');
- }
-
- if (!no_control_file.empty())
- {
- System::print2(System::Color::error,
- "The following packages do not have a valid CONTROL or vcpkg.json:\n");
- System::print2(Strings::join("",
- no_control_file,
- [](const PackageSpec& spec) { return " " + spec.to_string() + "\n"; }),
- '\n');
- }
-
- Checks::check_exit(VCPKG_LINE_INFO, not_installed.empty() && no_control_file.empty());
-
- if (to_upgrade.empty()) Checks::exit_success(VCPKG_LINE_INFO);
-
- action_plan = Dependencies::create_upgrade_plan(provider, var_provider, to_upgrade, status_db);
- }
-
- Checks::check_exit(VCPKG_LINE_INFO, !action_plan.empty());
-
- // Set build settings for all install actions
- for (auto&& action : action_plan.install_actions)
- {
- action.build_options = vcpkg::Build::default_build_package_options;
- }
-
- Dependencies::print_plan(action_plan, true, paths.builtin_ports_directory());
-
- if (!no_dry_run)
- {
- System::print2(System::Color::warning,
- "If you are sure you want to rebuild the above packages, run this command with the "
- "--no-dry-run option.\n");
- Checks::exit_fail(VCPKG_LINE_INFO);
- }
-
- var_provider.load_tag_vars(action_plan, provider);
-
- const Install::InstallSummary summary =
- Install::perform(args,
- action_plan,
- keep_going,
- paths,
- status_db,
- args.binary_caching_enabled() ? *binaryprovider : null_binary_provider(),
- Build::null_build_logs_recorder(),
- var_provider);
-
- System::print2("\nTotal elapsed time: ", summary.total_elapsed_time, "\n\n");
-
- if (keep_going == KeepGoing::YES)
- {
- summary.print();
- }
-
- Checks::exit_success(VCPKG_LINE_INFO);
- }
-
- void UpgradeCommand::perform_and_exit(const VcpkgCmdArguments& args,
- const VcpkgPaths& paths,
- Triplet default_triplet) const
- {
- Upgrade::perform_and_exit(args, paths, default_triplet);
- }
-}
diff --git a/toolsrc/src/vcpkg/commands.upload-metrics.cpp b/toolsrc/src/vcpkg/commands.upload-metrics.cpp
deleted file mode 100644
index acf5a5377..000000000
--- a/toolsrc/src/vcpkg/commands.upload-metrics.cpp
+++ /dev/null
@@ -1,29 +0,0 @@
-#include <vcpkg/commands.upload-metrics.h>
-
-#if defined(_WIN32)
-#include <vcpkg/base/checks.h>
-#include <vcpkg/base/files.h>
-
-#include <vcpkg/metrics.h>
-#include <vcpkg/vcpkgcmdarguments.h>
-
-using namespace vcpkg;
-
-namespace vcpkg::Commands::UploadMetrics
-{
- const CommandStructure COMMAND_STRUCTURE = {
- create_example_string("x-upload-metrics metrics.txt"),
- 1,
- 1,
- };
-
- void UploadMetricsCommand::perform_and_exit(const VcpkgCmdArguments& args, Files::Filesystem& fs) const
- {
- (void)args.parse_arguments(COMMAND_STRUCTURE);
- const auto& payload_path = args.command_arguments[0];
- auto payload = fs.read_contents(payload_path).value_or_exit(VCPKG_LINE_INFO);
- Metrics::g_metrics.lock()->upload(payload);
- Checks::exit_success(VCPKG_LINE_INFO);
- }
-}
-#endif // defined(_WIN32)
diff --git a/toolsrc/src/vcpkg/commands.version.cpp b/toolsrc/src/vcpkg/commands.version.cpp
deleted file mode 100644
index 5ee8e270e..000000000
--- a/toolsrc/src/vcpkg/commands.version.cpp
+++ /dev/null
@@ -1,60 +0,0 @@
-#include <vcpkg/base/system.print.h>
-
-#include <vcpkg/commands.version.h>
-#include <vcpkg/help.h>
-#include <vcpkg/metrics.h>
-#include <vcpkg/vcpkgcmdarguments.h>
-#include <vcpkg/vcpkgpaths.h>
-
-#define STRINGIFY(...) #__VA_ARGS__
-#define MACRO_TO_STRING(X) STRINGIFY(X)
-
-#if !defined(VCPKG_VERSION)
-#error VCPKG_VERSION must be defined
-#endif
-
-#define VCPKG_VERSION_AS_STRING MACRO_TO_STRING(VCPKG_VERSION)
-
-#if !defined(VCPKG_BASE_VERSION)
-#error VCPKG_BASE_VERSION must be defined
-#endif
-
-#define VCPKG_BASE_VERSION_AS_STRING MACRO_TO_STRING(VCPKG_BASE_VERSION)
-
-namespace vcpkg::Commands::Version
-{
- const char* base_version() noexcept { return VCPKG_BASE_VERSION_AS_STRING; }
-
- const char* version() noexcept
- {
- return VCPKG_BASE_VERSION_AS_STRING "-" VCPKG_VERSION_AS_STRING
-#ifndef NDEBUG
- "-debug"
-#endif
- ;
- }
-
- const CommandStructure COMMAND_STRUCTURE = {
- create_example_string("version"),
- 0,
- 0,
- {},
- nullptr,
- };
-
- void perform_and_exit(const VcpkgCmdArguments& args, Files::Filesystem&)
- {
- (void)args.parse_arguments(COMMAND_STRUCTURE);
- System::print2("Vcpkg package management program version ",
- version(),
- "\n"
- "\n"
- "See LICENSE.txt for license information.\n");
- Checks::exit_success(VCPKG_LINE_INFO);
- }
-
- void VersionCommand::perform_and_exit(const VcpkgCmdArguments& args, Files::Filesystem& fs) const
- {
- Version::perform_and_exit(args, fs);
- }
-}
diff --git a/toolsrc/src/vcpkg/commands.xvsinstances.cpp b/toolsrc/src/vcpkg/commands.xvsinstances.cpp
deleted file mode 100644
index 67f35f542..000000000
--- a/toolsrc/src/vcpkg/commands.xvsinstances.cpp
+++ /dev/null
@@ -1,41 +0,0 @@
-#include <vcpkg/base/system.print.h>
-
-#include <vcpkg/commands.xvsinstances.h>
-#include <vcpkg/help.h>
-#include <vcpkg/vcpkgcmdarguments.h>
-#include <vcpkg/visualstudio.h>
-
-namespace vcpkg::Commands::X_VSInstances
-{
- const CommandStructure COMMAND_STRUCTURE = {
- create_example_string("x-vsinstances"),
- 0,
- 0,
- {{}, {}},
- nullptr,
- };
-
- void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths)
- {
-#if defined(_WIN32)
- const ParsedArguments parsed_args = args.parse_arguments(COMMAND_STRUCTURE);
-
- const auto instances = vcpkg::VisualStudio::get_visual_studio_instances(paths);
- for (const std::string& instance : instances)
- {
- System::print2(instance, '\n');
- }
-
- Checks::exit_success(VCPKG_LINE_INFO);
-#else
- (void)args;
- (void)paths;
- Checks::exit_with_message(VCPKG_LINE_INFO, "This command is not supported on non-windows platforms.");
-#endif
- }
-
- void VSInstancesCommand::perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) const
- {
- X_VSInstances::perform_and_exit(args, paths);
- }
-}
diff --git a/toolsrc/src/vcpkg/configuration.cpp b/toolsrc/src/vcpkg/configuration.cpp
deleted file mode 100644
index 3fa02876f..000000000
--- a/toolsrc/src/vcpkg/configuration.cpp
+++ /dev/null
@@ -1,84 +0,0 @@
-#include <vcpkg/base/jsonreader.h>
-#include <vcpkg/base/system.print.h>
-
-#include <vcpkg/configuration.h>
-#include <vcpkg/vcpkgcmdarguments.h>
-
-namespace
-{
- using namespace vcpkg;
-
- struct ConfigurationDeserializer final : Json::IDeserializer<Configuration>
- {
- virtual StringView type_name() const override { return "a configuration object"; }
-
- constexpr static StringLiteral DEFAULT_REGISTRY = "default-registry";
- constexpr static StringLiteral REGISTRIES = "registries";
- virtual View<StringView> valid_fields() const override
- {
- constexpr static StringView t[] = {DEFAULT_REGISTRY, REGISTRIES};
- return t;
- }
-
- virtual Optional<Configuration> visit_object(Json::Reader& r, const Json::Object& obj) override;
-
- ConfigurationDeserializer(const fs::path& configuration_directory);
-
- private:
- fs::path configuration_directory;
- };
-
- constexpr StringLiteral ConfigurationDeserializer::DEFAULT_REGISTRY;
- constexpr StringLiteral ConfigurationDeserializer::REGISTRIES;
-
- Optional<Configuration> ConfigurationDeserializer::visit_object(Json::Reader& r, const Json::Object& obj)
- {
- RegistrySet registries;
-
- auto impl_des = get_registry_implementation_deserializer(configuration_directory);
-
- std::unique_ptr<RegistryImplementation> default_registry;
- if (r.optional_object_field(obj, DEFAULT_REGISTRY, default_registry, *impl_des))
- {
- registries.set_default_registry(std::move(default_registry));
- }
-
- auto reg_des = get_registry_array_deserializer(configuration_directory);
- std::vector<Registry> regs;
- r.optional_object_field(obj, REGISTRIES, regs, *reg_des);
-
- for (Registry& reg : regs)
- {
- registries.add_registry(std::move(reg));
- }
-
- return Configuration{std::move(registries)};
- }
-
- ConfigurationDeserializer::ConfigurationDeserializer(const fs::path& configuration_directory)
- : configuration_directory(configuration_directory)
- {
- }
-
-}
-
-std::unique_ptr<Json::IDeserializer<Configuration>> vcpkg::make_configuration_deserializer(
- const fs::path& config_directory)
-{
- return std::make_unique<ConfigurationDeserializer>(config_directory);
-}
-
-namespace vcpkg
-{
- void Configuration::validate_feature_flags(const FeatureFlagSettings& flags)
- {
- if (!flags.registries && registry_set.has_modifications())
- {
- System::printf(System::Color::warning,
- "Warning: configuration specified the \"registries\" or \"default-registries\" field, but "
- "the %s feature flag was not enabled.\n",
- VcpkgCmdArguments::REGISTRIES_FEATURE);
- registry_set = RegistrySet();
- }
- }
-}
diff --git a/toolsrc/src/vcpkg/dependencies.cpp b/toolsrc/src/vcpkg/dependencies.cpp
deleted file mode 100644
index aafdec065..000000000
--- a/toolsrc/src/vcpkg/dependencies.cpp
+++ /dev/null
@@ -1,1896 +0,0 @@
-#include <vcpkg/base/files.h>
-#include <vcpkg/base/graphs.h>
-#include <vcpkg/base/strings.h>
-#include <vcpkg/base/util.h>
-
-#include <vcpkg/cmakevars.h>
-#include <vcpkg/dependencies.h>
-#include <vcpkg/packagespec.h>
-#include <vcpkg/paragraphs.h>
-#include <vcpkg/portfileprovider.h>
-#include <vcpkg/statusparagraphs.h>
-#include <vcpkg/vcpkglib.h>
-#include <vcpkg/vcpkgpaths.h>
-
-using namespace vcpkg;
-
-namespace vcpkg::Dependencies
-{
- namespace
- {
- struct ClusterInstalled
- {
- ClusterInstalled(const InstalledPackageView& ipv) : ipv(ipv)
- {
- original_features.emplace("core");
- for (auto&& feature : ipv.features)
- {
- original_features.emplace(feature->package.feature);
- }
- }
-
- InstalledPackageView ipv;
- std::unordered_set<PackageSpec> remove_edges;
- std::unordered_set<std::string> original_features;
-
- // Tracks whether an incoming request has asked for the default features -- on reinstall, add them
- bool defaults_requested = false;
- };
-
- struct ClusterInstallInfo
- {
- std::map<std::string, std::vector<FeatureSpec>> build_edges;
- bool defaults_requested = false;
- };
-
- /// <summary>
- /// Representation of a package and its features in a ClusterGraph.
- /// </summary>
- struct Cluster : Util::MoveOnlyBase
- {
- Cluster(const InstalledPackageView& ipv, ExpectedS<const SourceControlFileLocation&>&& scfl)
- : m_spec(ipv.spec()), m_scfl(std::move(scfl)), m_installed(ipv)
- {
- }
-
- Cluster(const PackageSpec& spec, const SourceControlFileLocation& scfl) : m_spec(spec), m_scfl(scfl) { }
-
- bool has_feature_installed(const std::string& feature) const
- {
- if (const ClusterInstalled* inst = m_installed.get())
- {
- return inst->original_features.find(feature) != inst->original_features.end();
- }
- return false;
- }
-
- bool has_defaults_installed() const
- {
- if (const ClusterInstalled* inst = m_installed.get())
- {
- return std::all_of(inst->ipv.core->package.default_features.begin(),
- inst->ipv.core->package.default_features.end(),
- [&](const std::string& feature) {
- return inst->original_features.find(feature) !=
- inst->original_features.end();
- });
- }
- return false;
- }
-
- // Returns dependencies which were added as a result of this call.
- // Precondition: must have called "mark_for_reinstall()" or "create_install_info()" on this cluster
- void add_feature(const std::string& feature,
- const CMakeVars::CMakeVarProvider& var_provider,
- std::vector<FeatureSpec>& out_new_dependencies)
- {
- ClusterInstallInfo& info = m_install_info.value_or_exit(VCPKG_LINE_INFO);
- if (feature == "default")
- {
- if (!info.defaults_requested)
- {
- info.defaults_requested = true;
- for (auto&& f : get_scfl_or_exit().source_control_file->core_paragraph->default_features)
- out_new_dependencies.emplace_back(m_spec, f);
- }
- return;
- }
-
- if (Util::Sets::contains(info.build_edges, feature))
- {
- // This feature has already been completely handled
- return;
- }
- auto maybe_vars = var_provider.get_dep_info_vars(m_spec);
- const std::vector<Dependency>* qualified_deps =
- &get_scfl_or_exit().source_control_file->find_dependencies_for_feature(feature).value_or_exit(
- VCPKG_LINE_INFO);
-
- std::vector<FeatureSpec> dep_list;
- if (auto vars = maybe_vars.get())
- {
- // Qualified dependency resolution is available
- auto fullspec_list = filter_dependencies(*qualified_deps, m_spec.triplet(), *vars);
-
- for (auto&& fspec : fullspec_list)
- {
- Util::Vectors::append(&dep_list, fspec.to_feature_specs({"default"}, {"default"}));
- }
-
- Util::sort_unique_erase(dep_list);
- info.build_edges.emplace(feature, dep_list);
- }
- else
- {
- bool requires_qualified_resolution = false;
- for (const Dependency& dep : *qualified_deps)
- {
- if (dep.platform.is_empty())
- {
- Util::Vectors::append(&dep_list,
- FullPackageSpec({dep.name, m_spec.triplet()}, dep.features)
- .to_feature_specs({"default"}, {"default"}));
- }
- else
- {
- requires_qualified_resolution = true;
- }
- }
- Util::sort_unique_erase(dep_list);
- if (!requires_qualified_resolution)
- {
- info.build_edges.emplace(feature, dep_list);
- }
- }
- Util::Vectors::append(&out_new_dependencies, dep_list);
- }
-
- void create_install_info(std::vector<FeatureSpec>& out_reinstall_requirements)
- {
- bool defaults_requested = false;
- if (const ClusterInstalled* inst = m_installed.get())
- {
- for (const std::string& installed_feature : inst->original_features)
- {
- out_reinstall_requirements.emplace_back(m_spec, installed_feature);
- }
- defaults_requested = inst->defaults_requested;
- }
-
- Checks::check_exit(VCPKG_LINE_INFO, !m_install_info.has_value());
- m_install_info = make_optional(ClusterInstallInfo{});
-
- if (defaults_requested)
- {
- for (auto&& def_feature : get_scfl_or_exit().source_control_file->core_paragraph->default_features)
- out_reinstall_requirements.emplace_back(m_spec, def_feature);
- }
- else if (request_type != RequestType::USER_REQUESTED)
- {
- // If the user did not explicitly request this installation, we need to add all new default features
- auto&& new_defaults = get_scfl_or_exit().source_control_file->core_paragraph->default_features;
- std::set<std::string> defaults_set{new_defaults.begin(), new_defaults.end()};
-
- // Install only features that were not previously available
- if (auto p_inst = m_installed.get())
- {
- for (auto&& prev_default : p_inst->ipv.core->package.default_features)
- {
- defaults_set.erase(prev_default);
- }
- }
-
- for (const std::string& feature : defaults_set)
- {
- // Instead of dealing with adding default features to each of our dependencies right
- // away we just defer to the next pass of the loop.
- out_reinstall_requirements.emplace_back(m_spec, feature);
- }
- }
- }
-
- const SourceControlFileLocation& get_scfl_or_exit() const
- {
-#if defined(_WIN32)
- static auto vcpkg_remove_cmd = ".\\vcpkg";
-#else
- static auto vcpkg_remove_cmd = "./vcpkg";
-#endif
- if (!m_scfl)
- {
- Checks::exit_maybe_upgrade(
- VCPKG_LINE_INFO,
- "Error: while loading control file for %s: %s.\nPlease run \"%s remove %s\" and re-attempt.",
- m_spec,
- m_scfl.error(),
- vcpkg_remove_cmd,
- m_spec);
- }
-
- return *m_scfl.get();
- }
-
- PackageSpec m_spec;
- ExpectedS<const SourceControlFileLocation&> m_scfl;
-
- Optional<ClusterInstalled> m_installed;
- Optional<ClusterInstallInfo> m_install_info;
-
- RequestType request_type = RequestType::AUTO_SELECTED;
- };
-
- struct PackageGraph
- {
- PackageGraph(const PortFileProvider::PortFileProvider& provider,
- const CMakeVars::CMakeVarProvider& var_provider,
- const StatusParagraphs& status_db);
- ~PackageGraph();
-
- void install(Span<const FeatureSpec> specs);
- void upgrade(Span<const PackageSpec> specs);
- void mark_user_requested(const PackageSpec& spec);
-
- ActionPlan serialize(const CreateInstallPlanOptions& options = {}) const;
-
- void mark_for_reinstall(const PackageSpec& spec, std::vector<FeatureSpec>& out_reinstall_requirements);
- const CMakeVars::CMakeVarProvider& m_var_provider;
-
- std::unique_ptr<ClusterGraph> m_graph;
- };
-
- }
-
- /// <summary>
- /// Directional graph representing a collection of packages with their features connected by their dependencies.
- /// </summary>
- struct ClusterGraph : Util::MoveOnlyBase
- {
- explicit ClusterGraph(const PortFileProvider::PortFileProvider& port_provider) : m_port_provider(port_provider)
- {
- }
-
- /// <summary>
- /// Find the cluster associated with spec or if not found, create it from the PortFileProvider.
- /// </summary>
- /// <param name="spec">Package spec to get the cluster for.</param>
- /// <returns>The cluster found or created for spec.</returns>
- Cluster& get(const PackageSpec& spec)
- {
- auto it = m_graph.find(spec);
- if (it == m_graph.end())
- {
- const SourceControlFileLocation* scfl = m_port_provider.get_control_file(spec.name()).get();
-
- Checks::check_maybe_upgrade(
- VCPKG_LINE_INFO, scfl, "Error: Cannot find definition for package `%s`.", spec.name());
-
- return m_graph
- .emplace(std::piecewise_construct, std::forward_as_tuple(spec), std::forward_as_tuple(spec, *scfl))
- .first->second;
- }
-
- return it->second;
- }
-
- Cluster& get(const InstalledPackageView& ipv)
- {
- auto it = m_graph.find(ipv.spec());
-
- if (it == m_graph.end())
- {
- ExpectedS<const SourceControlFileLocation&> maybe_scfl =
- m_port_provider.get_control_file(ipv.spec().name());
-
- return m_graph
- .emplace(std::piecewise_construct,
- std::forward_as_tuple(ipv.spec()),
- std::forward_as_tuple(ipv, std::move(maybe_scfl)))
- .first->second;
- }
-
- if (!it->second.m_installed)
- {
- it->second.m_installed = {ipv};
- }
-
- return it->second;
- }
-
- const Cluster& find_or_exit(const PackageSpec& spec, LineInfo linfo) const
- {
- auto it = m_graph.find(spec);
- Checks::check_maybe_upgrade(linfo, it != m_graph.end(), "Failed to locate spec in graph");
- return it->second;
- }
-
- auto begin() const { return m_graph.begin(); }
- auto end() const { return m_graph.end(); }
-
- private:
- std::map<PackageSpec, Cluster> m_graph;
- const PortFileProvider::PortFileProvider& m_port_provider;
- };
-
- static std::string to_output_string(RequestType request_type,
- const CStringView s,
- const Build::BuildPackageOptions& options,
- const SourceControlFileLocation* scfl,
- const InstalledPackageView* ipv,
- const fs::path& builtin_ports_dir)
- {
- std::string ret;
- switch (request_type)
- {
- case RequestType::AUTO_SELECTED: Strings::append(ret, " * "); break;
- case RequestType::USER_REQUESTED: Strings::append(ret, " "); break;
- default: Checks::unreachable(VCPKG_LINE_INFO);
- }
- Strings::append(ret, s);
- if (scfl)
- {
- Strings::append(ret, " -> ", scfl->to_versiont());
- }
- else if (ipv)
- {
- Strings::append(ret, " -> ", VersionT{ipv->core->package.version, ipv->core->package.port_version});
- }
- if (options.use_head_version == Build::UseHeadVersion::YES)
- {
- Strings::append(ret, " (+HEAD)");
- }
- if (scfl)
- {
- const auto s_install_port_path = fs::u8string(scfl->source_location);
- if (!builtin_ports_dir.empty() &&
- !Strings::case_insensitive_ascii_starts_with(s_install_port_path, fs::u8string(builtin_ports_dir)))
- {
- Strings::append(ret, " -- ", s_install_port_path);
- }
- }
- return ret;
- }
-
- std::string to_output_string(RequestType request_type,
- const CStringView s,
- const Build::BuildPackageOptions& options)
- {
- return to_output_string(request_type, s, options, {}, {}, {});
- }
-
- std::string to_output_string(RequestType request_type, const CStringView s)
- {
- return to_output_string(request_type, s, {}, {}, {}, {});
- }
-
- InstallPlanAction::InstallPlanAction() noexcept
- : plan_type(InstallPlanType::UNKNOWN), request_type(RequestType::UNKNOWN), build_options{}
- {
- }
-
- InstallPlanAction::InstallPlanAction(const PackageSpec& spec,
- const SourceControlFileLocation& scfl,
- const RequestType& request_type,
- std::map<std::string, std::vector<FeatureSpec>>&& dependencies)
- : spec(spec)
- , source_control_file_location(scfl)
- , plan_type(InstallPlanType::BUILD_AND_INSTALL)
- , request_type(request_type)
- , build_options{}
- , feature_dependencies(std::move(dependencies))
- {
- for (const auto& kv : feature_dependencies)
- {
- feature_list.emplace_back(kv.first);
- for (const FeatureSpec& fspec : kv.second)
- {
- if (spec != fspec.spec())
- {
- package_dependencies.emplace_back(fspec.spec());
- }
- }
- }
-
- Util::sort_unique_erase(package_dependencies);
- Util::sort_unique_erase(feature_list);
- }
-
- InstallPlanAction::InstallPlanAction(InstalledPackageView&& ipv, const RequestType& request_type)
- : spec(ipv.spec())
- , installed_package(std::move(ipv))
- , plan_type(InstallPlanType::ALREADY_INSTALLED)
- , request_type(request_type)
- , build_options{}
- , feature_dependencies(installed_package.get()->feature_dependencies())
- , package_dependencies(installed_package.get()->dependencies())
- {
- for (const auto& kv : feature_dependencies)
- {
- feature_list.emplace_back(kv.first);
- }
- }
-
- std::string InstallPlanAction::displayname() const
- {
- if (this->feature_list.empty())
- {
- return this->spec.to_string();
- }
-
- const std::string features = Strings::join(",", feature_list);
- return Strings::format("%s[%s]:%s", this->spec.name(), features, this->spec.triplet());
- }
- const std::string& InstallPlanAction::public_abi() const
- {
- switch (plan_type)
- {
- case InstallPlanType::ALREADY_INSTALLED:
- return installed_package.value_or_exit(VCPKG_LINE_INFO).core->package.abi;
- case InstallPlanType::BUILD_AND_INSTALL:
- {
- auto&& i = abi_info.value_or_exit(VCPKG_LINE_INFO);
- if (auto o = i.pre_build_info->public_abi_override.get())
- return *o;
- else
- return i.package_abi;
- }
- default: Checks::unreachable(VCPKG_LINE_INFO);
- }
- }
- bool InstallPlanAction::has_package_abi() const
- {
- if (!abi_info) return false;
- return !abi_info.get()->package_abi.empty();
- }
- Optional<const std::string&> InstallPlanAction::package_abi() const
- {
- if (!abi_info) return nullopt;
- if (abi_info.get()->package_abi.empty()) return nullopt;
- return abi_info.get()->package_abi;
- }
- const Build::PreBuildInfo& InstallPlanAction::pre_build_info(LineInfo linfo) const
- {
- return *abi_info.value_or_exit(linfo).pre_build_info.get();
- }
-
- bool InstallPlanAction::compare_by_name(const InstallPlanAction* left, const InstallPlanAction* right)
- {
- return left->spec.name() < right->spec.name();
- }
-
- RemovePlanAction::RemovePlanAction() noexcept
- : plan_type(RemovePlanType::UNKNOWN), request_type(RequestType::UNKNOWN)
- {
- }
-
- RemovePlanAction::RemovePlanAction(const PackageSpec& spec,
- const RemovePlanType& plan_type,
- const RequestType& request_type)
- : spec(spec), plan_type(plan_type), request_type(request_type)
- {
- }
-
- bool ExportPlanAction::compare_by_name(const ExportPlanAction* left, const ExportPlanAction* right)
- {
- return left->spec.name() < right->spec.name();
- }
-
- ExportPlanAction::ExportPlanAction() noexcept
- : plan_type(ExportPlanType::UNKNOWN), request_type(RequestType::UNKNOWN)
- {
- }
-
- ExportPlanAction::ExportPlanAction(const PackageSpec& spec,
- InstalledPackageView&& installed_package,
- const RequestType& request_type)
- : spec(spec)
- , plan_type(ExportPlanType::ALREADY_BUILT)
- , request_type(request_type)
- , m_installed_package(std::move(installed_package))
- {
- }
-
- ExportPlanAction::ExportPlanAction(const PackageSpec& spec, const RequestType& request_type)
- : spec(spec), plan_type(ExportPlanType::NOT_BUILT), request_type(request_type)
- {
- }
-
- Optional<const BinaryParagraph&> ExportPlanAction::core_paragraph() const
- {
- if (auto p_ip = m_installed_package.get())
- {
- return p_ip->core->package;
- }
- return nullopt;
- }
-
- std::vector<PackageSpec> ExportPlanAction::dependencies() const
- {
- if (auto p_ip = m_installed_package.get())
- return p_ip->dependencies();
- else
- return {};
- }
-
- bool RemovePlanAction::compare_by_name(const RemovePlanAction* left, const RemovePlanAction* right)
- {
- return left->spec.name() < right->spec.name();
- }
-
- std::vector<RemovePlanAction> create_remove_plan(const std::vector<PackageSpec>& specs,
- const StatusParagraphs& status_db)
- {
- struct RemoveAdjacencyProvider final : Graphs::AdjacencyProvider<PackageSpec, RemovePlanAction>
- {
- const StatusParagraphs& status_db;
- const std::vector<InstalledPackageView>& installed_ports;
- const std::unordered_set<PackageSpec>& specs_as_set;
-
- RemoveAdjacencyProvider(const StatusParagraphs& status_db,
- const std::vector<InstalledPackageView>& installed_ports,
- const std::unordered_set<PackageSpec>& specs_as_set)
- : status_db(status_db), installed_ports(installed_ports), specs_as_set(specs_as_set)
- {
- }
-
- std::vector<PackageSpec> adjacency_list(const RemovePlanAction& plan) const override
- {
- if (plan.plan_type == RemovePlanType::NOT_INSTALLED)
- {
- return {};
- }
-
- const PackageSpec& spec = plan.spec;
- std::vector<PackageSpec> dependents;
- for (auto&& ipv : installed_ports)
- {
- auto deps = ipv.dependencies();
-
- if (std::find(deps.begin(), deps.end(), spec) == deps.end()) continue;
-
- dependents.push_back(ipv.spec());
- }
-
- return dependents;
- }
-
- RemovePlanAction load_vertex_data(const PackageSpec& spec) const override
- {
- const RequestType request_type = specs_as_set.find(spec) != specs_as_set.end()
- ? RequestType::USER_REQUESTED
- : RequestType::AUTO_SELECTED;
- const StatusParagraphs::const_iterator it = status_db.find_installed(spec);
- if (it == status_db.end())
- {
- return RemovePlanAction{spec, RemovePlanType::NOT_INSTALLED, request_type};
- }
- return RemovePlanAction{spec, RemovePlanType::REMOVE, request_type};
- }
-
- std::string to_string(const PackageSpec& spec) const override { return spec.to_string(); }
- };
-
- auto installed_ports = get_installed_ports(status_db);
- const std::unordered_set<PackageSpec> specs_as_set(specs.cbegin(), specs.cend());
- return Graphs::topological_sort(
- std::move(specs), RemoveAdjacencyProvider{status_db, installed_ports, specs_as_set}, {});
- }
-
- std::vector<ExportPlanAction> create_export_plan(const std::vector<PackageSpec>& specs,
- const StatusParagraphs& status_db)
- {
- struct ExportAdjacencyProvider final : Graphs::AdjacencyProvider<PackageSpec, ExportPlanAction>
- {
- const StatusParagraphs& status_db;
- const std::unordered_set<PackageSpec>& specs_as_set;
-
- ExportAdjacencyProvider(const StatusParagraphs& s, const std::unordered_set<PackageSpec>& specs_as_set)
- : status_db(s), specs_as_set(specs_as_set)
- {
- }
-
- std::vector<PackageSpec> adjacency_list(const ExportPlanAction& plan) const override
- {
- return plan.dependencies();
- }
-
- ExportPlanAction load_vertex_data(const PackageSpec& spec) const override
- {
- const RequestType request_type = specs_as_set.find(spec) != specs_as_set.end()
- ? RequestType::USER_REQUESTED
- : RequestType::AUTO_SELECTED;
-
- auto maybe_ipv = status_db.get_installed_package_view(spec);
-
- if (auto p_ipv = maybe_ipv.get())
- {
- return ExportPlanAction{spec, std::move(*p_ipv), request_type};
- }
-
- return ExportPlanAction{spec, request_type};
- }
-
- std::string to_string(const PackageSpec& spec) const override { return spec.to_string(); }
- };
-
- const std::unordered_set<PackageSpec> specs_as_set(specs.cbegin(), specs.cend());
- std::vector<ExportPlanAction> toposort =
- Graphs::topological_sort(specs, ExportAdjacencyProvider{status_db, specs_as_set}, {});
- return toposort;
- }
-
- void PackageGraph::mark_user_requested(const PackageSpec& spec)
- {
- m_graph->get(spec).request_type = RequestType::USER_REQUESTED;
- }
-
- // `features` should have "default" instead of missing "core"
- std::vector<FullPackageSpec> resolve_deps_as_top_level(const SourceControlFile& scf,
- Triplet triplet,
- std::vector<std::string> features,
- CMakeVars::CMakeVarProvider& var_provider)
- {
- PackageSpec spec{scf.core_paragraph->name, triplet};
- std::map<std::string, std::vector<std::string>> specs_to_features;
-
- Optional<const PlatformExpression::Context&> ctx_storage = var_provider.get_dep_info_vars(spec);
- auto ctx = [&]() -> const PlatformExpression::Context& {
- if (!ctx_storage)
- {
- var_provider.load_dep_info_vars({&spec, 1});
- ctx_storage = var_provider.get_dep_info_vars(spec);
- }
- return ctx_storage.value_or_exit(VCPKG_LINE_INFO);
- };
-
- auto handle_deps = [&](View<Dependency> deps) {
- for (auto&& dep : deps)
- {
- if (dep.platform.is_empty() || dep.platform.evaluate(ctx()))
- {
- if (dep.name == spec.name())
- Util::Vectors::append(&features, dep.features);
- else
- Util::Vectors::append(&specs_to_features[dep.name], dep.features);
- }
- }
- };
-
- handle_deps(scf.core_paragraph->dependencies);
- enum class State
- {
- NotVisited = 0,
- Visited,
- };
- std::map<std::string, State> feature_state;
- while (!features.empty())
- {
- auto feature = std::move(features.back());
- features.pop_back();
-
- if (feature_state[feature] == State::Visited) continue;
- feature_state[feature] = State::Visited;
- if (feature == "default")
- {
- Util::Vectors::append(&features, scf.core_paragraph->default_features);
- }
- else
- {
- auto it =
- Util::find_if(scf.feature_paragraphs, [&feature](const std::unique_ptr<FeatureParagraph>& ptr) {
- return ptr->name == feature;
- });
- if (it != scf.feature_paragraphs.end()) handle_deps(it->get()->dependencies);
- }
- }
- return Util::fmap(specs_to_features, [triplet](std::pair<const std::string, std::vector<std::string>>& p) {
- return FullPackageSpec({p.first, triplet}, Util::sort_unique_erase(std::move(p.second)));
- });
- }
-
- ActionPlan create_feature_install_plan(const PortFileProvider::PortFileProvider& port_provider,
- const CMakeVars::CMakeVarProvider& var_provider,
- const std::vector<FullPackageSpec>& specs,
- const StatusParagraphs& status_db,
- const CreateInstallPlanOptions& options)
- {
- PackageGraph pgraph(port_provider, var_provider, status_db);
-
- std::vector<FeatureSpec> feature_specs;
- for (const FullPackageSpec& spec : specs)
- {
- auto maybe_scfl = port_provider.get_control_file(spec.package_spec.name());
-
- Checks::check_maybe_upgrade(VCPKG_LINE_INFO,
- maybe_scfl.has_value(),
- "Error: while loading port `%s`: %s",
- spec.package_spec.name(),
- maybe_scfl.error());
-
- const SourceControlFileLocation* scfl = maybe_scfl.get();
-
- const std::vector<std::string> all_features =
- Util::fmap(scfl->source_control_file->feature_paragraphs,
- [](auto&& feature_paragraph) { return feature_paragraph->name; });
-
- auto fspecs =
- spec.to_feature_specs(scfl->source_control_file->core_paragraph->default_features, all_features);
- feature_specs.insert(
- feature_specs.end(), std::make_move_iterator(fspecs.begin()), std::make_move_iterator(fspecs.end()));
- }
- Util::sort_unique_erase(feature_specs);
-
- for (const FeatureSpec& spec : feature_specs)
- {
- pgraph.mark_user_requested(spec.spec());
- }
- pgraph.install(feature_specs);
-
- auto res = pgraph.serialize(options);
-
- return res;
- }
-
- void PackageGraph::mark_for_reinstall(const PackageSpec& first_remove_spec,
- std::vector<FeatureSpec>& out_reinstall_requirements)
- {
- std::set<PackageSpec> removed;
- std::vector<PackageSpec> to_remove{first_remove_spec};
-
- while (!to_remove.empty())
- {
- PackageSpec remove_spec = std::move(to_remove.back());
- to_remove.pop_back();
-
- if (!removed.insert(remove_spec).second) continue;
-
- Cluster& clust = m_graph->get(remove_spec);
- ClusterInstalled& info = clust.m_installed.value_or_exit(VCPKG_LINE_INFO);
-
- if (!clust.m_install_info)
- {
- clust.create_install_info(out_reinstall_requirements);
- }
-
- to_remove.insert(to_remove.end(), info.remove_edges.begin(), info.remove_edges.end());
- }
- }
-
- /// The list of specs to install should already have default features expanded
- void PackageGraph::install(Span<const FeatureSpec> specs)
- {
- // We batch resolving qualified dependencies, because it's an invocation of CMake which
- // takes ~150ms per call.
- std::vector<FeatureSpec> qualified_dependencies;
- std::vector<FeatureSpec> next_dependencies{specs.begin(), specs.end()};
-
- // Keep running while there is any chance of finding more dependencies
- while (!next_dependencies.empty())
- {
- // Keep running until the only dependencies left are qualified
- while (!next_dependencies.empty())
- {
- // Extract the top of the stack
- FeatureSpec spec = std::move(next_dependencies.back());
- next_dependencies.pop_back();
-
- // Get the cluster for the PackageSpec of the FeatureSpec we are adding to the install graph
- Cluster& clust = m_graph->get(spec.spec());
-
- // If this spec hasn't already had its qualified dependencies resolved
- if (!m_var_provider.get_dep_info_vars(spec.spec()).has_value())
- {
- // TODO: There's always the chance that we don't find the feature we're looking for (probably a
- // malformed CONTROL file somewhere). We should probably output a better error.
- const std::vector<Dependency>* paragraph_depends = nullptr;
- if (spec.feature() == "core")
- {
- paragraph_depends = &clust.get_scfl_or_exit().source_control_file->core_paragraph->dependencies;
- }
- else if (spec.feature() == "default")
- {
- }
- else
- {
- auto maybe_paragraph =
- clust.get_scfl_or_exit().source_control_file->find_feature(spec.feature());
- Checks::check_maybe_upgrade(VCPKG_LINE_INFO,
- maybe_paragraph.has_value(),
- "Package %s does not have a %s feature",
- spec.name(),
- spec.feature());
- paragraph_depends = &maybe_paragraph.value_or_exit(VCPKG_LINE_INFO).dependencies;
- }
-
- // And it has at least one qualified dependency
- if (paragraph_depends &&
- Util::any_of(*paragraph_depends, [](auto&& dep) { return !dep.platform.is_empty(); }))
- {
- // Add it to the next batch run
- qualified_dependencies.emplace_back(spec);
- }
- }
-
- if (clust.m_install_info.has_value())
- {
- clust.add_feature(spec.feature(), m_var_provider, next_dependencies);
- }
- else
- {
- if (!clust.m_installed.has_value())
- {
- clust.create_install_info(next_dependencies);
- clust.add_feature(spec.feature(), m_var_provider, next_dependencies);
- }
- else
- {
- if (spec.feature() == "default")
- {
- if (!clust.m_installed.get()->defaults_requested)
- {
- clust.m_installed.get()->defaults_requested = true;
- if (!clust.has_defaults_installed())
- {
- mark_for_reinstall(spec.spec(), next_dependencies);
- }
- }
- }
- else if (!clust.has_feature_installed(spec.feature()))
- {
- // If install_info is not present and it is already installed, we have never added a feature
- // which hasn't already been installed to this cluster. In this case, we need to reinstall
- // the port if the feature isn't already present.
- mark_for_reinstall(spec.spec(), next_dependencies);
- clust.add_feature(spec.feature(), m_var_provider, next_dependencies);
- }
- }
- }
- }
-
- if (!qualified_dependencies.empty())
- {
- Util::sort_unique_erase(qualified_dependencies);
-
- // Extract the package specs we need to get dependency info from. We don't run the triplet on a per
- // feature basis. We run it once for the whole port.
- auto qualified_package_specs =
- Util::fmap(qualified_dependencies, [](const FeatureSpec& fspec) { return fspec.spec(); });
- Util::sort_unique_erase(qualified_package_specs);
- m_var_provider.load_dep_info_vars(qualified_package_specs);
-
- // Put all the FeatureSpecs for which we had qualified dependencies back on the dependencies stack.
- // We need to recheck if evaluating the triplet revealed any new dependencies.
- next_dependencies.insert(next_dependencies.end(),
- std::make_move_iterator(qualified_dependencies.begin()),
- std::make_move_iterator(qualified_dependencies.end()));
- qualified_dependencies.clear();
- }
- }
- }
-
- void PackageGraph::upgrade(Span<const PackageSpec> specs)
- {
- std::vector<FeatureSpec> reinstall_reqs;
-
- for (const PackageSpec& spec : specs)
- mark_for_reinstall(spec, reinstall_reqs);
-
- Util::sort_unique_erase(reinstall_reqs);
-
- install(reinstall_reqs);
- }
-
- ActionPlan create_upgrade_plan(const PortFileProvider::PortFileProvider& port_provider,
- const CMakeVars::CMakeVarProvider& var_provider,
- const std::vector<PackageSpec>& specs,
- const StatusParagraphs& status_db,
- const CreateInstallPlanOptions& options)
- {
- PackageGraph pgraph(port_provider, var_provider, status_db);
-
- pgraph.upgrade(specs);
-
- return pgraph.serialize(options);
- }
-
- ActionPlan PackageGraph::serialize(const CreateInstallPlanOptions& options) const
- {
- struct BaseEdgeProvider : Graphs::AdjacencyProvider<PackageSpec, const Cluster*>
- {
- BaseEdgeProvider(const ClusterGraph& parent) : m_parent(parent) { }
-
- std::string to_string(const PackageSpec& spec) const override { return spec.to_string(); }
- const Cluster* load_vertex_data(const PackageSpec& spec) const override
- {
- return &m_parent.find_or_exit(spec, VCPKG_LINE_INFO);
- }
-
- const ClusterGraph& m_parent;
- };
-
- struct RemoveEdgeProvider final : BaseEdgeProvider
- {
- using BaseEdgeProvider::BaseEdgeProvider;
-
- std::vector<PackageSpec> adjacency_list(const Cluster* const& vertex) const override
- {
- auto&& set = vertex->m_installed.value_or_exit(VCPKG_LINE_INFO).remove_edges;
- return {set.begin(), set.end()};
- }
- } removeedgeprovider(*m_graph);
-
- struct InstallEdgeProvider final : BaseEdgeProvider
- {
- using BaseEdgeProvider::BaseEdgeProvider;
-
- std::vector<PackageSpec> adjacency_list(const Cluster* const& vertex) const override
- {
- if (!vertex->m_install_info.has_value()) return {};
-
- auto& info = vertex->m_install_info.value_or_exit(VCPKG_LINE_INFO);
- std::vector<PackageSpec> deps;
- for (auto&& kv : info.build_edges)
- for (auto&& e : kv.second)
- {
- auto spec = e.spec();
- if (spec != vertex->m_spec) deps.push_back(std::move(spec));
- }
- Util::sort_unique_erase(deps);
- return deps;
- }
- } installedgeprovider(*m_graph);
-
- std::vector<PackageSpec> removed_vertices;
- std::vector<PackageSpec> installed_vertices;
- for (auto&& kv : *m_graph)
- {
- if (kv.second.m_install_info.has_value() && kv.second.m_installed.has_value())
- {
- removed_vertices.push_back(kv.first);
- }
- if (kv.second.m_install_info.has_value() || kv.second.request_type == RequestType::USER_REQUESTED)
- {
- installed_vertices.push_back(kv.first);
- }
- }
- auto remove_toposort = Graphs::topological_sort(removed_vertices, removeedgeprovider, options.randomizer);
- auto insert_toposort = Graphs::topological_sort(installed_vertices, installedgeprovider, options.randomizer);
-
- ActionPlan plan;
-
- for (auto&& p_cluster : remove_toposort)
- {
- plan.remove_actions.emplace_back(p_cluster->m_spec, RemovePlanType::REMOVE, p_cluster->request_type);
- }
-
- for (auto&& p_cluster : insert_toposort)
- {
- // Every cluster that has an install_info needs to be built
- // If a cluster only has an installed object and is marked as user requested we should still report it.
- if (auto info_ptr = p_cluster->m_install_info.get())
- {
- std::map<std::string, std::vector<FeatureSpec>> computed_edges;
- for (auto&& kv : info_ptr->build_edges)
- {
- std::set<FeatureSpec> fspecs;
- for (auto&& fspec : kv.second)
- {
- if (fspec.feature() != "default")
- {
- fspecs.insert(fspec);
- continue;
- }
- auto&& dep_clust = m_graph->get(fspec.spec());
- const auto& default_features = [&] {
- if (dep_clust.m_install_info.has_value())
- return dep_clust.get_scfl_or_exit()
- .source_control_file->core_paragraph->default_features;
- if (auto p = dep_clust.m_installed.get()) return p->ipv.core->package.default_features;
- Checks::unreachable(VCPKG_LINE_INFO);
- }();
- for (auto&& default_feature : default_features)
- fspecs.emplace(fspec.spec(), default_feature);
- }
- computed_edges[kv.first].assign(fspecs.begin(), fspecs.end());
- }
- plan.install_actions.emplace_back(p_cluster->m_spec,
- p_cluster->get_scfl_or_exit(),
- p_cluster->request_type,
- std::move(computed_edges));
- }
- else if (p_cluster->request_type == RequestType::USER_REQUESTED && p_cluster->m_installed.has_value())
- {
- auto&& installed = p_cluster->m_installed.value_or_exit(VCPKG_LINE_INFO);
- plan.already_installed.emplace_back(InstalledPackageView(installed.ipv), p_cluster->request_type);
- }
- }
-
- return plan;
- }
-
- static std::unique_ptr<ClusterGraph> create_feature_install_graph(
- const PortFileProvider::PortFileProvider& port_provider, const StatusParagraphs& status_db)
- {
- std::unique_ptr<ClusterGraph> graph = std::make_unique<ClusterGraph>(port_provider);
-
- auto installed_ports = get_installed_ports(status_db);
-
- for (auto&& ipv : installed_ports)
- {
- graph->get(ipv);
- }
-
- // Populate the graph with "remove edges", which are the reverse of the Build-Depends edges.
- for (auto&& ipv : installed_ports)
- {
- auto deps = ipv.dependencies();
-
- for (auto&& dep : deps)
- {
- auto p_installed = graph->get(dep).m_installed.get();
- Checks::check_maybe_upgrade(
- VCPKG_LINE_INFO,
- p_installed,
- "Error: database corrupted. Package %s is installed but dependency %s is not.",
- ipv.spec(),
- dep);
- p_installed->remove_edges.emplace(ipv.spec());
- }
- }
- return graph;
- }
-
- PackageGraph::PackageGraph(const PortFileProvider::PortFileProvider& port_provider,
- const CMakeVars::CMakeVarProvider& var_provider,
- const StatusParagraphs& status_db)
- : m_var_provider(var_provider), m_graph(create_feature_install_graph(port_provider, status_db))
- {
- }
-
- PackageGraph::~PackageGraph() = default;
-
- void print_plan(const ActionPlan& action_plan, const bool is_recursive, const fs::path& builtin_ports_dir)
- {
- if (action_plan.remove_actions.empty() && action_plan.already_installed.empty() &&
- action_plan.install_actions.empty())
- {
- System::print2("All requested packages are currently installed.\n");
- return;
- }
-
- std::set<PackageSpec> remove_specs;
- std::vector<const InstallPlanAction*> rebuilt_plans;
- std::vector<const InstallPlanAction*> only_install_plans;
- std::vector<const InstallPlanAction*> new_plans;
- std::vector<const InstallPlanAction*> already_installed_plans;
- std::vector<const InstallPlanAction*> excluded;
-
- const bool has_non_user_requested_packages =
- Util::find_if(action_plan.install_actions, [](const InstallPlanAction& action) -> bool {
- return action.request_type != RequestType::USER_REQUESTED;
- }) != action_plan.install_actions.cend();
-
- for (auto&& remove_action : action_plan.remove_actions)
- {
- remove_specs.emplace(remove_action.spec);
- }
- for (auto&& install_action : action_plan.install_actions)
- {
- // remove plans are guaranteed to come before install plans, so we know the plan will be contained
- // if at all.
- auto it = remove_specs.find(install_action.spec);
- if (it != remove_specs.end())
- {
- remove_specs.erase(it);
- rebuilt_plans.push_back(&install_action);
- }
- else
- {
- if (install_action.plan_type == InstallPlanType::EXCLUDED)
- excluded.push_back(&install_action);
- else
- new_plans.push_back(&install_action);
- }
- }
- for (auto&& action : action_plan.already_installed)
- {
- if (action.request_type == RequestType::USER_REQUESTED) already_installed_plans.emplace_back(&action);
- }
- already_installed_plans = Util::fmap(action_plan.already_installed, [](auto&& action) { return &action; });
-
- std::sort(rebuilt_plans.begin(), rebuilt_plans.end(), &InstallPlanAction::compare_by_name);
- std::sort(only_install_plans.begin(), only_install_plans.end(), &InstallPlanAction::compare_by_name);
- std::sort(new_plans.begin(), new_plans.end(), &InstallPlanAction::compare_by_name);
- std::sort(already_installed_plans.begin(), already_installed_plans.end(), &InstallPlanAction::compare_by_name);
- std::sort(excluded.begin(), excluded.end(), &InstallPlanAction::compare_by_name);
-
- static auto actions_to_output_string = [&](const std::vector<const InstallPlanAction*>& v) {
- return Strings::join("\n", v, [&](const InstallPlanAction* p) {
- return to_output_string(p->request_type,
- p->displayname(),
- p->build_options,
- p->source_control_file_location.get(),
- p->installed_package.get(),
- builtin_ports_dir);
- });
- };
-
- if (!excluded.empty())
- {
- System::print2("The following packages are excluded:\n", actions_to_output_string(excluded), '\n');
- }
-
- if (!already_installed_plans.empty())
- {
- System::print2("The following packages are already installed:\n",
- actions_to_output_string(already_installed_plans),
- '\n');
- }
-
- if (!remove_specs.empty())
- {
- std::string msg = "The following packages will be removed:\n";
- for (auto spec : remove_specs)
- {
- Strings::append(msg, to_output_string(RequestType::USER_REQUESTED, spec.to_string()), '\n');
- }
- System::print2(msg);
- }
-
- if (!rebuilt_plans.empty())
- {
- System::print2("The following packages will be rebuilt:\n", actions_to_output_string(rebuilt_plans), '\n');
- }
-
- if (!new_plans.empty())
- {
- System::print2(
- "The following packages will be built and installed:\n", actions_to_output_string(new_plans), '\n');
- }
-
- if (!only_install_plans.empty())
- {
- System::print2("The following packages will be directly installed:\n",
- actions_to_output_string(only_install_plans),
- '\n');
- }
-
- if (has_non_user_requested_packages)
- System::print2("Additional packages (*) will be modified to complete this operation.\n");
- bool have_removals = !remove_specs.empty() || !rebuilt_plans.empty();
- if (have_removals && !is_recursive)
- {
- System::print2(System::Color::warning,
- "If you are sure you want to rebuild the above packages, run the command with the "
- "--recurse option\n");
- Checks::exit_fail(VCPKG_LINE_INFO);
- }
- }
-
- namespace
- {
- struct VersionedPackageGraph
- {
- private:
- using IVersionedPortfileProvider = PortFileProvider::IVersionedPortfileProvider;
- using IBaselineProvider = PortFileProvider::IBaselineProvider;
-
- public:
- VersionedPackageGraph(const IVersionedPortfileProvider& ver_provider,
- const IBaselineProvider& base_provider,
- const PortFileProvider::IOverlayProvider& oprovider,
- const CMakeVars::CMakeVarProvider& var_provider)
- : m_ver_provider(ver_provider)
- , m_base_provider(base_provider)
- , m_o_provider(oprovider)
- , m_var_provider(var_provider)
- {
- }
-
- void add_override(const std::string& name, const Versions::Version& v);
-
- void add_roots(View<Dependency> dep, const PackageSpec& toplevel);
-
- ExpectedS<ActionPlan> finalize_extract_plan();
-
- private:
- const IVersionedPortfileProvider& m_ver_provider;
- const IBaselineProvider& m_base_provider;
- const PortFileProvider::IOverlayProvider& m_o_provider;
- const CMakeVars::CMakeVarProvider& m_var_provider;
-
- struct DepSpec
- {
- PackageSpec spec;
- Versions::Version ver;
- std::vector<std::string> features;
- };
-
- // This object contains the current version within a given column.
- // Each "string" scheme text is treated as a separate column
- // "relaxed" versions all share the same column
- struct VersionSchemeInfo
- {
- const SourceControlFileLocation* scfl = nullptr;
- Versions::Version version;
- // This tracks a list of constraint sources for debugging purposes
- std::vector<std::string> origins;
- std::map<std::string, std::vector<FeatureSpec>> deps;
-
- bool is_less_than(const Versions::Version& new_ver) const;
- };
-
- struct PackageNode : Util::MoveOnlyBase
- {
- std::map<Versions::Version, VersionSchemeInfo*, VersionTMapLess> vermap;
- std::map<std::string, VersionSchemeInfo> exacts;
- Optional<std::unique_ptr<VersionSchemeInfo>> relaxed;
- Optional<std::unique_ptr<VersionSchemeInfo>> semver;
- Optional<std::unique_ptr<VersionSchemeInfo>> date;
- std::set<std::string> features;
- bool default_features = true;
-
- VersionSchemeInfo* get_node(const Versions::Version& ver);
- VersionSchemeInfo& emplace_node(Versions::Scheme scheme, const Versions::Version& ver);
- };
-
- std::vector<DepSpec> m_roots;
- std::map<std::string, Versions::Version> m_overrides;
- std::map<PackageSpec, PackageNode> m_graph;
-
- std::pair<const PackageSpec, PackageNode>& emplace_package(const PackageSpec& spec);
-
- void add_constraint(std::pair<const PackageSpec, PackageNode>& ref,
- const Dependency& dep,
- const std::string& origin);
- void add_constraint(std::pair<const PackageSpec, PackageNode>& ref,
- const Versions::Version& ver,
- const std::string& origin);
- void add_constraint(std::pair<const PackageSpec, PackageNode>& ref,
- const std::string& feature,
- const std::string& origin);
-
- void add_constraint_default_features(std::pair<const PackageSpec, PackageNode>& ref,
- const std::string& origin);
-
- void add_feature_to(std::pair<const PackageSpec, PackageNode>& ref,
- VersionSchemeInfo& vsi,
- const std::string& feature);
-
- Optional<Versions::Version> dep_to_version(const std::string& name, const DependencyConstraint& dc);
-
- std::vector<std::string> m_errors;
- };
-
- VersionedPackageGraph::VersionSchemeInfo& VersionedPackageGraph::PackageNode::emplace_node(
- Versions::Scheme scheme, const Versions::Version& ver)
- {
- auto it = vermap.find(ver);
- if (it != vermap.end()) return *it->second;
-
- VersionSchemeInfo* vsi = nullptr;
- if (scheme == Versions::Scheme::String)
- {
- vsi = &exacts[ver.text()];
- }
- else if (scheme == Versions::Scheme::Relaxed)
- {
- if (auto p = relaxed.get())
- {
- vsi = p->get();
- }
- else
- {
- relaxed = std::make_unique<VersionSchemeInfo>();
- vsi = relaxed.get()->get();
- }
- }
- else if (scheme == Versions::Scheme::Semver)
- {
- if (auto p = semver.get())
- {
- vsi = p->get();
- }
- else
- {
- semver = std::make_unique<VersionSchemeInfo>();
- vsi = semver.get()->get();
- }
- }
- else if (scheme == Versions::Scheme::Date)
- {
- if (auto p = date.get())
- {
- vsi = p->get();
- }
- else
- {
- date = std::make_unique<VersionSchemeInfo>();
- vsi = date.get()->get();
- }
- }
- else
- {
- // not implemented
- Checks::unreachable(VCPKG_LINE_INFO);
- }
- vermap.emplace(ver, vsi);
- return *vsi;
- }
-
- VersionedPackageGraph::VersionSchemeInfo* VersionedPackageGraph::PackageNode::get_node(
- const Versions::Version& ver)
- {
- auto it = vermap.find(ver);
- return it == vermap.end() ? nullptr : it->second;
- }
-
- using Versions::VerComp;
-
- static VerComp compare_versions(Versions::Scheme sa,
- const Versions::Version& a,
- Versions::Scheme sb,
- const Versions::Version& b)
- {
- if (sa != sb) return VerComp::unk;
-
- if (a.text() != b.text())
- {
- auto result = Versions::compare(a.text(), b.text(), sa);
- if (result != VerComp::eq) return result;
- }
-
- if (a.port_version() < b.port_version()) return VerComp::lt;
- if (a.port_version() > b.port_version()) return VerComp::gt;
- return VerComp::eq;
- }
-
- bool VersionedPackageGraph::VersionSchemeInfo::is_less_than(const Versions::Version& new_ver) const
- {
- Checks::check_exit(VCPKG_LINE_INFO, scfl);
- ASSUME(scfl != nullptr);
- auto scheme = scfl->source_control_file->core_paragraph->version_scheme;
- auto r = compare_versions(scheme, version, scheme, new_ver);
- Checks::check_exit(VCPKG_LINE_INFO, r != VerComp::unk);
- return r == VerComp::lt;
- }
-
- Versions::Version to_version(const SourceControlFile& scf)
- {
- return {
- scf.core_paragraph->version,
- scf.core_paragraph->port_version,
- };
- }
- Optional<Versions::Version> to_version(const DependencyConstraint& dc)
- {
- if (dc.type == Versions::Constraint::Type::None)
- {
- return nullopt;
- }
- else
- {
- return Versions::Version{
- dc.value,
- dc.port_version,
- };
- }
- }
-
- void VersionedPackageGraph::add_feature_to(std::pair<const PackageSpec, PackageNode>& ref,
- VersionSchemeInfo& vsi,
- const std::string& feature)
- {
- auto deps = vsi.scfl->source_control_file->find_dependencies_for_feature(feature);
- if (!deps)
- {
- // This version doesn't have this feature. This may result in an error during finalize if the
- // constraint is not removed via upgrades.
- return;
- }
- auto p = vsi.deps.emplace(feature, std::vector<FeatureSpec>{});
- if (!p.second)
- {
- // This feature has already been handled
- return;
- }
-
- for (auto&& dep : *deps.get())
- {
- PackageSpec dep_spec(dep.name, ref.first.triplet());
-
- if (!dep.platform.is_empty())
- {
- auto maybe_vars = m_var_provider.get_dep_info_vars(ref.first);
- if (!maybe_vars)
- {
- m_var_provider.load_dep_info_vars({&ref.first, 1});
- maybe_vars = m_var_provider.get_dep_info_vars(ref.first);
- }
-
- if (!dep.platform.evaluate(maybe_vars.value_or_exit(VCPKG_LINE_INFO)))
- {
- continue;
- }
- }
-
- auto& dep_node = emplace_package(dep_spec);
- // Todo: cycle detection
- add_constraint(dep_node, dep, ref.first.name());
-
- p.first->second.emplace_back(dep_spec, "core");
- for (auto&& f : dep.features)
- {
- p.first->second.emplace_back(dep_spec, f);
- }
- }
- }
-
- void VersionedPackageGraph::add_constraint_default_features(std::pair<const PackageSpec, PackageNode>& ref,
- const std::string& origin)
- {
- (void)origin;
- if (!ref.second.default_features)
- {
- ref.second.default_features = true;
-
- if (auto relaxed = ref.second.relaxed.get())
- {
- for (auto&& f : relaxed->get()->scfl->source_control_file->core_paragraph->default_features)
- {
- add_feature_to(ref, **relaxed, f);
- }
- }
- for (auto&& vsi : ref.second.exacts)
- {
- for (auto&& f : vsi.second.scfl->source_control_file->core_paragraph->default_features)
- {
- add_feature_to(ref, vsi.second, f);
- }
- }
- }
- }
-
- void VersionedPackageGraph::add_constraint(std::pair<const PackageSpec, PackageNode>& ref,
- const Dependency& dep,
- const std::string& origin)
- {
- auto maybe_overlay = m_o_provider.get_control_file(ref.first.name());
- auto over_it = m_overrides.find(ref.first.name());
- if (auto p_overlay = maybe_overlay.get())
- {
- auto overlay_version = to_version(*p_overlay->source_control_file);
- add_constraint(ref, overlay_version, origin);
- }
- else if (over_it != m_overrides.end())
- {
- add_constraint(ref, over_it->second, origin);
- }
- else
- {
- auto base_ver = m_base_provider.get_baseline_version(dep.name);
- auto dep_ver = to_version(dep.constraint);
-
- if (auto dv = dep_ver.get())
- {
- add_constraint(ref, *dv, origin);
- }
-
- if (auto bv = base_ver.get())
- {
- add_constraint(ref, *bv, origin);
- }
- }
-
- for (auto&& f : dep.features)
- {
- add_constraint(ref, f, origin);
- }
- }
- void VersionedPackageGraph::add_constraint(std::pair<const PackageSpec, PackageNode>& ref,
- const Versions::Version& version,
- const std::string& origin)
- {
- ExpectedS<const vcpkg::SourceControlFileLocation&> maybe_scfl;
-
- auto maybe_overlay = m_o_provider.get_control_file(ref.first.name());
- if (auto p_overlay = maybe_overlay.get())
- {
- auto overlay_version = to_version(*p_overlay->source_control_file);
- if (version != overlay_version)
- {
- return add_constraint(ref, overlay_version, origin);
- }
- maybe_scfl = *p_overlay;
- }
- else
- {
- auto over_it = m_overrides.find(ref.first.name());
- if (over_it != m_overrides.end() && over_it->second != version)
- {
- return add_constraint(ref, over_it->second, origin);
- }
- maybe_scfl = m_ver_provider.get_control_file({ref.first.name(), version});
- }
-
- if (auto p_scfl = maybe_scfl.get())
- {
- auto& exact_ref =
- ref.second.emplace_node(p_scfl->source_control_file->core_paragraph->version_scheme, version);
- exact_ref.origins.push_back(origin);
-
- bool replace;
- if (exact_ref.scfl == nullptr)
- {
- replace = true;
- }
- else if (exact_ref.scfl == p_scfl)
- {
- replace = false;
- }
- else
- {
- replace = exact_ref.is_less_than(version);
- }
-
- if (replace)
- {
- exact_ref.scfl = p_scfl;
- exact_ref.version = to_version(*p_scfl->source_control_file);
- exact_ref.deps.clear();
-
- add_feature_to(ref, exact_ref, "core");
-
- for (auto&& f : ref.second.features)
- {
- add_feature_to(ref, exact_ref, f);
- }
-
- if (ref.second.default_features)
- {
- for (auto&& f : p_scfl->source_control_file->core_paragraph->default_features)
- {
- add_feature_to(ref, exact_ref, f);
- }
- }
- }
- }
- else
- {
- m_errors.push_back(maybe_scfl.error());
- }
- }
-
- void VersionedPackageGraph::add_constraint(std::pair<const PackageSpec, PackageNode>& ref,
- const std::string& feature,
- const std::string& origin)
- {
- auto inserted = ref.second.features.emplace(feature).second;
- if (inserted)
- {
- if (auto relaxed = ref.second.relaxed.get())
- {
- add_feature_to(ref, **relaxed, feature);
- }
- for (auto&& vsi : ref.second.exacts)
- {
- add_feature_to(ref, vsi.second, feature);
- }
- }
- (void)origin;
- }
-
- std::pair<const PackageSpec, VersionedPackageGraph::PackageNode>& VersionedPackageGraph::emplace_package(
- const PackageSpec& spec)
- {
- return *m_graph.emplace(spec, PackageNode{}).first;
- }
-
- Optional<Versions::Version> VersionedPackageGraph::dep_to_version(const std::string& name,
- const DependencyConstraint& dc)
- {
- auto maybe_overlay = m_o_provider.get_control_file(name);
- if (auto p_overlay = maybe_overlay.get())
- {
- return to_version(*p_overlay->source_control_file);
- }
-
- auto over_it = m_overrides.find(name);
- if (over_it != m_overrides.end())
- {
- return over_it->second;
- }
-
- auto maybe_cons = to_version(dc);
- if (maybe_cons)
- {
- return maybe_cons;
- }
- else
- {
- return m_base_provider.get_baseline_version(name);
- }
- }
-
- void VersionedPackageGraph::add_override(const std::string& name, const Versions::Version& v)
- {
- m_overrides.emplace(name, v);
- }
-
- void VersionedPackageGraph::add_roots(View<Dependency> deps, const PackageSpec& toplevel)
- {
- auto specs = Util::fmap(deps, [&toplevel](const Dependency& d) {
- return PackageSpec{d.name, toplevel.triplet()};
- });
- specs.push_back(toplevel);
- Util::sort_unique_erase(specs);
- m_var_provider.load_dep_info_vars(specs);
- const auto& vars = m_var_provider.get_dep_info_vars(toplevel).value_or_exit(VCPKG_LINE_INFO);
- std::vector<const Dependency*> active_deps;
-
- for (auto&& dep : deps)
- {
- PackageSpec spec(dep.name, toplevel.triplet());
- if (!dep.platform.evaluate(vars)) continue;
-
- active_deps.push_back(&dep);
-
- // Disable default features for deps with [core] as a dependency
- // Note: x[core], x[y] will still eventually depend on defaults due to the second x[y]
- if (Util::find(dep.features, "core") != dep.features.end())
- {
- auto& node = emplace_package(spec);
- node.second.default_features = false;
- }
- }
-
- for (auto pdep : active_deps)
- {
- const auto& dep = *pdep;
- PackageSpec spec(dep.name, toplevel.triplet());
-
- auto& node = emplace_package(spec);
-
- auto maybe_overlay = m_o_provider.get_control_file(dep.name);
- if (auto p_overlay = maybe_overlay.get())
- {
- auto ver = to_version(*p_overlay->source_control_file);
- m_roots.push_back(DepSpec{spec, ver, dep.features});
- add_constraint(node, ver, toplevel.name());
- continue;
- }
-
- auto over_it = m_overrides.find(dep.name);
- if (over_it != m_overrides.end())
- {
- m_roots.push_back(DepSpec{spec, over_it->second, dep.features});
- add_constraint(node, over_it->second, toplevel.name());
- continue;
- }
-
- auto dep_ver = to_version(dep.constraint);
- auto base_ver = m_base_provider.get_baseline_version(dep.name);
- if (auto p_dep_ver = dep_ver.get())
- {
- m_roots.push_back(DepSpec{spec, *p_dep_ver, dep.features});
- if (auto p_base_ver = base_ver.get())
- {
- // Compare version constraint with baseline to only evaluate the "tighter" constraint
- auto dep_scfl = m_ver_provider.get_control_file({dep.name, *p_dep_ver});
- auto base_scfl = m_ver_provider.get_control_file({dep.name, *p_base_ver});
- if (dep_scfl && base_scfl)
- {
- auto r =
- compare_versions(dep_scfl.get()->source_control_file->core_paragraph->version_scheme,
- *p_dep_ver,
- base_scfl.get()->source_control_file->core_paragraph->version_scheme,
- *p_base_ver);
- if (r == VerComp::lt)
- {
- add_constraint(node, *p_base_ver, "baseline");
- add_constraint(node, *p_dep_ver, toplevel.name());
- }
- else
- {
- add_constraint(node, *p_dep_ver, toplevel.name());
- add_constraint(node, *p_base_ver, "baseline");
- }
- }
- else
- {
- if (!dep_scfl) m_errors.push_back(dep_scfl.error());
- if (!base_scfl) m_errors.push_back(base_scfl.error());
- }
- }
- else
- {
- add_constraint(node, *p_dep_ver, toplevel.name());
- }
- }
- else if (auto p_base_ver = base_ver.get())
- {
- m_roots.push_back(DepSpec{spec, *p_base_ver, dep.features});
- add_constraint(node, *p_base_ver, toplevel.name());
- }
- else
- {
- m_errors.push_back(Strings::concat("Cannot resolve unversioned dependency from top-level to ",
- dep.name,
- " without a baseline entry or override."));
- }
-
- for (auto&& f : dep.features)
- {
- add_constraint(node, f, toplevel.name());
- }
- if (Util::find(dep.features, "core") == dep.features.end())
- {
- add_constraint_default_features(node, toplevel.name());
- }
- }
- }
-
- ExpectedS<ActionPlan> VersionedPackageGraph::finalize_extract_plan()
- {
- if (m_errors.size() > 0)
- {
- return Strings::join("\n", m_errors);
- }
-
- ActionPlan ret;
-
- // second == nullptr means "in progress"
- std::map<PackageSpec, VersionSchemeInfo*> emitted;
- struct Frame
- {
- InstallPlanAction ipa;
- std::vector<DepSpec> deps;
- };
- std::vector<Frame> stack;
-
- auto push = [&emitted, this, &stack](const PackageSpec& spec,
- const Versions::Version& new_ver) -> Optional<std::string> {
- auto&& node = m_graph[spec];
- auto overlay = m_o_provider.get_control_file(spec.name());
- auto over_it = m_overrides.find(spec.name());
-
- VersionedPackageGraph::VersionSchemeInfo* p_vnode;
- if (auto p_overlay = overlay.get())
- p_vnode = node.get_node(to_version(*p_overlay->source_control_file));
- else if (over_it != m_overrides.end())
- p_vnode = node.get_node(over_it->second);
- else
- p_vnode = node.get_node(new_ver);
-
- if (!p_vnode) return Strings::concat("Version was not found during discovery: ", spec, "@", new_ver);
-
- auto p = emitted.emplace(spec, nullptr);
- if (p.second)
- {
- // Newly inserted
- if (!overlay && over_it == m_overrides.end())
- {
- // Not overridden -- Compare against baseline
- if (auto baseline = m_base_provider.get_baseline_version(spec.name()))
- {
- if (auto base_node = node.get_node(*baseline.get()))
- {
- if (base_node != p_vnode)
- {
- return Strings::concat("Version conflict on ",
- spec.name(),
- "@",
- new_ver,
- ": baseline required ",
- *baseline.get());
- }
- }
- }
- }
-
- // -> Add stack frame
- auto maybe_vars = m_var_provider.get_dep_info_vars(spec);
-
- InstallPlanAction ipa(spec, *p_vnode->scfl, RequestType::USER_REQUESTED, std::move(p_vnode->deps));
- std::vector<DepSpec> deps;
- for (auto&& f : ipa.feature_list)
- {
- if (auto maybe_deps =
- p_vnode->scfl->source_control_file->find_dependencies_for_feature(f).get())
- {
- for (auto&& dep : *maybe_deps)
- {
- if (dep.name == spec.name()) continue;
-
- if (!dep.platform.is_empty() &&
- !dep.platform.evaluate(maybe_vars.value_or_exit(VCPKG_LINE_INFO)))
- {
- continue;
- }
- auto maybe_cons = dep_to_version(dep.name, dep.constraint);
-
- if (auto cons = maybe_cons.get())
- {
- deps.emplace_back(DepSpec{{dep.name, spec.triplet()}, std::move(*cons)});
- }
- else
- {
- return Strings::concat("Cannot resolve unconstrained dependency from ",
- spec.name(),
- " to ",
- dep.name,
- " without a baseline entry or override.");
- }
- }
- }
- }
- stack.push_back(Frame{std::move(ipa), std::move(deps)});
- return nullopt;
- }
- else
- {
- // spec already present in map
- if (p.first->second == nullptr)
- {
- return Strings::concat(
- "Cycle detected during ",
- spec,
- ":\n",
- Strings::join("\n", stack, [](const auto& p) -> const PackageSpec& { return p.ipa.spec; }));
- }
- else if (p.first->second != p_vnode)
- {
- // comparable versions should retrieve the same info node
- return Strings::concat(
- "Version conflict on ", spec.name(), "@", p.first->second->version, ": required ", new_ver);
- }
- return nullopt;
- }
- };
-
- for (auto&& root : m_roots)
- {
- if (auto err = push(root.spec, root.ver))
- {
- return std::move(*err.get());
- }
-
- while (stack.size() > 0)
- {
- auto& back = stack.back();
- if (back.deps.empty())
- {
- emitted[back.ipa.spec] = m_graph[back.ipa.spec].get_node(
- to_version(*back.ipa.source_control_file_location.get()->source_control_file));
- ret.install_actions.push_back(std::move(back.ipa));
- stack.pop_back();
- }
- else
- {
- auto dep = std::move(back.deps.back());
- back.deps.pop_back();
- if (auto err = push(dep.spec, dep.ver))
- {
- return std::move(*err.get());
- }
- }
- }
- }
- return ret;
- }
- }
-
- ExpectedS<ActionPlan> create_versioned_install_plan(const PortFileProvider::IVersionedPortfileProvider& provider,
- const PortFileProvider::IBaselineProvider& bprovider,
- const PortFileProvider::IOverlayProvider& oprovider,
- const CMakeVars::CMakeVarProvider& var_provider,
- const std::vector<Dependency>& deps,
- const std::vector<DependencyOverride>& overrides,
- const PackageSpec& toplevel)
- {
- VersionedPackageGraph vpg(provider, bprovider, oprovider, var_provider);
- for (auto&& o : overrides)
- vpg.add_override(o.name, {o.version, o.port_version});
- vpg.add_roots(deps, toplevel);
- return vpg.finalize_extract_plan();
- }
-}
diff --git a/toolsrc/src/vcpkg/export.chocolatey.cpp b/toolsrc/src/vcpkg/export.chocolatey.cpp
deleted file mode 100644
index 875982ed6..000000000
--- a/toolsrc/src/vcpkg/export.chocolatey.cpp
+++ /dev/null
@@ -1,233 +0,0 @@
-#include <vcpkg/base/system.print.h>
-#include <vcpkg/base/system.process.h>
-
-#include <vcpkg/commands.h>
-#include <vcpkg/export.chocolatey.h>
-#include <vcpkg/export.h>
-#include <vcpkg/install.h>
-#include <vcpkg/tools.h>
-
-namespace vcpkg::Export::Chocolatey
-{
- using Dependencies::ExportPlanAction;
- using Dependencies::ExportPlanType;
- using Install::InstallDir;
-
- static std::string create_nuspec_dependencies(const BinaryParagraph& binary_paragraph,
- const std::map<std::string, std::string>& packages_version)
- {
- static constexpr auto CONTENT_TEMPLATE = R"(<dependency id="@PACKAGE_ID@" version="[@PACKAGE_VERSION@]" />)";
-
- std::string nuspec_dependencies;
- for (const std::string& depend : binary_paragraph.dependencies)
- {
- auto found = packages_version.find(depend);
- if (found == packages_version.end())
- {
- Checks::exit_with_message(VCPKG_LINE_INFO, "Cannot find desired dependency version.");
- }
-
- std::string nuspec_dependency = Strings::replace_all(CONTENT_TEMPLATE, "@PACKAGE_ID@", depend);
- Strings::inplace_replace_all(nuspec_dependency, "@PACKAGE_VERSION@", found->second);
- nuspec_dependencies += nuspec_dependency;
- }
- return nuspec_dependencies;
- }
-
- static std::string create_nuspec_file_contents(const std::string& exported_root_dir,
- const BinaryParagraph& binary_paragraph,
- const std::map<std::string, std::string>& packages_version,
- const Options& chocolatey_options)
- {
- static constexpr auto CONTENT_TEMPLATE = R"(<?xml version="1.0" encoding="utf-8"?>
-<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
- <metadata>
- <id>@PACKAGE_ID@</id>
- <version>@PACKAGE_VERSION@</version>
- <authors>@PACKAGE_MAINTAINER@</authors>
- <description><![CDATA[
- @PACKAGE_DESCRIPTION@
- ]]></description>
- <dependencies>
- @PACKAGE_DEPENDENCIES@
- </dependencies>
- </metadata>
- <files>
- <file src="@EXPORTED_ROOT_DIR@\installed\**" target="installed" />
- <file src="@EXPORTED_ROOT_DIR@\tools\**" target="tools" />
- </files>
-</package>
-)";
- auto package_version = packages_version.find(binary_paragraph.spec.name());
- if (package_version == packages_version.end())
- {
- Checks::exit_with_message(VCPKG_LINE_INFO, "Cannot find desired package version.");
- }
-
- std::string nuspec_file_content =
- Strings::replace_all(CONTENT_TEMPLATE, "@PACKAGE_ID@", binary_paragraph.spec.name());
- Strings::inplace_replace_all(nuspec_file_content, "@PACKAGE_VERSION@", package_version->second);
- Strings::inplace_replace_all(
- nuspec_file_content, "@PACKAGE_MAINTAINER@", chocolatey_options.maybe_maintainer.value_or(""));
- Strings::inplace_replace_all(
- nuspec_file_content, "@PACKAGE_DESCRIPTION@", Strings::join("\n", binary_paragraph.description));
- Strings::inplace_replace_all(nuspec_file_content, "@EXPORTED_ROOT_DIR@", exported_root_dir);
- Strings::inplace_replace_all(nuspec_file_content,
- "@PACKAGE_DEPENDENCIES@",
- create_nuspec_dependencies(binary_paragraph, packages_version));
- return nuspec_file_content;
- }
-
- static std::string create_chocolatey_install_contents()
- {
- static constexpr auto CONTENT_TEMPLATE = R"###(
-$ErrorActionPreference = 'Stop';
-
-$packageName= $env:ChocolateyPackageName
-$toolsDir = "$(Split-Path -parent $MyInvocation.MyCommand.Definition)"
-$rootDir = "$(Split-Path -parent $toolsDir)"
-$installedDir = Join-Path $rootDir 'installed'
-
-$whereToInstall = (pwd).path
-$whereToInstallCache = Join-Path $rootDir 'install.txt'
-Set-Content -Path $whereToInstallCache -Value $whereToInstall
-Copy-Item $installedDir -destination $whereToInstall -recurse -force
-)###";
- return CONTENT_TEMPLATE;
- }
-
- static std::string create_chocolatey_uninstall_contents(const BinaryParagraph& binary_paragraph)
- {
- static constexpr auto CONTENT_TEMPLATE = R"###(
-$ErrorActionPreference = 'Stop';
-
-$packageName= $env:ChocolateyPackageName
-$toolsDir = "$(Split-Path -parent $MyInvocation.MyCommand.Definition)"
-$rootDir = "$(Split-Path -parent $toolsDir)"
-$listFile = Join-Path $rootDir 'installed\vcpkg\info\@PACKAGE_FULLSTEM@.list'
-
-$whereToInstall = $null
-$whereToInstallCache = Join-Path $rootDir 'install.txt'
-Get-Content $whereToInstallCache | Foreach-Object {
- $whereToInstall = $_
-}
-
-$installedDir = Join-Path $whereToInstall 'installed'
-Get-Content $listFile | Foreach-Object {
- $fileToRemove = Join-Path $installedDir $_
- if (Test-Path $fileToRemove -PathType Leaf) {
- Remove-Item $fileToRemove
- }
-}
-
-Get-Content $listFile | Foreach-Object {
- $fileToRemove = Join-Path $installedDir $_
- if (Test-Path $fileToRemove -PathType Container) {
- $folderToDelete = Join-Path $fileToRemove *
- if (-Not (Test-Path $folderToDelete))
- {
- Remove-Item $fileToRemove
- }
- }
-}
-
-$listFileToRemove = Join-Path $whereToInstall 'installed\vcpkg\info\@PACKAGE_FULLSTEM@.list'
-Remove-Item $listFileToRemove
-
-if (Test-Path $installedDir)
-{
- while (
- $empties = Get-ChildItem $installedDir -recurse -Directory | Where-Object {
- $_.GetFiles().Count -eq 0 -and $_.GetDirectories().Count -eq 0
- }
- ) { $empties | Remove-Item }
-}
-)###";
- std::string chocolatey_uninstall_content =
- Strings::replace_all(CONTENT_TEMPLATE, "@PACKAGE_FULLSTEM@", binary_paragraph.fullstem());
- return chocolatey_uninstall_content;
- }
-
- void do_export(const std::vector<ExportPlanAction>& export_plan,
- const VcpkgPaths& paths,
- const Options& chocolatey_options)
- {
- Checks::check_exit(
- VCPKG_LINE_INFO, chocolatey_options.maybe_maintainer.has_value(), "--x-maintainer option is required.");
-
- Files::Filesystem& fs = paths.get_filesystem();
- const fs::path vcpkg_root_path = paths.root;
- const fs::path raw_exported_dir_path = vcpkg_root_path / "chocolatey";
- const fs::path exported_dir_path = vcpkg_root_path / "chocolatey_exports";
- const fs::path& nuget_exe = paths.get_tool_exe(Tools::NUGET);
-
- std::error_code ec;
- fs.remove_all(raw_exported_dir_path, VCPKG_LINE_INFO);
- fs.create_directory(raw_exported_dir_path, ec);
- fs.remove_all(exported_dir_path, VCPKG_LINE_INFO);
- fs.create_directory(exported_dir_path, ec);
-
- // execute the plan
- std::map<std::string, std::string> packages_version;
- for (const ExportPlanAction& action : export_plan)
- {
- if (action.plan_type != ExportPlanType::ALREADY_BUILT)
- {
- Checks::unreachable(VCPKG_LINE_INFO);
- }
-
- const BinaryParagraph& binary_paragraph = action.core_paragraph().value_or_exit(VCPKG_LINE_INFO);
- auto norm_version = binary_paragraph.version;
-
- // normalize the version string to be separated by dots to be compliant with Nuspec.
- Strings::inplace_replace_all(norm_version, '-', '.');
- Strings::inplace_replace_all(norm_version, '_', '.');
- norm_version += chocolatey_options.maybe_version_suffix.value_or("");
- packages_version.insert(std::make_pair(binary_paragraph.spec.name(), norm_version));
- }
-
- for (const ExportPlanAction& action : export_plan)
- {
- const std::string display_name = action.spec.to_string();
- System::print2("Exporting package ", display_name, "...\n");
-
- const fs::path per_package_dir_path = raw_exported_dir_path / action.spec.name();
-
- const BinaryParagraph& binary_paragraph = action.core_paragraph().value_or_exit(VCPKG_LINE_INFO);
-
- const InstallDir dirs = InstallDir::from_destination_root(
- per_package_dir_path / "installed",
- action.spec.triplet().to_string(),
- per_package_dir_path / "installed" / "vcpkg" / "info" / (binary_paragraph.fullstem() + ".list"));
-
- Install::install_package_and_write_listfile(paths, action.spec, dirs);
-
- const std::string nuspec_file_content = create_nuspec_file_contents(
- per_package_dir_path.string(), binary_paragraph, packages_version, chocolatey_options);
- const fs::path nuspec_file_path =
- per_package_dir_path / Strings::concat(binary_paragraph.spec.name(), ".nuspec");
- fs.write_contents(nuspec_file_path, nuspec_file_content, VCPKG_LINE_INFO);
-
- fs.create_directory(per_package_dir_path / "tools", ec);
-
- const std::string chocolatey_install_content = create_chocolatey_install_contents();
- const fs::path chocolatey_install_file_path = per_package_dir_path / "tools" / "chocolateyInstall.ps1";
- fs.write_contents(chocolatey_install_file_path, chocolatey_install_content, VCPKG_LINE_INFO);
-
- const std::string chocolatey_uninstall_content = create_chocolatey_uninstall_contents(binary_paragraph);
- const fs::path chocolatey_uninstall_file_path = per_package_dir_path / "tools" / "chocolateyUninstall.ps1";
- fs.write_contents(chocolatey_uninstall_file_path, chocolatey_uninstall_content, VCPKG_LINE_INFO);
-
- auto cmd_line = System::Command(nuget_exe)
- .string_arg("pack")
- .string_arg("-OutputDirectory")
- .path_arg(exported_dir_path)
- .path_arg(nuspec_file_path)
- .string_arg("-NoDefaultExcludes");
-
- const int exit_code =
- System::cmd_execute_and_capture_output(cmd_line, System::get_clean_environment()).exit_code;
- Checks::check_exit(VCPKG_LINE_INFO, exit_code == 0, "Error: NuGet package creation failed");
- }
- }
-}
diff --git a/toolsrc/src/vcpkg/export.cpp b/toolsrc/src/vcpkg/export.cpp
deleted file mode 100644
index 1f202a9d5..000000000
--- a/toolsrc/src/vcpkg/export.cpp
+++ /dev/null
@@ -1,707 +0,0 @@
-#include <vcpkg/base/stringliteral.h>
-#include <vcpkg/base/system.print.h>
-#include <vcpkg/base/system.process.h>
-#include <vcpkg/base/util.h>
-#include <vcpkg/base/xmlserializer.h>
-
-#include <vcpkg/commands.h>
-#include <vcpkg/dependencies.h>
-#include <vcpkg/export.chocolatey.h>
-#include <vcpkg/export.h>
-#include <vcpkg/export.ifw.h>
-#include <vcpkg/export.prefab.h>
-#include <vcpkg/help.h>
-#include <vcpkg/input.h>
-#include <vcpkg/install.h>
-#include <vcpkg/paragraphs.h>
-#include <vcpkg/portfileprovider.h>
-#include <vcpkg/tools.h>
-#include <vcpkg/vcpkglib.h>
-
-namespace vcpkg::Export
-{
- using Dependencies::ExportPlanAction;
- using Dependencies::ExportPlanType;
- using Dependencies::RequestType;
- using Install::InstallDir;
-
- static std::string create_nuspec_file_contents(const std::string& raw_exported_dir,
- const fs::path& targets_redirect_path,
- const fs::path& props_redirect_path,
- const std::string& nuget_id,
- const std::string& nupkg_version,
- const std::string& nuget_description)
- {
- XmlSerializer xml;
- xml.open_tag("package").line_break();
- xml.open_tag("metadata").line_break();
- xml.simple_tag("id", nuget_id).line_break();
- xml.simple_tag("version", nupkg_version).line_break();
- xml.simple_tag("authors", "vcpkg").line_break();
- xml.simple_tag("description", nuget_description).line_break();
- xml.close_tag("metadata").line_break();
- xml.open_tag("files").line_break();
- xml.start_complex_open_tag("file")
- .text_attr("src", raw_exported_dir + "\\installed\\**")
- .text_attr("target", "installed")
- .finish_self_closing_complex_tag();
-
- xml.start_complex_open_tag("file")
- .text_attr("src", raw_exported_dir + "\\scripts\\**")
- .text_attr("target", "scripts")
- .finish_self_closing_complex_tag();
-
- xml.start_complex_open_tag("file")
- .text_attr("src", raw_exported_dir + "\\.vcpkg-root")
- .text_attr("target", "")
- .finish_self_closing_complex_tag();
-
- xml.start_complex_open_tag("file")
- .text_attr("src", fs::u8string(targets_redirect_path))
- .text_attr("target", Strings::concat("build\\native\\", nuget_id, ".targets"))
- .finish_self_closing_complex_tag();
-
- xml.start_complex_open_tag("file")
- .text_attr("src", fs::u8string(props_redirect_path))
- .text_attr("target", Strings::concat("build\\native\\", nuget_id, ".props"))
- .finish_self_closing_complex_tag();
-
- xml.close_tag("files").line_break();
- xml.close_tag("package").line_break();
-
- return std::move(xml.buf);
- }
-
- static std::string create_targets_redirect(const std::string& target_path) noexcept
- {
- return Strings::format(R"###(
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Condition="Exists('%s')" Project="%s" />
-</Project>
-)###",
- target_path,
- target_path);
- }
-
- static void print_plan(const std::map<ExportPlanType, std::vector<const ExportPlanAction*>>& group_by_plan_type)
- {
- static constexpr std::array<ExportPlanType, 2> ORDER = {ExportPlanType::ALREADY_BUILT,
- ExportPlanType::NOT_BUILT};
- for (const ExportPlanType plan_type : ORDER)
- {
- const auto it = group_by_plan_type.find(plan_type);
- if (it == group_by_plan_type.cend())
- {
- continue;
- }
-
- std::vector<const ExportPlanAction*> cont = it->second;
- std::sort(cont.begin(), cont.end(), &ExportPlanAction::compare_by_name);
- const std::string as_string = Strings::join("\n", cont, [](const ExportPlanAction* p) {
- return Dependencies::to_output_string(
- p->request_type, p->spec.to_string(), vcpkg::Build::default_build_package_options);
- });
-
- switch (plan_type)
- {
- case ExportPlanType::ALREADY_BUILT:
- System::print2("The following packages are already built and will be exported:\n", as_string, '\n');
- continue;
- case ExportPlanType::NOT_BUILT:
- System::print2("The following packages need to be built:\n", as_string, '\n');
- continue;
- default: Checks::unreachable(VCPKG_LINE_INFO);
- }
- }
- }
-
- static std::string create_export_id()
- {
- const tm date_time = Chrono::get_current_date_time_local();
-
- // Format is: YYYYmmdd-HHMMSS
- // 15 characters + 1 null terminating character will be written for a total of 16 chars
- char mbstr[16];
- const size_t bytes_written = std::strftime(mbstr, sizeof(mbstr), "%Y%m%d-%H%M%S", &date_time);
- Checks::check_exit(VCPKG_LINE_INFO,
- bytes_written == 15,
- "Expected 15 bytes to be written, but %u were written",
- bytes_written);
- const std::string date_time_as_string(mbstr);
- return ("vcpkg-export-" + date_time_as_string);
- }
-
- static fs::path do_nuget_export(const VcpkgPaths& paths,
- const std::string& nuget_id,
- const std::string& nuget_version,
- const std::string& nuget_description,
- const fs::path& raw_exported_dir,
- const fs::path& output_dir)
- {
- Files::Filesystem& fs = paths.get_filesystem();
- const fs::path& nuget_exe = paths.get_tool_exe(Tools::NUGET);
-
- std::error_code ec;
- fs.create_directories(paths.buildsystems / "tmp", ec);
-
- // This file will be placed in "build\native" in the nuget package. Therefore, go up two dirs.
- const std::string targets_redirect_content =
- create_targets_redirect("$(MSBuildThisFileDirectory)../../scripts/buildsystems/msbuild/vcpkg.targets");
- const fs::path targets_redirect = paths.buildsystems / "tmp" / "vcpkg.export.nuget.targets";
- fs.write_contents(targets_redirect, targets_redirect_content, VCPKG_LINE_INFO);
-
- // This file will be placed in "build\native" in the nuget package. Therefore, go up two dirs.
- const std::string props_redirect_content =
- create_targets_redirect("$(MSBuildThisFileDirectory)../../scripts/buildsystems/msbuild/vcpkg.props");
- const fs::path props_redirect = paths.buildsystems / "tmp" / "vcpkg.export.nuget.props";
- fs.write_contents(props_redirect, props_redirect_content, VCPKG_LINE_INFO);
-
- const std::string nuspec_file_content = create_nuspec_file_contents(
- raw_exported_dir.string(), targets_redirect, props_redirect, nuget_id, nuget_version, nuget_description);
- const fs::path nuspec_file_path = paths.buildsystems / "tmp" / "vcpkg.export.nuspec";
- fs.write_contents(nuspec_file_path, nuspec_file_content, VCPKG_LINE_INFO);
-
- // -NoDefaultExcludes is needed for ".vcpkg-root"
- System::Command cmd;
-#ifndef _WIN32
- cmd.path_arg(paths.get_tool_exe(Tools::MONO));
-#endif
- cmd.path_arg(nuget_exe)
- .string_arg("pack")
- .path_arg(nuspec_file_path)
- .string_arg("-OutputDirectory")
- .path_arg(output_dir)
- .string_arg("-NoDefaultExcludes");
-
- const int exit_code = System::cmd_execute_and_capture_output(cmd, System::get_clean_environment()).exit_code;
- Checks::check_exit(VCPKG_LINE_INFO, exit_code == 0, "Error: NuGet package creation failed");
-
- const fs::path output_path = output_dir / (nuget_id + "." + nuget_version + ".nupkg");
- return output_path;
- }
-
- struct ArchiveFormat final
- {
- enum class BackingEnum
- {
- ZIP = 1,
- SEVEN_ZIP,
- };
-
- constexpr ArchiveFormat() = delete;
-
- constexpr ArchiveFormat(BackingEnum backing_enum, const char* extension, const char* cmake_option)
- : backing_enum(backing_enum), m_extension(extension), m_cmake_option(cmake_option)
- {
- }
-
- constexpr operator BackingEnum() const { return backing_enum; }
- constexpr CStringView extension() const { return this->m_extension; }
- constexpr CStringView cmake_option() const { return this->m_cmake_option; }
-
- private:
- BackingEnum backing_enum;
- const char* m_extension;
- const char* m_cmake_option;
- };
-
- namespace ArchiveFormatC
- {
- constexpr const ArchiveFormat ZIP(ArchiveFormat::BackingEnum::ZIP, "zip", "zip");
- constexpr const ArchiveFormat SEVEN_ZIP(ArchiveFormat::BackingEnum::SEVEN_ZIP, "7z", "7zip");
- }
-
- static fs::path do_archive_export(const VcpkgPaths& paths,
- const fs::path& raw_exported_dir,
- const fs::path& output_dir,
- const ArchiveFormat& format)
- {
- const fs::path& cmake_exe = paths.get_tool_exe(Tools::CMAKE);
-
- const std::string exported_dir_filename = fs::u8string(raw_exported_dir.filename());
- const std::string exported_archive_filename =
- Strings::format("%s.%s", exported_dir_filename, format.extension());
- const fs::path exported_archive_path = (output_dir / exported_archive_filename);
-
- System::Command cmd;
- cmd.path_arg(cmake_exe)
- .string_arg("-E")
- .string_arg("tar")
- .string_arg("cf")
- .path_arg(exported_archive_path)
- .string_arg(Strings::concat("--format=", format.cmake_option()))
- .string_arg("--")
- .path_arg(raw_exported_dir);
-
- const int exit_code =
- System::cmd_execute_clean(cmd, System::InWorkingDirectory{raw_exported_dir.parent_path()});
- Checks::check_exit(
- VCPKG_LINE_INFO, exit_code == 0, "Error: %s creation failed", exported_archive_path.generic_string());
- return exported_archive_path;
- }
-
- static Optional<std::string> maybe_lookup(std::unordered_map<std::string, std::string> const& m,
- std::string const& key)
- {
- const auto it = m.find(key);
- if (it != m.end()) return it->second;
- return nullopt;
- }
-
- void export_integration_files(const fs::path& raw_exported_dir_path, const VcpkgPaths& paths)
- {
- const std::vector<fs::path> integration_files_relative_to_root = {
- {fs::path{"scripts"} / "buildsystems" / "msbuild" / "applocal.ps1"},
- {fs::path{"scripts"} / "buildsystems" / "msbuild" / "vcpkg.targets"},
- {fs::path{"scripts"} / "buildsystems" / "msbuild" / "vcpkg.props"},
- {fs::path{"scripts"} / "buildsystems" / "msbuild" / "vcpkg-general.xml"},
- {fs::path{"scripts"} / "buildsystems" / "vcpkg.cmake"},
- {fs::path{"scripts"} / "cmake" / "vcpkg_get_windows_sdk.cmake"},
- };
-
- Files::Filesystem& fs = paths.get_filesystem();
- for (const fs::path& file : integration_files_relative_to_root)
- {
- const fs::path source = paths.root / file;
- fs::path destination = raw_exported_dir_path / file;
- fs.create_directories(destination.parent_path(), ignore_errors);
- fs.copy_file(source, destination, fs::copy_options::overwrite_existing, VCPKG_LINE_INFO);
- }
- fs.write_contents(raw_exported_dir_path / fs::u8path(".vcpkg-root"), "", VCPKG_LINE_INFO);
- }
-
- struct ExportArguments
- {
- bool dry_run = false;
- bool raw = false;
- bool nuget = false;
- bool ifw = false;
- bool zip = false;
- bool seven_zip = false;
- bool chocolatey = false;
- bool prefab = false;
- bool all_installed = false;
-
- Optional<std::string> maybe_output;
- fs::path output_dir;
-
- Optional<std::string> maybe_nuget_id;
- Optional<std::string> maybe_nuget_version;
- Optional<std::string> maybe_nuget_description;
-
- IFW::Options ifw_options;
- Prefab::Options prefab_options;
- Chocolatey::Options chocolatey_options;
- std::vector<PackageSpec> specs;
- };
-
- static constexpr StringLiteral OPTION_OUTPUT = "output";
- static constexpr StringLiteral OPTION_OUTPUT_DIR = "output-dir";
- static constexpr StringLiteral OPTION_DRY_RUN = "dry-run";
- static constexpr StringLiteral OPTION_RAW = "raw";
- static constexpr StringLiteral OPTION_NUGET = "nuget";
- static constexpr StringLiteral OPTION_IFW = "ifw";
- static constexpr StringLiteral OPTION_ZIP = "zip";
- static constexpr StringLiteral OPTION_SEVEN_ZIP = "7zip";
- static constexpr StringLiteral OPTION_NUGET_ID = "nuget-id";
- static constexpr StringLiteral OPTION_NUGET_DESCRIPTION = "nuget-description";
- static constexpr StringLiteral OPTION_NUGET_VERSION = "nuget-version";
- static constexpr StringLiteral OPTION_IFW_REPOSITORY_URL = "ifw-repository-url";
- static constexpr StringLiteral OPTION_IFW_PACKAGES_DIR_PATH = "ifw-packages-directory-path";
- static constexpr StringLiteral OPTION_IFW_REPOSITORY_DIR_PATH = "ifw-repository-directory-path";
- static constexpr StringLiteral OPTION_IFW_CONFIG_FILE_PATH = "ifw-configuration-file-path";
- static constexpr StringLiteral OPTION_IFW_INSTALLER_FILE_PATH = "ifw-installer-file-path";
- static constexpr StringLiteral OPTION_CHOCOLATEY = "x-chocolatey";
- static constexpr StringLiteral OPTION_CHOCOLATEY_MAINTAINER = "x-maintainer";
- static constexpr StringLiteral OPTION_CHOCOLATEY_VERSION_SUFFIX = "x-version-suffix";
- static constexpr StringLiteral OPTION_ALL_INSTALLED = "x-all-installed";
-
- static constexpr StringLiteral OPTION_PREFAB = "prefab";
- static constexpr StringLiteral OPTION_PREFAB_GROUP_ID = "prefab-group-id";
- static constexpr StringLiteral OPTION_PREFAB_ARTIFACT_ID = "prefab-artifact-id";
- static constexpr StringLiteral OPTION_PREFAB_VERSION = "prefab-version";
- static constexpr StringLiteral OPTION_PREFAB_SDK_MIN_VERSION = "prefab-min-sdk";
- static constexpr StringLiteral OPTION_PREFAB_SDK_TARGET_VERSION = "prefab-target-sdk";
- static constexpr StringLiteral OPTION_PREFAB_ENABLE_MAVEN = "prefab-maven";
- static constexpr StringLiteral OPTION_PREFAB_ENABLE_DEBUG = "prefab-debug";
-
- static constexpr std::array<CommandSwitch, 11> EXPORT_SWITCHES = {{
- {OPTION_DRY_RUN, "Do not actually export"},
- {OPTION_RAW, "Export to an uncompressed directory"},
- {OPTION_NUGET, "Export a NuGet package"},
- {OPTION_IFW, "Export to an IFW-based installer"},
- {OPTION_ZIP, "Export to a zip file"},
- {OPTION_SEVEN_ZIP, "Export to a 7zip (.7z) file"},
- {OPTION_CHOCOLATEY, "Export a Chocolatey package (experimental feature)"},
- {OPTION_PREFAB, "Export to Prefab format"},
- {OPTION_PREFAB_ENABLE_MAVEN, "Enable maven"},
- {OPTION_PREFAB_ENABLE_DEBUG, "Enable prefab debug"},
- {OPTION_ALL_INSTALLED, "Export all installed packages"},
- }};
-
- static constexpr std::array<CommandSetting, 17> EXPORT_SETTINGS = {{
- {OPTION_OUTPUT, "Specify the output name (used to construct filename)"},
- {OPTION_OUTPUT_DIR, "Specify the output directory for produced artifacts"},
- {OPTION_NUGET_ID, "Specify the id for the exported NuGet package (overrides --output)"},
- {OPTION_NUGET_DESCRIPTION, "Specify a description for the exported NuGet package"},
- {OPTION_NUGET_VERSION, "Specify the version for the exported NuGet package"},
- {OPTION_IFW_REPOSITORY_URL, "Specify the remote repository URL for the online installer"},
- {OPTION_IFW_PACKAGES_DIR_PATH, "Specify the temporary directory path for the repacked packages"},
- {OPTION_IFW_REPOSITORY_DIR_PATH, "Specify the directory path for the exported repository"},
- {OPTION_IFW_CONFIG_FILE_PATH, "Specify the temporary file path for the installer configuration"},
- {OPTION_IFW_INSTALLER_FILE_PATH, "Specify the file path for the exported installer"},
- {OPTION_CHOCOLATEY_MAINTAINER,
- "Specify the maintainer for the exported Chocolatey package (experimental feature)"},
- {OPTION_CHOCOLATEY_VERSION_SUFFIX,
- "Specify the version suffix to add for the exported Chocolatey package (experimental feature)"},
- {OPTION_PREFAB_GROUP_ID, "GroupId uniquely identifies your project according maven specifications"},
- {OPTION_PREFAB_ARTIFACT_ID, "Artifact Id is the name of the project according maven specifications"},
- {OPTION_PREFAB_VERSION, "Version is the name of the project according maven specifications"},
- {OPTION_PREFAB_SDK_MIN_VERSION, "Android minimum supported sdk version"},
- {OPTION_PREFAB_SDK_TARGET_VERSION, "Android target sdk version"},
- }};
-
- const CommandStructure COMMAND_STRUCTURE = {
- create_example_string("export zlib zlib:x64-windows boost --nuget"),
- 0,
- SIZE_MAX,
- {EXPORT_SWITCHES, EXPORT_SETTINGS},
- nullptr,
- };
-
- static ExportArguments handle_export_command_arguments(const VcpkgPaths& paths,
- const VcpkgCmdArguments& args,
- Triplet default_triplet,
- const StatusParagraphs& status_db)
- {
- ExportArguments ret;
-
- const auto options = args.parse_arguments(COMMAND_STRUCTURE);
-
- ret.dry_run = options.switches.find(OPTION_DRY_RUN) != options.switches.cend();
- ret.raw = options.switches.find(OPTION_RAW) != options.switches.cend();
- ret.nuget = options.switches.find(OPTION_NUGET) != options.switches.cend();
- ret.ifw = options.switches.find(OPTION_IFW) != options.switches.cend();
- ret.zip = options.switches.find(OPTION_ZIP) != options.switches.cend();
- ret.seven_zip = options.switches.find(OPTION_SEVEN_ZIP) != options.switches.cend();
- ret.chocolatey = options.switches.find(OPTION_CHOCOLATEY) != options.switches.cend();
- ret.prefab = options.switches.find(OPTION_PREFAB) != options.switches.cend();
- ret.prefab_options.enable_maven = options.switches.find(OPTION_PREFAB_ENABLE_MAVEN) != options.switches.cend();
- ret.prefab_options.enable_debug = options.switches.find(OPTION_PREFAB_ENABLE_DEBUG) != options.switches.cend();
- ret.maybe_output = maybe_lookup(options.settings, OPTION_OUTPUT);
- auto maybe_output_dir = maybe_lookup(options.settings, OPTION_OUTPUT_DIR);
- if (auto output_dir = maybe_output_dir.get())
- {
- ret.output_dir = Files::combine(paths.original_cwd, fs::u8path(*output_dir));
- }
- else
- {
- ret.output_dir = paths.root;
- }
- ret.all_installed = options.switches.find(OPTION_ALL_INSTALLED) != options.switches.end();
-
- if (ret.all_installed)
- {
- auto installed_ipv = get_installed_ports(status_db);
- std::transform(installed_ipv.begin(),
- installed_ipv.end(),
- std::back_inserter(ret.specs),
- [](const auto& ipv) { return ipv.spec(); });
- }
- else
- {
- // input sanitization
- ret.specs = Util::fmap(args.command_arguments, [&](auto&& arg) {
- return Input::check_and_get_package_spec(
- std::string(arg), default_triplet, COMMAND_STRUCTURE.example_text);
- });
- }
-
- if (!ret.raw && !ret.nuget && !ret.ifw && !ret.zip && !ret.seven_zip && !ret.dry_run && !ret.chocolatey &&
- !ret.prefab)
- {
- System::print2(
- System::Color::error,
- "Must provide at least one export type: --raw --nuget --ifw --zip --7zip --chocolatey --prefab\n");
- System::print2(COMMAND_STRUCTURE.example_text);
- Checks::exit_fail(VCPKG_LINE_INFO);
- }
-
- struct OptionPair
- {
- const StringLiteral& name;
- Optional<std::string>& out_opt;
- };
- const auto options_implies = [&](const StringLiteral& main_opt_name,
- bool is_main_opt,
- const std::initializer_list<OptionPair>& implying_opts) {
- if (is_main_opt)
- {
- for (auto&& opt : implying_opts)
- opt.out_opt = maybe_lookup(options.settings, opt.name);
- }
- else
- {
- for (auto&& opt : implying_opts)
- Checks::check_exit(VCPKG_LINE_INFO,
- !maybe_lookup(options.settings, opt.name),
- "%s is only valid with %s",
- opt.name,
- main_opt_name);
- }
- };
-
-#if defined(_MSC_VER) && _MSC_VER <= 1900
-// there's a bug in VS 2015 that causes a bunch of "unreferenced local variable" warnings
-#pragma warning(push)
-#pragma warning(disable : 4189)
-#endif
-
- options_implies(OPTION_NUGET,
- ret.nuget,
- {
- {OPTION_NUGET_ID, ret.maybe_nuget_id},
- {OPTION_NUGET_VERSION, ret.maybe_nuget_version},
- {OPTION_NUGET_DESCRIPTION, ret.maybe_nuget_description},
- });
-
- options_implies(OPTION_IFW,
- ret.ifw,
- {
- {OPTION_IFW_REPOSITORY_URL, ret.ifw_options.maybe_repository_url},
- {OPTION_IFW_PACKAGES_DIR_PATH, ret.ifw_options.maybe_packages_dir_path},
- {OPTION_IFW_REPOSITORY_DIR_PATH, ret.ifw_options.maybe_repository_dir_path},
- {OPTION_IFW_CONFIG_FILE_PATH, ret.ifw_options.maybe_config_file_path},
- {OPTION_IFW_INSTALLER_FILE_PATH, ret.ifw_options.maybe_installer_file_path},
- });
-
- options_implies(OPTION_PREFAB,
- ret.prefab,
- {
- {OPTION_PREFAB_ARTIFACT_ID, ret.prefab_options.maybe_artifact_id},
- {OPTION_PREFAB_GROUP_ID, ret.prefab_options.maybe_group_id},
- {OPTION_PREFAB_SDK_MIN_VERSION, ret.prefab_options.maybe_min_sdk},
- {OPTION_PREFAB_SDK_TARGET_VERSION, ret.prefab_options.maybe_target_sdk},
- {OPTION_PREFAB_VERSION, ret.prefab_options.maybe_version},
- });
-
- options_implies(OPTION_CHOCOLATEY,
- ret.chocolatey,
- {
- {OPTION_CHOCOLATEY_MAINTAINER, ret.chocolatey_options.maybe_maintainer},
- {OPTION_CHOCOLATEY_VERSION_SUFFIX, ret.chocolatey_options.maybe_version_suffix},
- });
-
-#if defined(_MSC_VER) && _MSC_VER <= 1900
-#pragma warning(pop)
-#endif
- return ret;
- }
-
- static void print_next_step_info(const fs::path& prefix)
- {
- const fs::path cmake_toolchain = prefix / "scripts" / "buildsystems" / "vcpkg.cmake";
- const System::CMakeVariable cmake_variable =
- System::CMakeVariable("CMAKE_TOOLCHAIN_FILE", cmake_toolchain.generic_string());
- System::print2("\n"
- "To use the exported libraries in CMake projects use:"
- "\n"
- " ",
- cmake_variable.s,
- "\n\n");
- }
-
- static void handle_raw_based_export(Span<const ExportPlanAction> export_plan,
- const ExportArguments& opts,
- const std::string& export_id,
- const VcpkgPaths& paths)
- {
- Files::Filesystem& fs = paths.get_filesystem();
- const fs::path raw_exported_dir_path = opts.output_dir / export_id;
- fs.remove_all(raw_exported_dir_path, VCPKG_LINE_INFO);
-
- // TODO: error handling
- std::error_code ec;
- fs.create_directory(raw_exported_dir_path, ec);
-
- // execute the plan
- for (const ExportPlanAction& action : export_plan)
- {
- if (action.plan_type != ExportPlanType::ALREADY_BUILT)
- {
- Checks::unreachable(VCPKG_LINE_INFO);
- }
-
- const std::string display_name = action.spec.to_string();
- System::print2("Exporting package ", display_name, "...\n");
-
- const BinaryParagraph& binary_paragraph = action.core_paragraph().value_or_exit(VCPKG_LINE_INFO);
-
- const InstallDir dirs = InstallDir::from_destination_root(
- raw_exported_dir_path / "installed",
- action.spec.triplet().to_string(),
- raw_exported_dir_path / "installed" / "vcpkg" / "info" / (binary_paragraph.fullstem() + ".list"));
-
- auto lines = fs.read_lines(paths.listfile_path(binary_paragraph)).value_or_exit(VCPKG_LINE_INFO);
- std::vector<fs::path> files;
- for (auto&& suffix : lines)
- {
- if (suffix.empty()) continue;
- if (suffix.back() == '/') suffix.pop_back();
- if (suffix == action.spec.triplet().to_string()) continue;
- files.push_back(paths.installed / fs::u8path(suffix));
- }
-
- Install::install_files_and_write_listfile(
- fs, paths.installed / action.spec.triplet().to_string(), files, dirs);
- }
-
- // Copy files needed for integration
- export_integration_files(raw_exported_dir_path, paths);
-
- if (opts.raw)
- {
- System::printf(System::Color::success,
- R"(Files exported at: "%s")"
- "\n",
- fs::u8string(raw_exported_dir_path));
- print_next_step_info(raw_exported_dir_path);
- }
-
- if (opts.nuget)
- {
- System::print2("Packing nuget package...\n");
-
- const std::string nuget_id = opts.maybe_nuget_id.value_or(raw_exported_dir_path.filename().string());
- const std::string nuget_version = opts.maybe_nuget_version.value_or("1.0.0");
- const std::string nuget_description = opts.maybe_nuget_description.value_or("Vcpkg NuGet export");
- const fs::path output_path = do_nuget_export(
- paths, nuget_id, nuget_version, nuget_description, raw_exported_dir_path, opts.output_dir);
- System::print2(System::Color::success, "NuGet package exported at: ", fs::u8string(output_path), "\n");
-
- System::printf(R"(
-With a project open, go to Tools->NuGet Package Manager->Package Manager Console and paste:
- Install-Package %s -Source "%s"
-)"
- "\n\n",
- nuget_id,
- fs::u8string(output_path.parent_path()));
- }
-
- if (opts.zip)
- {
- System::print2("Creating zip archive...\n");
- const fs::path output_path =
- do_archive_export(paths, raw_exported_dir_path, opts.output_dir, ArchiveFormatC::ZIP);
- System::print2(System::Color::success, "Zip archive exported at: ", fs::u8string(output_path), "\n");
- print_next_step_info("[...]");
- }
-
- if (opts.seven_zip)
- {
- System::print2("Creating 7zip archive...\n");
- const fs::path output_path =
- do_archive_export(paths, raw_exported_dir_path, opts.output_dir, ArchiveFormatC::SEVEN_ZIP);
- System::print2(System::Color::success, "7zip archive exported at: ", fs::u8string(output_path), "\n");
- print_next_step_info("[...]");
- }
-
- if (!opts.raw)
- {
- fs.remove_all(raw_exported_dir_path, VCPKG_LINE_INFO);
- }
- }
-
- void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, Triplet default_triplet)
- {
- if (paths.manifest_mode_enabled())
- {
- Checks::exit_maybe_upgrade(
- VCPKG_LINE_INFO,
- "vcpkg export does not support manifest mode, in order to allow for future design considerations. You "
- "may use export in classic mode by running vcpkg outside of a manifest-based project.");
- }
- const StatusParagraphs status_db = database_load_check(paths);
- const auto opts = handle_export_command_arguments(paths, args, default_triplet, status_db);
- for (auto&& spec : opts.specs)
- Input::check_triplet(spec.triplet(), paths);
-
- // Load ports from ports dirs
- PortFileProvider::PathsPortFileProvider provider(paths, args.overlay_ports);
-
- // create the plan
- std::vector<ExportPlanAction> export_plan = Dependencies::create_export_plan(opts.specs, status_db);
- Checks::check_exit(VCPKG_LINE_INFO, !export_plan.empty(), "Export plan cannot be empty");
-
- std::map<ExportPlanType, std::vector<const ExportPlanAction*>> group_by_plan_type;
- Util::group_by(export_plan, &group_by_plan_type, [](const ExportPlanAction& p) { return p.plan_type; });
- print_plan(group_by_plan_type);
-
- const bool has_non_user_requested_packages =
- Util::find_if(export_plan, [](const ExportPlanAction& package) -> bool {
- return package.request_type != RequestType::USER_REQUESTED;
- }) != export_plan.cend();
-
- if (has_non_user_requested_packages)
- {
- System::print2(System::Color::warning,
- "Additional packages (*) need to be exported to complete this operation.\n");
- }
-
- const auto it = group_by_plan_type.find(ExportPlanType::NOT_BUILT);
- if (it != group_by_plan_type.cend() && !it->second.empty())
- {
- System::print2(System::Color::error, "There are packages that have not been built.\n");
-
- // No need to show all of them, just the user-requested ones. Dependency resolution will handle the rest.
- std::vector<const ExportPlanAction*> unbuilt = it->second;
- Util::erase_remove_if(
- unbuilt, [](const ExportPlanAction* a) { return a->request_type != RequestType::USER_REQUESTED; });
-
- const auto s = Strings::join(" ", unbuilt, [](const ExportPlanAction* a) { return a->spec.to_string(); });
- System::print2("To build them, run:\n"
- " vcpkg install ",
- s,
- "\n");
- Checks::exit_fail(VCPKG_LINE_INFO);
- }
-
- if (opts.dry_run)
- {
- Checks::exit_success(VCPKG_LINE_INFO);
- }
-
- std::string export_id = opts.maybe_output.value_or(create_export_id());
-
- if (opts.raw || opts.nuget || opts.zip || opts.seven_zip)
- {
- handle_raw_based_export(export_plan, opts, export_id, paths);
- }
-
- if (opts.ifw)
- {
- IFW::do_export(export_plan, export_id, opts.ifw_options, paths);
-
- print_next_step_info("@RootDir@/src/vcpkg");
- }
-
- if (opts.chocolatey)
- {
- Chocolatey::do_export(export_plan, paths, opts.chocolatey_options);
- }
-
- if (opts.prefab)
- {
- Prefab::do_export(export_plan, paths, opts.prefab_options, default_triplet);
- }
-
- Checks::exit_success(VCPKG_LINE_INFO);
- }
-
- void ExportCommand::perform_and_exit(const VcpkgCmdArguments& args,
- const VcpkgPaths& paths,
- Triplet default_triplet) const
- {
- Export::perform_and_exit(args, paths, default_triplet);
- }
-}
diff --git a/toolsrc/src/vcpkg/export.ifw.cpp b/toolsrc/src/vcpkg/export.ifw.cpp
deleted file mode 100644
index 74b06f524..000000000
--- a/toolsrc/src/vcpkg/export.ifw.cpp
+++ /dev/null
@@ -1,517 +0,0 @@
-#include <vcpkg/base/system.print.h>
-#include <vcpkg/base/system.process.h>
-
-#include <vcpkg/commands.h>
-#include <vcpkg/export.h>
-#include <vcpkg/export.ifw.h>
-#include <vcpkg/install.h>
-#include <vcpkg/tools.h>
-
-namespace vcpkg::Export::IFW
-{
- using Dependencies::ExportPlanAction;
- using Dependencies::ExportPlanType;
- using Install::InstallDir;
-
- namespace
- {
- std::string create_release_date()
- {
- const tm date_time = Chrono::get_current_date_time_local();
-
- // Format is: YYYY-mm-dd
- // 10 characters + 1 null terminating character will be written for a total of 11 chars
- char mbstr[11];
- const size_t bytes_written = std::strftime(mbstr, sizeof(mbstr), "%Y-%m-%d", &date_time);
- Checks::check_exit(VCPKG_LINE_INFO,
- bytes_written == 10,
- "Expected 10 bytes to be written, but %u were written",
- bytes_written);
- const std::string date_time_as_string(mbstr);
- return date_time_as_string;
- }
-
- std::string safe_rich_from_plain_text(const std::string& text)
- {
- // match standalone ampersand, no HTML number or name
- std::regex standalone_ampersand(R"###(&(?!(#[0-9]+|\w+);))###");
-
- return std::regex_replace(text, standalone_ampersand, "&amp;");
- }
-
- fs::path get_packages_dir_path(const std::string& export_id,
- const Options& ifw_options,
- const VcpkgPaths& paths)
- {
- return ifw_options.maybe_packages_dir_path.has_value()
- ? fs::path(ifw_options.maybe_packages_dir_path.value_or_exit(VCPKG_LINE_INFO))
- : paths.root / (export_id + "-ifw-packages");
- }
-
- fs::path get_repository_dir_path(const std::string& export_id,
- const Options& ifw_options,
- const VcpkgPaths& paths)
- {
- return ifw_options.maybe_repository_dir_path.has_value()
- ? fs::path(ifw_options.maybe_repository_dir_path.value_or_exit(VCPKG_LINE_INFO))
- : paths.root / (export_id + "-ifw-repository");
- }
-
- fs::path get_config_file_path(const std::string& export_id, const Options& ifw_options, const VcpkgPaths& paths)
- {
- return ifw_options.maybe_config_file_path.has_value()
- ? fs::path(ifw_options.maybe_config_file_path.value_or_exit(VCPKG_LINE_INFO))
- : paths.root / (export_id + "-ifw-configuration.xml");
- }
-
- fs::path get_installer_file_path(const std::string& export_id,
- const Options& ifw_options,
- const VcpkgPaths& paths)
- {
- return ifw_options.maybe_installer_file_path.has_value()
- ? fs::path(ifw_options.maybe_installer_file_path.value_or_exit(VCPKG_LINE_INFO))
- : paths.root / (export_id + "-ifw-installer.exe");
- }
-
- fs::path export_real_package(const fs::path& ifw_packages_dir_path,
- const ExportPlanAction& action,
- Files::Filesystem& fs)
- {
- std::error_code ec;
-
- const BinaryParagraph& binary_paragraph = action.core_paragraph().value_or_exit(VCPKG_LINE_INFO);
-
- // Prepare meta dir
- const fs::path package_xml_file_path =
- ifw_packages_dir_path /
- Strings::format("packages.%s.%s", action.spec.name(), action.spec.triplet().canonical_name()) / "meta" /
- "package.xml";
- const fs::path package_xml_dir_path = package_xml_file_path.parent_path();
- fs.create_directories(package_xml_dir_path, ec);
- Checks::check_exit(VCPKG_LINE_INFO,
- !ec,
- "Could not create directory for package file %s",
- fs::generic_u8string(package_xml_file_path));
-
- auto deps = Strings::join(
- ",", binary_paragraph.dependencies, [](const std::string& dep) { return "packages." + dep + ":"; });
-
- if (!deps.empty()) deps = "\n <Dependencies>" + deps + "</Dependencies>";
-
- fs.write_contents(package_xml_file_path,
- Strings::format(
- R"###(<?xml version="1.0"?>
-<Package>
- <DisplayName>%s</DisplayName>
- <Version>%s</Version>
- <ReleaseDate>%s</ReleaseDate>
- <AutoDependOn>packages.%s:,triplets.%s:</AutoDependOn>%s
- <Virtual>true</Virtual>
-</Package>
-)###",
- action.spec.to_string(),
- binary_paragraph.version,
- create_release_date(),
- action.spec.name(),
- action.spec.triplet().canonical_name(),
- deps),
- VCPKG_LINE_INFO);
-
- // Return dir path for export package data
- return ifw_packages_dir_path /
- Strings::format("packages.%s.%s", action.spec.name(), action.spec.triplet().canonical_name()) /
- "data" / "installed";
- }
-
- void export_unique_packages(const fs::path& raw_exported_dir_path,
- std::map<std::string, const ExportPlanAction*> unique_packages,
- Files::Filesystem& fs)
- {
- std::error_code ec;
-
- // packages
-
- fs::path package_xml_file_path = raw_exported_dir_path / "packages" / "meta" / "package.xml";
- fs::path package_xml_dir_path = package_xml_file_path.parent_path();
- fs.create_directories(package_xml_dir_path, ec);
- Checks::check_exit(VCPKG_LINE_INFO,
- !ec,
- "Could not create directory for package file %s",
- fs::generic_u8string(package_xml_file_path));
- fs.write_contents(package_xml_file_path,
- Strings::format(
- R"###(<?xml version="1.0"?>
-<Package>
- <DisplayName>Packages</DisplayName>
- <Version>1.0.0</Version>
- <ReleaseDate>%s</ReleaseDate>
-</Package>
-)###",
- create_release_date()),
- VCPKG_LINE_INFO);
-
- for (const auto& unique_package : unique_packages)
- {
- const ExportPlanAction& action = *(unique_package.second);
- const BinaryParagraph& binary_paragraph = action.core_paragraph().value_or_exit(VCPKG_LINE_INFO);
-
- package_xml_file_path = raw_exported_dir_path / Strings::format("packages.%s", unique_package.first) /
- "meta" / "package.xml";
- package_xml_dir_path = package_xml_file_path.parent_path();
- fs.create_directories(package_xml_dir_path, ec);
- Checks::check_exit(VCPKG_LINE_INFO,
- !ec,
- "Could not create directory for package file %s",
- fs::generic_u8string(package_xml_file_path));
-
- fs.write_contents(package_xml_file_path,
- Strings::format(
- R"###(<?xml version="1.0"?>
-<Package>
- <DisplayName>%s</DisplayName>
- <Description>%s</Description>
- <Version>%s</Version>
- <ReleaseDate>%s</ReleaseDate>
-</Package>
-)###",
- action.spec.name(),
- safe_rich_from_plain_text(Strings::join("\n", binary_paragraph.description)),
- binary_paragraph.version,
- create_release_date()),
- VCPKG_LINE_INFO);
- }
- }
-
- void export_unique_triplets(const fs::path& raw_exported_dir_path,
- std::set<std::string> unique_triplets,
- Files::Filesystem& fs)
- {
- std::error_code ec;
-
- // triplets
-
- fs::path package_xml_file_path = raw_exported_dir_path / "triplets" / "meta" / "package.xml";
- fs::path package_xml_dir_path = package_xml_file_path.parent_path();
- fs.create_directories(package_xml_dir_path, ec);
- Checks::check_exit(VCPKG_LINE_INFO,
- !ec,
- "Could not create directory for package file %s",
- fs::generic_u8string(package_xml_file_path));
- fs.write_contents(package_xml_file_path,
- Strings::format(
- R"###(<?xml version="1.0"?>
-<Package>
- <DisplayName>Triplets</DisplayName>
- <Version>1.0.0</Version>
- <ReleaseDate>%s</ReleaseDate>
-</Package>
-)###",
- create_release_date()),
- VCPKG_LINE_INFO);
-
- for (const std::string& triplet : unique_triplets)
- {
- package_xml_file_path =
- raw_exported_dir_path / Strings::format("triplets.%s", triplet) / "meta" / "package.xml";
- package_xml_dir_path = package_xml_file_path.parent_path();
- fs.create_directories(package_xml_dir_path, ec);
- Checks::check_exit(VCPKG_LINE_INFO,
- !ec,
- "Could not create directory for package file %s",
- fs::generic_u8string(package_xml_file_path));
- fs.write_contents(package_xml_file_path,
- Strings::format(
- R"###(<?xml version="1.0"?>
-<Package>
- <DisplayName>%s</DisplayName>
- <Version>1.0.0</Version>
- <ReleaseDate>%s</ReleaseDate>
-</Package>
-)###",
- triplet,
- create_release_date()),
- VCPKG_LINE_INFO);
- }
- }
-
- void export_integration(const fs::path& raw_exported_dir_path, Files::Filesystem& fs)
- {
- std::error_code ec;
-
- // integration
- fs::path package_xml_file_path = raw_exported_dir_path / "integration" / "meta" / "package.xml";
- fs::path package_xml_dir_path = package_xml_file_path.parent_path();
- fs.create_directories(package_xml_dir_path, ec);
- Checks::check_exit(VCPKG_LINE_INFO,
- !ec,
- "Could not create directory for package file %s",
- fs::generic_u8string(package_xml_file_path));
-
- fs.write_contents(package_xml_file_path,
- Strings::format(
- R"###(<?xml version="1.0"?>
-<Package>
- <DisplayName>Integration</DisplayName>
- <Version>1.0.0</Version>
- <ReleaseDate>%s</ReleaseDate>
-</Package>
-)###",
- create_release_date()),
- VCPKG_LINE_INFO);
- }
-
- void export_config(const std::string& export_id, const Options& ifw_options, const VcpkgPaths& paths)
- {
- std::error_code ec;
- Files::Filesystem& fs = paths.get_filesystem();
-
- const fs::path config_xml_file_path = get_config_file_path(export_id, ifw_options, paths);
-
- fs::path config_xml_dir_path = config_xml_file_path.parent_path();
- fs.create_directories(config_xml_dir_path, ec);
- Checks::check_exit(VCPKG_LINE_INFO,
- !ec,
- "Could not create directory for configuration file %s",
- fs::generic_u8string(config_xml_file_path));
-
- std::string formatted_repo_url;
- std::string ifw_repo_url = ifw_options.maybe_repository_url.value_or("");
- if (!ifw_repo_url.empty())
- {
- formatted_repo_url = Strings::format(R"###(
- <RemoteRepositories>
- <Repository>
- <Url>%s</Url>
- </Repository>
- </RemoteRepositories>)###",
- ifw_repo_url);
- }
-
- fs.write_contents(config_xml_file_path,
- Strings::format(
- R"###(<?xml version="1.0"?>
-<Installer>
- <Name>vcpkg</Name>
- <Version>1.0.0</Version>
- <StartMenuDir>vcpkg</StartMenuDir>
- <TargetDir>@RootDir@/src/vcpkg</TargetDir>%s
-</Installer>
-)###",
- formatted_repo_url),
- VCPKG_LINE_INFO);
- }
-
- void export_maintenance_tool(const fs::path& ifw_packages_dir_path, const VcpkgPaths& paths)
- {
- System::print2("Exporting maintenance tool...\n");
-
- std::error_code ec;
- Files::Filesystem& fs = paths.get_filesystem();
-
- const fs::path& installerbase_exe = paths.get_tool_exe(Tools::IFW_INSTALLER_BASE);
- fs::path tempmaintenancetool = ifw_packages_dir_path / "maintenance" / "data" / "tempmaintenancetool.exe";
- fs.create_directories(tempmaintenancetool.parent_path(), ec);
- Checks::check_exit(VCPKG_LINE_INFO,
- !ec,
- "Could not create directory for package file %s",
- fs::generic_u8string(tempmaintenancetool));
- fs.copy_file(installerbase_exe, tempmaintenancetool, fs::copy_options::overwrite_existing, ec);
- Checks::check_exit(
- VCPKG_LINE_INFO, !ec, "Could not write package file %s", fs::generic_u8string(tempmaintenancetool));
-
- fs::path package_xml_file_path = ifw_packages_dir_path / "maintenance" / "meta" / "package.xml";
- fs::path package_xml_dir_path = package_xml_file_path.parent_path();
- fs.create_directories(package_xml_dir_path, ec);
- Checks::check_exit(VCPKG_LINE_INFO,
- !ec,
- "Could not create directory for package file %s",
- fs::generic_u8string(package_xml_file_path));
- fs.write_contents(package_xml_file_path,
- Strings::format(
- R"###(<?xml version="1.0"?>
-<Package>
- <DisplayName>Maintenance Tool</DisplayName>
- <Description>Maintenance Tool</Description>
- <Version>1.0.0</Version>
- <ReleaseDate>%s</ReleaseDate>
- <Script>maintenance.qs</Script>
- <Essential>true</Essential>
- <Virtual>true</Virtual>
- <ForcedInstallation>true</ForcedInstallation>
-</Package>
-)###",
- create_release_date()),
- VCPKG_LINE_INFO);
- const fs::path script_source = paths.root / "scripts" / "ifw" / "maintenance.qs";
- const fs::path script_destination = ifw_packages_dir_path / "maintenance" / "meta" / "maintenance.qs";
- fs.copy_file(script_source, script_destination, fs::copy_options::overwrite_existing, ec);
- Checks::check_exit(
- VCPKG_LINE_INFO, !ec, "Could not write package file %s", fs::generic_u8string(script_destination));
-
- System::print2("Exporting maintenance tool... done\n");
- }
-
- void do_repository(const std::string& export_id, const Options& ifw_options, const VcpkgPaths& paths)
- {
- const fs::path& repogen_exe = paths.get_tool_exe(Tools::IFW_REPOGEN);
- const fs::path packages_dir = get_packages_dir_path(export_id, ifw_options, paths);
- const fs::path repository_dir = get_repository_dir_path(export_id, ifw_options, paths);
-
- System::print2("Generating repository ", fs::generic_u8string(repository_dir), "...\n");
-
- std::error_code ec;
- fs::path failure_point;
- Files::Filesystem& fs = paths.get_filesystem();
-
- fs.remove_all(repository_dir, ec, failure_point);
- Checks::check_exit(VCPKG_LINE_INFO,
- !ec,
- "Could not remove outdated repository directory %s due to file %s",
- fs::generic_u8string(repository_dir),
- failure_point.string());
-
- auto cmd_line =
- System::Command(repogen_exe).string_arg("--packages").path_arg(packages_dir).path_arg(repository_dir);
-
- const int exit_code =
- System::cmd_execute_and_capture_output(cmd_line, System::get_clean_environment()).exit_code;
- Checks::check_exit(VCPKG_LINE_INFO, exit_code == 0, "Error: IFW repository generating failed");
-
- System::printf(
- System::Color::success, "Generating repository %s... done.\n", fs::generic_u8string(repository_dir));
- }
-
- void do_installer(const std::string& export_id, const Options& ifw_options, const VcpkgPaths& paths)
- {
- const fs::path& binarycreator_exe = paths.get_tool_exe(Tools::IFW_BINARYCREATOR);
- const fs::path config_file = get_config_file_path(export_id, ifw_options, paths);
- const fs::path packages_dir = get_packages_dir_path(export_id, ifw_options, paths);
- const fs::path repository_dir = get_repository_dir_path(export_id, ifw_options, paths);
- const fs::path installer_file = get_installer_file_path(export_id, ifw_options, paths);
-
- System::printf("Generating installer %s...\n", fs::generic_u8string(installer_file));
-
- System::Command cmd_line;
-
- std::string ifw_repo_url = ifw_options.maybe_repository_url.value_or("");
- if (!ifw_repo_url.empty())
- {
- cmd_line = System::Command(binarycreator_exe)
- .string_arg("--online-only")
- .string_arg("--config")
- .path_arg(config_file)
- .string_arg("--repository")
- .path_arg(repository_dir)
- .path_arg(installer_file);
- }
- else
- {
- cmd_line = System::Command(binarycreator_exe)
- .string_arg("--config")
- .path_arg(config_file)
- .string_arg("--packages")
- .path_arg(packages_dir)
- .path_arg(installer_file);
- }
-
- const int exit_code =
- System::cmd_execute_and_capture_output(cmd_line, System::get_clean_environment()).exit_code;
- Checks::check_exit(VCPKG_LINE_INFO, exit_code == 0, "Error: IFW installer generating failed");
-
- System::printf(
- System::Color::success, "Generating installer %s... done.\n", fs::generic_u8string(installer_file));
- }
- }
-
- void do_export(const std::vector<ExportPlanAction>& export_plan,
- const std::string& export_id,
- const Options& ifw_options,
- const VcpkgPaths& paths)
- {
- std::error_code ec;
- fs::path failure_point;
- Files::Filesystem& fs = paths.get_filesystem();
-
- // Prepare packages directory
- const fs::path ifw_packages_dir_path = get_packages_dir_path(export_id, ifw_options, paths);
-
- fs.remove_all(ifw_packages_dir_path, ec, failure_point);
- Checks::check_exit(VCPKG_LINE_INFO,
- !ec,
- "Could not remove outdated packages directory %s due to file %s",
- fs::generic_u8string(ifw_packages_dir_path),
- failure_point.string());
-
- fs.create_directory(ifw_packages_dir_path, ec);
- Checks::check_exit(VCPKG_LINE_INFO,
- !ec,
- "Could not create packages directory %s",
- fs::generic_u8string(ifw_packages_dir_path));
-
- // Export maintenance tool
- export_maintenance_tool(ifw_packages_dir_path, paths);
-
- System::printf("Exporting packages %s...\n", fs::generic_u8string(ifw_packages_dir_path));
-
- // execute the plan
- std::map<std::string, const ExportPlanAction*> unique_packages;
- std::set<std::string> unique_triplets;
- for (const ExportPlanAction& action : export_plan)
- {
- if (action.plan_type != ExportPlanType::ALREADY_BUILT)
- {
- Checks::unreachable(VCPKG_LINE_INFO);
- }
-
- System::print2("Exporting package ", action.spec, "...\n");
-
- const BinaryParagraph& binary_paragraph = action.core_paragraph().value_or_exit(VCPKG_LINE_INFO);
-
- unique_packages[action.spec.name()] = &action;
- unique_triplets.insert(action.spec.triplet().canonical_name());
-
- // Export real package and return data dir for installation
- fs::path ifw_package_dir_path = export_real_package(ifw_packages_dir_path, action, fs);
-
- // Copy package data
- const InstallDir dirs = InstallDir::from_destination_root(ifw_package_dir_path,
- action.spec.triplet().to_string(),
- ifw_package_dir_path / "vcpkg" / "info" /
- (binary_paragraph.fullstem() + ".list"));
-
- Install::install_package_and_write_listfile(paths, action.spec, dirs);
- }
-
- System::printf("Exporting packages %s... done\n", fs::generic_u8string(ifw_packages_dir_path));
-
- const fs::path config_file = get_config_file_path(export_id, ifw_options, paths);
-
- System::printf("Generating configuration %s...\n", fs::generic_u8string(config_file));
-
- // Unique packages
- export_unique_packages(ifw_packages_dir_path, unique_packages, fs);
-
- // Unique triplets
- export_unique_triplets(ifw_packages_dir_path, unique_triplets, fs);
-
- // Copy files needed for integration
- export_integration_files(ifw_packages_dir_path / "integration" / "data", paths);
- // Integration
- export_integration(ifw_packages_dir_path, fs);
-
- // Configuration
- export_config(export_id, ifw_options, paths);
-
- System::printf("Generating configuration %s... done.\n", fs::generic_u8string(config_file));
-
- // Do repository (optional)
- std::string ifw_repo_url = ifw_options.maybe_repository_url.value_or("");
- if (!ifw_repo_url.empty())
- {
- do_repository(export_id, ifw_options, paths);
- }
-
- // Do installer
- do_installer(export_id, ifw_options, paths);
- }
-}
diff --git a/toolsrc/src/vcpkg/export.prefab.cpp b/toolsrc/src/vcpkg/export.prefab.cpp
deleted file mode 100644
index 2ca8e87f7..000000000
--- a/toolsrc/src/vcpkg/export.prefab.cpp
+++ /dev/null
@@ -1,719 +0,0 @@
-#include <vcpkg/base/checks.h>
-#include <vcpkg/base/files.h>
-#include <vcpkg/base/system.print.h>
-#include <vcpkg/base/system.process.h>
-
-#include <vcpkg/build.h>
-#include <vcpkg/cmakevars.h>
-#include <vcpkg/commands.h>
-#include <vcpkg/export.h>
-#include <vcpkg/export.prefab.h>
-#include <vcpkg/install.h>
-#include <vcpkg/tools.h>
-
-namespace vcpkg::Export::Prefab
-{
- using Dependencies::ExportPlanAction;
- using Dependencies::ExportPlanType;
- using Install::InstallDir;
- using System::CPUArchitecture;
-
- static std::vector<fs::path> find_modules(const VcpkgPaths& system, const fs::path& root, const std::string& ext)
- {
- std::vector<fs::path> paths;
- Files::Filesystem& utils = system.get_filesystem();
- std::error_code error_code;
- if (!utils.exists(root, error_code) || !utils.is_directory(root)) return paths;
-
- fs::stdfs::recursive_directory_iterator it(root);
- fs::stdfs::recursive_directory_iterator endit;
-
- while (it != endit)
- {
- if (utils.is_regular_file(*it) && it->path().extension() == ext)
- {
- paths.push_back(it->path().filename());
- }
- ++it;
- }
- return paths;
- }
-
- std::string NdkVersion::to_string()
- {
- std::string ret;
- this->to_string(ret);
- return ret;
- }
- void NdkVersion::to_string(std::string& out)
- {
- out.append("NdkVersion{major=")
- .append(std::to_string(major()))
- .append(",minor=")
- .append(std::to_string(minor()))
- .append(",patch=")
- .append(std::to_string(patch()))
- .append("}");
- }
-
- static std::string jsonify(const std::vector<std::string>& dependencies)
- {
- std::vector<std::string> deps;
- for (const auto& dep : dependencies)
- {
- deps.push_back("\"" + dep + "\"");
- }
- return Strings::join(",", deps);
- }
-
- static std::string null_if_empty(const std::string& str)
- {
- std::string copy = str;
- if (copy.size() == 0)
- {
- copy = "null";
- }
- else
- {
- copy = "\"" + copy + "\"";
- }
- return copy;
- }
-
- static std::string null_if_empty_array(const std::string& str)
- {
- std::string copy = str;
- if (copy.size() == 0)
- {
- copy = "null";
- }
- else
- {
- copy = "[" + copy + "]";
- }
- return copy;
- }
-
- std::string ABIMetadata::to_string()
- {
- std::string TEMPLATE = R"({
- "abi":"@ABI@",
- "api":@API@,
- "ndk":@NDK@,
- "stl":"@STL@"
-})";
- std::string json = Strings::replace_all(std::move(TEMPLATE), "@ABI@", abi);
- Strings::inplace_replace_all(json, "@API@", std::to_string(api));
- Strings::inplace_replace_all(json, "@NDK@", std::to_string(ndk));
- Strings::inplace_replace_all(json, "@STL@", stl);
- return json;
- }
-
- std::string PlatformModuleMetadata::to_json()
- {
- std::string TEMPLATE = R"({
- "export_libraries": @LIBRARIES@,
- "library_name": @LIBRARY_NAME@
-})";
-
- std::string json = Strings::replace_all(std::move(TEMPLATE), "@LIBRARY_NAME@", null_if_empty(library_name));
- Strings::inplace_replace_all(json, "@LIBRARIES@", null_if_empty_array(jsonify(export_libraries)));
- return json;
- }
-
- std::string ModuleMetadata::to_json()
- {
- std::string TEMPLATE = R"({
- "export_libraries": [@LIBRARIES@],
- "library_name":@LIBRARY_NAME@,
- "android": @ANDROID_METADATA@
-})";
-
- std::string json = Strings::replace_all(std::move(TEMPLATE), "@LIBRARY_NAME@", null_if_empty(library_name));
- Strings::inplace_replace_all(json, "@LIBRARIES@", jsonify(export_libraries));
- Strings::inplace_replace_all(json, "@ANDROID_METADATA@", android.to_json());
- return json;
- }
-
- std::string PackageMetadata::to_json()
- {
- std::string deps = jsonify(dependencies);
-
- std::string TEMPLATE = R"({
- "name":"@PACKAGE_NAME@",
- "schema_version": @PACKAGE_SCHEMA@,
- "dependencies":[@PACKAGE_DEPS@],
- "version":"@PACKAGE_VERSION@"
-})";
- std::string json = Strings::replace_all(std::move(TEMPLATE), "@PACKAGE_NAME@", name);
- Strings::inplace_replace_all(json, "@PACKAGE_SCHEMA@", std::to_string(schema));
- Strings::inplace_replace_all(json, "@PACKAGE_DEPS@", deps);
- Strings::inplace_replace_all(json, "@PACKAGE_VERSION@", version);
- return json;
- }
-
- Optional<std::string> find_ndk_version(const std::string& content)
- {
- std::smatch pkg_match;
- std::regex pkg_regex(R"(Pkg\.Revision\s*=\s*(\d+)(\.\d+)(\.\d+)\s*)");
-
- if (std::regex_search(content, pkg_match, pkg_regex))
- {
- for (const auto& p : pkg_match)
- {
- std::string delimiter = "=";
- std::string s = p.str();
- auto it = s.find(delimiter);
- if (it != std::string::npos)
- {
- std::string token = (s.substr(s.find(delimiter) + 1, s.size()));
- return Strings::trim(std::move(token));
- }
- }
- }
- return {};
- }
-
- Optional<NdkVersion> to_version(const std::string& version)
- {
- if (version.size() > 100) return {};
- size_t last = 0;
- size_t next = 0;
- std::vector<int> fragments(0);
-
- while ((next = version.find(".", last)) != std::string::npos)
- {
- fragments.push_back(std::stoi(version.substr(last, next - last)));
- last = next + 1;
- }
- fragments.push_back(std::stoi(version.substr(last)));
- if (fragments.size() == kFragmentSize)
- {
- return NdkVersion(fragments[0], fragments[1], fragments[2]);
- }
- return {};
- }
-
- static void compress_directory(const VcpkgPaths& paths, const fs::path& source, const fs::path& destination)
- {
- auto& fs = paths.get_filesystem();
-
- std::error_code ec;
-
- fs.remove(destination, ec);
- Checks::check_exit(
- VCPKG_LINE_INFO, !fs.exists(destination), "Could not remove file: %s", fs::u8string(destination));
-#if defined(_WIN32)
- auto&& seven_zip_exe = paths.get_tool_exe(Tools::SEVEN_ZIP);
-
- System::cmd_execute_and_capture_output(
- System::Command(seven_zip_exe).string_arg("a").path_arg(destination).path_arg(source / fs::u8path("*")),
- System::get_clean_environment());
-#else
- System::cmd_execute_clean(
- System::Command{"zip"}.string_arg("--quiet").string_arg("-r").path_arg(destination).string_arg("*"),
- System::InWorkingDirectory{source});
-#endif
- }
-
- static void maven_install(const fs::path& aar, const fs::path& pom, const Options& prefab_options)
- {
- if (prefab_options.enable_debug)
- {
- System::print2("\n[DEBUG] Installing POM and AAR file to ~/.m2\n\n");
- }
- auto cmd_line = System::Command(Tools::MAVEN);
- if (!prefab_options.enable_debug)
- {
- cmd_line.string_arg("-q");
- }
- cmd_line.string_arg("install:install-file")
- .string_arg(Strings::concat("-Dfile=", fs::u8string(aar)))
- .string_arg(Strings::concat("-DpomFile=", fs::u8string(pom)));
- const int exit_code = System::cmd_execute_clean(cmd_line);
- Checks::check_exit(
- VCPKG_LINE_INFO, exit_code == 0, "Error: %s installing maven file", fs::generic_u8string(aar));
- }
-
- static std::unique_ptr<Build::PreBuildInfo> build_info_from_triplet(
- const VcpkgPaths& paths, const std::unique_ptr<CMakeVars::CMakeVarProvider>& provider, const Triplet& triplet)
- {
- provider->load_generic_triplet_vars(triplet);
- return std::make_unique<Build::PreBuildInfo>(
- paths, triplet, provider->get_generic_triplet_vars(triplet).value_or_exit(VCPKG_LINE_INFO));
- }
-
- static bool is_supported(const Build::PreBuildInfo& info)
- {
- return Strings::case_insensitive_ascii_equals(info.cmake_system_name, "android");
- }
-
- void do_export(const std::vector<ExportPlanAction>& export_plan,
- const VcpkgPaths& paths,
- const Options& prefab_options,
- const Triplet& default_triplet)
- {
- auto provider = CMakeVars::make_triplet_cmake_var_provider(paths);
-
- {
- auto build_info = build_info_from_triplet(paths, provider, default_triplet);
- Checks::check_maybe_upgrade(
- VCPKG_LINE_INFO, is_supported(*build_info), "Currenty supported on android triplets");
- }
-
- std::vector<VcpkgPaths::TripletFile> available_triplets = paths.get_available_triplets();
-
- std::unordered_map<CPUArchitecture, std::string> required_archs = {{CPUArchitecture::ARM, "armeabi-v7a"},
- {CPUArchitecture::ARM64, "arm64-v8a"},
- {CPUArchitecture::X86, "x86"},
- {CPUArchitecture::X64, "x86_64"}};
-
- std::unordered_map<CPUArchitecture, int> cpu_architecture_api_map = {{CPUArchitecture::ARM64, 21},
- {CPUArchitecture::ARM, 16},
- {CPUArchitecture::X64, 21},
- {CPUArchitecture::X86, 16}};
-
- std::vector<Triplet> triplets;
- std::unordered_map<Triplet, std::string> triplet_abi_map;
- std::unordered_map<Triplet, int> triplet_api_map;
-
- for (auto& triplet_file : available_triplets)
- {
- if (triplet_file.name.size() > 0)
- {
- Triplet triplet = Triplet::from_canonical_name(std::move(triplet_file.name));
- auto triplet_build_info = build_info_from_triplet(paths, provider, triplet);
- if (is_supported(*triplet_build_info))
- {
- auto cpu_architecture = System::to_cpu_architecture(triplet_build_info->target_architecture)
- .value_or_exit(VCPKG_LINE_INFO);
- auto required_arch = required_archs.find(cpu_architecture);
- if (required_arch != required_archs.end())
- {
- triplets.push_back(triplet);
- triplet_abi_map[triplet] = required_archs[cpu_architecture];
- triplet_api_map[triplet] = cpu_architecture_api_map[cpu_architecture];
- required_archs.erase(required_arch);
- }
- }
- }
- }
-
- Checks::check_exit(
- VCPKG_LINE_INFO,
- required_archs.empty(),
- "Export requires the following architectures arm64-v8a, armeabi-v7a, x86_64, x86 to be present");
-
- Optional<std::string> android_ndk_home = System::get_environment_variable("ANDROID_NDK_HOME");
-
- Checks::check_exit(
- VCPKG_LINE_INFO, android_ndk_home.has_value(), "Error: ANDROID_NDK_HOME environment missing");
-
- Files::Filesystem& utils = paths.get_filesystem();
-
- const fs::path ndk_location = android_ndk_home.value_or_exit(VCPKG_LINE_INFO);
-
- Checks::check_maybe_upgrade(VCPKG_LINE_INFO,
- utils.exists(ndk_location),
- "Error: ANDROID_NDK_HOME Directory does not exists %s",
- fs::generic_u8string(ndk_location));
- const fs::path source_properties_location = ndk_location / "source.properties";
-
- Checks::check_maybe_upgrade(VCPKG_LINE_INFO,
- utils.exists(ndk_location),
- "Error: source.properties missing in ANDROID_NDK_HOME directory %s",
- fs::generic_u8string(source_properties_location));
-
- std::string content = utils.read_contents(source_properties_location, VCPKG_LINE_INFO);
-
- Optional<std::string> version_opt = find_ndk_version(content);
-
- Checks::check_maybe_upgrade(VCPKG_LINE_INFO,
- version_opt.has_value(),
- "Error: NDK version missing %s",
- fs::generic_u8string(source_properties_location));
-
- NdkVersion version = to_version(version_opt.value_or_exit(VCPKG_LINE_INFO)).value_or_exit(VCPKG_LINE_INFO);
-
- utils.remove_all(paths.prefab, VCPKG_LINE_INFO);
-
- /*
- prefab
- +-- <name>
- +-- aar
- | +-- AndroidManifest.xml
- | +-- META-INF
- | | +-- LICENCE
- | +-- prefab
- | +-- modules
- | | +-- <module>
- | | +-- include
- | | +-- libs
- | | | +-- android.arm64-v8a
- | | | | +-- abi.json
- | | | | +-- lib<module>.so
- | | | +-- android.armeabi-v7a
- | | | | +-- abi.json
- | | | | +-- lib<module>.so
- | | | +-- android.x86
- | | | | +-- abi.json
- | | | | +-- lib<module>.so
- | | | +-- android.x86_64
- | | | +-- abi.json
- | | | +-- lib<module>.so
- | | +-- module.json
- | +-- prefab.json
- +-- <name>-<version>.aar
- +-- pom.xml
- */
-
- std::unordered_map<std::string, std::string> version_map;
-
- std::error_code error_code;
-
- std::unordered_map<std::string, std::set<PackageSpec>> empty_package_dependencies;
-
- //
-
- for (const auto& action : export_plan)
- {
- const std::string name = action.spec.name();
- auto dependencies = action.dependencies();
-
- const auto action_build_info = Build::read_build_info(utils, paths.build_info_file_path(action.spec));
- const bool is_empty_package = action_build_info.policies.is_enabled(Build::BuildPolicy::EMPTY_PACKAGE);
-
- if (is_empty_package)
- {
- empty_package_dependencies[name] = std::set<PackageSpec>();
- for (auto dependency : dependencies)
- {
- if (empty_package_dependencies.find(dependency.name()) != empty_package_dependencies.end())
- {
- auto& child_deps = empty_package_dependencies[name];
- auto& parent_deps = empty_package_dependencies[dependency.name()];
- for (auto parent_dep : parent_deps)
- {
- child_deps.insert(parent_dep);
- }
- }
- else
- {
- empty_package_dependencies[name].insert(dependency);
- }
- }
- continue;
- }
-
- const fs::path per_package_dir_path = paths.prefab / fs::u8path(name);
-
- const auto& binary_paragraph = action.core_paragraph().value_or_exit(VCPKG_LINE_INFO);
- const std::string norm_version = binary_paragraph.version;
-
- version_map[name] = norm_version;
-
- System::print2("\nExporting package ", name, "...\n");
-
- fs::path package_directory = per_package_dir_path / "aar";
- fs::path prefab_directory = package_directory / "prefab";
- fs::path modules_directory = prefab_directory / "modules";
-
- utils.create_directories(modules_directory, error_code);
-
- std::string artifact_id = prefab_options.maybe_artifact_id.value_or(name);
- std::string group_id = prefab_options.maybe_group_id.value_or("com.vcpkg.ndk.support");
- std::string sdk_min_version = prefab_options.maybe_min_sdk.value_or("16");
- std::string sdk_target_version = prefab_options.maybe_target_sdk.value_or("29");
-
- std::string MANIFEST_TEMPLATE =
- R"(<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="@GROUP_ID@.@ARTIFACT_ID@" android:versionCode="1" android:versionName="1.0">
- <uses-sdk android:minSdkVersion="@MIN_SDK_VERSION@" android:targetSdkVersion="@SDK_TARGET_VERSION@" />
-</manifest>)";
- std::string manifest = Strings::replace_all(std::move(MANIFEST_TEMPLATE), "@GROUP_ID@", group_id);
- Strings::inplace_replace_all(manifest, "@ARTIFACT_ID@", artifact_id);
- Strings::inplace_replace_all(manifest, "@MIN_SDK_VERSION@", sdk_min_version);
- Strings::inplace_replace_all(manifest, "@SDK_TARGET_VERSION@", sdk_target_version);
-
- fs::path manifest_path = package_directory / "AndroidManifest.xml";
- fs::path prefab_path = prefab_directory / "prefab.json";
-
- fs::path meta_dir = package_directory / "META-INF";
-
- utils.create_directories(meta_dir, error_code);
-
- const fs::path share_root =
- paths.packages / fs::u8path(Strings::format("%s_%s", name, action.spec.triplet()));
-
- utils.copy_file(share_root / "share" / name / "copyright",
- meta_dir / "LICENSE",
- fs::copy_options::overwrite_existing,
- error_code);
-
- PackageMetadata pm;
- pm.name = artifact_id;
- pm.schema = 1;
- pm.version = norm_version;
-
- std::set<PackageSpec> dependencies_minus_empty_packages;
-
- for (auto dependency : dependencies)
- {
- if (empty_package_dependencies.find(dependency.name()) != empty_package_dependencies.end())
- {
- for (auto& empty_package_dep : empty_package_dependencies[dependency.name()])
- {
- dependencies_minus_empty_packages.insert(empty_package_dep);
- }
- }
- else
- {
- dependencies_minus_empty_packages.insert(dependency);
- }
- }
-
- std::vector<std::string> pom_dependencies;
-
- if (dependencies_minus_empty_packages.size() > 0)
- {
- pom_dependencies.push_back("\n<dependencies>");
- }
-
- for (const auto& it : dependencies_minus_empty_packages)
- {
- std::string maven_pom = R"( <dependency>
- <groupId>@GROUP_ID@</groupId>
- <artifactId>@ARTIFACT_ID@</artifactId>
- <version>@VERSION@</version>
- <type>aar</type>
- <scope>runtime</scope>
- </dependency>)";
- std::string pom = Strings::replace_all(std::move(maven_pom), "@GROUP_ID@", group_id);
- Strings::inplace_replace_all(pom, "@ARTIFACT_ID@", it.name());
- Strings::inplace_replace_all(pom, "@VERSION@", version_map[it.name()]);
- pom_dependencies.push_back(pom);
- pm.dependencies.push_back(it.name());
- }
-
- if (dependencies_minus_empty_packages.size() > 0)
- {
- pom_dependencies.push_back("</dependencies>\n");
- }
-
- if (prefab_options.enable_debug)
- {
- System::print2(
- Strings::format("[DEBUG]\n\tWriting manifest\n\tTo %s\n\tWriting prefab meta data\n\tTo %s\n\n",
- fs::generic_u8string(manifest_path),
- fs::generic_u8string(prefab_path)));
- }
-
- utils.write_contents(manifest_path, manifest, VCPKG_LINE_INFO);
- utils.write_contents(prefab_path, pm.to_json(), VCPKG_LINE_INFO);
-
- if (prefab_options.enable_debug)
- {
- std::vector<std::string> triplet_names;
- for (auto triplet : triplets)
- {
- triplet_names.push_back(triplet.canonical_name());
- }
- System::print2(Strings::format(
- "[DEBUG] Found %d triplets\n\t%s\n\n", triplets.size(), Strings::join("\n\t", triplet_names)));
- }
-
- for (const auto& triplet : triplets)
- {
- const fs::path listfile =
- paths.vcpkg_dir_info /
- fs::u8path(Strings::format("%s_%s_%s", name, norm_version, triplet) + ".list");
- const fs::path installed_dir = paths.packages / fs::u8path(Strings::format("%s_%s", name, triplet));
- Checks::check_exit(VCPKG_LINE_INFO,
- utils.exists(listfile),
- "Error: Packages not installed %s:%s %s",
- name,
- triplet,
- fs::generic_u8string(listfile));
-
- fs::path libs = installed_dir / fs::u8path("lib");
-
- std::vector<fs::path> modules;
-
- std::vector<fs::path> modules_shared = find_modules(paths, libs, ".so");
-
- for (const auto& module : modules_shared)
- {
- modules.push_back(module);
- }
-
- std::vector<fs::path> modules_static = find_modules(paths, libs, ".a");
- for (const auto& module : modules_static)
- {
- modules.push_back(module);
- }
-
- // header only libs
- if (modules.empty())
- {
- fs::path module_dir = modules_directory / name;
- fs::path module_libs_dir = module_dir / fs::u8path("libs");
- utils.create_directories(module_libs_dir, error_code);
- fs::path installed_headers_dir = installed_dir / fs::u8path("include");
- fs::path exported_headers_dir = module_dir / fs::u8path("include");
-
- ModuleMetadata meta;
- fs::path module_meta_path = module_dir / fs::u8path("module.json");
- utils.write_contents(module_meta_path, meta.to_json(), VCPKG_LINE_INFO);
-
- utils.copy(installed_headers_dir, exported_headers_dir, fs::copy_options::recursive);
- break;
- }
- else
- {
- for (const auto& module : modules)
- {
- std::string module_name = fs::generic_u8string(module.stem());
- std::string extension = fs::generic_u8string(module.extension());
-
- ABIMetadata ab;
- ab.abi = triplet_abi_map[triplet];
- ab.api = triplet_api_map[triplet];
-
- ab.stl = Strings::contains(extension, "a") ? "c++_static" : "c++_shared";
- ab.ndk = version.major();
-
- if (prefab_options.enable_debug)
- {
- System::print2(Strings::format("[DEBUG] Found module %s:%s\n", module_name, ab.abi));
- }
-
- module_name = Strings::trim(std::move(module_name));
-
- if (Strings::starts_with(module_name, "lib"))
- {
- module_name = module_name.substr(3);
- }
- fs::path module_dir = (modules_directory / module_name);
- fs::path module_libs_dir = module_dir / "libs" / Strings::format("android.%s", ab.abi);
- utils.create_directories(module_libs_dir, error_code);
-
- fs::path abi_path = module_libs_dir / "abi.json";
-
- if (prefab_options.enable_debug)
- {
- System::print2(
- Strings::format("\tWriting abi metadata\n\tTo %s\n", fs::generic_u8string(abi_path)));
- }
- utils.write_contents(abi_path, ab.to_string(), VCPKG_LINE_INFO);
-
- fs::path installed_module_path = libs / module.filename();
- fs::path exported_module_path = module_libs_dir / module.filename();
-
- utils.copy_file(installed_module_path,
- exported_module_path,
- fs::copy_options::overwrite_existing,
- error_code);
- if (prefab_options.enable_debug)
- {
- System::print2(Strings::format("\tCopying libs\n\tFrom %s\n\tTo %s\n",
- fs::generic_u8string(installed_module_path),
- fs::generic_u8string(exported_module_path)));
- }
- fs::path installed_headers_dir = installed_dir / "include";
- fs::path exported_headers_dir = module_libs_dir / "include";
-
- if (prefab_options.enable_debug)
- {
- System::print2(Strings::format("\tCopying headers\n\tFrom %s\n\tTo %s\n",
- fs::generic_u8string(installed_headers_dir),
- fs::generic_u8string(exported_headers_dir)));
- }
-
- utils.copy(installed_headers_dir, exported_headers_dir, fs::copy_options::recursive);
-
- ModuleMetadata meta;
-
- fs::path module_meta_path = module_dir / "module.json";
-
- if (prefab_options.enable_debug)
- {
- System::print2(Strings::format("\tWriting module metadata\n\tTo %s\n\n",
- fs::generic_u8string(module_meta_path)));
- }
-
- utils.write_contents(module_meta_path, meta.to_json(), VCPKG_LINE_INFO);
- }
- }
- }
-
- fs::path exported_archive_path = per_package_dir_path / Strings::format("%s-%s.aar", name, norm_version);
- fs::path pom_path = per_package_dir_path / "pom.xml";
-
- if (prefab_options.enable_debug)
- {
- System::print2(Strings::format("[DEBUG] Exporting AAR And POM\n\tAAR Path %s\n\tPOM Path %s\n",
- fs::generic_u8string(exported_archive_path),
- fs::generic_u8string(pom_path)));
- }
-
- compress_directory(paths, package_directory, exported_archive_path);
-
- std::string POM = R"(<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
-
-
- <groupId>@GROUP_ID@</groupId>
- <artifactId>@ARTIFACT_ID@</artifactId>
- <version>@VERSION@</version>
- <packaging>aar</packaging>
- <description>The Vcpkg AAR for @ARTIFACT_ID@</description>
- <url>https://github.com/microsoft/vcpkg.git</url>
- @DEPENDENCIES@
-</project>)";
-
- std::string pom = Strings::replace_all(std::move(POM), "@GROUP_ID@", group_id);
- Strings::inplace_replace_all(pom, "@ARTIFACT_ID@", artifact_id);
- Strings::inplace_replace_all(pom, "@DEPENDENCIES@", Strings::join("\n", pom_dependencies));
- Strings::inplace_replace_all(pom, "@VERSION@", norm_version);
-
- utils.write_contents(pom_path, pom, VCPKG_LINE_INFO);
-
- if (prefab_options.enable_maven)
- {
- maven_install(exported_archive_path, pom_path, prefab_options);
- if (prefab_options.enable_debug)
- {
- System::print2(Strings::format(
- "\n\n[DEBUG] Configuration properties in Android Studio\nIn app/build.gradle\n\n\t%s:%s:%s\n\n",
- group_id,
- artifact_id,
- norm_version));
-
- System::print2(R"(And cmake flags
-
- externalNativeBuild {
- cmake {
- arguments '-DANDROID_STL=c++_shared'
- cppFlags "-std=c++17"
- }
- }
-
-)");
-
- System::print2(R"(In gradle.properties
-
- android.enablePrefab=true
- android.enableParallelJsonGen=false
- android.prefabVersion=${prefab.version}
-
-)");
- }
- }
- System::print2(
- System::Color::success,
- Strings::format("Successfuly exported %s. Checkout %s \n", name, fs::generic_u8string(paths.prefab)));
- }
- }
-}
diff --git a/toolsrc/src/vcpkg/globalstate.cpp b/toolsrc/src/vcpkg/globalstate.cpp
deleted file mode 100644
index 896e96c81..000000000
--- a/toolsrc/src/vcpkg/globalstate.cpp
+++ /dev/null
@@ -1,13 +0,0 @@
-#include <vcpkg/base/lockguarded.h>
-
-#include <vcpkg/globalstate.h>
-
-namespace vcpkg
-{
- Util::LockGuarded<Chrono::ElapsedTimer> GlobalState::timer;
- Util::LockGuarded<std::string> GlobalState::g_surveydate;
-
- std::atomic<int> GlobalState::g_init_console_cp(0);
- std::atomic<int> GlobalState::g_init_console_output_cp(0);
- std::atomic<bool> GlobalState::g_init_console_initialized(false);
-}
diff --git a/toolsrc/src/vcpkg/help.cpp b/toolsrc/src/vcpkg/help.cpp
deleted file mode 100644
index 0556b4fa0..000000000
--- a/toolsrc/src/vcpkg/help.cpp
+++ /dev/null
@@ -1,205 +0,0 @@
-#include <vcpkg/base/system.print.h>
-
-#include <vcpkg/binarycaching.h>
-#include <vcpkg/commands.create.h>
-#include <vcpkg/commands.dependinfo.h>
-#include <vcpkg/commands.edit.h>
-#include <vcpkg/commands.env.h>
-#include <vcpkg/commands.integrate.h>
-#include <vcpkg/commands.list.h>
-#include <vcpkg/commands.owns.h>
-#include <vcpkg/commands.search.h>
-#include <vcpkg/export.h>
-#include <vcpkg/help.h>
-#include <vcpkg/install.h>
-#include <vcpkg/remove.h>
-
-namespace vcpkg::Help
-{
- struct Topic
- {
- using topic_function = void (*)(const VcpkgPaths& paths);
-
- constexpr Topic(CStringView n, topic_function fn) : name(n), print(fn) { }
-
- CStringView name;
- topic_function print;
- };
-
- template<const CommandStructure& S>
- static void command_topic_fn(const VcpkgPaths&)
- {
- print_usage(S);
- }
-
- static void integrate_topic_fn(const VcpkgPaths&)
- {
- System::print2("Commands:\n", Commands::Integrate::get_helpstring());
- }
-
- static void help_topics(const VcpkgPaths&);
-
- const CommandStructure COMMAND_STRUCTURE = {
- create_example_string("help"),
- 0,
- 1,
- {},
- nullptr,
- };
-
- static void help_topic_versioning(const VcpkgPaths&)
- {
- HelpTableFormatter tbl;
- tbl.text("Versioning allows you to deterministically control the precise revisions of dependencies used by "
- "your project from within your manifest file.");
- tbl.blank();
- tbl.blank();
- tbl.text("** This feature is experimental and requires `--feature-flags=versions` **");
- tbl.blank();
- tbl.blank();
- tbl.header("Versions in vcpkg come in four primary flavors");
- tbl.format("version", "A dot-separated sequence of numbers (1.2.3.4)");
- tbl.format("version-date", "A date (2021-01-01.5)");
- tbl.format("version-semver", "A Semantic Version 2.0 (2.1.0-rc2)");
- tbl.format("version-string", "An exact, incomparable version (Vista)");
- tbl.blank();
- tbl.text("Each version additionally has a \"port-version\" which is a nonnegative integer. When rendered as "
- "text, the port version (if nonzero) is added as a suffix to the primary version text separated by a "
- "hash (#). Port-versions are sorted lexographically after the primary version text, for example:");
- tbl.blank();
- tbl.blank();
- tbl.text(" 1.0.0 < 1.0.0#1 < 1.0.1 < 1.0.1#5 < 2.0.0");
- tbl.blank();
- tbl.blank();
- tbl.header("Manifests can place three kinds of constraints upon the versions used");
- tbl.format("builtin-baseline",
- "The baseline references a commit within the vcpkg repository that establishes a minimum version on "
- "every dependency in the graph. If no other constraints are specified (directly or transitively), "
- "then the version from the baseline of the top level manifest will be used. Baselines of transitive "
- "dependencies are ignored.");
- tbl.blank();
- tbl.format("version>=",
- "Within the \"dependencies\" field, each dependency can have a minimum constraint listed. These "
- "minimum constraints will be used when transitively depending upon this library. A minimum "
- "port-version can additionally be specified with a '#' suffix.");
- tbl.blank();
- tbl.format(
- "overrides",
- "When used as the top-level manifest (such as when running `vcpkg install` in the directory), overrides "
- "allow a manifest to short-circuit dependency resolution and specify exactly the version to use. These can "
- "be used to handle version conflicts, such as with `version-string` dependencies. They will not be "
- "considered when transitively depended upon.");
- tbl.blank();
- tbl.text("Example manifest:");
- tbl.blank();
- tbl.text(R"({
- "name": "example",
- "version": "1.0",
- "builtin-baseline": "a14a6bcb27287e3ec138dba1b948a0cdbc337a3a",
- "dependencies": [
- { "name": "zlib", "version>=": "1.2.11#8" },
- "rapidjson"
- ],
- "overrides": [
- { "name": "rapidjson", "version": "2020-09-14" }
- ]
-})");
- System::print2(tbl.m_str,
- "\nExtended documentation is available at "
- "https://github.com/Microsoft/vcpkg/tree/master/docs/users/versioning.md\n");
- }
-
- static constexpr std::array<Topic, 16> topics = {{
- {"binarycaching", help_topic_binary_caching},
- {"create", command_topic_fn<Commands::Create::COMMAND_STRUCTURE>},
- {"depend-info", command_topic_fn<Commands::DependInfo::COMMAND_STRUCTURE>},
- {"edit", command_topic_fn<Commands::Edit::COMMAND_STRUCTURE>},
- {"env", command_topic_fn<Commands::Env::COMMAND_STRUCTURE>},
- {"export", command_topic_fn<Export::COMMAND_STRUCTURE>},
- {"help", command_topic_fn<Help::COMMAND_STRUCTURE>},
- {"install", command_topic_fn<Install::COMMAND_STRUCTURE>},
- {"integrate", integrate_topic_fn},
- {"list", command_topic_fn<Commands::List::COMMAND_STRUCTURE>},
- {"owns", command_topic_fn<Commands::Owns::COMMAND_STRUCTURE>},
- {"remove", command_topic_fn<Remove::COMMAND_STRUCTURE>},
- {"search", command_topic_fn<Commands::Search::COMMAND_STRUCTURE>},
- {"topics", help_topics},
- {"triplet", help_topic_valid_triplet},
- {"versioning", help_topic_versioning},
- }};
-
- static void help_topics(const VcpkgPaths&)
- {
- System::print2("Available help topics:",
- Strings::join("", topics, [](const Topic& topic) { return std::string("\n ") + topic.name; }),
- "\n");
- }
-
- void help_topic_valid_triplet(const VcpkgPaths& paths)
- {
- std::map<std::string, std::vector<const VcpkgPaths::TripletFile*>> triplets_per_location;
- vcpkg::Util::group_by(paths.get_available_triplets(),
- &triplets_per_location,
- [](const VcpkgPaths::TripletFile& triplet_file) -> std::string {
- return fs::u8string(triplet_file.location);
- });
-
- System::print2("Available architecture triplets\n");
-
- System::print2("VCPKG built-in triplets:\n");
- for (auto* triplet : triplets_per_location[fs::u8string(paths.triplets)])
- {
- System::print2(" ", triplet->name, '\n');
- }
- triplets_per_location.erase(fs::u8string(paths.triplets));
-
- System::print2("\nVCPKG community triplets:\n");
- for (auto* triplet : triplets_per_location[fs::u8string(paths.community_triplets)])
- {
- System::print2(" ", triplet->name, '\n');
- }
- triplets_per_location.erase(fs::u8string(paths.community_triplets));
-
- for (auto&& kv_pair : triplets_per_location)
- {
- System::print2("\nOverlay triplets from ", kv_pair.first, ":\n");
- for (auto* triplet : kv_pair.second)
- {
- System::print2(" ", triplet->name, '\n');
- }
- }
- }
-
- void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths)
- {
- (void)args.parse_arguments(COMMAND_STRUCTURE);
-
- if (args.command_arguments.empty())
- {
- print_usage();
- Checks::exit_success(VCPKG_LINE_INFO);
- }
- const auto& topic = args.command_arguments[0];
- if (topic == "triplets" || topic == "triple")
- {
- help_topic_valid_triplet(paths);
- Checks::exit_success(VCPKG_LINE_INFO);
- }
-
- auto it_topic = Util::find_if(topics, [&](const Topic& t) { return t.name == topic; });
- if (it_topic != topics.end())
- {
- it_topic->print(paths);
- Checks::exit_success(VCPKG_LINE_INFO);
- }
-
- System::print2(System::Color::error, "Error: unknown topic ", topic, '\n');
- help_topics(paths);
- Checks::exit_fail(VCPKG_LINE_INFO);
- }
-
- void HelpCommand::perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) const
- {
- Help::perform_and_exit(args, paths);
- }
-}
diff --git a/toolsrc/src/vcpkg/input.cpp b/toolsrc/src/vcpkg/input.cpp
deleted file mode 100644
index 0d7a9fd7d..000000000
--- a/toolsrc/src/vcpkg/input.cpp
+++ /dev/null
@@ -1,56 +0,0 @@
-#include <vcpkg/base/system.print.h>
-
-#include <vcpkg/commands.h>
-#include <vcpkg/help.h>
-#include <vcpkg/input.h>
-#include <vcpkg/metrics.h>
-#include <vcpkg/packagespec.h>
-#include <vcpkg/vcpkgpaths.h>
-
-namespace vcpkg
-{
- PackageSpec Input::check_and_get_package_spec(std::string&& spec_string,
- Triplet default_triplet,
- CStringView example_text)
- {
- const std::string as_lowercase = Strings::ascii_to_lowercase(std::move(spec_string));
- auto expected_spec = FullPackageSpec::from_string(as_lowercase, default_triplet);
- if (const auto spec = expected_spec.get())
- {
- return PackageSpec{spec->package_spec};
- }
-
- // Intentionally show the lowercased string
- System::print2(System::Color::error, expected_spec.error());
- System::print2(example_text);
- Checks::exit_fail(VCPKG_LINE_INFO);
- }
-
- void Input::check_triplet(Triplet t, const VcpkgPaths& paths)
- {
- if (!paths.is_valid_triplet(t))
- {
- System::print2(System::Color::error, "Error: invalid triplet: ", t, '\n');
- Metrics::g_metrics.lock()->track_property("error", "invalid triplet: " + t.to_string());
- Help::help_topic_valid_triplet(paths);
- Checks::exit_fail(VCPKG_LINE_INFO);
- }
- }
-
- FullPackageSpec Input::check_and_get_full_package_spec(std::string&& full_package_spec_as_string,
- Triplet default_triplet,
- CStringView example_text)
- {
- const std::string as_lowercase = Strings::ascii_to_lowercase(std::move(full_package_spec_as_string));
- auto expected_spec = FullPackageSpec::from_string(as_lowercase, default_triplet);
- if (const auto spec = expected_spec.get())
- {
- return *spec;
- }
-
- // Intentionally show the lowercased string
- System::print2(System::Color::error, expected_spec.error());
- System::print2(example_text);
- Checks::exit_fail(VCPKG_LINE_INFO);
- }
-}
diff --git a/toolsrc/src/vcpkg/install.cpp b/toolsrc/src/vcpkg/install.cpp
deleted file mode 100644
index 59212d651..000000000
--- a/toolsrc/src/vcpkg/install.cpp
+++ /dev/null
@@ -1,1105 +0,0 @@
-#include <vcpkg/base/files.h>
-#include <vcpkg/base/hash.h>
-#include <vcpkg/base/system.debug.h>
-#include <vcpkg/base/system.print.h>
-#include <vcpkg/base/util.h>
-
-#include <vcpkg/binarycaching.h>
-#include <vcpkg/build.h>
-#include <vcpkg/cmakevars.h>
-#include <vcpkg/commands.setinstalled.h>
-#include <vcpkg/configuration.h>
-#include <vcpkg/dependencies.h>
-#include <vcpkg/globalstate.h>
-#include <vcpkg/help.h>
-#include <vcpkg/input.h>
-#include <vcpkg/install.h>
-#include <vcpkg/metrics.h>
-#include <vcpkg/paragraphs.h>
-#include <vcpkg/remove.h>
-#include <vcpkg/tools.h>
-#include <vcpkg/vcpkglib.h>
-#include <vcpkg/vcpkgpaths.h>
-
-namespace vcpkg::Install
-{
- using namespace vcpkg;
- using namespace Dependencies;
-
- using file_pack = std::pair<std::string, std::string>;
-
- InstallDir InstallDir::from_destination_root(const fs::path& destination_root,
- const std::string& destination_subdirectory,
- const fs::path& listfile)
- {
- InstallDir dirs;
- dirs.m_destination = destination_root / destination_subdirectory;
- dirs.m_destination_subdirectory = destination_subdirectory;
- dirs.m_listfile = listfile;
- return dirs;
- }
-
- const fs::path& InstallDir::destination() const { return this->m_destination; }
-
- const std::string& InstallDir::destination_subdirectory() const { return this->m_destination_subdirectory; }
-
- const fs::path& InstallDir::listfile() const { return this->m_listfile; }
-
- void install_package_and_write_listfile(const VcpkgPaths& paths,
- const PackageSpec& spec,
- const InstallDir& destination_dir)
- {
- auto& fs = paths.get_filesystem();
- auto source_dir = paths.package_dir(spec);
- Checks::check_exit(VCPKG_LINE_INFO,
- fs.exists(source_dir),
- Strings::concat("Source directory ", fs::u8string(source_dir), "does not exist"));
- auto files = fs.get_files_recursive(source_dir);
- install_files_and_write_listfile(fs, source_dir, files, destination_dir);
- }
- void install_files_and_write_listfile(Files::Filesystem& fs,
- const fs::path& source_dir,
- const std::vector<fs::path>& files,
- const InstallDir& destination_dir)
- {
- std::vector<std::string> output;
- std::error_code ec;
-
- const size_t prefix_length = fs::generic_u8string(source_dir).size();
- const fs::path& destination = destination_dir.destination();
- const std::string& destination_subdirectory = destination_dir.destination_subdirectory();
- const fs::path& listfile = destination_dir.listfile();
-
- fs.create_directories(destination, ec);
- Checks::check_exit(
- VCPKG_LINE_INFO, !ec, "Could not create destination directory %s", fs::u8string(destination));
- const fs::path listfile_parent = listfile.parent_path();
- fs.create_directories(listfile_parent, ec);
- Checks::check_exit(VCPKG_LINE_INFO, !ec, "Could not create directory for listfile %s", fs::u8string(listfile));
-
- output.push_back(Strings::format(R"(%s/)", destination_subdirectory));
- for (auto&& file : files)
- {
- const auto status = fs.symlink_status(file, ec);
- if (ec)
- {
- System::print2(System::Color::error, "failed: ", fs::u8string(file), ": ", ec.message(), "\n");
- continue;
- }
-
- const std::string filename = fs::generic_u8string(file.filename());
- if (fs::is_regular_file(status) && (Strings::case_insensitive_ascii_equals(filename, "CONTROL") ||
- Strings::case_insensitive_ascii_equals(filename, "vcpkg.json") ||
- Strings::case_insensitive_ascii_equals(filename, "BUILD_INFO")))
- {
- // Do not copy the control file or manifest file
- continue;
- }
-
- const std::string suffix = fs::generic_u8string(file).substr(prefix_length + 1);
- const fs::path target = destination / suffix;
-
- switch (status.type())
- {
- case fs::file_type::directory:
- {
- fs.create_directory(target, ec);
- if (ec)
- {
- System::printf(System::Color::error, "failed: %s: %s\n", fs::u8string(target), ec.message());
- }
-
- // Trailing backslash for directories
- output.push_back(Strings::format(R"(%s/%s/)", destination_subdirectory, suffix));
- break;
- }
- case fs::file_type::regular:
- {
- if (fs.exists(target))
- {
- System::print2(System::Color::warning,
- "File ",
- fs::u8string(target),
- " was already present and will be overwritten\n");
- }
- fs.copy_file(file, target, fs::copy_options::overwrite_existing, ec);
- if (ec)
- {
- System::printf(System::Color::error, "failed: %s: %s\n", fs::u8string(target), ec.message());
- }
- output.push_back(Strings::format(R"(%s/%s)", destination_subdirectory, suffix));
- break;
- }
- case fs::file_type::symlink:
- {
- if (fs.exists(target))
- {
- System::print2(System::Color::warning,
- "File ",
- fs::u8string(target),
- " was already present and will be overwritten\n");
- }
- fs.copy_symlink(file, target, ec);
- if (ec)
- {
- System::printf(System::Color::error, "failed: %s: %s\n", fs::u8string(target), ec.message());
- }
- output.push_back(Strings::format(R"(%s/%s)", destination_subdirectory, suffix));
- break;
- }
- default:
- System::printf(System::Color::error, "failed: %s: cannot handle file type\n", fs::u8string(file));
- break;
- }
- }
-
- std::sort(output.begin(), output.end());
-
- fs.write_lines(listfile, output, VCPKG_LINE_INFO);
- }
-
- static std::vector<file_pack> extract_files_in_triplet(
- const std::vector<StatusParagraphAndAssociatedFiles>& pgh_and_files,
- Triplet triplet,
- const size_t remove_chars = 0)
- {
- std::vector<file_pack> output;
- for (const StatusParagraphAndAssociatedFiles& t : pgh_and_files)
- {
- if (t.pgh.package.spec.triplet() != triplet)
- {
- continue;
- }
-
- const std::string name = t.pgh.package.displayname();
-
- for (const std::string& file : t.files)
- {
- output.emplace_back(file_pack{std::string(file, remove_chars), name});
- }
- }
-
- std::sort(output.begin(), output.end(), [](const file_pack& lhs, const file_pack& rhs) {
- return lhs.first < rhs.first;
- });
- return output;
- }
-
- static SortedVector<std::string> build_list_of_package_files(const Files::Filesystem& fs,
- const fs::path& package_dir)
- {
- const std::vector<fs::path> package_file_paths = fs.get_files_recursive(package_dir);
- const size_t package_remove_char_count = package_dir.generic_string().size() + 1; // +1 for the slash
- auto package_files = Util::fmap(package_file_paths, [package_remove_char_count](const fs::path& path) {
- return std::string(path.generic_string(), package_remove_char_count);
- });
-
- return SortedVector<std::string>(std::move(package_files));
- }
-
- static SortedVector<file_pack> build_list_of_installed_files(
- const std::vector<StatusParagraphAndAssociatedFiles>& pgh_and_files, Triplet triplet)
- {
- const size_t installed_remove_char_count = triplet.canonical_name().size() + 1; // +1 for the slash
- std::vector<file_pack> installed_files =
- extract_files_in_triplet(pgh_and_files, triplet, installed_remove_char_count);
-
- return SortedVector<file_pack>(std::move(installed_files));
- }
-
- InstallResult install_package(const VcpkgPaths& paths, const BinaryControlFile& bcf, StatusParagraphs* status_db)
- {
- const fs::path package_dir = paths.package_dir(bcf.core_paragraph.spec);
- Triplet triplet = bcf.core_paragraph.spec.triplet();
- const std::vector<StatusParagraphAndAssociatedFiles> pgh_and_files = get_installed_files(paths, *status_db);
-
- const SortedVector<std::string> package_files =
- build_list_of_package_files(paths.get_filesystem(), package_dir);
- const SortedVector<file_pack> installed_files = build_list_of_installed_files(pgh_and_files, triplet);
-
- struct intersection_compare
- {
- // The VS2015 standard library requires comparison operators of T and U
- // to also support comparison of T and T, and of U and U, due to debug checks.
-#if _MSC_VER <= 1910
- bool operator()(const std::string& lhs, const std::string& rhs) { return lhs < rhs; }
- bool operator()(const file_pack& lhs, const file_pack& rhs) { return lhs.first < rhs.first; }
-#endif
- bool operator()(const std::string& lhs, const file_pack& rhs) { return lhs < rhs.first; }
- bool operator()(const file_pack& lhs, const std::string& rhs) { return lhs.first < rhs; }
- };
-
- std::vector<file_pack> intersection;
-
- std::set_intersection(installed_files.begin(),
- installed_files.end(),
- package_files.begin(),
- package_files.end(),
- std::back_inserter(intersection),
- intersection_compare());
-
- std::sort(intersection.begin(), intersection.end(), [](const file_pack& lhs, const file_pack& rhs) {
- return lhs.second < rhs.second;
- });
-
- if (!intersection.empty())
- {
- const fs::path triplet_install_path = paths.installed / triplet.canonical_name();
- System::printf(System::Color::error,
- "The following files are already installed in %s and are in conflict with %s\n\n",
- triplet_install_path.generic_string(),
- bcf.core_paragraph.spec);
-
- auto i = intersection.begin();
- while (i != intersection.end())
- {
- System::print2("Installed by ", i->second, "\n ");
- auto next =
- std::find_if(i, intersection.end(), [i](const auto& val) { return i->second != val.second; });
-
- System::print2(Strings::join("\n ", i, next, [](const file_pack& file) { return file.first; }));
- System::print2("\n\n");
-
- i = next;
- }
-
- return InstallResult::FILE_CONFLICTS;
- }
-
- StatusParagraph source_paragraph;
- source_paragraph.package = bcf.core_paragraph;
- source_paragraph.want = Want::INSTALL;
- source_paragraph.state = InstallState::HALF_INSTALLED;
-
- write_update(paths, source_paragraph);
- status_db->insert(std::make_unique<StatusParagraph>(source_paragraph));
-
- std::vector<StatusParagraph> features_spghs;
- for (auto&& feature : bcf.features)
- {
- features_spghs.emplace_back();
-
- StatusParagraph& feature_paragraph = features_spghs.back();
- feature_paragraph.package = feature;
- feature_paragraph.want = Want::INSTALL;
- feature_paragraph.state = InstallState::HALF_INSTALLED;
-
- write_update(paths, feature_paragraph);
- status_db->insert(std::make_unique<StatusParagraph>(feature_paragraph));
- }
-
- const InstallDir install_dir = InstallDir::from_destination_root(
- paths.installed, triplet.to_string(), paths.listfile_path(bcf.core_paragraph));
-
- install_package_and_write_listfile(paths, bcf.core_paragraph.spec, install_dir);
-
- source_paragraph.state = InstallState::INSTALLED;
- write_update(paths, source_paragraph);
- status_db->insert(std::make_unique<StatusParagraph>(source_paragraph));
-
- for (auto&& feature_paragraph : features_spghs)
- {
- feature_paragraph.state = InstallState::INSTALLED;
- write_update(paths, feature_paragraph);
- status_db->insert(std::make_unique<StatusParagraph>(feature_paragraph));
- }
-
- return InstallResult::SUCCESS;
- }
-
- using Build::BuildResult;
- using Build::ExtendedBuildResult;
-
- static ExtendedBuildResult perform_install_plan_action(const VcpkgCmdArguments& args,
- const VcpkgPaths& paths,
- InstallPlanAction& action,
- StatusParagraphs& status_db,
- IBinaryProvider& binaries_provider,
- const Build::IBuildLogsRecorder& build_logs_recorder)
- {
- const InstallPlanType& plan_type = action.plan_type;
- const std::string display_name = action.spec.to_string();
- const std::string display_name_with_features = action.displayname();
-
- const bool is_user_requested = action.request_type == RequestType::USER_REQUESTED;
- const bool use_head_version = Util::Enum::to_bool(action.build_options.use_head_version);
-
- if (plan_type == InstallPlanType::ALREADY_INSTALLED)
- {
- if (use_head_version && is_user_requested)
- System::printf(System::Color::warning,
- "Package %s is already installed -- not building from HEAD\n",
- display_name);
- else
- System::printf(System::Color::success, "Package %s is already installed\n", display_name);
- return BuildResult::SUCCEEDED;
- }
-
- if (plan_type == InstallPlanType::BUILD_AND_INSTALL)
- {
- if (use_head_version)
- System::printf("Building package %s from HEAD...\n", display_name_with_features);
- else
- System::printf("Building package %s...\n", display_name_with_features);
-
- auto result = Build::build_package(args, paths, action, binaries_provider, build_logs_recorder, status_db);
-
- if (BuildResult::DOWNLOADED == result.code)
- {
- System::print2(
- System::Color::success, "Downloaded sources for package ", display_name_with_features, "\n");
- return result;
- }
-
- if (result.code != Build::BuildResult::SUCCEEDED)
- {
- System::print2(System::Color::error, Build::create_error_message(result.code, action.spec), "\n");
- return result;
- }
-
- System::printf("Building package %s... done\n", display_name_with_features);
-
- auto bcf = std::make_unique<BinaryControlFile>(
- Paragraphs::try_load_cached_package(paths, action.spec).value_or_exit(VCPKG_LINE_INFO));
- System::printf("Installing package %s...\n", display_name_with_features);
- const auto install_result = install_package(paths, *bcf, &status_db);
- BuildResult code;
- switch (install_result)
- {
- case InstallResult::SUCCESS:
- System::printf(
- System::Color::success, "Installing package %s... done\n", display_name_with_features);
- code = BuildResult::SUCCEEDED;
- break;
- case InstallResult::FILE_CONFLICTS: code = BuildResult::FILE_CONFLICTS; break;
- default: Checks::unreachable(VCPKG_LINE_INFO);
- }
-
- if (action.build_options.clean_packages == Build::CleanPackages::YES)
- {
- auto& fs = paths.get_filesystem();
- const fs::path package_dir = paths.package_dir(action.spec);
- fs.remove_all(package_dir, VCPKG_LINE_INFO);
- }
-
- if (action.build_options.clean_downloads == Build::CleanDownloads::YES)
- {
- auto& fs = paths.get_filesystem();
- const fs::path download_dir = paths.downloads;
- std::error_code ec;
- for (auto& p : fs.get_files_non_recursive(download_dir))
- {
- if (!fs.is_directory(p))
- {
- fs.remove(p, VCPKG_LINE_INFO);
- }
- }
- }
-
- return {code, std::move(bcf)};
- }
-
- if (plan_type == InstallPlanType::EXCLUDED)
- {
- System::printf(System::Color::warning, "Package %s is excluded\n", display_name);
- return BuildResult::EXCLUDED;
- }
-
- Checks::unreachable(VCPKG_LINE_INFO);
- }
-
- void InstallSummary::print() const
- {
- System::print2("RESULTS\n");
-
- for (const SpecSummary& result : this->results)
- {
- System::printf(" %s: %s: %s\n", result.spec, Build::to_string(result.build_result.code), result.timing);
- }
-
- std::map<BuildResult, int> summary;
- for (const BuildResult& v : Build::BUILD_RESULT_VALUES)
- {
- summary[v] = 0;
- }
-
- for (const SpecSummary& r : this->results)
- {
- summary[r.build_result.code]++;
- }
-
- System::print2("\nSUMMARY\n");
- for (const std::pair<const BuildResult, int>& entry : summary)
- {
- System::printf(" %s: %d\n", Build::to_string(entry.first), entry.second);
- }
- }
-
- struct TrackedPackageInstallGuard
- {
- SpecSummary* current_summary = nullptr;
- Chrono::ElapsedTimer build_timer = Chrono::ElapsedTimer::create_started();
-
- TrackedPackageInstallGuard(const size_t action_index,
- const size_t action_count,
- std::vector<SpecSummary>& results,
- const PackageSpec& spec)
- {
- results.emplace_back(spec, nullptr);
- current_summary = &results.back();
- System::printf("Starting package %zd/%zd: %s\n", action_index, action_count, spec.to_string());
- }
-
- ~TrackedPackageInstallGuard()
- {
- current_summary->timing = build_timer.elapsed();
- System::printf(
- "Elapsed time for package %s: %s\n", current_summary->spec.to_string(), current_summary->timing);
- }
-
- TrackedPackageInstallGuard(const TrackedPackageInstallGuard&) = delete;
- TrackedPackageInstallGuard& operator=(const TrackedPackageInstallGuard&) = delete;
- };
-
- InstallSummary perform(const VcpkgCmdArguments& args,
- ActionPlan& action_plan,
- const KeepGoing keep_going,
- const VcpkgPaths& paths,
- StatusParagraphs& status_db,
- IBinaryProvider& binaryprovider,
- const Build::IBuildLogsRecorder& build_logs_recorder,
- const CMakeVars::CMakeVarProvider& var_provider)
- {
- std::vector<SpecSummary> results;
- const size_t action_count = action_plan.remove_actions.size() + action_plan.install_actions.size();
- size_t action_index = 1;
-
- const auto timer = Chrono::ElapsedTimer::create_started();
- for (auto&& action : action_plan.remove_actions)
- {
- TrackedPackageInstallGuard this_install(action_index++, action_count, results, action.spec);
- Remove::perform_remove_plan_action(paths, action, Remove::Purge::YES, &status_db);
- }
-
- for (auto&& action : action_plan.already_installed)
- {
- results.emplace_back(action.spec, &action);
- results.back().build_result =
- perform_install_plan_action(args, paths, action, status_db, binaryprovider, build_logs_recorder);
- }
-
- Build::compute_all_abis(paths, action_plan, var_provider, status_db);
-
- auto to_prefetch = Util::fmap(action_plan.install_actions, [](const auto& x) { return &x; });
- binaryprovider.prefetch(paths, to_prefetch);
-
- for (auto&& action : action_plan.install_actions)
- {
- TrackedPackageInstallGuard this_install(action_index++, action_count, results, action.spec);
- auto result =
- perform_install_plan_action(args, paths, action, status_db, binaryprovider, build_logs_recorder);
- if (result.code != BuildResult::SUCCEEDED && keep_going == KeepGoing::NO)
- {
- System::print2(Build::create_user_troubleshooting_message(action.spec), '\n');
- Checks::exit_fail(VCPKG_LINE_INFO);
- }
-
- this_install.current_summary->action = &action;
- this_install.current_summary->build_result = std::move(result);
- }
-
- return InstallSummary{std::move(results), timer.to_string()};
- }
-
- static constexpr StringLiteral OPTION_DRY_RUN = "dry-run";
- static constexpr StringLiteral OPTION_USE_HEAD_VERSION = "head";
- static constexpr StringLiteral OPTION_NO_DOWNLOADS = "no-downloads";
- static constexpr StringLiteral OPTION_ONLY_BINARYCACHING = "only-binarycaching";
- static constexpr StringLiteral OPTION_ONLY_DOWNLOADS = "only-downloads";
- static constexpr StringLiteral OPTION_RECURSE = "recurse";
- static constexpr StringLiteral OPTION_KEEP_GOING = "keep-going";
- static constexpr StringLiteral OPTION_EDITABLE = "editable";
- static constexpr StringLiteral OPTION_XUNIT = "x-xunit";
- static constexpr StringLiteral OPTION_USE_ARIA2 = "x-use-aria2";
- static constexpr StringLiteral OPTION_CLEAN_AFTER_BUILD = "clean-after-build";
- static constexpr StringLiteral OPTION_WRITE_PACKAGES_CONFIG = "x-write-nuget-packages-config";
- static constexpr StringLiteral OPTION_MANIFEST_NO_DEFAULT_FEATURES = "x-no-default-features";
- static constexpr StringLiteral OPTION_MANIFEST_FEATURE = "x-feature";
- static constexpr StringLiteral OPTION_PROHIBIT_BACKCOMPAT_FEATURES = "x-prohibit-backcompat-features";
-
- static constexpr std::array<CommandSwitch, 11> INSTALL_SWITCHES = {{
- {OPTION_DRY_RUN, "Do not actually build or install"},
- {OPTION_USE_HEAD_VERSION, "Install the libraries on the command line using the latest upstream sources"},
- {OPTION_NO_DOWNLOADS, "Do not download new sources"},
- {OPTION_ONLY_DOWNLOADS, "Download sources but don't build packages"},
- {OPTION_ONLY_BINARYCACHING, "Fail if cached binaries are not available"},
- {OPTION_RECURSE, "Allow removal of packages as part of installation"},
- {OPTION_KEEP_GOING, "Continue installing packages on failure"},
- {OPTION_EDITABLE, "Disable source re-extraction and binary caching for libraries on the command line"},
-
- {OPTION_USE_ARIA2, "Use aria2 to perform download tasks"},
- {OPTION_CLEAN_AFTER_BUILD, "Clean buildtrees, packages and downloads after building each package"},
- {OPTION_PROHIBIT_BACKCOMPAT_FEATURES,
- "(experimental) Fail install if a package attempts to use a deprecated feature"},
- }};
- static constexpr std::array<CommandSwitch, 11> MANIFEST_INSTALL_SWITCHES = {{
- {OPTION_DRY_RUN, "Do not actually build or install"},
- {OPTION_USE_HEAD_VERSION, "Install the libraries on the command line using the latest upstream sources"},
- {OPTION_NO_DOWNLOADS, "Do not download new sources"},
- {OPTION_ONLY_DOWNLOADS, "Download sources but don't build packages"},
- {OPTION_ONLY_BINARYCACHING, "Fail if cached binaries are not available"},
- {OPTION_RECURSE, "Allow removal of packages as part of installation"},
- {OPTION_KEEP_GOING, "Continue installing packages on failure"},
- {OPTION_EDITABLE, "Disable source re-extraction and binary caching for libraries on the command line"},
- {OPTION_USE_ARIA2, "Use aria2 to perform download tasks"},
- {OPTION_CLEAN_AFTER_BUILD, "Clean buildtrees, packages and downloads after building each package"},
- {OPTION_MANIFEST_NO_DEFAULT_FEATURES, "Don't install the default features from the manifest."},
- }};
-
- static constexpr std::array<CommandSetting, 2> INSTALL_SETTINGS = {{
- {OPTION_XUNIT, "File to output results in XUnit format (Internal use)"},
- {OPTION_WRITE_PACKAGES_CONFIG,
- "Writes out a NuGet packages.config-formatted file for use with external binary caching.\nSee `vcpkg help "
- "binarycaching` for more information."},
- }};
-
- static constexpr std::array<CommandMultiSetting, 1> MANIFEST_INSTALL_MULTISETTINGS = {{
- {OPTION_MANIFEST_FEATURE, "A feature from the manifest to install."},
- }};
-
- std::vector<std::string> get_all_port_names(const VcpkgPaths& paths)
- {
- auto sources_and_errors = Paragraphs::try_load_all_registry_ports(paths);
-
- return Util::fmap(sources_and_errors.paragraphs, Paragraphs::get_name_of_control_file);
- }
-
- const CommandStructure COMMAND_STRUCTURE = {
- create_example_string("install zlib zlib:x64-windows curl boost"),
- 1,
- SIZE_MAX,
- {INSTALL_SWITCHES, INSTALL_SETTINGS},
- &get_all_port_names,
- };
-
- const CommandStructure MANIFEST_COMMAND_STRUCTURE = {
- create_example_string("install --triplet x64-windows"),
- 0,
- 0,
- {MANIFEST_INSTALL_SWITCHES, INSTALL_SETTINGS, MANIFEST_INSTALL_MULTISETTINGS},
- nullptr,
- };
-
- static void print_cmake_information(const BinaryParagraph& bpgh, const VcpkgPaths& paths)
- {
- auto usage = get_cmake_usage(bpgh, paths);
-
- if (!usage.message.empty())
- {
- System::print2(usage.message);
- }
- }
-
- CMakeUsageInfo get_cmake_usage(const BinaryParagraph& bpgh, const VcpkgPaths& paths)
- {
- static const std::regex cmake_library_regex(R"(\badd_library\(([^\$\s\)]+)\s)",
- std::regex_constants::ECMAScript);
-
- CMakeUsageInfo ret;
-
- auto& fs = paths.get_filesystem();
-
- auto usage_file = paths.installed / bpgh.spec.triplet().canonical_name() / "share" / bpgh.spec.name() / "usage";
- if (fs.exists(usage_file))
- {
- ret.usage_file = true;
- auto maybe_contents = fs.read_contents(usage_file);
- if (auto p_contents = maybe_contents.get())
- {
- ret.message = std::move(*p_contents);
- ret.message.push_back('\n');
- }
- return ret;
- }
-
- auto files = fs.read_lines(paths.listfile_path(bpgh));
- if (auto p_lines = files.get())
- {
- std::map<std::string, std::string> config_files;
- std::map<std::string, std::vector<std::string>> library_targets;
- bool is_header_only = true;
- std::string header_path;
-
- for (auto&& suffix : *p_lines)
- {
- if (Strings::case_insensitive_ascii_contains(suffix, "/share/") && Strings::ends_with(suffix, ".cmake"))
- {
- // CMake file is inside the share folder
- auto path = paths.installed / suffix;
- auto maybe_contents = fs.read_contents(path);
- auto find_package_name = fs::u8string(path.parent_path().filename());
- if (auto p_contents = maybe_contents.get())
- {
- std::sregex_iterator next(p_contents->begin(), p_contents->end(), cmake_library_regex);
- std::sregex_iterator last;
-
- while (next != last)
- {
- auto match = *next;
- auto& targets = library_targets[find_package_name];
- if (std::find(targets.cbegin(), targets.cend(), match[1]) == targets.cend())
- targets.push_back(match[1]);
- ++next;
- }
- }
-
- auto filename = fs::u8string(fs::u8path(suffix).filename());
-
- if (Strings::ends_with(filename, "Config.cmake"))
- {
- auto root = filename.substr(0, filename.size() - 12);
- if (Strings::case_insensitive_ascii_equals(root, find_package_name))
- config_files[find_package_name] = root;
- }
- else if (Strings::ends_with(filename, "-config.cmake"))
- {
- auto root = filename.substr(0, filename.size() - 13);
- if (Strings::case_insensitive_ascii_equals(root, find_package_name))
- config_files[find_package_name] = root;
- }
- }
- if (Strings::case_insensitive_ascii_contains(suffix, "/lib/") ||
- Strings::case_insensitive_ascii_contains(suffix, "/bin/"))
- {
- if (!Strings::ends_with(suffix, ".pc") && !Strings::ends_with(suffix, "/")) is_header_only = false;
- }
-
- if (is_header_only && header_path.empty())
- {
- auto it = suffix.find("/include/");
- if (it != std::string::npos && !Strings::ends_with(suffix, "/"))
- {
- header_path = suffix.substr(it + 9);
- }
- }
- }
-
- ret.header_only = is_header_only;
-
- if (library_targets.empty())
- {
- if (is_header_only && !header_path.empty())
- {
- static auto cmakeify = [](std::string name) {
- auto n = Strings::ascii_to_uppercase(Strings::replace_all(std::move(name), "-", "_"));
- if (n.empty() || Parse::ParserBase::is_ascii_digit(n[0]))
- {
- n.insert(n.begin(), '_');
- }
- return n;
- };
-
- const auto name = cmakeify(bpgh.spec.name());
- auto msg = Strings::concat(
- "The package ", bpgh.spec, " is header only and can be used from CMake via:\n\n");
- Strings::append(msg, " find_path(", name, "_INCLUDE_DIRS \"", header_path, "\")\n");
- Strings::append(msg, " target_include_directories(main PRIVATE ${", name, "_INCLUDE_DIRS})\n\n");
-
- ret.message = std::move(msg);
- }
- }
- else
- {
- auto msg = Strings::concat("The package ", bpgh.spec, " provides CMake targets:\n\n");
-
- for (auto&& library_target_pair : library_targets)
- {
- auto config_it = config_files.find(library_target_pair.first);
- if (config_it != config_files.end())
- Strings::append(msg, " find_package(", config_it->second, " CONFIG REQUIRED)\n");
- else
- Strings::append(msg, " find_package(", library_target_pair.first, " CONFIG REQUIRED)\n");
-
- std::sort(library_target_pair.second.begin(),
- library_target_pair.second.end(),
- [](const std::string& l, const std::string& r) {
- if (l.size() < r.size()) return true;
- if (l.size() > r.size()) return false;
- return l < r;
- });
-
- if (library_target_pair.second.size() <= 4)
- {
- Strings::append(msg,
- " target_link_libraries(main PRIVATE ",
- Strings::join(" ", library_target_pair.second),
- ")\n\n");
- }
- else
- {
- auto omitted = library_target_pair.second.size() - 4;
- library_target_pair.second.erase(library_target_pair.second.begin() + 4,
- library_target_pair.second.end());
- msg += Strings::format(" # Note: %zd target(s) were omitted.\n"
- " target_link_libraries(main PRIVATE %s)\n\n",
- omitted,
- Strings::join(" ", library_target_pair.second));
- }
- }
- ret.message = std::move(msg);
- }
- ret.cmake_targets_map = std::move(library_targets);
- }
- return ret;
- }
-
- ///
- /// <summary>
- /// Run "install" command.
- /// </summary>
- ///
- void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, Triplet default_triplet)
- {
- // input sanitization
- const ParsedArguments options =
- args.parse_arguments(paths.manifest_mode_enabled() ? MANIFEST_COMMAND_STRUCTURE : COMMAND_STRUCTURE);
-
- auto binaryprovider = create_binary_provider_from_configs(args.binary_sources).value_or_exit(VCPKG_LINE_INFO);
-
- const bool dry_run = Util::Sets::contains(options.switches, OPTION_DRY_RUN);
- const bool use_head_version = Util::Sets::contains(options.switches, (OPTION_USE_HEAD_VERSION));
- const bool no_downloads = Util::Sets::contains(options.switches, (OPTION_NO_DOWNLOADS));
- const bool only_downloads = Util::Sets::contains(options.switches, (OPTION_ONLY_DOWNLOADS));
- const bool no_build_missing = Util::Sets::contains(options.switches, OPTION_ONLY_BINARYCACHING);
- const bool is_recursive = Util::Sets::contains(options.switches, (OPTION_RECURSE));
- const bool is_editable = Util::Sets::contains(options.switches, (OPTION_EDITABLE)) || !args.cmake_args.empty();
- const bool use_aria2 = Util::Sets::contains(options.switches, (OPTION_USE_ARIA2));
- const bool clean_after_build = Util::Sets::contains(options.switches, (OPTION_CLEAN_AFTER_BUILD));
- const KeepGoing keep_going =
- to_keep_going(Util::Sets::contains(options.switches, OPTION_KEEP_GOING) || only_downloads);
- const bool prohibit_backcompat_features =
- Util::Sets::contains(options.switches, (OPTION_PROHIBIT_BACKCOMPAT_FEATURES));
-
- auto& fs = paths.get_filesystem();
-
- Build::DownloadTool download_tool = Build::DownloadTool::BUILT_IN;
- if (use_aria2) download_tool = Build::DownloadTool::ARIA2;
-
- const Build::BuildPackageOptions install_plan_options = {
- Util::Enum::to_enum<Build::BuildMissing>(!no_build_missing),
- Util::Enum::to_enum<Build::UseHeadVersion>(use_head_version),
- Util::Enum::to_enum<Build::AllowDownloads>(!no_downloads),
- Util::Enum::to_enum<Build::OnlyDownloads>(only_downloads),
- Util::Enum::to_enum<Build::CleanBuildtrees>(clean_after_build),
- Util::Enum::to_enum<Build::CleanPackages>(clean_after_build),
- Util::Enum::to_enum<Build::CleanDownloads>(clean_after_build),
- download_tool,
- Build::PurgeDecompressFailure::NO,
- Util::Enum::to_enum<Build::Editable>(is_editable),
- prohibit_backcompat_features ? Build::BackcompatFeatures::PROHIBIT : Build::BackcompatFeatures::ALLOW,
- };
-
- PortFileProvider::PathsPortFileProvider provider(paths, args.overlay_ports);
- auto var_provider_storage = CMakeVars::make_triplet_cmake_var_provider(paths);
- auto& var_provider = *var_provider_storage;
-
- if (auto manifest = paths.get_manifest().get())
- {
- Optional<fs::path> pkgsconfig;
- auto it_pkgsconfig = options.settings.find(OPTION_WRITE_PACKAGES_CONFIG);
- if (it_pkgsconfig != options.settings.end())
- {
- Metrics::g_metrics.lock()->track_property("x-write-nuget-packages-config", "defined");
- pkgsconfig = fs::u8path(it_pkgsconfig->second);
- }
- const auto& manifest_path = paths.get_manifest_path().value_or_exit(VCPKG_LINE_INFO);
- auto maybe_manifest_scf = SourceControlFile::parse_manifest_file(manifest_path, *manifest);
- if (!maybe_manifest_scf)
- {
- print_error_message(maybe_manifest_scf.error());
- System::print2("See https://github.com/Microsoft/vcpkg/tree/master/docs/users/manifests.md for "
- "more information.\n");
- Checks::exit_fail(VCPKG_LINE_INFO);
- }
-
- auto& manifest_scf = *maybe_manifest_scf.value_or_exit(VCPKG_LINE_INFO);
-
- if (auto maybe_error = manifest_scf.check_against_feature_flags(manifest_path, paths.get_feature_flags()))
- {
- Checks::exit_with_message(VCPKG_LINE_INFO, maybe_error.value_or_exit(VCPKG_LINE_INFO));
- }
-
- std::vector<std::string> features;
- auto manifest_feature_it = options.multisettings.find(OPTION_MANIFEST_FEATURE);
- if (manifest_feature_it != options.multisettings.end())
- {
- features.insert(features.end(), manifest_feature_it->second.begin(), manifest_feature_it->second.end());
- }
- auto core_it = Util::find(features, "core");
- if (core_it == features.end())
- {
- if (!Util::Sets::contains(options.switches, OPTION_MANIFEST_NO_DEFAULT_FEATURES))
- features.push_back("default");
- }
- else
- {
- // remove "core" because resolve_deps_as_top_level uses default-inversion
- features.erase(core_it);
- }
-
- if (!manifest_scf.core_paragraph->overrides.empty())
- {
- Metrics::g_metrics.lock()->track_property("manifest_overrides", "defined");
- }
- if (auto p_baseline = manifest_scf.core_paragraph->builtin_baseline.get())
- {
- Metrics::g_metrics.lock()->track_property("manifest_baseline", "defined");
- if (p_baseline->size() != 40 || !std::all_of(p_baseline->begin(), p_baseline->end(), [](char ch) {
- return (ch >= 'a' || ch <= 'f') || Parse::ParserBase::is_ascii_digit(ch);
- }))
- {
- Checks::exit_maybe_upgrade(VCPKG_LINE_INFO,
- "Error: the top-level builtin-baseline (%s) was not a valid commit sha: "
- "expected 40 lowercase hexadecimal characters.\n%s\n",
- *p_baseline,
- paths.get_current_git_sha_message());
- }
-
- paths.get_configuration().registry_set.experimental_set_builtin_registry_baseline(*p_baseline);
- }
- auto verprovider = PortFileProvider::make_versioned_portfile_provider(paths);
- auto baseprovider = PortFileProvider::make_baseline_provider(paths);
- auto oprovider = PortFileProvider::make_overlay_provider(paths, args.overlay_ports);
-
- auto install_plan =
- Dependencies::create_versioned_install_plan(*verprovider,
- *baseprovider,
- *oprovider,
- var_provider,
- manifest_scf.core_paragraph->dependencies,
- manifest_scf.core_paragraph->overrides,
- {manifest_scf.core_paragraph->name, default_triplet})
- .value_or_exit(VCPKG_LINE_INFO);
-
- for (InstallPlanAction& action : install_plan.install_actions)
- {
- action.build_options = install_plan_options;
- action.build_options.use_head_version = Build::UseHeadVersion::NO;
- action.build_options.editable = Build::Editable::NO;
- }
-
- Commands::SetInstalled::perform_and_exit_ex(args,
- paths,
- provider,
- *binaryprovider,
- var_provider,
- std::move(install_plan),
- dry_run ? Commands::DryRun::Yes : Commands::DryRun::No,
- pkgsconfig);
- }
-
- const std::vector<FullPackageSpec> specs = Util::fmap(args.command_arguments, [&](auto&& arg) {
- return Input::check_and_get_full_package_spec(
- std::string(arg), default_triplet, COMMAND_STRUCTURE.example_text);
- });
-
- for (auto&& spec : specs)
- {
- Input::check_triplet(spec.package_spec.triplet(), paths);
- }
-
- // create the plan
- System::print2("Computing installation plan...\n");
- StatusParagraphs status_db = database_load_check(paths);
-
- // Note: action_plan will hold raw pointers to SourceControlFileLocations from this map
- auto action_plan = Dependencies::create_feature_install_plan(provider, var_provider, specs, status_db);
-
- for (auto&& action : action_plan.install_actions)
- {
- action.build_options = install_plan_options;
- if (action.request_type != RequestType::USER_REQUESTED)
- {
- action.build_options.use_head_version = Build::UseHeadVersion::NO;
- action.build_options.editable = Build::Editable::NO;
- }
- }
-
- var_provider.load_tag_vars(action_plan, provider);
-
- // install plan will be empty if it is already installed - need to change this at status paragraph part
- Checks::check_exit(VCPKG_LINE_INFO, !action_plan.empty(), "Install plan cannot be empty");
-
- // log the plan
- std::string specs_string;
- for (auto&& remove_action : action_plan.remove_actions)
- {
- if (!specs_string.empty()) specs_string.push_back(',');
- specs_string += "R$" + Hash::get_string_hash(remove_action.spec.to_string(), Hash::Algorithm::Sha256);
- }
-
- for (auto&& install_action : action_plan.install_actions)
- {
- if (!specs_string.empty()) specs_string.push_back(',');
- specs_string += Hash::get_string_hash(install_action.spec.to_string(), Hash::Algorithm::Sha256);
- }
-
-#if defined(_WIN32)
- const auto maybe_common_triplet = common_projection(
- action_plan.install_actions, [](const InstallPlanAction& to_install) { return to_install.spec.triplet(); });
- if (maybe_common_triplet)
- {
- const auto& common_triplet = maybe_common_triplet.value_or_exit(VCPKG_LINE_INFO);
- const auto maybe_common_arch = common_triplet.guess_architecture();
- if (maybe_common_arch)
- {
- const auto maybe_vs_prompt = System::guess_visual_studio_prompt_target_architecture();
- if (maybe_vs_prompt)
- {
- const auto common_arch = maybe_common_arch.value_or_exit(VCPKG_LINE_INFO);
- const auto vs_prompt = maybe_vs_prompt.value_or_exit(VCPKG_LINE_INFO);
- if (common_arch != vs_prompt)
- {
- const auto vs_prompt_view = to_zstring_view(vs_prompt);
- System::print2(vcpkg::System::Color::warning,
- "warning: vcpkg appears to be in a Visual Studio prompt targeting ",
- vs_prompt_view,
- " but is installing packages for ",
- common_triplet.to_string(),
- ". Consider using --triplet ",
- vs_prompt_view,
- "-windows or --triplet ",
- vs_prompt_view,
- "-uwp.\n");
- }
- }
- }
- }
-#endif // defined(_WIN32)
-
- Metrics::g_metrics.lock()->track_property("installplan_1", specs_string);
-
- Dependencies::print_plan(action_plan, is_recursive, paths.builtin_ports_directory());
-
- auto it_pkgsconfig = options.settings.find(OPTION_WRITE_PACKAGES_CONFIG);
- if (it_pkgsconfig != options.settings.end())
- {
- Metrics::g_metrics.lock()->track_property("x-write-nuget-packages-config", "defined");
- Build::compute_all_abis(paths, action_plan, var_provider, status_db);
-
- auto pkgsconfig_path = Files::combine(paths.original_cwd, fs::u8path(it_pkgsconfig->second));
- auto pkgsconfig_contents = generate_nuget_packages_config(action_plan);
- fs.write_contents(pkgsconfig_path, pkgsconfig_contents, VCPKG_LINE_INFO);
- System::print2("Wrote NuGet packages config information to ", fs::u8string(pkgsconfig_path), "\n");
- }
-
- if (dry_run)
- {
- Checks::exit_success(VCPKG_LINE_INFO);
- }
-
- const InstallSummary summary =
- perform(args,
- action_plan,
- keep_going,
- paths,
- status_db,
- args.binary_caching_enabled() && !only_downloads ? *binaryprovider : null_binary_provider(),
- Build::null_build_logs_recorder(),
- var_provider);
-
- System::print2("\nTotal elapsed time: ", summary.total_elapsed_time, "\n\n");
-
- if (keep_going == KeepGoing::YES)
- {
- summary.print();
- }
-
- auto it_xunit = options.settings.find(OPTION_XUNIT);
- if (it_xunit != options.settings.end())
- {
- std::string xunit_doc = "<assemblies><assembly><collection>\n";
-
- xunit_doc += summary.xunit_results();
-
- xunit_doc += "</collection></assembly></assemblies>\n";
- fs.write_contents(fs::u8path(it_xunit->second), xunit_doc, VCPKG_LINE_INFO);
- }
-
- for (auto&& result : summary.results)
- {
- if (!result.action) continue;
- if (result.action->request_type != RequestType::USER_REQUESTED) continue;
- auto bpgh = result.get_binary_paragraph();
- if (!bpgh) continue;
- print_cmake_information(*bpgh, paths);
- }
-
- Checks::exit_success(VCPKG_LINE_INFO);
- }
-
- void InstallCommand::perform_and_exit(const VcpkgCmdArguments& args,
- const VcpkgPaths& paths,
- Triplet default_triplet) const
- {
- Install::perform_and_exit(args, paths, default_triplet);
- }
-
- SpecSummary::SpecSummary(const PackageSpec& spec, const Dependencies::InstallPlanAction* action)
- : spec(spec), build_result{BuildResult::NULLVALUE, nullptr}, action(action)
- {
- }
-
- const BinaryParagraph* SpecSummary::get_binary_paragraph() const
- {
- if (build_result.binary_control_file) return &build_result.binary_control_file->core_paragraph;
- if (action)
- if (auto p_status = action->installed_package.get())
- {
- return &p_status->core->package;
- }
- return nullptr;
- }
-
- static std::string xunit_result(const PackageSpec& spec, Chrono::ElapsedTime time, BuildResult code)
- {
- std::string message_block;
- const char* result_string = "";
- switch (code)
- {
- case BuildResult::POST_BUILD_CHECKS_FAILED:
- case BuildResult::FILE_CONFLICTS:
- case BuildResult::BUILD_FAILED:
- case BuildResult::CACHE_MISSING:
- result_string = "Fail";
- message_block =
- Strings::format("<failure><message><![CDATA[%s]]></message></failure>", to_string(code));
- break;
- case BuildResult::EXCLUDED:
- case BuildResult::CASCADED_DUE_TO_MISSING_DEPENDENCIES:
- result_string = "Skip";
- message_block = Strings::format("<reason><![CDATA[%s]]></reason>", to_string(code));
- break;
- case BuildResult::SUCCEEDED: result_string = "Pass"; break;
- default: Checks::unreachable(VCPKG_LINE_INFO);
- }
-
- return Strings::format(R"(<test name="%s" method="%s" time="%lld" result="%s">%s</test>)"
- "\n",
- spec,
- spec,
- time.as<std::chrono::seconds>().count(),
- result_string,
- message_block);
- }
-
- std::string InstallSummary::xunit_results() const
- {
- std::string xunit_doc;
- for (auto&& result : results)
- {
- xunit_doc += xunit_result(result.spec, result.timing, result.build_result.code);
- }
- return xunit_doc;
- }
-}
diff --git a/toolsrc/src/vcpkg/metrics.cpp b/toolsrc/src/vcpkg/metrics.cpp
deleted file mode 100644
index e0a4e5017..000000000
--- a/toolsrc/src/vcpkg/metrics.cpp
+++ /dev/null
@@ -1,501 +0,0 @@
-#include <vcpkg/base/chrono.h>
-#include <vcpkg/base/files.h>
-#include <vcpkg/base/hash.h>
-#include <vcpkg/base/json.h>
-#include <vcpkg/base/strings.h>
-#include <vcpkg/base/system.process.h>
-
-#include <vcpkg/commands.h>
-#include <vcpkg/commands.version.h>
-#include <vcpkg/metrics.h>
-
-#if defined(_WIN32)
-#pragma comment(lib, "version")
-#pragma comment(lib, "winhttp")
-#endif
-
-namespace vcpkg::Metrics
-{
- Util::LockGuarded<Metrics> g_metrics;
-
- static std::string get_current_date_time()
- {
- auto maybe_time = Chrono::CTime::get_current_date_time();
- if (auto ptime = maybe_time.get())
- {
- return ptime->to_string();
- }
-
- return "";
- }
-
- struct append_hexits
- {
- constexpr static char hex[17] = "0123456789abcdef";
- void operator()(std::string& res, std::uint8_t bits) const
- {
- res.push_back(hex[(bits >> 4) & 0x0F]);
- res.push_back(hex[(bits >> 0) & 0x0F]);
- }
- };
- constexpr char append_hexits::hex[17];
-
- // note: this ignores the bits of these numbers that would be where format and variant go
- static std::string uuid_of_integers(uint64_t top, uint64_t bottom)
- {
- // uuid_field_size in bytes, not hex characters
- constexpr size_t uuid_top_field_size[] = {4, 2, 2};
- constexpr size_t uuid_bottom_field_size[] = {2, 6};
-
- // uuid_field_size in hex characters, not bytes
- constexpr size_t uuid_size = 8 + 1 + 4 + 1 + 4 + 1 + 4 + 1 + 12;
-
- constexpr static append_hexits write_byte;
-
- // set the version bits to 4
- top &= 0xFFFF'FFFF'FFFF'0FFFULL;
- top |= 0x0000'0000'0000'4000ULL;
-
- // set the variant bits to 2 (variant one)
- bottom &= 0x3FFF'FFFF'FFFF'FFFFULL;
- bottom |= 0x8000'0000'0000'0000ULL;
-
- std::string res;
- res.reserve(uuid_size);
-
- bool first = true;
- size_t start_byte = 0;
- for (auto field_size : uuid_top_field_size)
- {
- if (!first)
- {
- res.push_back('-');
- }
- first = false;
- for (size_t i = start_byte; i < start_byte + field_size; ++i)
- {
- auto shift = 64 - (i + 1) * 8;
- write_byte(res, (top >> shift) & 0xFF);
- }
- start_byte += field_size;
- }
-
- start_byte = 0;
- for (auto field_size : uuid_bottom_field_size)
- {
- res.push_back('-');
- for (size_t i = start_byte; i < start_byte + field_size; ++i)
- {
- auto shift = 64 - (i + 1) * 8;
- write_byte(res, (bottom >> shift) & 0xFF);
- }
- start_byte += field_size;
- }
-
- return res;
- }
-
- // UUID format version 4, variant 1
- // http://en.wikipedia.org/wiki/Universally_unique_identifier
- // [0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}
- static std::string generate_random_UUID()
- {
- std::random_device rnd{};
- std::uniform_int_distribution<std::uint64_t> uid{};
- return uuid_of_integers(uid(rnd), uid(rnd));
- }
-
- static const std::string& get_session_id()
- {
- static const std::string ID = generate_random_UUID();
- return ID;
- }
-
- static std::string get_os_version_string()
- {
-#if defined(_WIN32)
- std::wstring path;
- path.resize(MAX_PATH);
- const auto n = GetSystemDirectoryW(&path[0], static_cast<UINT>(path.size()));
- path.resize(n);
- path += L"\\kernel32.dll";
-
- const auto versz = GetFileVersionInfoSizeW(path.c_str(), nullptr);
- if (versz == 0) return "";
-
- std::vector<char> verbuf;
- verbuf.resize(versz);
-
- if (!GetFileVersionInfoW(path.c_str(), 0, static_cast<DWORD>(verbuf.size()), &verbuf[0])) return "";
-
- void* rootblock;
- UINT rootblocksize;
- if (!VerQueryValueW(&verbuf[0], L"\\", &rootblock, &rootblocksize)) return "";
-
- auto rootblock_ffi = static_cast<VS_FIXEDFILEINFO*>(rootblock);
-
- return Strings::format("%d.%d.%d",
- static_cast<int>(HIWORD(rootblock_ffi->dwProductVersionMS)),
- static_cast<int>(LOWORD(rootblock_ffi->dwProductVersionMS)),
- static_cast<int>(HIWORD(rootblock_ffi->dwProductVersionLS)));
-#else
- return "unknown";
-#endif
- }
-
- struct MetricMessage
- {
- std::string user_id = generate_random_UUID();
- std::string user_timestamp;
- std::string timestamp = get_current_date_time();
-
- Json::Object properties;
- Json::Object measurements;
-
- Json::Array buildtime_names;
- Json::Array buildtime_times;
-
- void track_property(const std::string& name, const std::string& value)
- {
- properties.insert_or_replace(name, Json::Value::string(value));
- }
-
- void track_metric(const std::string& name, double value)
- {
- measurements.insert_or_replace(name, Json::Value::number(value));
- }
-
- void track_buildtime(const std::string& name, double value)
- {
- buildtime_names.push_back(Json::Value::string(name));
- buildtime_times.push_back(Json::Value::number(value));
- }
- void track_feature(const std::string& name, bool value)
- {
- properties.insert("feature-flag-" + name, Json::Value::boolean(value));
- }
-
- std::string format_event_data_template() const
- {
- auto props_plus_buildtimes = properties;
- if (buildtime_names.size() > 0)
- {
- props_plus_buildtimes.insert("buildnames_1", buildtime_names);
- props_plus_buildtimes.insert("buildtimes", buildtime_times);
- }
-
- Json::Array arr = Json::Array();
- Json::Object& obj = arr.push_back(Json::Object());
-
- obj.insert("ver", Json::Value::integer(1));
- obj.insert("name", Json::Value::string("Microsoft.ApplicationInsights.Event"));
- obj.insert("time", Json::Value::string(timestamp));
- obj.insert("sampleRate", Json::Value::number(100.0));
- obj.insert("seq", Json::Value::string("0:0"));
- obj.insert("iKey", Json::Value::string("b4e88960-4393-4dd9-ab8e-97e8fe6d7603"));
- obj.insert("flags", Json::Value::integer(0));
-
- {
- Json::Object& tags = obj.insert("tags", Json::Object());
-
- tags.insert("ai.device.os", Json::Value::string("Other"));
-
- const char* os_name =
-#if defined(_WIN32)
- "Windows";
-#elif defined(__APPLE__)
- "OSX";
-#elif defined(__linux__)
- "Linux";
-#elif defined(__FreeBSD__)
- "FreeBSD";
-#elif defined(__unix__)
- "Unix";
-#else
- "Other";
-#endif
-
- tags.insert("ai.device.osVersion",
- Json::Value::string(Strings::format("%s-%s", os_name, get_os_version_string())));
- tags.insert("ai.session.id", Json::Value::string(get_session_id()));
- tags.insert("ai.user.id", Json::Value::string(user_id));
- tags.insert("ai.user.accountAcquisitionDate", Json::Value::string(user_timestamp));
- }
-
- {
- Json::Object& data = obj.insert("data", Json::Object());
-
- data.insert("baseType", Json::Value::string("EventData"));
- Json::Object& base_data = data.insert("baseData", Json::Object());
-
- base_data.insert("ver", Json::Value::integer(2));
- base_data.insert("name", Json::Value::string("commandline_test7"));
- base_data.insert("properties", std::move(props_plus_buildtimes));
- base_data.insert("measurements", measurements);
- }
-
- return Json::stringify(arr, vcpkg::Json::JsonStyle());
- }
- };
-
- static MetricMessage g_metricmessage;
- static bool g_should_send_metrics =
-#if defined(NDEBUG)
- true
-#else
- false
-#endif
- ;
- static bool g_should_print_metrics = false;
- static bool g_metrics_disabled = false;
-
- std::string get_MAC_user()
- {
-#if defined(_WIN32)
- if (!g_metrics.lock()->metrics_enabled())
- {
- return "{}";
- }
-
- auto getmac = System::cmd_execute_and_capture_output(System::Command("getmac"));
-
- if (getmac.exit_code != 0) return "0";
-
- std::regex mac_regex("([a-fA-F0-9]{2}(-[a-fA-F0-9]{2}){5})");
- std::sregex_iterator next(getmac.output.begin(), getmac.output.end(), mac_regex);
- std::sregex_iterator last;
-
- while (next != last)
- {
- const auto match = *next;
- if (match[0] != "00-00-00-00-00-00")
- {
- return vcpkg::Hash::get_string_hash(match[0].str(), Hash::Algorithm::Sha256);
- }
- ++next;
- }
-
- return "0";
-#else
- return "{}";
-#endif
- }
-
- void Metrics::set_user_information(const std::string& user_id, const std::string& first_use_time)
- {
- g_metricmessage.user_id = user_id;
- g_metricmessage.user_timestamp = first_use_time;
- }
-
- void Metrics::init_user_information(std::string& user_id, std::string& first_use_time)
- {
- user_id = generate_random_UUID();
- first_use_time = get_current_date_time();
- }
-
- void Metrics::set_send_metrics(bool should_send_metrics) { g_should_send_metrics = should_send_metrics; }
-
- void Metrics::set_print_metrics(bool should_print_metrics) { g_should_print_metrics = should_print_metrics; }
-
- void Metrics::set_disabled(bool disabled) { g_metrics_disabled = disabled; }
-
- bool Metrics::metrics_enabled() { return !g_metrics_disabled; }
-
- void Metrics::track_metric(const std::string& name, double value)
- {
- if (!metrics_enabled())
- {
- return;
- }
- g_metricmessage.track_metric(name, value);
- }
-
- void Metrics::track_buildtime(const std::string& name, double value)
- {
- if (!metrics_enabled())
- {
- return;
- }
- g_metricmessage.track_buildtime(name, value);
- }
-
- void Metrics::track_property(const std::string& name, const std::string& value)
- {
- if (!metrics_enabled())
- {
- return;
- }
- g_metricmessage.track_property(name, value);
- }
-
- void Metrics::track_feature(const std::string& name, bool value)
- {
- if (!metrics_enabled())
- {
- return;
- }
- g_metricmessage.track_feature(name, value);
- }
-
- void Metrics::upload(const std::string& payload)
- {
- if (!metrics_enabled())
- {
- return;
- }
-
-#if defined(_WIN32)
- HINTERNET connect = nullptr, request = nullptr;
- BOOL results = FALSE;
-
- const HINTERNET session = WinHttpOpen(
- L"vcpkg/1.0", WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);
-
- unsigned long secure_protocols = WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_2;
- if (session && WinHttpSetOption(session, WINHTTP_OPTION_SECURE_PROTOCOLS, &secure_protocols, sizeof(DWORD)))
- {
- connect = WinHttpConnect(session, L"dc.services.visualstudio.com", INTERNET_DEFAULT_HTTPS_PORT, 0);
- }
-
- if (connect)
- {
- request = WinHttpOpenRequest(connect,
- L"POST",
- L"/v2/track",
- nullptr,
- WINHTTP_NO_REFERER,
- WINHTTP_DEFAULT_ACCEPT_TYPES,
- WINHTTP_FLAG_SECURE);
- }
-
- if (request)
- {
- if (MAXDWORD <= payload.size()) abort();
- std::wstring hdrs = L"Content-Type: application/json\r\n";
- std::string& p = const_cast<std::string&>(payload);
- results = WinHttpSendRequest(request,
- hdrs.c_str(),
- static_cast<DWORD>(hdrs.size()),
- static_cast<void*>(&p[0]),
- static_cast<DWORD>(payload.size()),
- static_cast<DWORD>(payload.size()),
- 0);
- }
-
- if (results)
- {
- results = WinHttpReceiveResponse(request, nullptr);
- }
-
- DWORD http_code = 0, junk = sizeof(DWORD);
-
- if (results)
- {
- results = WinHttpQueryHeaders(request,
- WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER,
- nullptr,
- &http_code,
- &junk,
- WINHTTP_NO_HEADER_INDEX);
- }
-
- std::vector<char> response_buffer;
- if (results)
- {
- DWORD available_data = 0, read_data = 0, total_data = 0;
- while ((results = WinHttpQueryDataAvailable(request, &available_data)) == TRUE && available_data > 0)
- {
- response_buffer.resize(response_buffer.size() + available_data);
-
- results = WinHttpReadData(request, &response_buffer.data()[total_data], available_data, &read_data);
-
- if (!results)
- {
- break;
- }
-
- total_data += read_data;
-
- response_buffer.resize(total_data);
- }
- }
-
- if (!results)
- {
-#ifndef NDEBUG
- __debugbreak();
- auto err = GetLastError();
- std::cerr << "[DEBUG] failed to connect to server: " << err << "\n";
-#endif // NDEBUG
- }
-
- if (request) WinHttpCloseHandle(request);
- if (connect) WinHttpCloseHandle(connect);
- if (session) WinHttpCloseHandle(session);
-#else // ^^^ _WIN32 // !_WIN32 vvv
- (void)payload;
-#endif // ^^^ !_WIN32
- }
-
- void Metrics::flush(Files::Filesystem& fs)
- {
- if (!metrics_enabled())
- {
- return;
- }
-
- const std::string payload = g_metricmessage.format_event_data_template();
- if (g_should_print_metrics) std::cerr << payload << "\n";
- if (!g_should_send_metrics) return;
-
-#if defined(_WIN32)
- wchar_t temp_folder[MAX_PATH];
- GetTempPathW(MAX_PATH, temp_folder);
-
- const fs::path temp_folder_path = fs::path(temp_folder) / "vcpkg";
- const fs::path temp_folder_path_exe =
- temp_folder_path / Strings::format("vcpkg-%s.exe", Commands::Version::base_version());
-#endif
-
- std::error_code ec;
-#if defined(_WIN32)
- fs.create_directories(temp_folder_path, ec);
- if (ec) return;
- fs.copy_file(
- System::get_exe_path_of_current_process(), temp_folder_path_exe, fs::copy_options::skip_existing, ec);
- if (ec) return;
-#else
- if (!fs.exists("/tmp")) return;
- const fs::path temp_folder_path = "/tmp/vcpkg";
- fs.create_directory(temp_folder_path, ignore_errors);
-#endif
- const fs::path vcpkg_metrics_txt_path = temp_folder_path / ("vcpkg" + generate_random_UUID() + ".txt");
- fs.write_contents(vcpkg_metrics_txt_path, payload, ec);
- if (ec) return;
-
-#if defined(_WIN32)
- System::Command builder;
- builder.path_arg(temp_folder_path_exe);
- builder.string_arg("x-upload-metrics");
- builder.path_arg(vcpkg_metrics_txt_path);
- System::cmd_execute_background(builder);
-#else
- // TODO: convert to cmd_execute_background or something.
- auto curl = System::Command("curl")
- .string_arg("https://dc.services.visualstudio.com/v2/track")
- .string_arg("-H")
- .string_arg("Content-Type: application/json")
- .string_arg("-X")
- .string_arg("POST")
- .string_arg("--tlsv1.2")
- .string_arg("--data")
- .string_arg(Strings::concat("@", fs::u8string(vcpkg_metrics_txt_path)))
- .raw_arg(">/dev/null")
- .raw_arg("2>&1");
- auto remove = System::Command("rm").path_arg(vcpkg_metrics_txt_path);
- System::Command cmd_line;
- cmd_line.raw_arg("(").raw_arg(curl.command_line()).raw_arg(";").raw_arg(remove.command_line()).raw_arg(") &");
- System::cmd_execute_clean(cmd_line);
-#endif
- }
-}
diff --git a/toolsrc/src/vcpkg/packagespec.cpp b/toolsrc/src/vcpkg/packagespec.cpp
deleted file mode 100644
index 3f35e118e..000000000
--- a/toolsrc/src/vcpkg/packagespec.cpp
+++ /dev/null
@@ -1,291 +0,0 @@
-#include <vcpkg/base/checks.h>
-#include <vcpkg/base/parse.h>
-#include <vcpkg/base/util.h>
-
-#include <vcpkg/packagespec.h>
-#include <vcpkg/paragraphparser.h>
-
-namespace vcpkg
-{
- std::string FeatureSpec::to_string() const
- {
- std::string ret;
- this->to_string(ret);
- return ret;
- }
- void FeatureSpec::to_string(std::string& out) const
- {
- if (feature().empty()) return spec().to_string(out);
- Strings::append(out, name(), '[', feature(), "]:", triplet());
- }
-
- std::vector<FeatureSpec> FullPackageSpec::to_feature_specs(const std::vector<std::string>& default_features,
- const std::vector<std::string>& all_features) const
- {
- std::vector<FeatureSpec> feature_specs;
-
- if (Util::find(features, "*") != features.end())
- {
- feature_specs.emplace_back(package_spec, "core");
- for (const std::string& feature : all_features)
- {
- feature_specs.emplace_back(package_spec, feature);
- }
- }
- else
- {
- bool core = false;
- for (const std::string& feature : features)
- {
- feature_specs.emplace_back(package_spec, feature);
-
- if (!core)
- {
- core = feature == "core";
- }
- }
-
- if (!core)
- {
- feature_specs.emplace_back(package_spec, "core");
-
- for (const std::string& def : default_features)
- {
- feature_specs.emplace_back(package_spec, def);
- }
- }
- }
-
- return feature_specs;
- }
-
- ExpectedS<FullPackageSpec> FullPackageSpec::from_string(const std::string& spec_as_string, Triplet default_triplet)
- {
- return parse_qualified_specifier(spec_as_string)
- .then([&](ParsedQualifiedSpecifier&& p) -> ExpectedS<FullPackageSpec> {
- if (p.platform)
- return "Error: platform specifier not allowed in this context: " + spec_as_string + "\n";
- auto triplet = p.triplet ? Triplet::from_canonical_name(std::move(*p.triplet.get())) : default_triplet;
- return FullPackageSpec({p.name, triplet}, p.features.value_or({}));
- });
- }
-
- std::vector<PackageSpec> PackageSpec::to_package_specs(const std::vector<std::string>& ports, Triplet triplet)
- {
- return Util::fmap(ports, [&](const std::string& spec_as_string) -> PackageSpec {
- return {spec_as_string, triplet};
- });
- }
-
- const std::string& PackageSpec::name() const { return this->m_name; }
-
- Triplet PackageSpec::triplet() const { return this->m_triplet; }
-
- std::string PackageSpec::dir() const { return Strings::format("%s_%s", this->m_name, this->m_triplet); }
-
- std::string PackageSpec::to_string() const { return Strings::format("%s:%s", this->name(), this->triplet()); }
- void PackageSpec::to_string(std::string& s) const { Strings::append(s, this->name(), ':', this->triplet()); }
-
- bool operator==(const PackageSpec& left, const PackageSpec& right)
- {
- return left.name() == right.name() && left.triplet() == right.triplet();
- }
-
- ExpectedS<Features> Features::from_string(const std::string& name)
- {
- return parse_qualified_specifier(name).then([&](ParsedQualifiedSpecifier&& pqs) -> ExpectedS<Features> {
- if (pqs.triplet) return "Error: triplet not allowed in this context: " + name + "\n";
- if (pqs.platform) return "Error: platform specifier not allowed in this context: " + name + "\n";
- return Features{pqs.name, pqs.features.value_or({})};
- });
- }
-
- static bool is_package_name_char(char32_t ch)
- {
- return Parse::ParserBase::is_lower_alpha(ch) || Parse::ParserBase::is_ascii_digit(ch) || ch == '-';
- }
-
- static bool is_feature_name_char(char32_t ch)
- {
- // TODO: we do not intend underscores to be valid, however there is currently a feature using them
- // (libwebp[vwebp_sdl]).
- // TODO: we need to rename this feature, then remove underscores from this list.
- return is_package_name_char(ch) || ch == '_';
- }
-
- ExpectedS<ParsedQualifiedSpecifier> parse_qualified_specifier(StringView input)
- {
- auto parser = Parse::ParserBase(input, "<unknown>");
- auto maybe_pqs = parse_qualified_specifier(parser);
- if (!parser.at_eof()) parser.add_error("expected eof");
- if (auto e = parser.get_error()) return e->format();
- return std::move(maybe_pqs).value_or_exit(VCPKG_LINE_INFO);
- }
-
- Optional<std::string> parse_feature_name(Parse::ParserBase& parser)
- {
- using Parse::ParserBase;
- auto ret = parser.match_zero_or_more(is_feature_name_char).to_string();
- auto ch = parser.cur();
-
- // ignores the feature name vwebp_sdl as a back-compat thing
- const bool has_underscore = std::find(ret.begin(), ret.end(), '_') != ret.end() && ret != "vwebp_sdl";
- if (has_underscore || ParserBase::is_upper_alpha(ch))
- {
- parser.add_error("invalid character in feature name (must be lowercase, digits, '-')");
- return nullopt;
- }
-
- if (ret.empty())
- {
- parser.add_error("expected feature name (must be lowercase, digits, '-')");
- return nullopt;
- }
- return ret;
- }
- Optional<std::string> parse_package_name(Parse::ParserBase& parser)
- {
- using Parse::ParserBase;
- auto ret = parser.match_zero_or_more(is_package_name_char).to_string();
- auto ch = parser.cur();
- if (ParserBase::is_upper_alpha(ch) || ch == '_')
- {
- parser.add_error("invalid character in package name (must be lowercase, digits, '-')");
- return nullopt;
- }
- if (ret.empty())
- {
- parser.add_error("expected package name (must be lowercase, digits, '-')");
- return nullopt;
- }
- return ret;
- }
-
- Optional<ParsedQualifiedSpecifier> parse_qualified_specifier(Parse::ParserBase& parser)
- {
- using Parse::ParserBase;
- ParsedQualifiedSpecifier ret;
- auto name = parse_package_name(parser);
- if (auto n = name.get())
- ret.name = std::move(*n);
- else
- return nullopt;
- auto ch = parser.cur();
- if (ch == '[')
- {
- std::vector<std::string> features;
- do
- {
- parser.next();
- parser.skip_tabs_spaces();
- if (parser.cur() == '*')
- {
- features.push_back("*");
- parser.next();
- }
- else
- {
- auto feature = parse_feature_name(parser);
- if (auto f = feature.get())
- features.push_back(std::move(*f));
- else
- return nullopt;
- }
- auto skipped_space = parser.skip_tabs_spaces();
- ch = parser.cur();
- if (ch == ']')
- {
- ch = parser.next();
- break;
- }
- else if (ch == ',')
- {
- continue;
- }
- else
- {
- if (skipped_space.size() > 0 || Parse::ParserBase::is_lineend(parser.cur()))
- parser.add_error("expected ',' or ']' in feature list");
- else
- parser.add_error("invalid character in feature name (must be lowercase, digits, '-', or '*')");
- return nullopt;
- }
- } while (true);
- ret.features = std::move(features);
- }
- if (ch == ':')
- {
- parser.next();
- ret.triplet = parser.match_zero_or_more(is_package_name_char).to_string();
- if (ret.triplet.get()->empty())
- {
- parser.add_error("expected triplet name (must be lowercase, digits, '-')");
- return nullopt;
- }
- }
- parser.skip_tabs_spaces();
- ch = parser.cur();
- if (ch == '(')
- {
- auto loc = parser.cur_loc();
- std::string platform_string;
- int depth = 1;
- while (depth > 0 && (ch = parser.next()) != 0)
- {
- if (ch == '(') ++depth;
- if (ch == ')') --depth;
- }
- if (depth > 0)
- {
- parser.add_error("unmatched open braces in platform specifier", loc);
- return nullopt;
- }
- platform_string.append((++loc.it).pointer_to_current(), parser.it().pointer_to_current());
- auto platform_opt = PlatformExpression::parse_platform_expression(
- platform_string, PlatformExpression::MultipleBinaryOperators::Allow);
- if (auto platform = platform_opt.get())
- {
- ret.platform = std::move(*platform);
- }
- else
- {
- parser.add_error(platform_opt.error(), loc);
- }
- parser.next();
- }
- // This makes the behavior of the parser more consistent -- otherwise, it will skip tabs and spaces only if
- // there isn't a qualifier.
- parser.skip_tabs_spaces();
- return ret;
- }
-
- bool operator==(const DependencyConstraint& lhs, const DependencyConstraint& rhs)
- {
- if (lhs.type != rhs.type) return false;
- if (lhs.value != rhs.value) return false;
- return lhs.port_version == rhs.port_version;
- }
- bool operator!=(const DependencyConstraint& lhs, const DependencyConstraint& rhs);
-
- bool operator==(const Dependency& lhs, const Dependency& rhs)
- {
- if (lhs.name != rhs.name) return false;
- if (lhs.features != rhs.features) return false;
- if (!structurally_equal(lhs.platform, rhs.platform)) return false;
- if (lhs.extra_info != rhs.extra_info) return false;
- if (lhs.constraint != rhs.constraint) return false;
-
- return true;
- }
- bool operator!=(const Dependency& lhs, const Dependency& rhs);
-
- bool operator==(const DependencyOverride& lhs, const DependencyOverride& rhs)
- {
- if (lhs.version_scheme != rhs.version_scheme) return false;
- if (lhs.port_version != rhs.port_version) return false;
- if (lhs.name != rhs.name) return false;
- if (lhs.version != rhs.version) return false;
- return lhs.extra_info == rhs.extra_info;
- }
- bool operator!=(const DependencyOverride& lhs, const DependencyOverride& rhs);
-}
diff --git a/toolsrc/src/vcpkg/paragraphs.cpp b/toolsrc/src/vcpkg/paragraphs.cpp
deleted file mode 100644
index 4b4621968..000000000
--- a/toolsrc/src/vcpkg/paragraphs.cpp
+++ /dev/null
@@ -1,531 +0,0 @@
-#include <vcpkg/base/files.h>
-#include <vcpkg/base/parse.h>
-#include <vcpkg/base/system.debug.h>
-#include <vcpkg/base/system.print.h>
-#include <vcpkg/base/util.h>
-
-#include <vcpkg/binaryparagraph.h>
-#include <vcpkg/configuration.h>
-#include <vcpkg/paragraphparser.h>
-#include <vcpkg/paragraphs.h>
-#include <vcpkg/registries.h>
-#include <vcpkg/vcpkgpaths.h>
-
-using namespace vcpkg::Parse;
-using namespace vcpkg;
-
-namespace vcpkg::Parse
-{
- static Optional<std::pair<std::string, TextRowCol>> remove_field(Paragraph* fields, const std::string& fieldname)
- {
- auto it = fields->find(fieldname);
- if (it == fields->end())
- {
- return nullopt;
- }
-
- auto value = std::move(it->second);
- fields->erase(it);
- return value;
- }
-
- void ParagraphParser::required_field(const std::string& fieldname, std::pair<std::string&, TextRowCol&> out)
- {
- auto maybe_field = remove_field(&fields, fieldname);
- if (const auto field = maybe_field.get())
- out = std::move(*field);
- else
- missing_fields.push_back(fieldname);
- }
- void ParagraphParser::optional_field(const std::string& fieldname, std::pair<std::string&, TextRowCol&> out)
- {
- auto maybe_field = remove_field(&fields, fieldname);
- if (auto field = maybe_field.get()) out = std::move(*field);
- }
- void ParagraphParser::required_field(const std::string& fieldname, std::string& out)
- {
- TextRowCol ignore;
- required_field(fieldname, {out, ignore});
- }
- std::string ParagraphParser::optional_field(const std::string& fieldname)
- {
- std::string out;
- TextRowCol ignore;
- optional_field(fieldname, {out, ignore});
- return out;
- }
- std::string ParagraphParser::required_field(const std::string& fieldname)
- {
- std::string out;
- TextRowCol ignore;
- required_field(fieldname, {out, ignore});
- return out;
- }
-
- std::unique_ptr<ParseControlErrorInfo> ParagraphParser::error_info(const std::string& name) const
- {
- if (!fields.empty() || !missing_fields.empty())
- {
- auto err = std::make_unique<ParseControlErrorInfo>();
- err->name = name;
- err->extra_fields["CONTROL"] = Util::extract_keys(fields);
- err->missing_fields["CONTROL"] = std::move(missing_fields);
- err->expected_types = std::move(expected_types);
- return err;
- }
- return nullptr;
- }
-
- template<class T, class F>
- static Optional<std::vector<T>> parse_list_until_eof(StringLiteral plural_item_name, Parse::ParserBase& parser, F f)
- {
- std::vector<T> ret;
- parser.skip_whitespace();
- if (parser.at_eof()) return std::vector<T>{};
- do
- {
- auto item = f(parser);
- if (!item) return nullopt;
- ret.push_back(std::move(item).value_or_exit(VCPKG_LINE_INFO));
- parser.skip_whitespace();
- if (parser.at_eof()) return {std::move(ret)};
- if (parser.cur() != ',')
- {
- parser.add_error(Strings::concat("expected ',' or end of text in ", plural_item_name, " list"));
- return nullopt;
- }
- parser.next();
- parser.skip_whitespace();
- } while (true);
- }
-
- ExpectedS<std::vector<std::string>> parse_default_features_list(const std::string& str,
- StringView origin,
- TextRowCol textrowcol)
- {
- auto parser = Parse::ParserBase(str, origin, textrowcol);
- auto opt = parse_list_until_eof<std::string>("default features", parser, &parse_feature_name);
- if (!opt) return {parser.get_error()->format(), expected_right_tag};
- return {std::move(opt).value_or_exit(VCPKG_LINE_INFO), expected_left_tag};
- }
- ExpectedS<std::vector<ParsedQualifiedSpecifier>> parse_qualified_specifier_list(const std::string& str,
- StringView origin,
- TextRowCol textrowcol)
- {
- auto parser = Parse::ParserBase(str, origin, textrowcol);
- auto opt = parse_list_until_eof<ParsedQualifiedSpecifier>(
- "dependencies", parser, [](ParserBase& parser) { return parse_qualified_specifier(parser); });
- if (!opt) return {parser.get_error()->format(), expected_right_tag};
-
- return {std::move(opt).value_or_exit(VCPKG_LINE_INFO), expected_left_tag};
- }
- ExpectedS<std::vector<Dependency>> parse_dependencies_list(const std::string& str,
- StringView origin,
- TextRowCol textrowcol)
- {
- auto parser = Parse::ParserBase(str, origin, textrowcol);
- auto opt = parse_list_until_eof<Dependency>("dependencies", parser, [](ParserBase& parser) {
- auto loc = parser.cur_loc();
- return parse_qualified_specifier(parser).then([&](ParsedQualifiedSpecifier&& pqs) -> Optional<Dependency> {
- if (pqs.triplet)
- {
- parser.add_error("triplet specifier not allowed in this context", loc);
- return nullopt;
- }
- return Dependency{pqs.name, pqs.features.value_or({}), pqs.platform.value_or({})};
- });
- });
- if (!opt) return {parser.get_error()->format(), expected_right_tag};
-
- return {std::move(opt).value_or_exit(VCPKG_LINE_INFO), expected_left_tag};
- }
-}
-
-namespace vcpkg::Paragraphs
-{
- struct PghParser : private Parse::ParserBase
- {
- private:
- void get_fieldvalue(std::string& fieldvalue)
- {
- fieldvalue.clear();
-
- do
- {
- // scan to end of current line (it is part of the field value)
- Strings::append(fieldvalue, match_until(is_lineend));
- skip_newline();
-
- if (cur() != ' ') return;
- auto spacing = skip_tabs_spaces();
- if (is_lineend(cur())) return add_error("unexpected end of line, to span a blank line use \" .\"");
- Strings::append(fieldvalue, "\n", spacing);
- } while (true);
- }
-
- void get_fieldname(std::string& fieldname)
- {
- fieldname = match_zero_or_more(is_alphanumdash).to_string();
- if (fieldname.empty()) return add_error("expected fieldname");
- }
-
- void get_paragraph(Paragraph& fields)
- {
- fields.clear();
- std::string fieldname;
- std::string fieldvalue;
- do
- {
- if (cur() == '#')
- {
- skip_line();
- continue;
- }
-
- auto loc = cur_loc();
- get_fieldname(fieldname);
- if (cur() != ':') return add_error("expected ':' after field name");
- if (Util::Sets::contains(fields, fieldname)) return add_error("duplicate field", loc);
- next();
- skip_tabs_spaces();
- auto rowcol = cur_rowcol();
- get_fieldvalue(fieldvalue);
-
- fields.emplace(fieldname, std::make_pair(fieldvalue, rowcol));
- } while (!is_lineend(cur()));
- }
-
- public:
- PghParser(StringView text, StringView origin) : Parse::ParserBase(text, origin) { }
-
- ExpectedS<std::vector<Paragraph>> get_paragraphs()
- {
- std::vector<Paragraph> paragraphs;
-
- skip_whitespace();
- while (!at_eof())
- {
- paragraphs.emplace_back();
- get_paragraph(paragraphs.back());
- match_zero_or_more(is_lineend);
- }
- if (get_error()) return get_error()->format();
-
- return paragraphs;
- }
- };
-
- ExpectedS<Paragraph> parse_single_paragraph(const std::string& str, const std::string& origin)
- {
- auto pghs = PghParser(str, origin).get_paragraphs();
-
- if (auto p = pghs.get())
- {
- if (p->size() != 1) return {"There should be exactly one paragraph", expected_right_tag};
- return std::move(p->front());
- }
- else
- {
- return pghs.error();
- }
- }
-
- ExpectedS<Paragraph> get_single_paragraph(const Files::Filesystem& fs, const fs::path& control_path)
- {
- const Expected<std::string> contents = fs.read_contents(control_path);
- if (auto spgh = contents.get())
- {
- return parse_single_paragraph(*spgh, fs::u8string(control_path));
- }
-
- return contents.error().message();
- }
-
- ExpectedS<std::vector<Paragraph>> get_paragraphs_text(const std::string& text, const std::string& origin)
- {
- return parse_paragraphs(text, origin);
- }
-
- ExpectedS<std::vector<Paragraph>> get_paragraphs(const Files::Filesystem& fs, const fs::path& control_path)
- {
- const Expected<std::string> contents = fs.read_contents(control_path);
- if (auto spgh = contents.get())
- {
- return parse_paragraphs(*spgh, fs::u8string(control_path));
- }
-
- return contents.error().message();
- }
-
- ExpectedS<std::vector<Paragraph>> parse_paragraphs(const std::string& str, const std::string& origin)
- {
- return PghParser(str, origin).get_paragraphs();
- }
-
- bool is_port_directory(const Files::Filesystem& fs, const fs::path& path)
- {
- return fs.exists(path / fs::u8path("CONTROL")) || fs.exists(path / fs::u8path("vcpkg.json"));
- }
-
- static ParseExpected<SourceControlFile> try_load_manifest_object(
- const std::string& origin,
- const ExpectedT<std::pair<vcpkg::Json::Value, vcpkg::Json::JsonStyle>, std::unique_ptr<Parse::IParseError>>&
- res)
- {
- auto error_info = std::make_unique<ParseControlErrorInfo>();
- if (auto val = res.get())
- {
- if (val->first.is_object())
- {
- return SourceControlFile::parse_manifest_object(origin, val->first.object());
- }
- else
- {
- error_info->name = origin;
- error_info->error = "Manifest files must have a top-level object";
- return error_info;
- }
- }
- else
- {
- error_info->name = origin;
- error_info->error = res.error()->format();
- return error_info;
- }
- }
-
- static ParseExpected<SourceControlFile> try_load_manifest_text(const std::string& text, const std::string& origin)
- {
- auto res = Json::parse(text);
- return try_load_manifest_object(origin, res);
- }
-
- static ParseExpected<SourceControlFile> try_load_manifest(const Files::Filesystem& fs,
- const std::string& port_name,
- const fs::path& path_to_manifest,
- std::error_code& ec)
- {
- (void)port_name;
-
- auto error_info = std::make_unique<ParseControlErrorInfo>();
- auto res = Json::parse_file(fs, path_to_manifest, ec);
- if (ec) return error_info;
-
- return try_load_manifest_object(fs::u8string(path_to_manifest), res);
- }
-
- ParseExpected<SourceControlFile> try_load_port_text(const std::string& text,
- const std::string& origin,
- bool is_manifest)
- {
- if (is_manifest)
- {
- return try_load_manifest_text(text, origin);
- }
-
- ExpectedS<std::vector<Paragraph>> pghs = get_paragraphs_text(text, origin);
- if (auto vector_pghs = pghs.get())
- {
- return SourceControlFile::parse_control_file(origin, std::move(*vector_pghs));
- }
- auto error_info = std::make_unique<ParseControlErrorInfo>();
- error_info->name = fs::u8string(origin);
- error_info->error = pghs.error();
- return error_info;
- }
-
- ParseExpected<SourceControlFile> try_load_port(const Files::Filesystem& fs, const fs::path& path)
- {
- const auto path_to_manifest = path / fs::u8path("vcpkg.json");
- const auto path_to_control = path / fs::u8path("CONTROL");
- if (fs.exists(path_to_manifest))
- {
- vcpkg::Checks::check_exit(VCPKG_LINE_INFO,
- !fs.exists(path_to_control),
- "Found both manifest and CONTROL file in port %s; please rename one or the other",
- fs::u8string(path));
-
- std::error_code ec;
- auto res = try_load_manifest(fs, fs::u8string(path.filename()), path_to_manifest, ec);
- if (ec)
- {
- auto error_info = std::make_unique<ParseControlErrorInfo>();
- error_info->name = fs::u8string(path.filename());
- error_info->error = Strings::format(
- "Failed to load manifest file for port: %s\n", fs::u8string(path_to_manifest), ec.message());
- return error_info;
- }
-
- return res;
- }
-
- if (fs.exists(path_to_control))
- {
- ExpectedS<std::vector<Paragraph>> pghs = get_paragraphs(fs, path_to_control);
- if (auto vector_pghs = pghs.get())
- {
- return SourceControlFile::parse_control_file(fs::u8string(path_to_control), std::move(*vector_pghs));
- }
- auto error_info = std::make_unique<ParseControlErrorInfo>();
- error_info->name = fs::u8string(path.filename());
- error_info->error = pghs.error();
- return error_info;
- }
-
- auto error_info = std::make_unique<ParseControlErrorInfo>();
- error_info->name = fs::u8string(path.filename());
- if (fs.exists(path))
- {
- error_info->error = "Failed to find either a CONTROL file or vcpkg.json file.";
- }
- else
- {
- error_info->error = "The port directory (" + fs::u8string(path) + ") does not exist";
- }
- return error_info;
- }
-
- ExpectedS<BinaryControlFile> try_load_cached_package(const VcpkgPaths& paths, const PackageSpec& spec)
- {
- ExpectedS<std::vector<Paragraph>> pghs =
- get_paragraphs(paths.get_filesystem(), paths.package_dir(spec) / "CONTROL");
-
- if (auto p = pghs.get())
- {
- BinaryControlFile bcf;
- bcf.core_paragraph = BinaryParagraph(p->front());
- p->erase(p->begin());
-
- bcf.features =
- Util::fmap(*p, [&](auto&& raw_feature) -> BinaryParagraph { return BinaryParagraph(raw_feature); });
-
- if (bcf.core_paragraph.spec != spec)
- {
- return Strings::concat("Mismatched spec in package at ",
- fs::u8string(paths.package_dir(spec)),
- ": expected ",
- spec,
- ", actual ",
- bcf.core_paragraph.spec);
- }
-
- return bcf;
- }
-
- return pghs.error();
- }
-
- LoadResults try_load_all_registry_ports(const VcpkgPaths& paths)
- {
- LoadResults ret;
- const auto& fs = paths.get_filesystem();
-
- std::vector<std::string> ports;
-
- const auto& registries = paths.get_configuration().registry_set;
-
- for (const auto& registry : registries.registries())
- {
- registry.implementation().get_all_port_names(ports, paths);
- }
- if (auto registry = registries.default_registry())
- {
- registry->get_all_port_names(ports, paths);
- }
-
- Util::sort_unique_erase(ports);
-
- for (const auto& port_name : ports)
- {
- auto impl = registries.registry_for_port(port_name);
- if (!impl)
- {
- // this is a port for which no registry is set
- // this can happen when there's no default registry,
- // and a registry has a port definition which it doesn't own the name of.
- continue;
- }
-
- auto port_entry = impl->get_port_entry(paths, port_name);
- auto baseline_version = impl->get_baseline_version(paths, port_name);
- if (port_entry && baseline_version)
- {
- auto port_path =
- port_entry->get_path_to_version(paths, *baseline_version.get()).value_or_exit(VCPKG_LINE_INFO);
- auto maybe_spgh = try_load_port(fs, port_path);
- if (const auto spgh = maybe_spgh.get())
- {
- ret.paragraphs.emplace_back(std::move(*spgh), std::move(port_path));
- }
- else
- {
- ret.errors.emplace_back(std::move(maybe_spgh).error());
- }
- }
- else
- {
- // the registry that owns the name of this port does not actually contain the port
- // this can happen if R1 contains the port definition for <abc>, but doesn't
- // declare it owns <abc>.
- continue;
- }
- }
-
- return ret;
- }
-
- static void load_results_print_error(const LoadResults& results)
- {
- if (!results.errors.empty())
- {
- if (Debug::g_debugging)
- {
- print_error_message(results.errors);
- }
- else
- {
- for (auto&& error : results.errors)
- {
- System::print2(
- System::Color::warning, "Warning: an error occurred while parsing '", error->name, "'\n");
- }
- System::print2(System::Color::warning,
- "Use '--debug' to get more information about the parse failures.\n\n");
- }
- }
- }
-
- std::vector<SourceControlFileLocation> load_all_registry_ports(const VcpkgPaths& paths)
- {
- auto results = try_load_all_registry_ports(paths);
- load_results_print_error(results);
- return std::move(results.paragraphs);
- }
-
- std::vector<SourceControlFileLocation> load_overlay_ports(const Files::Filesystem& fs, const fs::path& directory)
- {
- LoadResults ret;
-
- auto port_dirs = fs.get_files_non_recursive(directory);
- Util::sort(port_dirs);
-
- Util::erase_remove_if(port_dirs,
- [&](auto&& port_dir_entry) { return port_dir_entry.filename() == ".DS_Store"; });
-
- for (auto&& path : port_dirs)
- {
- auto maybe_spgh = try_load_port(fs, path);
- if (const auto spgh = maybe_spgh.get())
- {
- ret.paragraphs.emplace_back(std::move(*spgh), std::move(path));
- }
- else
- {
- ret.errors.emplace_back(std::move(maybe_spgh).error());
- }
- }
-
- load_results_print_error(ret);
- return std::move(ret.paragraphs);
- }
-}
diff --git a/toolsrc/src/vcpkg/platform-expression.cpp b/toolsrc/src/vcpkg/platform-expression.cpp
deleted file mode 100644
index a6177c85f..000000000
--- a/toolsrc/src/vcpkg/platform-expression.cpp
+++ /dev/null
@@ -1,577 +0,0 @@
-#include <vcpkg/base/parse.h>
-#include <vcpkg/base/strings.h>
-#include <vcpkg/base/system.print.h>
-#include <vcpkg/base/util.h>
-
-#include <vcpkg/platform-expression.h>
-
-#include <numeric>
-#include <string>
-#include <vector>
-
-namespace vcpkg::PlatformExpression
-{
- using vcpkg::Parse::ParseError;
-
- enum class Identifier
- {
- invalid = -1, // not a recognized identifier
- x86,
- x64,
- arm,
- arm64,
- wasm32,
-
- windows,
- mingw,
- linux,
- osx,
- uwp,
- android,
- emscripten,
- ios,
-
- static_link,
- static_crt,
- };
-
- static Identifier string2identifier(StringView name)
- {
- static const std::map<StringView, Identifier> id_map = {
- {"x86", Identifier::x86},
- {"x64", Identifier::x64},
- {"arm", Identifier::arm},
- {"arm64", Identifier::arm64},
- {"wasm32", Identifier::wasm32},
- {"windows", Identifier::windows},
- {"mingw", Identifier::mingw},
- {"linux", Identifier::linux},
- {"osx", Identifier::osx},
- {"uwp", Identifier::uwp},
- {"android", Identifier::android},
- {"emscripten", Identifier::emscripten},
- {"ios", Identifier::ios},
- {"static", Identifier::static_link},
- {"staticcrt", Identifier::static_link},
- };
-
- auto id_pair = id_map.find(name);
-
- if (id_pair == id_map.end())
- {
- return Identifier::invalid;
- }
-
- return id_pair->second;
- }
-
- namespace detail
- {
- enum class ExprKind
- {
- identifier,
- op_not,
- op_and,
- op_or
- };
-
- struct ExprImpl
- {
- ExprImpl(ExprKind k, std::string i, std::vector<std::unique_ptr<ExprImpl>> es)
- : kind(k), identifier(std::move(i)), exprs(std::move(es))
- {
- }
-
- ExprImpl(ExprKind k, std::string i) : kind(k), identifier(std::move(i)) { }
- ExprImpl(ExprKind k, std::unique_ptr<ExprImpl> a) : kind(k) { exprs.push_back(std::move(a)); }
- ExprImpl(ExprKind k, std::vector<std::unique_ptr<ExprImpl>> es) : kind(k), exprs(std::move(es)) { }
-
- ExprKind kind;
- std::string identifier;
- std::vector<std::unique_ptr<ExprImpl>> exprs;
-
- std::unique_ptr<ExprImpl> clone() const
- {
- return std::make_unique<ExprImpl>(
- ExprImpl{kind, identifier, Util::fmap(exprs, [](auto&& p) { return p->clone(); })});
- }
- };
-
- class ExpressionParser : public Parse::ParserBase
- {
- public:
- ExpressionParser(StringView str, MultipleBinaryOperators multiple_binary_operators)
- : Parse::ParserBase(str, "CONTROL"), multiple_binary_operators(multiple_binary_operators)
- {
- }
-
- MultipleBinaryOperators multiple_binary_operators;
-
- bool allow_multiple_binary_operators() const
- {
- return multiple_binary_operators == MultipleBinaryOperators::Allow;
- }
-
- // top-level-platform-expression = optional-whitespace, platform-expression
- PlatformExpression::Expr parse()
- {
- skip_whitespace();
- auto res = expr();
-
- if (!at_eof())
- {
- add_error("invalid logic expression, unexpected character");
- }
-
- return Expr(std::move(res));
- }
-
- private:
- // identifier-character =
- // | lowercase-alpha
- // | digit ;
- static bool is_identifier_char(char32_t ch) { return is_lower_alpha(ch) || is_ascii_digit(ch); }
-
- // platform-expression =
- // | platform-expression-not
- // | platform-expression-and
- // | platform-expression-or ;
- std::unique_ptr<ExprImpl> expr()
- {
- // this is the common prefix of all the variants
- // platform-expression-not,
- auto result = expr_not();
-
- switch (cur())
- {
- case '|':
- {
- // { "|", optional-whitespace, platform-expression-not }
- return expr_binary<'|', '&'>(std::make_unique<ExprImpl>(ExprKind::op_or, std::move(result)));
- }
- case '&':
- {
- // { "&", optional-whitespace, platform-expression-not }
- return expr_binary<'&', '|'>(std::make_unique<ExprImpl>(ExprKind::op_and, std::move(result)));
- }
- default: return result;
- }
- }
-
- // platform-expression-simple =
- // | platform-expression-identifier
- // | "(", optional-whitespace, platform-expression, ")", optional-whitespace ;
- std::unique_ptr<ExprImpl> expr_simple()
- {
- if (cur() == '(')
- {
- // "(",
- next();
- // optional-whitespace,
- skip_whitespace();
- // platform-expression,
- auto result = expr();
- if (cur() != ')')
- {
- add_error("missing closing )");
- return result;
- }
- // ")",
- next();
- // optional-whitespace
- skip_whitespace();
- return result;
- }
-
- // platform-expression-identifier
- return expr_identifier();
- }
-
- // platform-expression-identifier =
- // | identifier-character, { identifier-character }, optional-whitespace ;
- std::unique_ptr<ExprImpl> expr_identifier()
- {
- // identifier-character, { identifier-character },
- std::string name = match_zero_or_more(is_identifier_char).to_string();
-
- if (name.empty())
- {
- add_error("unexpected character in logic expression");
- }
-
- // optional-whitespace
- skip_whitespace();
-
- return std::make_unique<ExprImpl>(ExprKind::identifier, std::move(name));
- }
-
- // platform-expression-not =
- // | platform-expression-simple
- // | "!", optional-whitespace, platform-expression-simple ;
- std::unique_ptr<ExprImpl> expr_not()
- {
- if (cur() == '!')
- {
- // "!",
- next();
- // optional-whitespace,
- skip_whitespace();
- // platform-expression-simple
- return std::make_unique<ExprImpl>(ExprKind::op_not, expr_simple());
- }
-
- // platform-expression-simple
- return expr_simple();
- }
-
- // platform-expression-and =
- // | platform-expression-not, { "&", optional-whitespace, platform-expression-not } ;
- //
- // platform-expression-or =
- // | platform-expression-not, { "|", optional-whitespace, platform-expression-not } ;
- //
- // already taken care of by the caller: platform-expression-not
- // so we start at either "&" or "|"
- template<char oper, char other>
- std::unique_ptr<ExprImpl> expr_binary(std::unique_ptr<ExprImpl>&& seed)
- {
- do
- {
- // Support chains of the operator to avoid breaking backwards compatibility
- do
- {
- // "&" or "|",
- next();
- } while (allow_multiple_binary_operators() && cur() == oper);
-
- // optional-whitespace,
- skip_whitespace();
- // platform-expression-not, (go back to start of repetition)
- seed->exprs.push_back(expr_not());
- } while (cur() == oper);
-
- if (cur() == other)
- {
- add_error("mixing & and | is not allowed; use () to specify order of operations");
- }
-
- return std::move(seed);
- }
- };
- }
-
- using namespace detail;
-
- Expr::Expr() = default;
- Expr::Expr(Expr&& other) = default;
- Expr& Expr::operator=(Expr&& other) = default;
-
- Expr::Expr(const Expr& other)
- {
- if (other.underlying_)
- {
- this->underlying_ = other.underlying_->clone();
- }
- }
- Expr& Expr::operator=(const Expr& other)
- {
- if (other.underlying_)
- {
- this->underlying_ = other.underlying_->clone();
- }
- else
- {
- this->underlying_.reset();
- }
-
- return *this;
- }
-
- Expr::Expr(std::unique_ptr<ExprImpl>&& e) : underlying_(std::move(e)) { }
- Expr::~Expr() = default;
-
- Expr Expr::Identifier(StringView id)
- {
- return Expr(std::make_unique<ExprImpl>(ExprKind::identifier, id.to_string()));
- }
- Expr Expr::Not(Expr&& e) { return Expr(std::make_unique<ExprImpl>(ExprKind::op_not, std::move(e.underlying_))); }
- Expr Expr::And(std::vector<Expr>&& exprs)
- {
- return Expr(std::make_unique<ExprImpl>(
- ExprKind::op_and, Util::fmap(exprs, [](Expr& expr) { return std::move(expr.underlying_); })));
- }
- Expr Expr::Or(std::vector<Expr>&& exprs)
- {
- return Expr(std::make_unique<ExprImpl>(
- ExprKind::op_or, Util::fmap(exprs, [](Expr& expr) { return std::move(expr.underlying_); })));
- }
-
- bool Expr::evaluate(const Context& context) const
- {
- if (!this->underlying_)
- {
- return true; // empty expression is always true
- }
-
- std::map<std::string, bool> override_ctxt;
- {
- auto override_vars = context.find("VCPKG_DEP_INFO_OVERRIDE_VARS");
- if (override_vars != context.end())
- {
- auto cmake_list = Strings::split(override_vars->second, ';');
- for (auto& override_id : cmake_list)
- {
- if (!override_id.empty())
- {
- if (override_id[0] == '!')
- {
- override_ctxt.insert({override_id.substr(1), false});
- }
- else
- {
- override_ctxt.insert({override_id, true});
- }
- }
- }
- }
- }
-
- struct Visitor
- {
- const Context& context;
- const std::map<std::string, bool>& override_ctxt;
-
- bool true_if_exists_and_equal(const std::string& variable_name, const std::string& value) const
- {
- auto iter = context.find(variable_name);
- if (iter == context.end())
- {
- return false;
- }
- return iter->second == value;
- }
-
- bool visit(const ExprImpl& expr) const
- {
- if (expr.kind == ExprKind::identifier)
- {
- if (!override_ctxt.empty())
- {
- auto override_id = override_ctxt.find(expr.identifier);
- if (override_id != override_ctxt.end())
- {
- return override_id->second;
- }
- // Fall through to use the cmake logic if the id does not have an override
- }
-
- auto id = string2identifier(expr.identifier);
- switch (id)
- {
- case Identifier::invalid:
- // Point out in the diagnostic that they should add to the override list because that is
- // what most users should do, however it is also valid to update the built in identifiers to
- // recognize the name.
- System::printf(
- System::Color::error,
- "Error: Unrecognized identifer name %s. Add to override list in triplet file.\n",
- expr.identifier);
- return false;
- case Identifier::x64: return true_if_exists_and_equal("VCPKG_TARGET_ARCHITECTURE", "x64");
- case Identifier::x86: return true_if_exists_and_equal("VCPKG_TARGET_ARCHITECTURE", "x86");
- case Identifier::arm:
- // For backwards compatability arm is also true for arm64.
- // This is because it previously was only checking for a substring.
- return true_if_exists_and_equal("VCPKG_TARGET_ARCHITECTURE", "arm") ||
- true_if_exists_and_equal("VCPKG_TARGET_ARCHITECTURE", "arm64");
- case Identifier::arm64: return true_if_exists_and_equal("VCPKG_TARGET_ARCHITECTURE", "arm64");
- case Identifier::windows:
- return true_if_exists_and_equal("VCPKG_CMAKE_SYSTEM_NAME", "") ||
- true_if_exists_and_equal("VCPKG_CMAKE_SYSTEM_NAME", "WindowsStore");
- case Identifier::mingw: return true_if_exists_and_equal("VCPKG_CMAKE_SYSTEM_NAME", "MinGW");
- case Identifier::linux: return true_if_exists_and_equal("VCPKG_CMAKE_SYSTEM_NAME", "Linux");
- case Identifier::osx: return true_if_exists_and_equal("VCPKG_CMAKE_SYSTEM_NAME", "Darwin");
- case Identifier::uwp:
- return true_if_exists_and_equal("VCPKG_CMAKE_SYSTEM_NAME", "WindowsStore");
- case Identifier::android: return true_if_exists_and_equal("VCPKG_CMAKE_SYSTEM_NAME", "Android");
- case Identifier::emscripten:
- return true_if_exists_and_equal("VCPKG_CMAKE_SYSTEM_NAME", "Emscripten");
- case Identifier::ios: return true_if_exists_and_equal("VCPKG_CMAKE_SYSTEM_NAME", "iOS");
- case Identifier::wasm32: return true_if_exists_and_equal("VCPKG_TARGET_ARCHITECTURE", "wasm32");
- case Identifier::static_link:
- return true_if_exists_and_equal("VCPKG_LIBRARY_LINKAGE", "static");
- case Identifier::static_crt: return true_if_exists_and_equal("VCPKG_CRT_LINKAGE", "static");
- default: Checks::unreachable(VCPKG_LINE_INFO);
- }
- }
- else if (expr.kind == ExprKind::op_not)
- {
- return !visit(*expr.exprs.at(0));
- }
- else if (expr.kind == ExprKind::op_and)
- {
- bool valid = true;
-
- // we want to print errors in all expressions, so we check all of the expressions all the time
- for (const auto& e : expr.exprs)
- {
- valid &= visit(*e);
- }
-
- return valid;
- }
- else if (expr.kind == ExprKind::op_or)
- {
- bool valid = false;
-
- // we want to print errors in all expressions, so we check all of the expressions all the time
- for (const auto& e : expr.exprs)
- {
- valid |= visit(*e);
- }
-
- return valid;
- }
- else
- {
- Checks::unreachable(VCPKG_LINE_INFO);
- }
- }
- };
-
- return Visitor{context, override_ctxt}.visit(*this->underlying_);
- }
-
- int Expr::complexity() const
- {
- if (is_empty()) return 0;
-
- struct Impl
- {
- int operator()(const std::unique_ptr<detail::ExprImpl>& expr) const { return (*this)(*expr); }
- int operator()(const detail::ExprImpl& expr) const
- {
- if (expr.kind == ExprKind::identifier) return 1;
-
- if (expr.kind == ExprKind::op_not) return 1 + (*this)(expr.exprs.at(0));
-
- return 1 + std::accumulate(expr.exprs.begin(), expr.exprs.end(), 0, [](int acc, const auto& el) {
- return acc + Impl{}(el);
- });
- }
- };
-
- return Impl{}(underlying_);
- }
-
- ExpectedS<Expr> parse_platform_expression(StringView expression, MultipleBinaryOperators multiple_binary_operators)
- {
- ExpressionParser parser(expression, multiple_binary_operators);
- auto res = parser.parse();
-
- if (auto p = parser.extract_error())
- {
- return p->format();
- }
- else
- {
- return res;
- }
- }
-
- bool structurally_equal(const Expr& lhs, const Expr& rhs)
- {
- struct Impl
- {
- bool operator()(const std::unique_ptr<detail::ExprImpl>& lhs,
- const std::unique_ptr<detail::ExprImpl>& rhs) const
- {
- return (*this)(*lhs, *rhs);
- }
- bool operator()(const detail::ExprImpl& lhs, const detail::ExprImpl& rhs) const
- {
- if (lhs.kind != rhs.kind) return false;
-
- if (lhs.kind == ExprKind::identifier)
- {
- return lhs.identifier == rhs.identifier;
- }
- else
- {
- const auto& exprs_l = lhs.exprs;
- const auto& exprs_r = rhs.exprs;
- return std::equal(exprs_l.begin(), exprs_l.end(), exprs_r.begin(), exprs_r.end(), *this);
- }
- }
- };
-
- if (lhs.is_empty())
- {
- return rhs.is_empty();
- }
- if (rhs.is_empty())
- {
- return false;
- }
- return Impl{}(lhs.underlying_, rhs.underlying_);
- }
-
- int compare(const Expr& lhs, const Expr& rhs)
- {
- auto lhs_platform_complexity = lhs.complexity();
- auto rhs_platform_complexity = lhs.complexity();
-
- if (lhs_platform_complexity < rhs_platform_complexity) return -1;
- if (rhs_platform_complexity < lhs_platform_complexity) return 1;
-
- auto lhs_platform = to_string(lhs);
- auto rhs_platform = to_string(rhs);
-
- if (lhs_platform.size() < rhs_platform.size()) return -1;
- if (rhs_platform.size() < lhs_platform.size()) return 1;
-
- auto platform_cmp = lhs_platform.compare(rhs_platform);
- if (platform_cmp < 0) return -1;
- if (platform_cmp > 0) return 1;
-
- return 0;
- }
-
- std::string to_string(const Expr& expr)
- {
- struct Impl
- {
- std::string operator()(const std::unique_ptr<detail::ExprImpl>& expr) const
- {
- return (*this)(*expr, false);
- }
- std::string operator()(const detail::ExprImpl& expr, bool outer) const
- {
- const char* join = nullptr;
- switch (expr.kind)
- {
- case ExprKind::identifier: return expr.identifier;
- case ExprKind::op_and: join = " & "; break;
- case ExprKind::op_or: join = " | "; break;
- case ExprKind::op_not: return Strings::format("!%s", (*this)(expr.exprs.at(0)));
- default: Checks::unreachable(VCPKG_LINE_INFO);
- }
-
- if (outer)
- {
- return Strings::join(join, expr.exprs, *this);
- }
- else
- {
- return Strings::format("(%s)", Strings::join(join, expr.exprs, *this));
- }
- }
- };
-
- if (expr.is_empty())
- {
- return std::string{};
- }
- return Impl{}(*expr.underlying_, true);
- }
-}
diff --git a/toolsrc/src/vcpkg/portfileprovider.cpp b/toolsrc/src/vcpkg/portfileprovider.cpp
deleted file mode 100644
index 47aa2976c..000000000
--- a/toolsrc/src/vcpkg/portfileprovider.cpp
+++ /dev/null
@@ -1,390 +0,0 @@
-#include <vcpkg/base/json.h>
-#include <vcpkg/base/system.debug.h>
-
-#include <vcpkg/configuration.h>
-#include <vcpkg/paragraphs.h>
-#include <vcpkg/portfileprovider.h>
-#include <vcpkg/registries.h>
-#include <vcpkg/sourceparagraph.h>
-#include <vcpkg/vcpkgcmdarguments.h>
-#include <vcpkg/vcpkgpaths.h>
-#include <vcpkg/versiondeserializers.h>
-
-#include <regex>
-
-using namespace vcpkg;
-using namespace Versions;
-
-namespace
-{
- using namespace vcpkg;
-
- struct OverlayRegistryEntry final : RegistryEntry
- {
- OverlayRegistryEntry(fs::path&& p, VersionT&& v) : path(p), version(v) { }
-
- View<VersionT> get_port_versions() const override { return {&version, 1}; }
- ExpectedS<fs::path> get_path_to_version(const VcpkgPaths&, const VersionT& v) const override
- {
- if (v == version)
- {
- return path;
- }
- return Strings::format("Version %s not found; only %s is available.", v.to_string(), version.to_string());
- }
-
- fs::path path;
- VersionT version;
- };
-}
-
-namespace vcpkg::PortFileProvider
-{
- MapPortFileProvider::MapPortFileProvider(const std::unordered_map<std::string, SourceControlFileLocation>& map)
- : ports(map)
- {
- }
-
- ExpectedS<const SourceControlFileLocation&> MapPortFileProvider::get_control_file(const std::string& spec) const
- {
- auto scf = ports.find(spec);
- if (scf == ports.end()) return std::string("does not exist in map");
- return scf->second;
- }
-
- std::vector<const SourceControlFileLocation*> MapPortFileProvider::load_all_control_files() const
- {
- return Util::fmap(ports, [](auto&& kvpair) -> const SourceControlFileLocation* { return &kvpair.second; });
- }
-
- PathsPortFileProvider::PathsPortFileProvider(const VcpkgPaths& paths, const std::vector<std::string>& overlay_ports)
- : m_baseline(make_baseline_provider(paths))
- , m_versioned(make_versioned_portfile_provider(paths))
- , m_overlay(make_overlay_provider(paths, overlay_ports))
- {
- }
-
- ExpectedS<const SourceControlFileLocation&> PathsPortFileProvider::get_control_file(const std::string& spec) const
- {
- auto maybe_scfl = m_overlay->get_control_file(spec);
- if (auto scfl = maybe_scfl.get())
- {
- return *scfl;
- }
- auto maybe_baseline = m_baseline->get_baseline_version(spec);
- if (auto baseline = maybe_baseline.get())
- {
- return m_versioned->get_control_file({spec, *baseline});
- }
- else
- {
- return Strings::concat("Error: unable to get baseline for port ", spec);
- }
- }
-
- std::vector<const SourceControlFileLocation*> PathsPortFileProvider::load_all_control_files() const
- {
- std::map<std::string, const SourceControlFileLocation*> m;
- m_overlay->load_all_control_files(m);
- m_versioned->load_all_control_files(m);
- return Util::fmap(m, [](const auto& p) { return p.second; });
- }
-
- namespace
- {
- struct BaselineProviderImpl : IBaselineProvider, Util::ResourceBase
- {
- BaselineProviderImpl(const VcpkgPaths& paths_) : paths(paths_) { }
-
- virtual Optional<VersionT> get_baseline_version(StringView port_name) const override
- {
- auto it = m_baseline_cache.find(port_name);
- if (it != m_baseline_cache.end())
- {
- return it->second;
- }
- else
- {
- auto version = paths.get_configuration().registry_set.baseline_for_port(paths, port_name);
- m_baseline_cache.emplace(port_name.to_string(), version);
- return version;
- }
- }
-
- private:
- const VcpkgPaths& paths; // TODO: remove this data member
- mutable std::map<std::string, Optional<VersionT>, std::less<>> m_baseline_cache;
- };
-
- struct VersionedPortfileProviderImpl : IVersionedPortfileProvider, Util::ResourceBase
- {
- VersionedPortfileProviderImpl(const VcpkgPaths& paths_) : paths(paths_) { }
-
- const ExpectedS<std::unique_ptr<RegistryEntry>>& entry(StringView name) const
- {
- auto entry_it = m_entry_cache.find(name);
- if (entry_it == m_entry_cache.end())
- {
- if (auto reg = paths.get_configuration().registry_set.registry_for_port(name))
- {
- if (auto entry = reg->get_port_entry(paths, name))
- {
- entry_it = m_entry_cache.emplace(name.to_string(), std::move(entry)).first;
- }
- else
- {
- entry_it =
- m_entry_cache
- .emplace(name.to_string(),
- Strings::concat("Error: Could not find a definition for port ", name))
- .first;
- }
- }
- else
- {
- entry_it = m_entry_cache
- .emplace(name.to_string(),
- Strings::concat("Error: no registry configured for port ", name))
- .first;
- }
- }
- return entry_it->second;
- }
-
- virtual View<VersionT> get_port_versions(StringView port_name) const override
- {
- return entry(port_name).value_or_exit(VCPKG_LINE_INFO)->get_port_versions();
- }
-
- ExpectedS<std::unique_ptr<SourceControlFileLocation>> load_control_file(
- const VersionSpec& version_spec) const
- {
- const auto& maybe_ent = entry(version_spec.port_name);
- if (auto ent = maybe_ent.get())
- {
- auto maybe_path = ent->get()->get_path_to_version(paths, version_spec.version);
- if (auto path = maybe_path.get())
- {
- auto maybe_control_file = Paragraphs::try_load_port(paths.get_filesystem(), *path);
- if (auto scf = maybe_control_file.get())
- {
- if (scf->get()->core_paragraph->name == version_spec.port_name)
- {
- return std::make_unique<SourceControlFileLocation>(std::move(*scf), std::move(*path));
- }
- else
- {
- return Strings::format("Error: Failed to load port from %s: names did "
- "not match: '%s' != '%s'",
- fs::u8string(*path),
- version_spec.port_name,
- scf->get()->core_paragraph->name);
- }
- }
- else
- {
- // This should change to a soft error when ParseExpected is eliminated.
- print_error_message(maybe_control_file.error());
- Checks::exit_maybe_upgrade(VCPKG_LINE_INFO,
- "Error: Failed to load port %s from %s",
- version_spec.port_name,
- fs::u8string(*path));
- }
- }
- else
- {
- return maybe_path.error();
- }
- }
- return maybe_ent.error();
- }
-
- virtual ExpectedS<const SourceControlFileLocation&> get_control_file(
- const VersionSpec& version_spec) const override
- {
- auto it = m_control_cache.find(version_spec);
- if (it == m_control_cache.end())
- {
- it = m_control_cache.emplace(version_spec, load_control_file(version_spec)).first;
- }
- return it->second.map([](const auto& x) -> const SourceControlFileLocation& { return *x.get(); });
- }
-
- virtual void load_all_control_files(
- std::map<std::string, const SourceControlFileLocation*>& out) const override
- {
- auto all_ports = Paragraphs::load_all_registry_ports(paths);
- for (auto&& scfl : all_ports)
- {
- auto port_name = scfl.source_control_file->core_paragraph->name;
- auto version = scfl.source_control_file->core_paragraph->to_versiont();
- auto it = m_control_cache
- .emplace(VersionSpec{std::move(port_name), std::move(version)},
- std::make_unique<SourceControlFileLocation>(std::move(scfl)))
- .first;
- Checks::check_exit(VCPKG_LINE_INFO, it->second.has_value());
- out.emplace(it->first.port_name, it->second.get()->get());
- }
- }
-
- private:
- const VcpkgPaths& paths; // TODO: remove this data member
- mutable std::
- unordered_map<VersionSpec, ExpectedS<std::unique_ptr<SourceControlFileLocation>>, VersionSpecHasher>
- m_control_cache;
- mutable std::map<std::string, ExpectedS<std::unique_ptr<RegistryEntry>>, std::less<>> m_entry_cache;
- };
-
- struct OverlayProviderImpl : IOverlayProvider, Util::ResourceBase
- {
- OverlayProviderImpl(const VcpkgPaths& paths, View<std::string> overlay_ports)
- : m_fs(paths.get_filesystem())
- , m_overlay_ports(Util::fmap(overlay_ports, [&paths](const std::string& s) -> fs::path {
- return Files::combine(paths.original_cwd, fs::u8path(s));
- }))
- {
- for (auto&& overlay : m_overlay_ports)
- {
- auto s_overlay = fs::u8string(overlay);
- Debug::print("Using overlay: ", s_overlay, "\n");
-
- Checks::check_exit(VCPKG_LINE_INFO,
- fs::is_directory(m_fs.status(VCPKG_LINE_INFO, overlay)),
- "Error: Overlay path \"%s\" must exist and must be a directory",
- s_overlay);
- }
- }
-
- Optional<SourceControlFileLocation> load_port(StringView port_name) const
- {
- auto s_port_name = port_name.to_string();
-
- for (auto&& ports_dir : m_overlay_ports)
- {
- // Try loading individual port
- if (Paragraphs::is_port_directory(m_fs, ports_dir))
- {
- auto maybe_scf = Paragraphs::try_load_port(m_fs, ports_dir);
- if (auto scfp = maybe_scf.get())
- {
- auto& scf = *scfp;
- if (scf->core_paragraph->name == port_name)
- {
- return SourceControlFileLocation{std::move(scf), fs::path(ports_dir)};
- }
- }
- else
- {
- print_error_message(maybe_scf.error());
- Checks::exit_maybe_upgrade(VCPKG_LINE_INFO,
- "Error: Failed to load port %s from %s",
- port_name,
- fs::u8string(ports_dir));
- }
-
- continue;
- }
-
- auto ports_spec = ports_dir / fs::u8path(port_name);
- if (Paragraphs::is_port_directory(m_fs, ports_spec))
- {
- auto found_scf = Paragraphs::try_load_port(m_fs, ports_spec);
- if (auto scfp = found_scf.get())
- {
- auto& scf = *scfp;
- if (scf->core_paragraph->name == port_name)
- {
- return SourceControlFileLocation{std::move(scf), std::move(ports_spec)};
- }
- Checks::exit_maybe_upgrade(
- VCPKG_LINE_INFO,
- "Error: Failed to load port from %s: names did not match: '%s' != '%s'",
- fs::u8string(ports_spec),
- port_name,
- scf->core_paragraph->name);
- }
- else
- {
- print_error_message(found_scf.error());
- Checks::exit_maybe_upgrade(VCPKG_LINE_INFO,
- "Error: Failed to load port %s from %s",
- port_name,
- fs::u8string(ports_dir));
- }
- }
- }
- return nullopt;
- }
-
- virtual Optional<const SourceControlFileLocation&> get_control_file(StringView port_name) const override
- {
- auto it = m_overlay_cache.find(port_name);
- if (it == m_overlay_cache.end())
- {
- it = m_overlay_cache.emplace(port_name.to_string(), load_port(port_name)).first;
- }
- return it->second;
- }
-
- virtual void load_all_control_files(
- std::map<std::string, const SourceControlFileLocation*>& out) const override
- {
- for (auto&& ports_dir : m_overlay_ports)
- {
- // Try loading individual port
- if (Paragraphs::is_port_directory(m_fs, ports_dir))
- {
- auto maybe_scf = Paragraphs::try_load_port(m_fs, ports_dir);
- if (auto scfp = maybe_scf.get())
- {
- SourceControlFileLocation scfl{std::move(*scfp), fs::path(ports_dir)};
- auto name = scfl.source_control_file->core_paragraph->name;
- auto it = m_overlay_cache.emplace(std::move(name), std::move(scfl)).first;
- Checks::check_exit(VCPKG_LINE_INFO, it->second.get());
- out.emplace(it->first, it->second.get());
- }
- else
- {
- print_error_message(maybe_scf.error());
- Checks::exit_maybe_upgrade(
- VCPKG_LINE_INFO, "Error: Failed to load port from %s", fs::u8string(ports_dir));
- }
-
- continue;
- }
-
- // Try loading all ports inside ports_dir
- auto found_scfls = Paragraphs::load_overlay_ports(m_fs, ports_dir);
- for (auto&& scfl : found_scfls)
- {
- auto name = scfl.source_control_file->core_paragraph->name;
- auto it = m_overlay_cache.emplace(std::move(name), std::move(scfl)).first;
- Checks::check_exit(VCPKG_LINE_INFO, it->second.get());
- out.emplace(it->first, it->second.get());
- }
- }
- }
-
- private:
- const Files::Filesystem& m_fs;
- const std::vector<fs::path> m_overlay_ports;
- mutable std::map<std::string, Optional<SourceControlFileLocation>, std::less<>> m_overlay_cache;
- };
- }
-
- std::unique_ptr<IBaselineProvider> make_baseline_provider(const vcpkg::VcpkgPaths& paths)
- {
- return std::make_unique<BaselineProviderImpl>(paths);
- }
-
- std::unique_ptr<IVersionedPortfileProvider> make_versioned_portfile_provider(const vcpkg::VcpkgPaths& paths)
- {
- return std::make_unique<VersionedPortfileProviderImpl>(paths);
- }
-
- std::unique_ptr<IOverlayProvider> make_overlay_provider(const vcpkg::VcpkgPaths& paths,
- View<std::string> overlay_ports)
- {
- return std::make_unique<OverlayProviderImpl>(paths, std::move(overlay_ports));
- }
-}
diff --git a/toolsrc/src/vcpkg/postbuildlint.buildtype.cpp b/toolsrc/src/vcpkg/postbuildlint.buildtype.cpp
deleted file mode 100644
index 182625b78..000000000
--- a/toolsrc/src/vcpkg/postbuildlint.buildtype.cpp
+++ /dev/null
@@ -1,71 +0,0 @@
-#include <vcpkg/base/checks.h>
-
-#include <vcpkg/postbuildlint.buildtype.h>
-
-using vcpkg::Build::ConfigurationType;
-
-namespace vcpkg::PostBuildLint
-{
- BuildType BuildType::value_of(const ConfigurationType& config, const Build::LinkageType& linkage)
- {
- if (config == ConfigurationType::DEBUG && linkage == Build::LinkageType::STATIC)
- {
- return BuildTypeC::DEBUG_STATIC;
- }
-
- if (config == ConfigurationType::DEBUG && linkage == Build::LinkageType::DYNAMIC)
- {
- return BuildTypeC::DEBUG_DYNAMIC;
- }
-
- if (config == ConfigurationType::RELEASE && linkage == Build::LinkageType::STATIC)
- {
- return BuildTypeC::RELEASE_STATIC;
- }
-
- if (config == ConfigurationType::RELEASE && linkage == Build::LinkageType::DYNAMIC)
- {
- return BuildTypeC::RELEASE_DYNAMIC;
- }
-
- Checks::unreachable(VCPKG_LINE_INFO);
- }
-
- const ConfigurationType& BuildType::config() const { return this->m_config; }
-
- const Build::LinkageType& BuildType::linkage() const { return this->m_linkage; }
-
- const std::regex& BuildType::crt_regex() const
- {
- static const std::regex REGEX_DEBUG_STATIC(R"(/DEFAULTLIB:LIBCMTD)", std::regex_constants::icase);
- static const std::regex REGEX_DEBUG_DYNAMIC(R"(/DEFAULTLIB:MSVCRTD)", std::regex_constants::icase);
- static const std::regex REGEX_RELEASE_STATIC(R"(/DEFAULTLIB:LIBCMT[^D])", std::regex_constants::icase);
- static const std::regex REGEX_RELEASE_DYNAMIC(R"(/DEFAULTLIB:MSVCRT[^D])", std::regex_constants::icase);
-
- switch (backing_enum)
- {
- case BuildTypeC::DEBUG_STATIC: return REGEX_DEBUG_STATIC;
- case BuildTypeC::DEBUG_DYNAMIC: return REGEX_DEBUG_DYNAMIC;
- case BuildTypeC::RELEASE_STATIC: return REGEX_RELEASE_STATIC;
- case BuildTypeC::RELEASE_DYNAMIC: return REGEX_RELEASE_DYNAMIC;
- default: Checks::unreachable(VCPKG_LINE_INFO);
- }
- }
-
- const std::string& BuildType::to_string() const
- {
- static const std::string NAME_DEBUG_STATIC("Debug,Static");
- static const std::string NAME_DEBUG_DYNAMIC("Debug,Dynamic");
- static const std::string NAME_RELEASE_STATIC("Release,Static");
- static const std::string NAME_RELEASE_DYNAMIC("Release,Dynamic");
-
- switch (backing_enum)
- {
- case BuildTypeC::DEBUG_STATIC: return NAME_DEBUG_STATIC;
- case BuildTypeC::DEBUG_DYNAMIC: return NAME_DEBUG_DYNAMIC;
- case BuildTypeC::RELEASE_STATIC: return NAME_RELEASE_STATIC;
- case BuildTypeC::RELEASE_DYNAMIC: return NAME_RELEASE_DYNAMIC;
- default: Checks::unreachable(VCPKG_LINE_INFO);
- }
- }
-}
diff --git a/toolsrc/src/vcpkg/postbuildlint.cpp b/toolsrc/src/vcpkg/postbuildlint.cpp
deleted file mode 100644
index 29f6a9b32..000000000
--- a/toolsrc/src/vcpkg/postbuildlint.cpp
+++ /dev/null
@@ -1,981 +0,0 @@
-#include <vcpkg/base/cofffilereader.h>
-#include <vcpkg/base/files.h>
-#include <vcpkg/base/system.print.h>
-#include <vcpkg/base/system.process.h>
-#include <vcpkg/base/util.h>
-
-#include <vcpkg/build.h>
-#include <vcpkg/packagespec.h>
-#include <vcpkg/postbuildlint.buildtype.h>
-#include <vcpkg/postbuildlint.h>
-#include <vcpkg/vcpkgpaths.h>
-
-using vcpkg::Build::BuildInfo;
-using vcpkg::Build::BuildPolicy;
-using vcpkg::Build::PreBuildInfo;
-
-namespace vcpkg::PostBuildLint
-{
- static auto not_extension_pred(const Files::Filesystem& fs, const std::string& ext)
- {
- return [&fs, ext](const fs::path& path) { return fs.is_directory(path) || path.extension() != ext; };
- }
-
- enum class LintStatus
- {
- SUCCESS = 0,
- ERROR_DETECTED = 1
- };
-
- struct OutdatedDynamicCrt
- {
- std::string name;
- std::regex regex;
-
- OutdatedDynamicCrt(const std::string& name, const std::string& regex_as_string)
- : name(name), regex(std::regex(regex_as_string, std::regex_constants::icase))
- {
- }
- };
-
- static Span<const OutdatedDynamicCrt> get_outdated_dynamic_crts(const Optional<std::string>& toolset_version)
- {
- static const std::vector<OutdatedDynamicCrt> V_NO_120 = {
- {"msvcp100.dll", R"(msvcp100\.dll)"},
- {"msvcp100d.dll", R"(msvcp100d\.dll)"},
- {"msvcp110.dll", R"(msvcp110\.dll)"},
- {"msvcp110_win.dll", R"(msvcp110_win\.dll)"},
- {"msvcp60.dll", R"(msvcp60\.dll)"},
- {"msvcp60.dll", R"(msvcp60\.dll)"},
-
- {"msvcrt.dll", R"(msvcrt\.dll)"},
- {"msvcr100.dll", R"(msvcr100\.dll)"},
- {"msvcr100d.dll", R"(msvcr100d\.dll)"},
- {"msvcr100_clr0400.dll", R"(msvcr100_clr0400\.dll)"},
- {"msvcr110.dll", R"(msvcr110\.dll)"},
- {"msvcrt20.dll", R"(msvcrt20\.dll)"},
- {"msvcrt40.dll", R"(msvcrt40\.dll)"},
- };
-
- static const std::vector<OutdatedDynamicCrt> V_NO_MSVCRT = [&]() {
- auto ret = V_NO_120;
- ret.push_back({"msvcp120.dll", R"(msvcp120\.dll)"});
- ret.push_back({"msvcp120_clr0400.dll", R"(msvcp120_clr0400\.dll)"});
- ret.push_back({"msvcr120.dll", R"(msvcr120\.dll)"});
- ret.push_back({"msvcr120_clr0400.dll", R"(msvcr120_clr0400\.dll)"});
- return ret;
- }();
-
- const auto tsv = toolset_version.get();
- if (tsv && (*tsv) == "v120")
- {
- return V_NO_120;
- }
-
- // Default case for all version >= VS 2015.
- return V_NO_MSVCRT;
- }
-
- static LintStatus check_for_files_in_include_directory(const Files::Filesystem& fs,
- const Build::BuildPolicies& policies,
- const fs::path& package_dir)
- {
- if (policies.is_enabled(BuildPolicy::EMPTY_INCLUDE_FOLDER))
- {
- return LintStatus::SUCCESS;
- }
-
- const fs::path include_dir = package_dir / "include";
- if (!fs.exists(include_dir) || fs.is_empty(include_dir))
- {
- System::print2(System::Color::warning,
- "The folder /include is empty or not present. This indicates the library was not correctly "
- "installed.\n");
- return LintStatus::ERROR_DETECTED;
- }
-
- return LintStatus::SUCCESS;
- }
-
- static LintStatus check_for_restricted_include_files(const Files::Filesystem& fs,
- const Build::BuildPolicies& policies,
- const fs::path& package_dir)
- {
- if (policies.is_enabled(BuildPolicy::ALLOW_RESTRICTED_HEADERS))
- {
- return LintStatus::SUCCESS;
- }
-
- // These files are taken from the libc6-dev package on Ubuntu inside /usr/include/x86_64-linux-gnu/sys/
- static constexpr StringLiteral restricted_sys_filenames[] = {
- "acct.h", "auxv.h", "bitypes.h", "cdefs.h", "debugreg.h", "dir.h", "elf.h",
- "epoll.h", "errno.h", "eventfd.h", "fanotify.h", "fcntl.h", "file.h", "fsuid.h",
- "gmon.h", "gmon_out.h", "inotify.h", "io.h", "ioctl.h", "ipc.h", "kd.h",
- "klog.h", "mman.h", "mount.h", "msg.h", "mtio.h", "param.h", "pci.h",
- "perm.h", "personality.h", "poll.h", "prctl.h", "procfs.h", "profil.h", "ptrace.h",
- "queue.h", "quota.h", "random.h", "raw.h", "reboot.h", "reg.h", "resource.h",
- "select.h", "sem.h", "sendfile.h", "shm.h", "signal.h", "signalfd.h", "socket.h",
- "socketvar.h", "soundcard.h", "stat.h", "statfs.h", "statvfs.h", "stropts.h", "swap.h",
- "syscall.h", "sysctl.h", "sysinfo.h", "syslog.h", "sysmacros.h", "termios.h", "time.h",
- "timeb.h", "timerfd.h", "times.h", "timex.h", "ttychars.h", "ttydefaults.h", "types.h",
- "ucontext.h", "uio.h", "un.h", "unistd.h", "user.h", "ustat.h", "utsname.h",
- "vfs.h", "vlimit.h", "vm86.h", "vt.h", "vtimes.h", "wait.h", "xattr.h",
- };
- // These files are taken from the libc6-dev package on Ubuntu inside the /usr/include/ folder
- static constexpr StringLiteral restricted_crt_filenames[] = {
- "_G_config.h", "aio.h", "aliases.h", "alloca.h", "ar.h", "argp.h",
- "argz.h", "assert.h", "byteswap.h", "complex.h", "cpio.h", "crypt.h",
- "ctype.h", "dirent.h", "dlfcn.h", "elf.h", "endian.h", "envz.h",
- "err.h", "errno.h", "error.h", "execinfo.h", "fcntl.h", "features.h",
- "fenv.h", "fmtmsg.h", "fnmatch.h", "fstab.h", "fts.h", "ftw.h",
- "gconv.h", "getopt.h", "glob.h", "gnu-versions.h", "grp.h", "gshadow.h",
- "iconv.h", "ifaddrs.h", "inttypes.h", "langinfo.h", "lastlog.h", "libgen.h",
- "libintl.h", "libio.h", "limits.h", "link.h", "locale.h", "malloc.h",
- "math.h", "mcheck.h", "memory.h", "mntent.h", "monetary.h", "mqueue.h",
- "netash", "netdb.h", "nl_types.h", "nss.h", "obstack.h", "paths.h",
- "poll.h", "printf.h", "proc_service.h", "pthread.h", "pty.h", "pwd.h",
- "re_comp.h", "regex.h", "regexp.h", "resolv.h", "sched.h", "search.h",
- "semaphore.h", "setjmp.h", "sgtty.h", "shadow.h", "signal.h", "spawn.h",
- "stab.h", "stdc-predef.h", "stdint.h", "stdio.h", "stdio_ext.h", "stdlib.h",
- "string.h", "strings.h", "stropts.h", "syscall.h", "sysexits.h", "syslog.h",
- "tar.h", "termio.h", "termios.h", "tgmath.h", "thread_db.h", "time.h",
- "ttyent.h", "uchar.h", "ucontext.h", "ulimit.h", "unistd.h", "ustat.h",
- "utime.h", "utmp.h", "utmpx.h", "values.h", "wait.h", "wchar.h",
- "wctype.h", "wordexp.h",
- };
- // These files are general names that have shown to be problematic in the past
- static constexpr StringLiteral restricted_general_filenames[] = {
- "json.h",
- "parser.h",
- "lexer.h",
- "config.h",
- "local.h",
- "slice.h",
- "platform.h",
- };
- static constexpr Span<const StringLiteral> restricted_lists[] = {
- restricted_sys_filenames, restricted_crt_filenames, restricted_general_filenames};
- const fs::path include_dir = package_dir / "include";
- auto files = fs.get_files_non_recursive(include_dir);
- auto filenames_v = Util::fmap(files, [](const auto& file) { return fs::u8string(file.filename()); });
- std::set<std::string> filenames_s(filenames_v.begin(), filenames_v.end());
-
- std::vector<fs::path> violations;
- for (auto&& flist : restricted_lists)
- for (auto&& f : flist)
- {
- if (Util::Sets::contains(filenames_s, f))
- {
- violations.push_back(fs::u8path("include") / fs::u8path(f.c_str()));
- }
- }
-
- if (!violations.empty())
- {
- System::print2(System::Color::warning,
- "Restricted headers paths are present. These files can prevent the core C++ runtime and "
- "other packages from compiling correctly:\n");
- Files::print_paths(violations);
- System::print2("In exceptional circumstances, this policy can be disabled via ",
- Build::to_cmake_variable(BuildPolicy::ALLOW_RESTRICTED_HEADERS),
- "\n");
- return LintStatus::ERROR_DETECTED;
- }
-
- return LintStatus::SUCCESS;
- }
-
- static LintStatus check_for_files_in_debug_include_directory(const Files::Filesystem& fs,
- const fs::path& package_dir)
- {
- const fs::path debug_include_dir = package_dir / "debug" / "include";
-
- std::vector<fs::path> files_found = fs.get_files_recursive(debug_include_dir);
-
- Util::erase_remove_if(
- files_found, [&fs](const fs::path& path) { return fs.is_directory(path) || path.extension() == ".ifc"; });
-
- if (!files_found.empty())
- {
- System::print2(System::Color::warning,
- "Include files should not be duplicated into the /debug/include directory. If this cannot "
- "be disabled in the project cmake, use\n"
- " file(REMOVE_RECURSE \"${CURRENT_PACKAGES_DIR}/debug/include\")\n");
- return LintStatus::ERROR_DETECTED;
- }
-
- return LintStatus::SUCCESS;
- }
-
- static LintStatus check_for_files_in_debug_share_directory(const Files::Filesystem& fs, const fs::path& package_dir)
- {
- const fs::path debug_share = package_dir / "debug" / "share";
-
- if (fs.exists(debug_share))
- {
- System::print2(System::Color::warning,
- "/debug/share should not exist. Please reorganize any important files, then use\n"
- " file(REMOVE_RECURSE \"${CURRENT_PACKAGES_DIR}/debug/share\")\n");
- return LintStatus::ERROR_DETECTED;
- }
-
- return LintStatus::SUCCESS;
- }
-
- static LintStatus check_folder_lib_cmake(const Files::Filesystem& fs,
- const fs::path& package_dir,
- const PackageSpec& spec)
- {
- const fs::path lib_cmake = package_dir / "lib" / "cmake";
- if (fs.exists(lib_cmake))
- {
- System::printf(System::Color::warning,
- "The /lib/cmake folder should be merged with /debug/lib/cmake and moved to "
- "/share/%s/cmake.\nPlease use the helper function `vcpkg_fixup_cmake_targets()`\n",
- spec.name());
- return LintStatus::ERROR_DETECTED;
- }
-
- return LintStatus::SUCCESS;
- }
-
- static LintStatus check_for_misplaced_cmake_files(const Files::Filesystem& fs,
- const fs::path& package_dir,
- const PackageSpec& spec)
- {
- std::vector<fs::path> dirs = {
- package_dir / "cmake",
- package_dir / "debug" / "cmake",
- package_dir / "lib" / "cmake",
- package_dir / "debug" / "lib" / "cmake",
- };
-
- std::vector<fs::path> misplaced_cmake_files;
- for (auto&& dir : dirs)
- {
- auto files = fs.get_files_recursive(dir);
- for (auto&& file : files)
- {
- if (!fs.is_directory(file) && file.extension() == ".cmake")
- misplaced_cmake_files.push_back(std::move(file));
- }
- }
-
- if (!misplaced_cmake_files.empty())
- {
- System::printf(
- System::Color::warning,
- "The following cmake files were found outside /share/%s. Please place cmake files in /share/%s.\n",
- spec.name(),
- spec.name());
- Files::print_paths(misplaced_cmake_files);
- return LintStatus::ERROR_DETECTED;
- }
-
- return LintStatus::SUCCESS;
- }
-
- static LintStatus check_folder_debug_lib_cmake(const Files::Filesystem& fs,
- const fs::path& package_dir,
- const PackageSpec& spec)
- {
- const fs::path lib_cmake_debug = package_dir / "debug" / "lib" / "cmake";
- if (fs.exists(lib_cmake_debug))
- {
- System::printf(System::Color::warning,
- "The /debug/lib/cmake folder should be merged with /lib/cmake into /share/%s\n",
- spec.name());
- return LintStatus::ERROR_DETECTED;
- }
-
- return LintStatus::SUCCESS;
- }
-
- static LintStatus check_for_dlls_in_lib_dir(const Files::Filesystem& fs, const fs::path& package_dir)
- {
- std::vector<fs::path> dlls = fs.get_files_recursive(package_dir / "lib");
- Util::erase_remove_if(dlls, not_extension_pred(fs, ".dll"));
-
- if (!dlls.empty())
- {
- System::print2(System::Color::warning,
- "\nThe following dlls were found in /lib or /debug/lib. Please move them to /bin or "
- "/debug/bin, respectively.\n");
- Files::print_paths(dlls);
- return LintStatus::ERROR_DETECTED;
- }
-
- return LintStatus::SUCCESS;
- }
-
- static LintStatus check_for_copyright_file(const Files::Filesystem& fs,
- const PackageSpec& spec,
- const VcpkgPaths& paths)
- {
- const fs::path packages_dir = paths.packages / spec.dir();
- const fs::path copyright_file = packages_dir / "share" / spec.name() / "copyright";
- if (fs.exists(copyright_file))
- {
- return LintStatus::SUCCESS;
- }
- const fs::path current_buildtrees_dir = paths.build_dir(spec);
- const fs::path current_buildtrees_dir_src = current_buildtrees_dir / "src";
-
- std::vector<fs::path> potential_copyright_files;
- // We only search in the root of each unpacked source archive to reduce false positives
- auto src_dirs = fs.get_files_non_recursive(current_buildtrees_dir_src);
- for (auto&& src_dir : src_dirs)
- {
- if (!fs.is_directory(src_dir)) continue;
-
- for (auto&& src_file : fs.get_files_non_recursive(src_dir))
- {
- const std::string filename = src_file.filename().string();
-
- if (filename == "LICENSE" || filename == "LICENSE.txt" || filename == "COPYING")
- {
- potential_copyright_files.push_back(src_file);
- }
- }
- }
-
- System::printf(System::Color::warning,
- "The software license must be available at ${CURRENT_PACKAGES_DIR}/share/%s/copyright\n",
- spec.name());
- if (potential_copyright_files.size() == 1)
- {
- // if there is only one candidate, provide the cmake lines needed to place it in the proper location
- const fs::path found_file = potential_copyright_files[0];
- auto found_relative_native = found_file.native();
- found_relative_native.erase(current_buildtrees_dir.native().size() +
- 1); // The +1 is needed to remove the "/"
- const fs::path relative_path = found_relative_native;
- System::printf("\n configure_file(\"${CURRENT_BUILDTREES_DIR}/%s/%s\" "
- "\"${CURRENT_PACKAGES_DIR}/share/%s/copyright\" COPYONLY)\n",
- relative_path.generic_string(),
- found_file.filename().generic_string(),
- spec.name());
- }
- else if (potential_copyright_files.size() > 1)
- {
- System::print2(System::Color::warning, "The following files are potential copyright files:\n");
- Files::print_paths(potential_copyright_files);
- }
- return LintStatus::ERROR_DETECTED;
- }
-
- static LintStatus check_for_exes(const Files::Filesystem& fs, const fs::path& package_dir)
- {
- std::vector<fs::path> exes = fs.get_files_recursive(package_dir / "bin");
- Util::erase_remove_if(exes, not_extension_pred(fs, ".exe"));
-
- if (!exes.empty())
- {
- System::print2(
- System::Color::warning,
- "The following EXEs were found in /bin or /debug/bin. EXEs are not valid distribution targets.\n");
- Files::print_paths(exes);
- return LintStatus::ERROR_DETECTED;
- }
-
- return LintStatus::SUCCESS;
- }
-
- static LintStatus check_exports_of_dlls(const Build::BuildPolicies& policies,
- const std::vector<fs::path>& dlls,
- const fs::path& dumpbin_exe)
- {
- if (policies.is_enabled(BuildPolicy::DLLS_WITHOUT_EXPORTS)) return LintStatus::SUCCESS;
-
- std::vector<fs::path> dlls_with_no_exports;
- for (const fs::path& dll : dlls)
- {
- auto cmd_line = System::Command(dumpbin_exe).string_arg("/exports").path_arg(dll);
- System::ExitCodeAndOutput ec_data = System::cmd_execute_and_capture_output(cmd_line);
- Checks::check_exit(
- VCPKG_LINE_INFO, ec_data.exit_code == 0, "Running command:\n %s\n failed", cmd_line.command_line());
-
- if (ec_data.output.find("ordinal hint RVA name") == std::string::npos)
- {
- dlls_with_no_exports.push_back(dll);
- }
- }
-
- if (!dlls_with_no_exports.empty())
- {
- System::print2(System::Color::warning, "The following DLLs have no exports:\n");
- Files::print_paths(dlls_with_no_exports);
- System::print2(System::Color::warning, "DLLs without any exports are likely a bug in the build script.\n");
- System::printf(System::Color::warning,
- "If this is intended, add the following line in the portfile:\n"
- " SET(%s enabled)\n",
- to_cmake_variable(BuildPolicy::DLLS_WITHOUT_EXPORTS));
- return LintStatus::ERROR_DETECTED;
- }
-
- return LintStatus::SUCCESS;
- }
-
- static LintStatus check_uwp_bit_of_dlls(const std::string& expected_system_name,
- const std::vector<fs::path>& dlls,
- const fs::path dumpbin_exe)
- {
- if (expected_system_name != "WindowsStore")
- {
- return LintStatus::SUCCESS;
- }
-
- std::vector<fs::path> dlls_with_improper_uwp_bit;
- for (const fs::path& dll : dlls)
- {
- auto cmd_line = System::Command(dumpbin_exe).string_arg("/headers").path_arg(dll);
- System::ExitCodeAndOutput ec_data = System::cmd_execute_and_capture_output(cmd_line);
- Checks::check_exit(
- VCPKG_LINE_INFO, ec_data.exit_code == 0, "Running command:\n %s\n failed", cmd_line.command_line());
-
- if (ec_data.output.find("App Container") == std::string::npos)
- {
- dlls_with_improper_uwp_bit.push_back(dll);
- }
- }
-
- if (!dlls_with_improper_uwp_bit.empty())
- {
- System::print2(System::Color::warning, "The following DLLs do not have the App Container bit set:\n");
- Files::print_paths(dlls_with_improper_uwp_bit);
- System::print2(System::Color::warning, "This bit is required for Windows Store apps.\n");
- return LintStatus::ERROR_DETECTED;
- }
-
- return LintStatus::SUCCESS;
- }
-
- struct FileAndArch
- {
- fs::path file;
- std::string actual_arch;
- };
-
-#if defined(_WIN32)
- static std::string get_actual_architecture(const MachineType& machine_type)
- {
- switch (machine_type)
- {
- case MachineType::AMD64:
- case MachineType::IA64: return "x64";
- case MachineType::I386: return "x86";
- case MachineType::ARM:
- case MachineType::ARMNT: return "arm";
- case MachineType::ARM64: return "arm64";
- default: return "Machine Type Code = " + std::to_string(static_cast<uint16_t>(machine_type));
- }
- }
-#endif
-
-#if defined(_WIN32)
- static void print_invalid_architecture_files(const std::string& expected_architecture,
- std::vector<FileAndArch> binaries_with_invalid_architecture)
- {
- System::print2(System::Color::warning, "The following files were built for an incorrect architecture:\n\n");
- for (const FileAndArch& b : binaries_with_invalid_architecture)
- {
- System::print2(" ",
- fs::u8string(b.file),
- "\n"
- "Expected ",
- expected_architecture,
- ", but was: ",
- b.actual_arch,
- "\n\n");
- }
- }
-
- static LintStatus check_dll_architecture(const std::string& expected_architecture,
- const std::vector<fs::path>& files)
- {
- std::vector<FileAndArch> binaries_with_invalid_architecture;
-
- for (const fs::path& file : files)
- {
- Checks::check_exit(VCPKG_LINE_INFO,
- file.extension() == ".dll",
- "The file extension was not .dll: %s",
- file.generic_string());
- const CoffFileReader::DllInfo info = CoffFileReader::read_dll(file);
- const std::string actual_architecture = get_actual_architecture(info.machine_type);
-
- if (expected_architecture != actual_architecture)
- {
- binaries_with_invalid_architecture.push_back({file, actual_architecture});
- }
- }
-
- if (!binaries_with_invalid_architecture.empty())
- {
- print_invalid_architecture_files(expected_architecture, binaries_with_invalid_architecture);
- return LintStatus::ERROR_DETECTED;
- }
-
- return LintStatus::SUCCESS;
- }
-#endif
-
- static LintStatus check_lib_architecture(const std::string& expected_architecture,
- const std::vector<fs::path>& files)
- {
-#if defined(_WIN32)
- std::vector<FileAndArch> binaries_with_invalid_architecture;
-
- for (const fs::path& file : files)
- {
- Checks::check_exit(VCPKG_LINE_INFO,
- file.extension() == ".lib",
- "The file extension was not .lib: %s",
- file.generic_string());
- CoffFileReader::LibInfo info = CoffFileReader::read_lib(file);
-
- // This is zero for folly's debug library
- // TODO: Why?
- if (info.machine_types.size() == 0) return LintStatus::SUCCESS;
-
- Checks::check_exit(VCPKG_LINE_INFO,
- info.machine_types.size() == 1,
- "Found more than 1 architecture in file %s",
- file.generic_string());
-
- const std::string actual_architecture = get_actual_architecture(info.machine_types.at(0));
- if (expected_architecture != actual_architecture)
- {
- binaries_with_invalid_architecture.push_back({file, actual_architecture});
- }
- }
-
- if (!binaries_with_invalid_architecture.empty())
- {
- print_invalid_architecture_files(expected_architecture, binaries_with_invalid_architecture);
- return LintStatus::ERROR_DETECTED;
- }
-#endif
- (void)expected_architecture;
- (void)files;
- return LintStatus::SUCCESS;
- }
-
- static LintStatus check_no_dlls_present(const Build::BuildPolicies& policies, const std::vector<fs::path>& dlls)
- {
- if (dlls.empty() || policies.is_enabled(BuildPolicy::DLLS_IN_STATIC_LIBRARY))
- {
- return LintStatus::SUCCESS;
- }
-
- System::print2(System::Color::warning,
- "DLLs should not be present in a static build, but the following DLLs were found:\n");
- Files::print_paths(dlls);
- return LintStatus::ERROR_DETECTED;
- }
-
- static LintStatus check_matching_debug_and_release_binaries(const std::vector<fs::path>& debug_binaries,
- const std::vector<fs::path>& release_binaries)
- {
- const size_t debug_count = debug_binaries.size();
- const size_t release_count = release_binaries.size();
- if (debug_count == release_count)
- {
- return LintStatus::SUCCESS;
- }
-
- System::printf(System::Color::warning,
- "Mismatching number of debug and release binaries. Found %zd for debug but %zd for release.\n",
- debug_count,
- release_count);
- System::print2("Debug binaries\n");
- Files::print_paths(debug_binaries);
-
- System::print2("Release binaries\n");
- Files::print_paths(release_binaries);
-
- if (debug_count == 0)
- {
- System::print2(System::Color::warning, "Debug binaries were not found\n");
- }
- if (release_count == 0)
- {
- System::print2(System::Color::warning, "Release binaries were not found\n");
- }
-
- System::print2("\n");
-
- return LintStatus::ERROR_DETECTED;
- }
-
- static LintStatus check_lib_files_are_available_if_dlls_are_available(const Build::BuildPolicies& policies,
- const size_t lib_count,
- const size_t dll_count,
- const fs::path& lib_dir)
- {
- if (policies.is_enabled(BuildPolicy::DLLS_WITHOUT_LIBS)) return LintStatus::SUCCESS;
-
- if (lib_count == 0 && dll_count != 0)
- {
- System::print2(System::Color::warning, "Import libs were not present in ", fs::u8string(lib_dir), "\n");
- System::printf(System::Color::warning,
- "If this is intended, add the following line in the portfile:\n"
- " SET(%s enabled)\n",
- to_cmake_variable(BuildPolicy::DLLS_WITHOUT_LIBS));
- return LintStatus::ERROR_DETECTED;
- }
-
- return LintStatus::SUCCESS;
- }
-
- static LintStatus check_bin_folders_are_not_present_in_static_build(const Build::BuildPolicies& policies,
- const Files::Filesystem& fs,
- const fs::path& package_dir)
- {
- if (policies.is_enabled(BuildPolicy::DLLS_IN_STATIC_LIBRARY)) return LintStatus::SUCCESS;
-
- const fs::path bin = package_dir / "bin";
- const fs::path debug_bin = package_dir / "debug" / "bin";
-
- if (!fs.exists(bin) && !fs.exists(debug_bin))
- {
- return LintStatus::SUCCESS;
- }
-
- if (fs.exists(bin))
- {
- System::printf(System::Color::warning,
- R"(There should be no bin\ directory in a static build, but %s is present.)"
- "\n",
- fs::u8string(bin));
- }
-
- if (fs.exists(debug_bin))
- {
- System::printf(System::Color::warning,
- R"(There should be no debug\bin\ directory in a static build, but %s is present.)"
- "\n",
- fs::u8string(debug_bin));
- }
-
- System::print2(
- System::Color::warning,
- R"(If the creation of bin\ and/or debug\bin\ cannot be disabled, use this in the portfile to remove them)"
- "\n"
- "\n"
- R"###( if(VCPKG_LIBRARY_LINKAGE STREQUAL "static"))###"
- "\n"
- R"###( file(REMOVE_RECURSE "${CURRENT_PACKAGES_DIR}/bin" "${CURRENT_PACKAGES_DIR}/debug/bin"))###"
- "\n"
- R"###( endif())###"
- "\n\n");
-
- return LintStatus::ERROR_DETECTED;
- }
-
- static LintStatus check_no_empty_folders(const Files::Filesystem& fs, const fs::path& dir)
- {
- std::vector<fs::path> empty_directories = fs.get_files_recursive(dir);
-
- Util::erase_remove_if(empty_directories, [&fs](const fs::path& current) {
- return !fs.is_directory(current) || !fs.is_empty(current);
- });
-
- if (!empty_directories.empty())
- {
- System::print2(System::Color::warning, "There should be no empty directories in ", fs::u8string(dir), "\n");
- System::print2("The following empty directories were found:\n");
- Files::print_paths(empty_directories);
- System::print2(
- System::Color::warning,
- "If a directory should be populated but is not, this might indicate an error in the portfile.\n"
- "If the directories are not needed and their creation cannot be disabled, use something like this in "
- "the portfile to remove them:\n"
- "\n"
- R"###( file(REMOVE_RECURSE "${CURRENT_PACKAGES_DIR}/a/dir" "${CURRENT_PACKAGES_DIR}/some/other/dir"))###"
- "\n"
- "\n"
- "\n");
- return LintStatus::ERROR_DETECTED;
- }
-
- return LintStatus::SUCCESS;
- }
-
- struct BuildTypeAndFile
- {
- fs::path file;
- BuildType build_type;
- };
-
- static LintStatus check_crt_linkage_of_libs(const BuildType& expected_build_type,
- const std::vector<fs::path>& libs,
- const fs::path dumpbin_exe)
- {
- std::vector<BuildType> bad_build_types(BuildTypeC::VALUES.cbegin(), BuildTypeC::VALUES.cend());
- bad_build_types.erase(std::remove(bad_build_types.begin(), bad_build_types.end(), expected_build_type),
- bad_build_types.end());
-
- std::vector<BuildTypeAndFile> libs_with_invalid_crt;
-
- for (const fs::path& lib : libs)
- {
- auto cmd_line = System::Command(dumpbin_exe).string_arg("/directives").path_arg(lib);
- System::ExitCodeAndOutput ec_data = System::cmd_execute_and_capture_output(cmd_line);
- Checks::check_exit(VCPKG_LINE_INFO,
- ec_data.exit_code == 0,
- "Running command:\n %s\n failed with message:\n%s",
- cmd_line.command_line(),
- ec_data.output);
-
- for (const BuildType& bad_build_type : bad_build_types)
- {
- if (std::regex_search(ec_data.output.cbegin(), ec_data.output.cend(), bad_build_type.crt_regex()))
- {
- libs_with_invalid_crt.push_back({lib, bad_build_type});
- break;
- }
- }
- }
-
- if (!libs_with_invalid_crt.empty())
- {
- System::printf(System::Color::warning,
- "Expected %s crt linkage, but the following libs had invalid crt linkage:\n\n",
- expected_build_type.to_string());
- for (const BuildTypeAndFile& btf : libs_with_invalid_crt)
- {
- System::printf(" %s: %s\n", btf.file.generic_string(), btf.build_type.to_string());
- }
- System::print2("\n");
-
- System::print2(System::Color::warning,
- "To inspect the lib files, use:\n dumpbin.exe /directives mylibfile.lib\n");
- return LintStatus::ERROR_DETECTED;
- }
-
- return LintStatus::SUCCESS;
- }
-
- struct OutdatedDynamicCrtAndFile
- {
- fs::path file;
- OutdatedDynamicCrt outdated_crt;
- };
-
- static LintStatus check_outdated_crt_linkage_of_dlls(const std::vector<fs::path>& dlls,
- const fs::path dumpbin_exe,
- const BuildInfo& build_info,
- const PreBuildInfo& pre_build_info)
- {
- if (build_info.policies.is_enabled(BuildPolicy::ALLOW_OBSOLETE_MSVCRT)) return LintStatus::SUCCESS;
-
- std::vector<OutdatedDynamicCrtAndFile> dlls_with_outdated_crt;
-
- for (const fs::path& dll : dlls)
- {
- auto cmd_line = System::Command(dumpbin_exe).string_arg("/dependents").path_arg(dll);
- System::ExitCodeAndOutput ec_data = System::cmd_execute_and_capture_output(cmd_line);
- Checks::check_exit(
- VCPKG_LINE_INFO, ec_data.exit_code == 0, "Running command:\n %s\n failed", cmd_line.command_line());
-
- for (const OutdatedDynamicCrt& outdated_crt : get_outdated_dynamic_crts(pre_build_info.platform_toolset))
- {
- if (std::regex_search(ec_data.output.cbegin(), ec_data.output.cend(), outdated_crt.regex))
- {
- dlls_with_outdated_crt.push_back({dll, outdated_crt});
- break;
- }
- }
- }
-
- if (!dlls_with_outdated_crt.empty())
- {
- System::print2(System::Color::warning, "Detected outdated dynamic CRT in the following files:\n\n");
- for (const OutdatedDynamicCrtAndFile& btf : dlls_with_outdated_crt)
- {
- System::print2(" ", fs::u8string(btf.file), ": ", btf.outdated_crt.name, "\n");
- }
- System::print2("\n");
-
- System::print2(System::Color::warning,
- "To inspect the dll files, use:\n dumpbin.exe /dependents mydllfile.dll\n");
- return LintStatus::ERROR_DETECTED;
- }
-
- return LintStatus::SUCCESS;
- }
-
- static LintStatus check_no_files_in_dir(const Files::Filesystem& fs, const fs::path& dir)
- {
- std::vector<fs::path> misplaced_files = fs.get_files_non_recursive(dir);
- Util::erase_remove_if(misplaced_files, [&fs](const fs::path& path) {
- const std::string filename = path.filename().generic_string();
- if (Strings::case_insensitive_ascii_equals(filename, "CONTROL") ||
- Strings::case_insensitive_ascii_equals(filename, "BUILD_INFO"))
- {
- return true;
- }
-
- return fs.is_directory(path);
- });
-
- if (!misplaced_files.empty())
- {
- System::print2(System::Color::warning, "The following files are placed in\n", fs::u8string(dir), ":\n");
- Files::print_paths(misplaced_files);
- System::print2(System::Color::warning, "Files cannot be present in those directories.\n\n");
- return LintStatus::ERROR_DETECTED;
- }
-
- return LintStatus::SUCCESS;
- }
-
- static void operator+=(size_t& left, const LintStatus& right) { left += static_cast<size_t>(right); }
-
- static size_t perform_all_checks_and_return_error_count(const PackageSpec& spec,
- const VcpkgPaths& paths,
- const PreBuildInfo& pre_build_info,
- const BuildInfo& build_info)
- {
- const auto& fs = paths.get_filesystem();
-
- // for dumpbin
- const Toolset& toolset = paths.get_toolset(pre_build_info);
- const fs::path package_dir = paths.package_dir(spec);
-
- size_t error_count = 0;
-
- if (build_info.policies.is_enabled(BuildPolicy::EMPTY_PACKAGE))
- {
- return error_count;
- }
-
- error_count += check_for_files_in_include_directory(fs, build_info.policies, package_dir);
- error_count += check_for_restricted_include_files(fs, build_info.policies, package_dir);
- error_count += check_for_files_in_debug_include_directory(fs, package_dir);
- error_count += check_for_files_in_debug_share_directory(fs, package_dir);
- error_count += check_folder_lib_cmake(fs, package_dir, spec);
- error_count += check_for_misplaced_cmake_files(fs, package_dir, spec);
- error_count += check_folder_debug_lib_cmake(fs, package_dir, spec);
- error_count += check_for_dlls_in_lib_dir(fs, package_dir);
- error_count += check_for_dlls_in_lib_dir(fs, package_dir / "debug");
- error_count += check_for_copyright_file(fs, spec, paths);
- error_count += check_for_exes(fs, package_dir);
- error_count += check_for_exes(fs, package_dir / "debug");
-
- const fs::path debug_lib_dir = package_dir / "debug" / "lib";
- const fs::path release_lib_dir = package_dir / "lib";
- const fs::path debug_bin_dir = package_dir / "debug" / "bin";
- const fs::path release_bin_dir = package_dir / "bin";
-
- std::vector<fs::path> debug_libs = fs.get_files_recursive(debug_lib_dir);
- Util::erase_remove_if(debug_libs, not_extension_pred(fs, ".lib"));
- std::vector<fs::path> release_libs = fs.get_files_recursive(release_lib_dir);
- Util::erase_remove_if(release_libs, not_extension_pred(fs, ".lib"));
-
- if (!pre_build_info.build_type && !build_info.policies.is_enabled(BuildPolicy::MISMATCHED_NUMBER_OF_BINARIES))
- error_count += check_matching_debug_and_release_binaries(debug_libs, release_libs);
-
- if (!build_info.policies.is_enabled(BuildPolicy::SKIP_ARCHITECTURE_CHECK))
- {
- std::vector<fs::path> libs;
- libs.insert(libs.cend(), debug_libs.cbegin(), debug_libs.cend());
- libs.insert(libs.cend(), release_libs.cbegin(), release_libs.cend());
- error_count += check_lib_architecture(pre_build_info.target_architecture, libs);
- }
-
- std::vector<fs::path> debug_dlls = fs.get_files_recursive(debug_bin_dir);
- Util::erase_remove_if(debug_dlls, not_extension_pred(fs, ".dll"));
- std::vector<fs::path> release_dlls = fs.get_files_recursive(release_bin_dir);
- Util::erase_remove_if(release_dlls, not_extension_pred(fs, ".dll"));
-
- switch (build_info.library_linkage)
- {
- case Build::LinkageType::DYNAMIC:
- {
- if (!pre_build_info.build_type &&
- !build_info.policies.is_enabled(BuildPolicy::MISMATCHED_NUMBER_OF_BINARIES))
- error_count += check_matching_debug_and_release_binaries(debug_dlls, release_dlls);
-
- error_count += check_lib_files_are_available_if_dlls_are_available(
- build_info.policies, debug_libs.size(), debug_dlls.size(), debug_lib_dir);
- error_count += check_lib_files_are_available_if_dlls_are_available(
- build_info.policies, release_libs.size(), release_dlls.size(), release_lib_dir);
-
- std::vector<fs::path> dlls;
- dlls.insert(dlls.cend(), debug_dlls.cbegin(), debug_dlls.cend());
- dlls.insert(dlls.cend(), release_dlls.cbegin(), release_dlls.cend());
-
- if (!toolset.dumpbin.empty() && !build_info.policies.is_enabled(BuildPolicy::SKIP_DUMPBIN_CHECKS))
- {
- error_count += check_exports_of_dlls(build_info.policies, dlls, toolset.dumpbin);
- error_count += check_uwp_bit_of_dlls(pre_build_info.cmake_system_name, dlls, toolset.dumpbin);
- error_count +=
- check_outdated_crt_linkage_of_dlls(dlls, toolset.dumpbin, build_info, pre_build_info);
- }
-
-#if defined(_WIN32)
- error_count += check_dll_architecture(pre_build_info.target_architecture, dlls);
-#endif
- break;
- }
- case Build::LinkageType::STATIC:
- {
- auto dlls = release_dlls;
- dlls.insert(dlls.end(), debug_dlls.begin(), debug_dlls.end());
- error_count += check_no_dlls_present(build_info.policies, dlls);
-
- error_count += check_bin_folders_are_not_present_in_static_build(build_info.policies, fs, package_dir);
-
- if (!toolset.dumpbin.empty() && !build_info.policies.is_enabled(BuildPolicy::SKIP_DUMPBIN_CHECKS))
- {
- if (!build_info.policies.is_enabled(BuildPolicy::ONLY_RELEASE_CRT))
- {
- error_count += check_crt_linkage_of_libs(
- BuildType::value_of(Build::ConfigurationType::DEBUG, build_info.crt_linkage),
- debug_libs,
- toolset.dumpbin);
- }
- error_count += check_crt_linkage_of_libs(
- BuildType::value_of(Build::ConfigurationType::RELEASE, build_info.crt_linkage),
- release_libs,
- toolset.dumpbin);
- }
- break;
- }
- default: Checks::unreachable(VCPKG_LINE_INFO);
- }
-
- error_count += check_no_empty_folders(fs, package_dir);
- error_count += check_no_files_in_dir(fs, package_dir);
- error_count += check_no_files_in_dir(fs, package_dir / "debug");
-
- return error_count;
- }
-
- size_t perform_all_checks(const PackageSpec& spec,
- const VcpkgPaths& paths,
- const PreBuildInfo& pre_build_info,
- const BuildInfo& build_info,
- const fs::path& port_dir)
- {
- System::print2("-- Performing post-build validation\n");
- const size_t error_count = perform_all_checks_and_return_error_count(spec, paths, pre_build_info, build_info);
-
- if (error_count != 0)
- {
- const fs::path portfile = port_dir / "portfile.cmake";
- System::print2(System::Color::error,
- "Found ",
- error_count,
- " error(s). Please correct the portfile:\n ",
- fs::u8string(portfile),
- "\n");
- }
-
- System::print2("-- Performing post-build validation done\n");
-
- return error_count;
- }
-}
diff --git a/toolsrc/src/vcpkg/registries.cpp b/toolsrc/src/vcpkg/registries.cpp
deleted file mode 100644
index 971e8d0c2..000000000
--- a/toolsrc/src/vcpkg/registries.cpp
+++ /dev/null
@@ -1,1204 +0,0 @@
-#include <vcpkg/base/delayed_init.h>
-#include <vcpkg/base/json.h>
-#include <vcpkg/base/jsonreader.h>
-#include <vcpkg/base/system.debug.h>
-
-#include <vcpkg/paragraphs.h>
-#include <vcpkg/registries.h>
-#include <vcpkg/sourceparagraph.h>
-#include <vcpkg/vcpkgcmdarguments.h>
-#include <vcpkg/vcpkgpaths.h>
-#include <vcpkg/versiondeserializers.h>
-#include <vcpkg/versiont.h>
-
-#include <map>
-
-namespace
-{
- using namespace vcpkg;
-
- using Baseline = std::map<std::string, VersionT, std::less<>>;
-
- static const fs::path registry_versions_dir_name = fs::u8path("versions");
-
- // this class is an implementation detail of `BuiltinRegistryEntry`;
- // when `BuiltinRegistryEntry` is using a port versions file for a port,
- // it uses this as it's underlying type;
- // when `BuiltinRegistryEntry` is using a port tree, it uses the scfl
- struct GitRegistryEntry final : RegistryEntry
- {
- View<VersionT> get_port_versions() const override { return port_versions; }
- ExpectedS<fs::path> get_path_to_version(const VcpkgPaths&, const VersionT& version) const override;
-
- std::string port_name;
-
- // these two map port versions to git trees
- // these shall have the same size, and git_trees[i] shall be the git tree for port_versions[i]
- std::vector<VersionT> port_versions;
- std::vector<std::string> git_trees;
- };
-
- struct GitRegistry final : RegistryImplementation
- {
- GitRegistry(std::string&& repo, std::string&& baseline)
- : m_repo(std::move(repo)), m_baseline_identifier(std::move(baseline))
- {
- }
-
- std::unique_ptr<RegistryEntry> get_port_entry(const VcpkgPaths&, StringView) const override;
-
- void get_all_port_names(std::vector<std::string>&, const VcpkgPaths&) const override;
-
- Optional<VersionT> get_baseline_version(const VcpkgPaths&, StringView) const override;
-
- StringView get_commit_of_repo(const VcpkgPaths& paths) const
- {
- return m_commit.get([this, &paths]() -> std::string {
- auto maybe_hash = paths.git_fetch_from_remote_registry(m_repo);
- if (!maybe_hash.has_value())
- {
- Checks::exit_with_message(VCPKG_LINE_INFO,
- "Error: Failed to fetch from remote registry `%s`: %s",
- m_repo,
- maybe_hash.error());
- }
- return std::move(*maybe_hash.get());
- });
- }
-
- fs::path get_versions_tree_path(const VcpkgPaths& paths) const
- {
- return m_versions_tree.get([this, &paths]() -> fs::path {
- auto maybe_tree = paths.git_find_object_id_for_remote_registry_path(get_commit_of_repo(paths),
- registry_versions_dir_name);
- if (!maybe_tree)
- {
- Checks::exit_with_message(
- VCPKG_LINE_INFO,
- "Error: could not find the git tree for `versions` in repo `%s` at commit `%s`: %s",
- m_repo,
- get_commit_of_repo(paths),
- maybe_tree.error());
- }
- auto maybe_path = paths.git_checkout_object_from_remote_registry(*maybe_tree.get());
- if (!maybe_path)
- {
- Checks::exit_with_message(VCPKG_LINE_INFO,
- "Error: failed to check out `port_versions` from repo %s: %s",
- m_repo,
- maybe_path.error());
- }
- return std::move(*maybe_path.get());
- });
- }
-
- std::string m_repo;
- DelayedInit<std::string> m_commit; // TODO: eventually this should end up in the vcpkg-lock.json file
- DelayedInit<fs::path> m_versions_tree;
- std::string m_baseline_identifier;
- DelayedInit<Baseline> m_baseline;
- };
-
- struct BuiltinPortTreeRegistryEntry final : RegistryEntry
- {
- View<VersionT> get_port_versions() const override { return {&version, 1}; }
- ExpectedS<fs::path> get_path_to_version(const VcpkgPaths&, const VersionT& v) const override
- {
- if (v == version)
- {
- return path;
- }
-
- return {Strings::format("Error: no version entry for %s at version %s.\n"
- "We are currently using the version in the ports tree (%s).",
- name,
- v.to_string(),
- version.to_string()),
- expected_right_tag};
- }
-
- std::string name;
- fs::path path;
- VersionT version;
- };
-
- struct BuiltinGitRegistryEntry final : RegistryEntry
- {
- View<VersionT> get_port_versions() const override { return port_versions; }
- ExpectedS<fs::path> get_path_to_version(const VcpkgPaths&, const VersionT& version) const override;
-
- std::string port_name;
-
- // these two map port versions to git trees
- // these shall have the same size, and git_trees[i] shall be the git tree for port_versions[i]
- std::vector<VersionT> port_versions;
- std::vector<std::string> git_trees;
- };
-
- struct FilesystemRegistryEntry final : RegistryEntry
- {
- explicit FilesystemRegistryEntry(std::string&& port_name) : port_name(port_name) { }
-
- View<VersionT> get_port_versions() const override { return port_versions; }
-
- ExpectedS<fs::path> get_path_to_version(const VcpkgPaths& paths, const VersionT& version) const override;
-
- std::string port_name;
-
- // these two map port versions to paths
- // these shall have the same size, and paths[i] shall be the path for port_versions[i]
- std::vector<VersionT> port_versions;
- std::vector<fs::path> version_paths;
- };
-
- struct BuiltinRegistry final : RegistryImplementation
- {
- BuiltinRegistry(std::string&& baseline) : m_baseline_identifier(std::move(baseline))
- {
- Debug::print("BuiltinRegistry initialized with: \"", m_baseline_identifier, "\"\n");
- }
-
- std::unique_ptr<RegistryEntry> get_port_entry(const VcpkgPaths& paths, StringView port_name) const override;
-
- void get_all_port_names(std::vector<std::string>&, const VcpkgPaths&) const override;
-
- Optional<VersionT> get_baseline_version(const VcpkgPaths& paths, StringView port_name) const override;
-
- ~BuiltinRegistry() = default;
-
- std::string m_baseline_identifier;
- DelayedInit<Baseline> m_baseline;
- };
-
- struct FilesystemRegistry final : RegistryImplementation
- {
- FilesystemRegistry(fs::path&& path, std::string&& baseline)
- : m_path(std::move(path)), m_baseline_identifier(baseline)
- {
- }
-
- std::unique_ptr<RegistryEntry> get_port_entry(const VcpkgPaths&, StringView) const override;
-
- void get_all_port_names(std::vector<std::string>&, const VcpkgPaths&) const override;
-
- Optional<VersionT> get_baseline_version(const VcpkgPaths&, StringView) const override;
-
- private:
- fs::path m_path;
- std::string m_baseline_identifier;
- DelayedInit<Baseline> m_baseline;
- };
-
- struct VersionDbEntry
- {
- VersionT version;
- Versions::Scheme scheme = Versions::Scheme::String;
-
- // only one of these may be non-empty
- std::string git_tree;
- fs::path path;
- };
-
- // VersionDbType::Git => VersionDbEntry.git_tree is filled
- // VersionDbType::Filesystem => VersionDbEntry.path is filled
- enum class VersionDbType
- {
- Git,
- Filesystem,
- };
-
- fs::path relative_path_to_versions(StringView port_name);
- ExpectedS<std::vector<VersionDbEntry>> load_versions_file(const Files::Filesystem& fs,
- VersionDbType vdb,
- const fs::path& port_versions,
- StringView port_name,
- const fs::path& registry_root = {});
-
- // returns nullopt if the baseline is valid, but doesn't contain the specified baseline,
- // or (equivalently) if the baseline does not exist.
- ExpectedS<Optional<Baseline>> parse_baseline_versions(StringView contents, StringView baseline, StringView origin);
- ExpectedS<Optional<Baseline>> load_baseline_versions(const VcpkgPaths& paths,
- const fs::path& path_to_baseline,
- StringView identifier = {});
-
- void load_all_port_names_from_registry_versions(std::vector<std::string>& out,
- const VcpkgPaths& paths,
- const fs::path& port_versions_path)
- {
- for (auto super_directory : fs::directory_iterator(port_versions_path))
- {
- if (!fs::is_directory(paths.get_filesystem().status(VCPKG_LINE_INFO, super_directory))) continue;
-
- for (auto file : fs::directory_iterator(super_directory))
- {
- auto filename = fs::u8string(file.path().filename());
- if (!Strings::ends_with(filename, ".json")) continue;
-
- auto port_name = filename.substr(0, filename.size() - 5);
- if (!Json::PackageNameDeserializer::is_package_name(port_name))
- {
- Checks::exit_maybe_upgrade(
- VCPKG_LINE_INFO, "Error: found invalid port version file name: `%s`.", fs::u8string(file));
- }
- out.push_back(std::move(port_name));
- }
- }
- }
-
- // { RegistryImplementation
-
- // { BuiltinRegistry::RegistryImplementation
- std::unique_ptr<RegistryEntry> BuiltinRegistry::get_port_entry(const VcpkgPaths& paths, StringView port_name) const
- {
- const auto& fs = paths.get_filesystem();
- if (!m_baseline_identifier.empty())
- {
- auto versions_path = paths.builtin_registry_versions / relative_path_to_versions(port_name);
- if (fs.exists(versions_path))
- {
- auto maybe_version_entries =
- load_versions_file(fs, VersionDbType::Git, paths.builtin_registry_versions, port_name);
- Checks::check_maybe_upgrade(
- VCPKG_LINE_INFO, maybe_version_entries.has_value(), "Error: " + maybe_version_entries.error());
- auto version_entries = std::move(maybe_version_entries).value_or_exit(VCPKG_LINE_INFO);
-
- auto res = std::make_unique<BuiltinGitRegistryEntry>();
- res->port_name = port_name.to_string();
- for (auto&& version_entry : version_entries)
- {
- res->port_versions.push_back(version_entry.version);
- res->git_trees.push_back(version_entry.git_tree);
- }
- return res;
- }
- }
-
- // Fall back to current available version
- auto port_directory = paths.builtin_ports_directory() / fs::u8path(port_name);
- if (fs.exists(port_directory))
- {
- auto found_scf = Paragraphs::try_load_port(fs, port_directory);
- if (auto scfp = found_scf.get())
- {
- auto& scf = *scfp;
- auto maybe_error = scf->check_against_feature_flags(port_directory, paths.get_feature_flags());
- if (maybe_error)
- {
- Checks::exit_maybe_upgrade(VCPKG_LINE_INFO, "Parsing manifest failed: %s", *maybe_error.get());
- }
-
- if (scf->core_paragraph->name == port_name)
- {
- auto res = std::make_unique<BuiltinPortTreeRegistryEntry>();
- res->name = std::move(scf->core_paragraph->name);
- res->path = std::move(port_directory);
- res->version = scf->to_versiont();
- return res;
- }
- Checks::exit_maybe_upgrade(VCPKG_LINE_INFO,
- "Error: Failed to load port from %s: names did not match: '%s' != '%s'",
- fs::u8string(port_directory),
- port_name,
- scf->core_paragraph->name);
- }
- }
-
- return nullptr;
- }
-
- ExpectedS<Baseline> try_parse_builtin_baseline(const VcpkgPaths& paths, StringView baseline_identifier)
- {
- if (baseline_identifier.size() == 0) return Baseline{};
- auto path_to_baseline = paths.builtin_registry_versions / fs::u8path("baseline.json");
- auto res_baseline = load_baseline_versions(paths, path_to_baseline, baseline_identifier);
-
- if (!res_baseline.has_value())
- {
- return res_baseline.error();
- }
-
- auto opt_baseline = res_baseline.get();
- if (auto p = opt_baseline->get())
- {
- return std::move(*p);
- }
-
- if (baseline_identifier == "default")
- {
- return Strings::format(
- "Error: Couldn't find explicitly specified baseline `\"default\"` in baseline file: %s",
- fs::u8string(path_to_baseline));
- }
-
- // attempt to check out the baseline:
- auto maybe_path = paths.git_checkout_baseline(baseline_identifier);
- if (!maybe_path.has_value())
- {
- return Strings::format("Error: Couldn't find explicitly specified baseline `\"%s\"` in the baseline file, "
- "and there was no baseline at that commit or the commit didn't exist.\n%s\n%s",
- baseline_identifier,
- maybe_path.error(),
- paths.get_current_git_sha_message());
- }
-
- res_baseline = load_baseline_versions(paths, *maybe_path.get());
- if (!res_baseline.has_value())
- {
- return res_baseline.error();
- }
- opt_baseline = res_baseline.get();
- if (auto p = opt_baseline->get())
- {
- return std::move(*p);
- }
-
- return Strings::format("Error: Couldn't find explicitly specified baseline `\"%s\"` in the baseline "
- "file, and the `\"default\"` baseline does not exist at that commit.",
- baseline_identifier);
- }
-
- Baseline parse_builtin_baseline(const VcpkgPaths& paths, StringView baseline_identifier)
- {
- auto maybe_baseline = try_parse_builtin_baseline(paths, baseline_identifier);
- return maybe_baseline.value_or_exit(VCPKG_LINE_INFO);
- }
- Optional<VersionT> BuiltinRegistry::get_baseline_version(const VcpkgPaths& paths, StringView port_name) const
- {
- if (!m_baseline_identifier.empty())
- {
- const auto& baseline = m_baseline.get(
- [this, &paths]() -> Baseline { return parse_builtin_baseline(paths, m_baseline_identifier); });
-
- auto it = baseline.find(port_name);
- if (it != baseline.end())
- {
- return it->second;
- }
- return nullopt;
- }
-
- // if a baseline is not specified, use the ports directory version
- auto port_path = paths.builtin_ports_directory() / fs::u8path(port_name);
- auto maybe_scf = Paragraphs::try_load_port(paths.get_filesystem(), port_path);
- if (auto pscf = maybe_scf.get())
- {
- auto& scf = *pscf;
- return scf->to_versiont();
- }
- print_error_message(maybe_scf.error());
- Checks::exit_maybe_upgrade(VCPKG_LINE_INFO, "Error: failed to load port from %s", fs::u8string(port_path));
- }
-
- void BuiltinRegistry::get_all_port_names(std::vector<std::string>& out, const VcpkgPaths& paths) const
- {
- const auto& fs = paths.get_filesystem();
-
- if (!m_baseline_identifier.empty() && fs.exists(paths.builtin_registry_versions))
- {
- load_all_port_names_from_registry_versions(out, paths, paths.builtin_registry_versions);
- }
- std::error_code ec;
- fs::directory_iterator dir_it(paths.builtin_ports_directory(), ec);
- Checks::check_exit(VCPKG_LINE_INFO,
- !ec,
- "Error: failed while enumerating the builtin ports directory %s: %s",
- fs::u8string(paths.builtin_ports_directory()),
- ec.message());
- for (auto port_directory : dir_it)
- {
- if (!fs::is_directory(fs.status(VCPKG_LINE_INFO, port_directory))) continue;
- auto filename = fs::u8string(port_directory.path().filename());
- if (filename == ".DS_Store") continue;
- out.push_back(filename);
- }
- }
- // } BuiltinRegistry::RegistryImplementation
-
- // { FilesystemRegistry::RegistryImplementation
- Baseline parse_filesystem_baseline(const VcpkgPaths& paths, const fs::path& root, StringView baseline_identifier)
- {
- auto path_to_baseline = root / registry_versions_dir_name / fs::u8path("baseline.json");
- auto res_baseline = load_baseline_versions(paths, path_to_baseline, baseline_identifier);
- if (auto opt_baseline = res_baseline.get())
- {
- if (auto p = opt_baseline->get())
- {
- return std::move(*p);
- }
-
- if (baseline_identifier.size() == 0)
- {
- return {};
- }
-
- Checks::exit_maybe_upgrade(
- VCPKG_LINE_INFO,
- "Error: could not find explicitly specified baseline `\"%s\"` in baseline file `%s`.",
- baseline_identifier,
- fs::u8string(path_to_baseline));
- }
-
- Checks::exit_maybe_upgrade(VCPKG_LINE_INFO, res_baseline.error());
- }
- Optional<VersionT> FilesystemRegistry::get_baseline_version(const VcpkgPaths& paths, StringView port_name) const
- {
- const auto& baseline = m_baseline.get(
- [this, &paths]() -> Baseline { return parse_filesystem_baseline(paths, m_path, m_baseline_identifier); });
-
- auto it = baseline.find(port_name);
- if (it != baseline.end())
- {
- return it->second;
- }
- else
- {
- return nullopt;
- }
- }
-
- std::unique_ptr<RegistryEntry> FilesystemRegistry::get_port_entry(const VcpkgPaths& paths,
- StringView port_name) const
- {
- auto maybe_version_entries = load_versions_file(
- paths.get_filesystem(), VersionDbType::Filesystem, m_path / registry_versions_dir_name, port_name, m_path);
- Checks::check_maybe_upgrade(
- VCPKG_LINE_INFO, maybe_version_entries.has_value(), "Error: %s", maybe_version_entries.error());
- auto version_entries = std::move(maybe_version_entries).value_or_exit(VCPKG_LINE_INFO);
-
- auto res = std::make_unique<FilesystemRegistryEntry>(port_name.to_string());
- for (auto&& version_entry : version_entries)
- {
- res->port_versions.push_back(std::move(version_entry.version));
- res->version_paths.push_back(std::move(version_entry.path));
- }
- return res;
- }
-
- void FilesystemRegistry::get_all_port_names(std::vector<std::string>& out, const VcpkgPaths& paths) const
- {
- load_all_port_names_from_registry_versions(out, paths, m_path / registry_versions_dir_name);
- }
- // } FilesystemRegistry::RegistryImplementation
-
- // { GitRegistry::RegistryImplementation
- std::unique_ptr<RegistryEntry> GitRegistry::get_port_entry(const VcpkgPaths& paths, StringView port_name) const
- {
- auto port_versions = get_versions_tree_path(paths);
- auto maybe_version_entries =
- load_versions_file(paths.get_filesystem(), VersionDbType::Git, port_versions, port_name);
- Checks::check_maybe_upgrade(
- VCPKG_LINE_INFO, maybe_version_entries.has_value(), "Error: " + maybe_version_entries.error());
- auto version_entries = std::move(maybe_version_entries).value_or_exit(VCPKG_LINE_INFO);
-
- auto res = std::make_unique<GitRegistryEntry>();
- res->port_name = port_name.to_string();
- for (auto&& version_entry : version_entries)
- {
- res->port_versions.push_back(version_entry.version);
- res->git_trees.push_back(version_entry.git_tree);
- }
- return res;
- }
-
- Optional<VersionT> GitRegistry::get_baseline_version(const VcpkgPaths& paths, StringView port_name) const
- {
- const auto& baseline = m_baseline.get([this, &paths]() -> Baseline {
- auto baseline_file = get_versions_tree_path(paths) / fs::u8path("baseline.json");
-
- auto res_baseline = load_baseline_versions(paths, baseline_file, m_baseline_identifier);
-
- if (!res_baseline.has_value())
- {
- Checks::exit_maybe_upgrade(VCPKG_LINE_INFO, res_baseline.error());
- }
- auto opt_baseline = res_baseline.get();
- if (auto p = opt_baseline->get())
- {
- return std::move(*p);
- }
-
- if (m_baseline_identifier.empty())
- {
- return {};
- }
-
- if (m_baseline_identifier == "default")
- {
- Checks::exit_with_message(
- VCPKG_LINE_INFO,
- "Couldn't find explicitly specified baseline `\"default\"` in the baseline file.",
- m_baseline_identifier);
- }
-
- // attempt to check out the baseline:
- auto explicit_hash = paths.git_fetch_from_remote_registry(m_repo, m_baseline_identifier);
- if (!explicit_hash.has_value())
- {
- Checks::exit_with_message(
- VCPKG_LINE_INFO,
- "Error: Couldn't find explicitly specified baseline `\"%s\"` in the baseline file for repo %s, "
- "and that commit doesn't exist.\n%s",
- m_baseline_identifier,
- m_repo,
- explicit_hash.error());
- }
- auto path_to_baseline = registry_versions_dir_name / fs::u8path("baseline.json");
- auto maybe_contents = paths.git_show_from_remote_registry(*explicit_hash.get(), path_to_baseline);
- if (!maybe_contents.has_value())
- {
- Checks::exit_with_message(
- VCPKG_LINE_INFO,
- "Error: Couldn't find explicitly specified baseline `\"%s\"` in the baseline file for repo %s, "
- "and the baseline file doesn't exist at that commit.\n%s\n",
- m_baseline_identifier,
- m_repo,
- maybe_contents.error());
- }
-
- auto contents = maybe_contents.get();
- res_baseline = parse_baseline_versions(*contents, "default", fs::u8string(path_to_baseline));
- if (!res_baseline.has_value())
- {
- Checks::exit_with_message(VCPKG_LINE_INFO, res_baseline.error());
- }
- opt_baseline = res_baseline.get();
- if (auto p = opt_baseline->get())
- {
- return std::move(*p);
- }
- else
- {
- Checks::exit_maybe_upgrade(
- VCPKG_LINE_INFO,
- "Couldn't find explicitly specified baseline `\"%s\"` in the baseline file for repo %s, "
- "and the `\"default\"` baseline does not exist at that commit.",
- m_baseline_identifier,
- m_repo);
- }
- });
-
- auto it = baseline.find(port_name);
- if (it != baseline.end())
- {
- return it->second;
- }
-
- return nullopt;
- }
-
- void GitRegistry::get_all_port_names(std::vector<std::string>& out, const VcpkgPaths& paths) const
- {
- auto versions_path = get_versions_tree_path(paths);
- load_all_port_names_from_registry_versions(out, paths, versions_path);
- }
- // } GitRegistry::RegistryImplementation
-
- // } RegistryImplementation
-
- // { RegistryEntry
-
- // { BuiltinRegistryEntry::RegistryEntry
- ExpectedS<fs::path> BuiltinGitRegistryEntry::get_path_to_version(const VcpkgPaths& paths,
- const VersionT& version) const
- {
- auto it = std::find(port_versions.begin(), port_versions.end(), version);
- if (it == port_versions.end())
- {
- return {Strings::concat("Error: No version entry for ",
- port_name,
- " at version ",
- version,
- ". This may be fixed by updating vcpkg to the latest master via `git "
- "pull`.\nAvailable versions:\n",
- Strings::join("",
- port_versions,
- [](const VersionT& v) { return Strings::concat(" ", v, "\n"); }),
- "\nSee `vcpkg help versioning` for more information."),
- expected_right_tag};
- }
-
- const auto& git_tree = git_trees[it - port_versions.begin()];
- return paths.git_checkout_port(port_name, git_tree, paths.root / fs::u8path(".git"));
- }
- // } BuiltinRegistryEntry::RegistryEntry
-
- // { FilesystemRegistryEntry::RegistryEntry
- ExpectedS<fs::path> FilesystemRegistryEntry::get_path_to_version(const VcpkgPaths&, const VersionT& version) const
- {
- auto it = std::find(port_versions.begin(), port_versions.end(), version);
- if (it == port_versions.end())
- {
- return Strings::concat("Error: No version entry for ", port_name, " at version ", version, ".");
- }
- return version_paths[it - port_versions.begin()];
- }
- // } FilesystemRegistryEntry::RegistryEntry
-
- // { GitRegistryEntry::RegistryEntry
- ExpectedS<fs::path> GitRegistryEntry::get_path_to_version(const VcpkgPaths& paths, const VersionT& version) const
- {
- auto it = std::find(port_versions.begin(), port_versions.end(), version);
- if (it == port_versions.end())
- {
- // This message suggests that the user updates vcpkg -- this is appropriate for the builtin registry for now
- // but needs tweaking for external git registries
- return {Strings::concat("Error: No version entry for ",
- port_name,
- " at version ",
- version,
- ". This may be fixed by updating vcpkg to the latest master via `git "
- "pull`.\nAvailable versions:\n",
- Strings::join("",
- port_versions,
- [](const VersionT& v) { return Strings::concat(" ", v, "\n"); }),
- "\nSee `vcpkg help versioning` for more information."),
- expected_right_tag};
- }
-
- const auto& git_tree = git_trees[it - port_versions.begin()];
- return paths.git_checkout_object_from_remote_registry(git_tree);
- }
- // } GitRegistryEntry::RegistryEntry
-
- // } RegistryEntry
-}
-
-// deserializers
-namespace
-{
- using namespace vcpkg;
-
- struct BaselineDeserializer final : Json::IDeserializer<std::map<std::string, VersionT, std::less<>>>
- {
- StringView type_name() const override { return "a baseline object"; }
-
- Optional<type> visit_object(Json::Reader& r, const Json::Object& obj) override
- {
- std::map<std::string, VersionT, std::less<>> result;
-
- for (auto pr : obj)
- {
- const auto& version_value = pr.second;
- VersionT version;
- r.visit_in_key(version_value, pr.first, version, get_versiontag_deserializer_instance());
-
- result.emplace(pr.first.to_string(), std::move(version));
- }
-
- return std::move(result);
- }
-
- static BaselineDeserializer instance;
- };
- BaselineDeserializer BaselineDeserializer::instance;
-
- struct VersionDbEntryDeserializer final : Json::IDeserializer<VersionDbEntry>
- {
- static constexpr StringLiteral GIT_TREE = "git-tree";
- static constexpr StringLiteral PATH = "path";
-
- StringView type_name() const override { return "a version database entry"; }
- View<StringView> valid_fields() const override
- {
- static const StringView u_git[] = {GIT_TREE};
- static const StringView u_path[] = {PATH};
- static const auto t_git = vcpkg::Util::Vectors::concat<StringView>(schemed_deserializer_fields(), u_git);
- static const auto t_path = vcpkg::Util::Vectors::concat<StringView>(schemed_deserializer_fields(), u_path);
-
- return type == VersionDbType::Git ? t_git : t_path;
- }
-
- Optional<VersionDbEntry> visit_object(Json::Reader& r, const Json::Object& obj) override
- {
- VersionDbEntry ret;
-
- auto schemed_version = visit_required_schemed_deserializer(type_name(), r, obj);
- ret.scheme = schemed_version.scheme;
- ret.version = std::move(schemed_version.versiont);
-
- static Json::StringDeserializer git_tree_deserializer("a git object SHA");
- static Json::StringDeserializer path_deserializer("a registry path");
-
- switch (type)
- {
- case VersionDbType::Git:
- {
- r.required_object_field(type_name(), obj, GIT_TREE, ret.git_tree, git_tree_deserializer);
- break;
- }
- case VersionDbType::Filesystem:
- {
- std::string path_res;
- r.required_object_field(type_name(), obj, PATH, path_res, path_deserializer);
- fs::path p = fs::u8path(path_res);
- if (p.is_absolute())
- {
- r.add_generic_error("a registry path",
- "A registry path may not be absolute, and must start with a `$` to mean "
- "the registry root; e.g., `$/foo/bar`.");
- return ret;
- }
- else if (p.empty())
- {
- r.add_generic_error("a registry path", "A registry path must not be empty.");
- return ret;
- }
-
- auto it = p.begin();
- if (*it != "$")
- {
- r.add_generic_error(
- "a registry path",
- "A registry path must start with `$` to mean the registry root; e.g., `$/foo/bar`");
- }
-
- ret.path = registry_root;
- ++it;
- std::for_each(it, p.end(), [&r, &ret](const fs::path& p) {
- if (p == "..")
- {
- r.add_generic_error("a registry path", "A registry path must not contain `..`.");
- }
- else
- {
- ret.path /= p;
- }
- });
-
- break;
- }
- }
-
- return ret;
- }
-
- VersionDbEntryDeserializer(VersionDbType type, const fs::path& root) : type(type), registry_root(root) { }
-
- VersionDbType type;
- fs::path registry_root;
- };
-
- struct VersionDbEntryArrayDeserializer final : Json::IDeserializer<std::vector<VersionDbEntry>>
- {
- virtual StringView type_name() const override { return "an array of versions"; }
-
- virtual Optional<std::vector<VersionDbEntry>> visit_array(Json::Reader& r, const Json::Array& arr) override
- {
- return r.array_elements(arr, underlying);
- }
-
- VersionDbEntryArrayDeserializer(VersionDbType type, const fs::path& root) : underlying{type, root} { }
-
- VersionDbEntryDeserializer underlying;
- };
-
- struct RegistryImplDeserializer : Json::IDeserializer<std::unique_ptr<RegistryImplementation>>
- {
- constexpr static StringLiteral KIND = "kind";
- constexpr static StringLiteral BASELINE = "baseline";
- constexpr static StringLiteral PATH = "path";
- constexpr static StringLiteral REPO = "repository";
-
- constexpr static StringLiteral KIND_BUILTIN = "builtin";
- constexpr static StringLiteral KIND_FILESYSTEM = "filesystem";
- constexpr static StringLiteral KIND_GIT = "git";
-
- virtual StringView type_name() const override { return "a registry"; }
- virtual View<StringView> valid_fields() const override;
-
- virtual Optional<std::unique_ptr<RegistryImplementation>> visit_null(Json::Reader&) override;
- virtual Optional<std::unique_ptr<RegistryImplementation>> visit_object(Json::Reader&,
- const Json::Object&) override;
-
- RegistryImplDeserializer(const fs::path& configuration_directory)
- : config_directory(configuration_directory) { }
-
- fs::path config_directory;
- };
- constexpr StringLiteral RegistryImplDeserializer::KIND;
- constexpr StringLiteral RegistryImplDeserializer::BASELINE;
- constexpr StringLiteral RegistryImplDeserializer::PATH;
- constexpr StringLiteral RegistryImplDeserializer::REPO;
- constexpr StringLiteral RegistryImplDeserializer::KIND_BUILTIN;
- constexpr StringLiteral RegistryImplDeserializer::KIND_FILESYSTEM;
- constexpr StringLiteral RegistryImplDeserializer::KIND_GIT;
-
- struct RegistryDeserializer final : Json::IDeserializer<Registry>
- {
- constexpr static StringLiteral PACKAGES = "packages";
-
- virtual StringView type_name() const override { return "a registry"; }
- virtual View<StringView> valid_fields() const override;
-
- virtual Optional<Registry> visit_object(Json::Reader&, const Json::Object&) override;
-
- explicit RegistryDeserializer(const fs::path& configuration_directory) : impl_des(configuration_directory) { }
-
- RegistryImplDeserializer impl_des;
- };
- constexpr StringLiteral RegistryDeserializer::PACKAGES;
-
- View<StringView> RegistryImplDeserializer::valid_fields() const
- {
- static const StringView t[] = {KIND, BASELINE, PATH, REPO};
- return t;
- }
- View<StringView> valid_builtin_fields()
- {
- static const StringView t[] = {
- RegistryImplDeserializer::KIND,
- RegistryImplDeserializer::BASELINE,
- RegistryDeserializer::PACKAGES,
- };
- return t;
- }
- View<StringView> valid_filesystem_fields()
- {
- static const StringView t[] = {
- RegistryImplDeserializer::KIND,
- RegistryImplDeserializer::BASELINE,
- RegistryImplDeserializer::PATH,
- RegistryDeserializer::PACKAGES,
- };
- return t;
- }
- View<StringView> valid_git_fields()
- {
- static const StringView t[] = {
- RegistryImplDeserializer::KIND,
- RegistryImplDeserializer::BASELINE,
- RegistryImplDeserializer::REPO,
- RegistryDeserializer::PACKAGES,
- };
- return t;
- }
-
- Optional<std::unique_ptr<RegistryImplementation>> RegistryImplDeserializer::visit_null(Json::Reader&)
- {
- return nullptr;
- }
-
- Optional<std::unique_ptr<RegistryImplementation>> RegistryImplDeserializer::visit_object(Json::Reader& r,
- const Json::Object& obj)
- {
- static Json::StringDeserializer kind_deserializer{"a registry implementation kind"};
- static Json::StringDeserializer baseline_deserializer{"a baseline"};
- std::string kind;
- std::string baseline;
-
- r.required_object_field(type_name(), obj, KIND, kind, kind_deserializer);
- r.optional_object_field(obj, BASELINE, baseline, baseline_deserializer);
-
- std::unique_ptr<RegistryImplementation> res;
-
- if (kind == KIND_BUILTIN)
- {
- r.check_for_unexpected_fields(obj, valid_builtin_fields(), "a builtin registry");
- res = std::make_unique<BuiltinRegistry>(std::move(baseline));
- }
- else if (kind == KIND_FILESYSTEM)
- {
- r.check_for_unexpected_fields(obj, valid_filesystem_fields(), "a filesystem registry");
-
- fs::path path;
- r.required_object_field("a filesystem registry", obj, PATH, path, Json::PathDeserializer::instance);
-
- res = std::make_unique<FilesystemRegistry>(Files::combine(config_directory, path), std::move(baseline));
- }
- else if (kind == KIND_GIT)
- {
- r.check_for_unexpected_fields(obj, valid_git_fields(), "a git registry");
-
- std::string repo;
- Json::StringDeserializer repo_des{"a git repository URL"};
- r.required_object_field("a git registry", obj, REPO, repo, repo_des);
-
- res = std::make_unique<GitRegistry>(std::move(repo), std::move(baseline));
- }
- else
- {
- StringLiteral valid_kinds[] = {KIND_BUILTIN, KIND_FILESYSTEM, KIND_GIT};
- r.add_generic_error(type_name(),
- "Field \"kind\" did not have an expected value (expected one of: \"",
- Strings::join("\", \"", valid_kinds),
- "\", found \"",
- kind,
- "\").");
- return nullopt;
- }
-
- return std::move(res);
- }
-
- View<StringView> RegistryDeserializer::valid_fields() const
- {
- static const StringView t[] = {
- RegistryImplDeserializer::KIND,
- RegistryImplDeserializer::BASELINE,
- RegistryImplDeserializer::PATH,
- RegistryImplDeserializer::REPO,
- PACKAGES,
- };
- return t;
- }
-
- Optional<Registry> RegistryDeserializer::visit_object(Json::Reader& r, const Json::Object& obj)
- {
- auto impl = impl_des.visit_object(r, obj);
-
- if (!impl.has_value())
- {
- return nullopt;
- }
-
- static Json::ArrayDeserializer<Json::PackageNameDeserializer> package_names_deserializer{
- "an array of package names"};
-
- std::vector<std::string> packages;
- r.required_object_field(type_name(), obj, PACKAGES, packages, package_names_deserializer);
-
- return Registry{std::move(packages), std::move(impl).value_or_exit(VCPKG_LINE_INFO)};
- }
-
- fs::path relative_path_to_versions(StringView port_name)
- {
- auto port_filename = fs::u8path(port_name.to_string() + ".json");
- return fs::u8path({port_name.byte_at_index(0), '-'}) / port_filename;
- }
-
- ExpectedS<std::vector<VersionDbEntry>> load_versions_file(const Files::Filesystem& fs,
- VersionDbType type,
- const fs::path& registry_versions,
- StringView port_name,
- const fs::path& registry_root)
- {
- Checks::check_exit(VCPKG_LINE_INFO,
- !(type == VersionDbType::Filesystem && registry_root.empty()),
- "Bug in vcpkg; type should never = Filesystem when registry_root is empty.");
-
- auto versions_file_path = registry_versions / relative_path_to_versions(port_name);
-
- if (!fs.exists(versions_file_path))
- {
- return Strings::format("Couldn't find the versions database file: %s", fs::u8string(versions_file_path));
- }
-
- auto maybe_contents = fs.read_contents(versions_file_path);
- if (!maybe_contents.has_value())
- {
- return Strings::format("Failed to load the versions database file %s: %s",
- fs::u8string(versions_file_path),
- maybe_contents.error().message());
- }
-
- auto maybe_versions_json = Json::parse(*maybe_contents.get());
- if (!maybe_versions_json.has_value())
- {
- return Strings::format(
- "Error: failed to parse versions file for `%s`: %s", port_name, maybe_versions_json.error()->format());
- }
- if (!maybe_versions_json.get()->first.is_object())
- {
- return Strings::format("Error: versions file for `%s` does not have a top level object.", port_name);
- }
-
- const auto& versions_object = maybe_versions_json.get()->first.object();
- auto maybe_versions_array = versions_object.get("versions");
- if (!maybe_versions_array || !maybe_versions_array->is_array())
- {
- return Strings::format("Error: versions file for `%s` does not contain a versions array.", port_name);
- }
-
- std::vector<VersionDbEntry> db_entries;
- VersionDbEntryArrayDeserializer deserializer{type, registry_root};
- // Avoid warning treated as error.
- if (maybe_versions_array != nullptr)
- {
- Json::Reader r;
- r.visit_in_key(*maybe_versions_array, "versions", db_entries, deserializer);
- if (!r.errors().empty())
- {
- return Strings::format(
- "Error: failed to parse versions file for `%s`:\n%s", port_name, Strings::join("\n", r.errors()));
- }
- }
- return db_entries;
- }
-
- ExpectedS<Optional<Baseline>> parse_baseline_versions(StringView contents, StringView baseline, StringView origin)
- {
- auto maybe_value = Json::parse(contents, origin);
- if (!maybe_value.has_value())
- {
- return Strings::format(
- "Error: failed to parse baseline file: %s\n%s", origin, maybe_value.error()->format());
- }
-
- auto& value = *maybe_value.get();
-
- if (!value.first.is_object())
- {
- return Strings::concat("Error: baseline does not have a top-level object: ", origin);
- }
-
- auto real_baseline = baseline.size() == 0 ? "default" : baseline;
-
- const auto& obj = value.first.object();
- auto baseline_value = obj.get(real_baseline);
- if (!baseline_value)
- {
- return {nullopt, expected_left_tag};
- }
-
- Json::Reader r;
- std::map<std::string, VersionT, std::less<>> result;
- r.visit_in_key(*baseline_value, real_baseline, result, BaselineDeserializer::instance);
- if (r.errors().empty())
- {
- return {std::move(result), expected_left_tag};
- }
- else
- {
- return Strings::format("Error: failed to parse baseline: %s\n%s", origin, Strings::join("\n", r.errors()));
- }
- }
-
- ExpectedS<Optional<Baseline>> load_baseline_versions(const VcpkgPaths& paths,
- const fs::path& path_to_baseline,
- StringView baseline)
- {
- auto maybe_contents = paths.get_filesystem().read_contents(path_to_baseline);
- if (auto contents = maybe_contents.get())
- {
- return parse_baseline_versions(*contents, baseline, fs::u8string(path_to_baseline));
- }
- else if (maybe_contents.error() == std::errc::no_such_file_or_directory)
- {
- Debug::print("Failed to find baseline.json\n");
- return {nullopt, expected_left_tag};
- }
- else
- {
- return Strings::format("Error: failed to read file `%s`: %s",
- fs::u8string(path_to_baseline),
- maybe_contents.error().message());
- }
- }
-}
-
-namespace vcpkg
-{
- std::unique_ptr<Json::IDeserializer<std::unique_ptr<RegistryImplementation>>>
- get_registry_implementation_deserializer(const fs::path& configuration_directory)
- {
- return std::make_unique<RegistryImplDeserializer>(configuration_directory);
- }
- std::unique_ptr<Json::IDeserializer<std::vector<Registry>>> get_registry_array_deserializer(
- const fs::path& configuration_directory)
- {
- return std::make_unique<Json::ArrayDeserializer<RegistryDeserializer>>(
- "an array of registries", RegistryDeserializer(configuration_directory));
- }
-
- Registry::Registry(std::vector<std::string>&& packages, std::unique_ptr<RegistryImplementation>&& impl)
- : packages_(std::move(packages)), implementation_(std::move(impl))
- {
- Checks::check_exit(VCPKG_LINE_INFO, implementation_ != nullptr);
- }
-
- RegistrySet::RegistrySet() : default_registry_(std::make_unique<BuiltinRegistry>("")) { }
-
- const RegistryImplementation* RegistrySet::registry_for_port(StringView name) const
- {
- for (const auto& registry : registries())
- {
- const auto& packages = registry.packages();
- if (std::find(packages.begin(), packages.end(), name) != packages.end())
- {
- return &registry.implementation();
- }
- }
- return default_registry();
- }
-
- Optional<VersionT> RegistrySet::baseline_for_port(const VcpkgPaths& paths, StringView port_name) const
- {
- auto impl = registry_for_port(port_name);
- if (!impl) return nullopt;
- return impl->get_baseline_version(paths, port_name);
- }
-
- void RegistrySet::add_registry(Registry&& r) { registries_.push_back(std::move(r)); }
-
- void RegistrySet::set_default_registry(std::unique_ptr<RegistryImplementation>&& r)
- {
- default_registry_ = std::move(r);
- }
- void RegistrySet::set_default_registry(std::nullptr_t) { default_registry_.reset(); }
-
- void RegistrySet::experimental_set_builtin_registry_baseline(StringView baseline) const
- {
- // to check if we should warn
- bool default_registry_is_builtin = false;
- if (auto builtin_registry = dynamic_cast<BuiltinRegistry*>(default_registry_.get()))
- {
- default_registry_is_builtin = true;
- builtin_registry->m_baseline_identifier.assign(baseline.begin(), baseline.end());
- }
-
- if (!default_registry_is_builtin || registries_.size() != 0)
- {
- System::print2(System::Color::warning,
- "Warning: when using the registries feature, one should not use `\"builtin-baseline\"` "
- "to set the baseline.\n",
- " Instead, use the \"baseline\" field of the registry.\n");
- }
-
- for (auto& reg : registries_)
- {
- if (auto builtin_registry = dynamic_cast<BuiltinRegistry*>(reg.implementation_.get()))
- {
- builtin_registry->m_baseline_identifier.assign(baseline.begin(), baseline.end());
- }
- }
- }
-
- bool RegistrySet::has_modifications() const
- {
- if (!registries_.empty())
- {
- return true;
- }
- if (auto builtin_reg = dynamic_cast<const BuiltinRegistry*>(default_registry_.get()))
- {
- if (builtin_reg->m_baseline_identifier.empty())
- {
- return false;
- }
- return true;
- }
- // default_registry_ is not a BuiltinRegistry
- return true;
- }
-
- ExpectedS<std::vector<std::pair<SchemedVersion, std::string>>> get_builtin_versions(const VcpkgPaths& paths,
- StringView port_name)
- {
- auto maybe_versions =
- load_versions_file(paths.get_filesystem(), VersionDbType::Git, paths.builtin_registry_versions, port_name);
- if (auto pversions = maybe_versions.get())
- {
- return Util::fmap(
- *pversions, [](auto&& entry) -> auto {
- return std::make_pair(SchemedVersion{entry.scheme, entry.version}, entry.git_tree);
- });
- }
-
- return maybe_versions.error();
- }
-
- ExpectedS<std::map<std::string, VersionT, std::less<>>> get_builtin_baseline(const VcpkgPaths& paths)
- {
- return try_parse_builtin_baseline(paths, "default");
- }
-}
diff --git a/toolsrc/src/vcpkg/remove.cpp b/toolsrc/src/vcpkg/remove.cpp
deleted file mode 100644
index e29ae16c8..000000000
--- a/toolsrc/src/vcpkg/remove.cpp
+++ /dev/null
@@ -1,337 +0,0 @@
-#include <vcpkg/base/system.print.h>
-#include <vcpkg/base/util.h>
-
-#include <vcpkg/commands.h>
-#include <vcpkg/dependencies.h>
-#include <vcpkg/help.h>
-#include <vcpkg/input.h>
-#include <vcpkg/paragraphs.h>
-#include <vcpkg/portfileprovider.h>
-#include <vcpkg/remove.h>
-#include <vcpkg/update.h>
-#include <vcpkg/vcpkglib.h>
-
-namespace vcpkg::Remove
-{
- using Dependencies::RemovePlanAction;
- using Dependencies::RemovePlanType;
- using Dependencies::RequestType;
- using Update::OutdatedPackage;
-
- void remove_package(const VcpkgPaths& paths, const PackageSpec& spec, StatusParagraphs* status_db)
- {
- auto& fs = paths.get_filesystem();
- auto maybe_ipv = status_db->get_installed_package_view(spec);
-
- Checks::check_exit(
- VCPKG_LINE_INFO, maybe_ipv.has_value(), "unable to remove package %s: already removed", spec);
-
- auto&& ipv = maybe_ipv.value_or_exit(VCPKG_LINE_INFO);
-
- std::vector<StatusParagraph> spghs;
- spghs.emplace_back(*ipv.core);
- for (auto&& feature : ipv.features)
- {
- spghs.emplace_back(*feature);
- }
-
- for (auto&& spgh : spghs)
- {
- spgh.want = Want::PURGE;
- spgh.state = InstallState::HALF_INSTALLED;
- write_update(paths, spgh);
- }
-
- auto maybe_lines = fs.read_lines(paths.listfile_path(ipv.core->package));
-
- if (const auto lines = maybe_lines.get())
- {
- std::vector<fs::path> dirs_touched;
- for (auto&& suffix : *lines)
- {
- if (!suffix.empty() && suffix.back() == '\r') suffix.pop_back();
-
- std::error_code ec;
-
- auto target = paths.installed / suffix;
-
- const auto status = fs.symlink_status(target, ec);
- if (ec)
- {
- System::print2(
- System::Color::error, "failed: status(", fs::u8string(target), "): ", ec.message(), "\n");
- continue;
- }
-
- if (fs::is_directory(status))
- {
- dirs_touched.push_back(target);
- }
- else if (fs::is_regular_file(status) || fs::is_symlink(status))
- {
- fs.remove(target, ec);
- if (ec)
- {
- // TODO: this is racy; should we ignore this error?
-#if defined(_WIN32)
- fs::stdfs::permissions(target, fs::perms::owner_all | fs::perms::group_all, ec);
- fs.remove(target, ec);
- if (ec)
- {
- System::printf(
- System::Color::error, "failed: remove(%s): %s\n", fs::u8string(target), ec.message());
- }
-#else
- System::printf(
- System::Color::error, "failed: remove(%s): %s\n", fs::u8string(target), ec.message());
-#endif
- }
- }
- else if (!fs::exists(status))
- {
- System::printf(System::Color::warning, "Warning: %s: file not found\n", fs::u8string(target));
- }
- else
- {
- System::printf(
- System::Color::warning, "Warning: %s: cannot handle file type\n", fs::u8string(target));
- }
- }
-
- auto b = dirs_touched.rbegin();
- const auto e = dirs_touched.rend();
- for (; b != e; ++b)
- {
- if (fs.is_empty(*b))
- {
- std::error_code ec;
- fs.remove(*b, ec);
- if (ec)
- {
- System::print2(System::Color::error, "failed: ", ec.message(), "\n");
- }
- }
- }
-
- fs.remove(paths.listfile_path(ipv.core->package), VCPKG_LINE_INFO);
- }
-
- for (auto&& spgh : spghs)
- {
- spgh.state = InstallState::NOT_INSTALLED;
- write_update(paths, spgh);
-
- status_db->insert(std::make_unique<StatusParagraph>(std::move(spgh)));
- }
- }
-
- static void print_plan(const std::map<RemovePlanType, std::vector<const RemovePlanAction*>>& group_by_plan_type)
- {
- static constexpr std::array<RemovePlanType, 2> ORDER = {RemovePlanType::NOT_INSTALLED, RemovePlanType::REMOVE};
-
- for (const RemovePlanType plan_type : ORDER)
- {
- const auto it = group_by_plan_type.find(plan_type);
- if (it == group_by_plan_type.cend())
- {
- continue;
- }
-
- std::vector<const RemovePlanAction*> cont = it->second;
- std::sort(cont.begin(), cont.end(), &RemovePlanAction::compare_by_name);
- const std::string as_string = Strings::join("\n", cont, [](const RemovePlanAction* p) {
- return Dependencies::to_output_string(p->request_type, p->spec.to_string());
- });
-
- switch (plan_type)
- {
- case RemovePlanType::NOT_INSTALLED:
- System::print2("The following packages are not installed, so not removed:\n", as_string, "\n");
- continue;
- case RemovePlanType::REMOVE:
- System::print2("The following packages will be removed:\n", as_string, "\n");
- continue;
- default: Checks::unreachable(VCPKG_LINE_INFO);
- }
- }
- }
-
- void perform_remove_plan_action(const VcpkgPaths& paths,
- const RemovePlanAction& action,
- const Purge purge,
- StatusParagraphs* status_db)
- {
- const std::string display_name = action.spec.to_string();
-
- switch (action.plan_type)
- {
- case RemovePlanType::NOT_INSTALLED:
- System::printf(System::Color::success, "Package %s is not installed\n", display_name);
- break;
- case RemovePlanType::REMOVE:
- System::printf("Removing package %s...\n", display_name);
- remove_package(paths, action.spec, status_db);
- System::printf(System::Color::success, "Removing package %s... done\n", display_name);
- break;
- case RemovePlanType::UNKNOWN:
- default: Checks::unreachable(VCPKG_LINE_INFO);
- }
-
- if (purge == Purge::YES)
- {
- Files::Filesystem& fs = paths.get_filesystem();
- fs.remove_all(paths.packages / action.spec.dir(), VCPKG_LINE_INFO);
- }
- }
-
- static constexpr StringLiteral OPTION_PURGE = "purge";
- static constexpr StringLiteral OPTION_NO_PURGE = "no-purge";
- static constexpr StringLiteral OPTION_RECURSE = "recurse";
- static constexpr StringLiteral OPTION_DRY_RUN = "dry-run";
- static constexpr StringLiteral OPTION_OUTDATED = "outdated";
-
- static constexpr std::array<CommandSwitch, 5> SWITCHES = {{
- {OPTION_PURGE, "Remove the cached copy of the package (default)"},
- {OPTION_NO_PURGE, "Do not remove the cached copy of the package (deprecated)"},
- {OPTION_RECURSE, "Allow removal of packages not explicitly specified on the command line"},
- {OPTION_DRY_RUN, "Print the packages to be removed, but do not remove them"},
- {OPTION_OUTDATED, "Select all packages with versions that do not match the portfiles"},
- }};
-
- static std::vector<std::string> valid_arguments(const VcpkgPaths& paths)
- {
- const StatusParagraphs status_db = database_load_check(paths);
- auto installed_packages = get_installed_ports(status_db);
-
- return Util::fmap(installed_packages, [](auto&& pgh) -> std::string { return pgh.spec().to_string(); });
- }
-
- const CommandStructure COMMAND_STRUCTURE = {
- create_example_string("remove zlib zlib:x64-windows curl boost"),
- 0,
- SIZE_MAX,
- {SWITCHES, {}},
- &valid_arguments,
- };
-
- void RemoveCommand::perform_and_exit(const VcpkgCmdArguments& args,
- const VcpkgPaths& paths,
- Triplet default_triplet) const
- {
- if (paths.manifest_mode_enabled())
- {
- Checks::exit_maybe_upgrade(VCPKG_LINE_INFO,
- "vcpkg remove does not support manifest mode. In order to remove dependencies, "
- "you will need to edit your manifest (vcpkg.json).");
- }
- const ParsedArguments options = args.parse_arguments(COMMAND_STRUCTURE);
-
- StatusParagraphs status_db = database_load_check(paths);
- std::vector<PackageSpec> specs;
- if (Util::Sets::contains(options.switches, OPTION_OUTDATED))
- {
- if (args.command_arguments.size() != 0)
- {
- System::print2(System::Color::error, "Error: 'remove' accepts either libraries or '--outdated'\n");
- Checks::exit_fail(VCPKG_LINE_INFO);
- }
-
- // Load ports from ports dirs
- PortFileProvider::PathsPortFileProvider provider(paths, args.overlay_ports);
-
- specs = Util::fmap(Update::find_outdated_packages(provider, status_db),
- [](auto&& outdated) { return outdated.spec; });
-
- if (specs.empty())
- {
- System::print2(System::Color::success, "There are no outdated packages.\n");
- Checks::exit_success(VCPKG_LINE_INFO);
- }
- }
- else
- {
- if (args.command_arguments.size() < 1)
- {
- System::print2(System::Color::error, "Error: 'remove' accepts either libraries or '--outdated'\n");
- Checks::exit_fail(VCPKG_LINE_INFO);
- }
- specs = Util::fmap(args.command_arguments, [&](auto&& arg) {
- return Input::check_and_get_package_spec(
- std::string(arg), default_triplet, COMMAND_STRUCTURE.example_text);
- });
-
- for (auto&& spec : specs)
- Input::check_triplet(spec.triplet(), paths);
- }
-
- const bool no_purge_was_passed = Util::Sets::contains(options.switches, OPTION_NO_PURGE);
- const bool purge_was_passed = Util::Sets::contains(options.switches, OPTION_PURGE);
- if (purge_was_passed && no_purge_was_passed)
- {
- System::print2(System::Color::error, "Error: cannot specify both --no-purge and --purge.\n");
- System::print2(COMMAND_STRUCTURE.example_text);
- Checks::exit_fail(VCPKG_LINE_INFO);
- }
- const Purge purge = to_purge(purge_was_passed || !no_purge_was_passed);
- const bool is_recursive = Util::Sets::contains(options.switches, OPTION_RECURSE);
- const bool dry_run = Util::Sets::contains(options.switches, OPTION_DRY_RUN);
-
- const std::vector<RemovePlanAction> remove_plan = Dependencies::create_remove_plan(specs, status_db);
- Checks::check_exit(VCPKG_LINE_INFO, !remove_plan.empty(), "Remove plan cannot be empty");
-
- std::map<RemovePlanType, std::vector<const RemovePlanAction*>> group_by_plan_type;
- Util::group_by(remove_plan, &group_by_plan_type, [](const RemovePlanAction& p) { return p.plan_type; });
- print_plan(group_by_plan_type);
-
- const bool has_non_user_requested_packages =
- Util::find_if(remove_plan, [](const RemovePlanAction& package) -> bool {
- return package.request_type != RequestType::USER_REQUESTED;
- }) != remove_plan.cend();
-
- if (has_non_user_requested_packages)
- {
- System::print2(System::Color::warning,
- "Additional packages (*) need to be removed to complete this operation.\n");
-
- if (!is_recursive)
- {
- System::print2(System::Color::warning,
- "If you are sure you want to remove them, run the command with the --recurse option\n");
- Checks::exit_fail(VCPKG_LINE_INFO);
- }
- }
-
- for (const auto& action : remove_plan)
- {
- if (action.plan_type == RemovePlanType::NOT_INSTALLED && action.request_type == RequestType::USER_REQUESTED)
- {
- // The user requested removing a package that was not installed. If the port is installed for another
- // triplet, warn the user that they may have meant that other package.
- for (const auto& package : status_db)
- {
- if (package->is_installed() && !package->package.is_feature() &&
- package->package.spec.name() == action.spec.name())
- {
- System::print2(
- System::Color::warning,
- "Another installed package matches the name of an unmatched request. Did you mean ",
- package->package.spec,
- "?\n");
- }
- }
- }
- }
-
- if (dry_run)
- {
- Checks::exit_success(VCPKG_LINE_INFO);
- }
-
- for (const RemovePlanAction& action : remove_plan)
- {
- perform_remove_plan_action(paths, action, purge, &status_db);
- }
-
- Checks::exit_success(VCPKG_LINE_INFO);
- }
-}
diff --git a/toolsrc/src/vcpkg/sourceparagraph.cpp b/toolsrc/src/vcpkg/sourceparagraph.cpp
deleted file mode 100644
index 52f72da94..000000000
--- a/toolsrc/src/vcpkg/sourceparagraph.cpp
+++ /dev/null
@@ -1,1389 +0,0 @@
-#include <vcpkg/base/checks.h>
-#include <vcpkg/base/expected.h>
-#include <vcpkg/base/jsonreader.h>
-#include <vcpkg/base/span.h>
-#include <vcpkg/base/system.debug.h>
-#include <vcpkg/base/system.print.h>
-#include <vcpkg/base/util.h>
-
-#include <vcpkg/packagespec.h>
-#include <vcpkg/platform-expression.h>
-#include <vcpkg/sourceparagraph.h>
-#include <vcpkg/triplet.h>
-#include <vcpkg/vcpkgcmdarguments.h>
-#include <vcpkg/versiondeserializers.h>
-
-namespace vcpkg
-{
- using namespace vcpkg::Parse;
-
- template<class Lhs, class Rhs>
- static bool paragraph_equal(const Lhs& lhs, const Rhs& rhs)
- {
- return std::equal(
- lhs.begin(), lhs.end(), rhs.begin(), rhs.end(), [](const std::string& lhs, const std::string& rhs) {
- return Strings::trim(StringView(lhs)) == Strings::trim(StringView(rhs));
- });
- }
-
- bool operator==(const SourceParagraph& lhs, const SourceParagraph& rhs)
- {
- if (lhs.name != rhs.name) return false;
- if (lhs.version != rhs.version) return false;
- if (lhs.version_scheme != rhs.version_scheme) return false;
- if (lhs.port_version != rhs.port_version) return false;
- if (!paragraph_equal(lhs.description, rhs.description)) return false;
- if (!paragraph_equal(lhs.maintainers, rhs.maintainers)) return false;
- if (lhs.homepage != rhs.homepage) return false;
- if (lhs.documentation != rhs.documentation) return false;
- if (lhs.dependencies != rhs.dependencies) return false;
- if (lhs.default_features != rhs.default_features) return false;
- if (lhs.license != rhs.license) return false;
-
- if (lhs.type != rhs.type) return false;
- if (!structurally_equal(lhs.supports_expression, rhs.supports_expression)) return false;
-
- if (lhs.extra_info != rhs.extra_info) return false;
-
- return true;
- }
-
- bool operator==(const FeatureParagraph& lhs, const FeatureParagraph& rhs)
- {
- if (lhs.name != rhs.name) return false;
- if (lhs.dependencies != rhs.dependencies) return false;
- if (!paragraph_equal(lhs.description, rhs.description)) return false;
- if (lhs.extra_info != rhs.extra_info) return false;
-
- return true;
- }
-
- bool operator==(const SourceControlFile& lhs, const SourceControlFile& rhs)
- {
- if (*lhs.core_paragraph != *rhs.core_paragraph) return false;
- return std::equal(lhs.feature_paragraphs.begin(),
- lhs.feature_paragraphs.end(),
- rhs.feature_paragraphs.begin(),
- rhs.feature_paragraphs.end(),
- [](const std::unique_ptr<FeatureParagraph>& lhs,
- const std::unique_ptr<FeatureParagraph>& rhs) { return *lhs == *rhs; });
- }
-
- namespace SourceParagraphFields
- {
- static const std::string BUILD_DEPENDS = "Build-Depends";
- static const std::string DEFAULT_FEATURES = "Default-Features";
- static const std::string DESCRIPTION = "Description";
- static const std::string FEATURE = "Feature";
- static const std::string MAINTAINERS = "Maintainer";
- static const std::string NAME = "Source";
- static const std::string VERSION = "Version";
- static const std::string PORT_VERSION = "Port-Version";
- static const std::string HOMEPAGE = "Homepage";
- static const std::string TYPE = "Type";
- static const std::string SUPPORTS = "Supports";
- }
-
- static Span<const StringView> get_list_of_valid_fields()
- {
- static const StringView valid_fields[] = {
- SourceParagraphFields::NAME,
- SourceParagraphFields::VERSION,
- SourceParagraphFields::PORT_VERSION,
- SourceParagraphFields::DESCRIPTION,
- SourceParagraphFields::MAINTAINERS,
- SourceParagraphFields::BUILD_DEPENDS,
- SourceParagraphFields::HOMEPAGE,
- SourceParagraphFields::TYPE,
- SourceParagraphFields::SUPPORTS,
- SourceParagraphFields::DEFAULT_FEATURES,
- };
-
- return valid_fields;
- }
-
- void print_error_message(Span<const std::unique_ptr<Parse::ParseControlErrorInfo>> error_info_list);
-
- std::string Type::to_string(const Type& t)
- {
- switch (t.type)
- {
- case Type::ALIAS: return "Alias";
- case Type::PORT: return "Port";
- default: return "Unknown";
- }
- }
-
- Type Type::from_string(const std::string& t)
- {
- if (t == "Alias") return Type{Type::ALIAS};
- if (t == "Port" || t.empty()) return Type{Type::PORT};
- return Type{Type::UNKNOWN};
- }
-
- bool operator==(const Type& lhs, const Type& rhs) { return lhs.type == rhs.type; }
- bool operator!=(const Type& lhs, const Type& rhs) { return !(lhs == rhs); }
-
- static void trim_all(std::vector<std::string>& arr)
- {
- for (auto& el : arr)
- {
- el = Strings::trim(std::move(el));
- }
- }
-
- namespace
- {
- constexpr static struct Canonicalize
- {
- struct FeatureLess
- {
- bool operator()(const std::unique_ptr<FeatureParagraph>& lhs,
- const std::unique_ptr<FeatureParagraph>& rhs) const
- {
- return (*this)(*lhs, *rhs);
- }
- bool operator()(const FeatureParagraph& lhs, const FeatureParagraph& rhs) const
- {
- return lhs.name < rhs.name;
- }
- };
- struct FeatureEqual
- {
- bool operator()(const std::unique_ptr<FeatureParagraph>& lhs,
- const std::unique_ptr<FeatureParagraph>& rhs) const
- {
- return (*this)(*lhs, *rhs);
- }
- bool operator()(const FeatureParagraph& lhs, const FeatureParagraph& rhs) const
- {
- return lhs.name == rhs.name;
- }
- };
-
- // assume canonicalized feature list
- struct DependencyLess
- {
- bool operator()(const std::unique_ptr<Dependency>& lhs, const std::unique_ptr<Dependency>& rhs) const
- {
- return (*this)(*lhs, *rhs);
- }
- bool operator()(const Dependency& lhs, const Dependency& rhs) const
- {
- auto cmp = lhs.name.compare(rhs.name);
- if (cmp < 0) return true;
- if (cmp > 0) return false;
-
- // same dependency name
-
- // order by platform string:
- auto platform_cmp = compare(lhs.platform, rhs.platform);
- if (platform_cmp < 0) return true;
- if (platform_cmp > 0) return false;
-
- // then order by features
- // smaller list first, then lexicographical
- if (lhs.features.size() < rhs.features.size()) return true;
- if (rhs.features.size() < lhs.features.size()) return false;
-
- // then finally order by feature list
- if (std::lexicographical_compare(
- lhs.features.begin(), lhs.features.end(), rhs.features.begin(), rhs.features.end()))
- {
- return true;
- }
- return false;
- }
- };
-
- template<class T>
- void operator()(std::unique_ptr<T>& ptr) const
- {
- (*this)(*ptr);
- }
-
- void operator()(Dependency& dep) const
- {
- std::sort(dep.features.begin(), dep.features.end());
- dep.extra_info.sort_keys();
- }
- void operator()(SourceParagraph& spgh) const
- {
- std::for_each(spgh.dependencies.begin(), spgh.dependencies.end(), *this);
- std::sort(spgh.dependencies.begin(), spgh.dependencies.end(), DependencyLess{});
-
- std::sort(spgh.default_features.begin(), spgh.default_features.end());
-
- spgh.extra_info.sort_keys();
- }
- void operator()(FeatureParagraph& fpgh) const
- {
- std::for_each(fpgh.dependencies.begin(), fpgh.dependencies.end(), *this);
- std::sort(fpgh.dependencies.begin(), fpgh.dependencies.end(), DependencyLess{});
-
- fpgh.extra_info.sort_keys();
- }
- [[nodiscard]] std::unique_ptr<ParseControlErrorInfo> operator()(SourceControlFile& scf) const
- {
- (*this)(*scf.core_paragraph);
- std::for_each(scf.feature_paragraphs.begin(), scf.feature_paragraphs.end(), *this);
- std::sort(scf.feature_paragraphs.begin(), scf.feature_paragraphs.end(), FeatureLess{});
-
- auto adjacent_equal =
- std::adjacent_find(scf.feature_paragraphs.begin(), scf.feature_paragraphs.end(), FeatureEqual{});
- if (adjacent_equal != scf.feature_paragraphs.end())
- {
- auto error_info = std::make_unique<ParseControlErrorInfo>();
- error_info->name = scf.core_paragraph->name;
- error_info->error = Strings::format(R"(Multiple features with the same name for port %s: %s
- This is invalid; please make certain that features have distinct names.)",
- scf.core_paragraph->name,
- (*adjacent_equal)->name);
- return error_info;
- }
- return nullptr;
- }
- } canonicalize{};
- }
-
- static ParseExpected<SourceParagraph> parse_source_paragraph(const std::string& origin, Paragraph&& fields)
- {
- ParagraphParser parser(std::move(fields));
-
- auto spgh = std::make_unique<SourceParagraph>();
-
- parser.required_field(SourceParagraphFields::NAME, spgh->name);
- parser.required_field(SourceParagraphFields::VERSION, spgh->version);
-
- auto pv_str = parser.optional_field(SourceParagraphFields::PORT_VERSION);
- if (!pv_str.empty())
- {
- auto pv_opt = Strings::strto<int>(pv_str);
- if (auto pv = pv_opt.get())
- {
- spgh->port_version = *pv;
- }
- else
- {
- parser.add_type_error(SourceParagraphFields::PORT_VERSION, "a non-negative integer");
- }
- }
-
- spgh->description = Strings::split(parser.optional_field(SourceParagraphFields::DESCRIPTION), '\n');
- trim_all(spgh->description);
-
- spgh->maintainers = Strings::split(parser.optional_field(SourceParagraphFields::MAINTAINERS), '\n');
- trim_all(spgh->maintainers);
-
- spgh->homepage = parser.optional_field(SourceParagraphFields::HOMEPAGE);
- TextRowCol textrowcol;
- std::string buf;
- parser.optional_field(SourceParagraphFields::BUILD_DEPENDS, {buf, textrowcol});
-
- auto maybe_dependencies = parse_dependencies_list(buf, origin, textrowcol);
- if (maybe_dependencies.has_value())
- {
- spgh->dependencies = maybe_dependencies.value_or_exit(VCPKG_LINE_INFO);
- }
- else
- {
- auto error_info = std::make_unique<ParseControlErrorInfo>();
- error_info->name = origin;
- error_info->error = maybe_dependencies.error();
- return error_info;
- }
-
- buf.clear();
- parser.optional_field(SourceParagraphFields::DEFAULT_FEATURES, {buf, textrowcol});
-
- auto maybe_default_features = parse_default_features_list(buf, origin, textrowcol);
- if (maybe_default_features.has_value())
- {
- spgh->default_features = maybe_default_features.value_or_exit(VCPKG_LINE_INFO);
- }
- else
- {
- auto error_info = std::make_unique<ParseControlErrorInfo>();
- error_info->name = origin;
- error_info->error = maybe_default_features.error();
- return error_info;
- }
-
- auto supports_expr = parser.optional_field(SourceParagraphFields::SUPPORTS);
- if (!supports_expr.empty())
- {
- auto maybe_expr = PlatformExpression::parse_platform_expression(
- supports_expr, PlatformExpression::MultipleBinaryOperators::Allow);
- if (auto expr = maybe_expr.get())
- {
- spgh->supports_expression = std::move(*expr);
- }
- else
- {
- parser.add_type_error(SourceParagraphFields::SUPPORTS, "a platform expression");
- }
- }
-
- spgh->type = Type::from_string(parser.optional_field(SourceParagraphFields::TYPE));
- auto err = parser.error_info(spgh->name.empty() ? origin : spgh->name);
- if (err)
- return err;
- else
- return spgh;
- }
-
- static ParseExpected<FeatureParagraph> parse_feature_paragraph(const std::string& origin, Paragraph&& fields)
- {
- ParagraphParser parser(std::move(fields));
-
- auto fpgh = std::make_unique<FeatureParagraph>();
-
- parser.required_field(SourceParagraphFields::FEATURE, fpgh->name);
- fpgh->description = Strings::split(parser.required_field(SourceParagraphFields::DESCRIPTION), '\n');
- trim_all(fpgh->description);
-
- auto maybe_dependencies =
- parse_dependencies_list(parser.optional_field(SourceParagraphFields::BUILD_DEPENDS), origin);
- if (maybe_dependencies.has_value())
- {
- fpgh->dependencies = maybe_dependencies.value_or_exit(VCPKG_LINE_INFO);
- }
- else
- {
- auto error_info = std::make_unique<ParseControlErrorInfo>();
- error_info->name = origin;
- error_info->error = maybe_dependencies.error();
- return error_info;
- }
-
- auto err = parser.error_info(fpgh->name.empty() ? origin : fpgh->name);
- if (err)
- return err;
- else
- return fpgh;
- }
-
- ParseExpected<SourceControlFile> SourceControlFile::parse_control_file(
- const std::string& origin, std::vector<Parse::Paragraph>&& control_paragraphs)
- {
- if (control_paragraphs.size() == 0)
- {
- auto ret = std::make_unique<Parse::ParseControlErrorInfo>();
- ret->name = origin;
- return ret;
- }
-
- auto control_file = std::make_unique<SourceControlFile>();
-
- auto maybe_source = parse_source_paragraph(origin, std::move(control_paragraphs.front()));
- if (const auto source = maybe_source.get())
- control_file->core_paragraph = std::move(*source);
- else
- return std::move(maybe_source).error();
-
- control_paragraphs.erase(control_paragraphs.begin());
-
- for (auto&& feature_pgh : control_paragraphs)
- {
- auto maybe_feature = parse_feature_paragraph(origin, std::move(feature_pgh));
- if (const auto feature = maybe_feature.get())
- control_file->feature_paragraphs.emplace_back(std::move(*feature));
- else
- return std::move(maybe_feature).error();
- }
-
- if (auto maybe_error = canonicalize(*control_file))
- {
- return std::move(maybe_error);
- }
- return control_file;
- }
-
- struct PlatformExprDeserializer : Json::IDeserializer<PlatformExpression::Expr>
- {
- virtual StringView type_name() const override { return "a platform expression"; }
-
- virtual Optional<PlatformExpression::Expr> visit_string(Json::Reader& r, StringView sv) override
- {
- auto opt =
- PlatformExpression::parse_platform_expression(sv, PlatformExpression::MultipleBinaryOperators::Deny);
- if (auto res = opt.get())
- {
- return std::move(*res);
- }
- else
- {
- r.add_generic_error(type_name(), opt.error());
- return PlatformExpression::Expr::Empty();
- }
- }
-
- static PlatformExprDeserializer instance;
- };
- PlatformExprDeserializer PlatformExprDeserializer::instance;
-
- struct DependencyDeserializer : Json::IDeserializer<Dependency>
- {
- virtual StringView type_name() const override { return "a dependency"; }
-
- constexpr static StringLiteral NAME = "name";
- constexpr static StringLiteral FEATURES = "features";
- constexpr static StringLiteral DEFAULT_FEATURES = "default-features";
- constexpr static StringLiteral PLATFORM = "platform";
- constexpr static StringLiteral VERSION_GE = "version>=";
-
- virtual Span<const StringView> valid_fields() const override
- {
- static const StringView t[] = {
- NAME,
- FEATURES,
- DEFAULT_FEATURES,
- PLATFORM,
- VERSION_GE,
- };
-
- return t;
- }
-
- virtual Optional<Dependency> visit_string(Json::Reader& r, StringView sv) override
- {
- if (!Json::PackageNameDeserializer::is_package_name(sv))
- {
- r.add_generic_error(type_name(),
- "must be lowercase alphanumeric+hyphens, split with periods, and not reserved");
- }
-
- Dependency dep;
- dep.name = sv.to_string();
- return dep;
- }
-
- virtual Optional<Dependency> visit_object(Json::Reader& r, const Json::Object& obj) override
- {
- Dependency dep;
-
- for (const auto& el : obj)
- {
- if (Strings::starts_with(el.first, "$"))
- {
- dep.extra_info.insert_or_replace(el.first.to_string(), el.second);
- }
- }
-
- static Json::ArrayDeserializer<Json::IdentifierDeserializer> arr_id_d{"an array of identifiers"};
-
- r.required_object_field(type_name(), obj, NAME, dep.name, Json::PackageNameDeserializer::instance);
- r.optional_object_field(obj, FEATURES, dep.features, arr_id_d);
-
- bool default_features = true;
- r.optional_object_field(obj, DEFAULT_FEATURES, default_features, Json::BooleanDeserializer::instance);
- if (!default_features)
- {
- dep.features.push_back("core");
- }
-
- r.optional_object_field(obj, PLATFORM, dep.platform, PlatformExprDeserializer::instance);
-
- static Json::StringDeserializer version_deserializer("a version");
-
- auto has_ge_constraint =
- r.optional_object_field(obj, VERSION_GE, dep.constraint.value, version_deserializer);
-
- if (has_ge_constraint)
- {
- dep.constraint.type = Versions::Constraint::Type::Minimum;
- auto h = dep.constraint.value.find('#');
- if (h != std::string::npos)
- {
- auto opt = Strings::strto<int>(dep.constraint.value.c_str() + h + 1);
- auto v = opt.get();
- if (v && *v > 0)
- {
- dep.constraint.port_version = *v;
- }
- else
- {
- r.add_generic_error(type_name(),
- "embedded port-version ('#') in the primary "
- "constraint (\"",
- VERSION_GE,
- "\") must be a positive integer");
- }
- dep.constraint.value.erase(h);
- }
- }
-
- return dep;
- }
-
- static DependencyDeserializer instance;
- };
- DependencyDeserializer DependencyDeserializer::instance;
-
- struct DependencyArrayDeserializer final : Json::IDeserializer<std::vector<Dependency>>
- {
- virtual StringView type_name() const override { return "an array of dependencies"; }
-
- virtual Optional<std::vector<Dependency>> visit_array(Json::Reader& r, const Json::Array& arr) override
- {
- return r.array_elements(arr, DependencyDeserializer::instance);
- }
-
- static DependencyArrayDeserializer instance;
- };
- DependencyArrayDeserializer DependencyArrayDeserializer::instance;
-
- constexpr StringLiteral DependencyDeserializer::NAME;
- constexpr StringLiteral DependencyDeserializer::FEATURES;
- constexpr StringLiteral DependencyDeserializer::DEFAULT_FEATURES;
- constexpr StringLiteral DependencyDeserializer::PLATFORM;
- constexpr StringLiteral DependencyDeserializer::VERSION_GE;
-
- struct DependencyOverrideDeserializer : Json::IDeserializer<DependencyOverride>
- {
- virtual StringView type_name() const override { return "an override"; }
-
- constexpr static StringLiteral NAME = "name";
-
- virtual Span<const StringView> valid_fields() const override
- {
- static const StringView u[] = {NAME};
- static const auto t = Util::Vectors::concat<StringView>(schemed_deserializer_fields(), u);
- return t;
- }
-
- static void visit_impl(StringView type_name,
- Json::Reader& r,
- const Json::Object& obj,
- std::string& name,
- std::string& version,
- Versions::Scheme& version_scheme,
- int& port_version)
- {
- r.required_object_field(type_name, obj, NAME, name, Json::IdentifierDeserializer::instance);
-
- auto schemed_version = visit_required_schemed_deserializer(type_name, r, obj);
- version = schemed_version.versiont.text();
- version_scheme = schemed_version.scheme;
- port_version = schemed_version.versiont.port_version();
- }
-
- virtual Optional<DependencyOverride> visit_object(Json::Reader& r, const Json::Object& obj) override
- {
- DependencyOverride dep;
-
- for (const auto& el : obj)
- {
- if (Strings::starts_with(el.first, "$"))
- {
- dep.extra_info.insert_or_replace(el.first.to_string(), el.second);
- }
- }
-
- visit_impl(type_name(), r, obj, dep.name, dep.version, dep.version_scheme, dep.port_version);
-
- return dep;
- }
-
- static DependencyOverrideDeserializer instance;
- };
- DependencyOverrideDeserializer DependencyOverrideDeserializer::instance;
-
- constexpr StringLiteral DependencyOverrideDeserializer::NAME;
-
- // reasoning for these two distinct types -- FeatureDeserializer and ArrayFeatureDeserializer:
- // `"features"` may be defined in one of two ways:
- // - An array of feature objects, which contains the `"name"` field
- // - An object mapping feature names to feature objects, which do not contain the `"name"` field
- // `ArrayFeatureDeserializer` is used for the former, `FeatureDeserializer` is used for the latter.
- struct FeatureDeserializer : Json::IDeserializer<std::unique_ptr<FeatureParagraph>>
- {
- virtual StringView type_name() const override { return "a feature"; }
-
- constexpr static StringLiteral NAME = "name";
- constexpr static StringLiteral DESCRIPTION = "description";
- constexpr static StringLiteral DEPENDENCIES = "dependencies";
-
- virtual Span<const StringView> valid_fields() const override
- {
- static const StringView t[] = {DESCRIPTION, DEPENDENCIES};
- return t;
- }
-
- virtual Optional<std::unique_ptr<FeatureParagraph>> visit_object(Json::Reader& r,
- const Json::Object& obj) override
- {
- auto feature = std::make_unique<FeatureParagraph>();
- for (const auto& el : obj)
- {
- if (Strings::starts_with(el.first, "$"))
- {
- feature->extra_info.insert_or_replace(el.first.to_string(), el.second);
- }
- }
-
- r.required_object_field(
- type_name(), obj, DESCRIPTION, feature->description, Json::ParagraphDeserializer::instance);
- r.optional_object_field(obj, DEPENDENCIES, feature->dependencies, DependencyArrayDeserializer::instance);
-
- return std::move(feature);
- }
- static FeatureDeserializer instance;
- };
- FeatureDeserializer FeatureDeserializer::instance;
- constexpr StringLiteral FeatureDeserializer::NAME;
- constexpr StringLiteral FeatureDeserializer::DESCRIPTION;
- constexpr StringLiteral FeatureDeserializer::DEPENDENCIES;
-
- struct ArrayFeatureDeserializer : Json::IDeserializer<std::unique_ptr<FeatureParagraph>>
- {
- virtual StringView type_name() const override { return "a feature"; }
-
- virtual Span<const StringView> valid_fields() const override
- {
- static const StringView t[] = {
- FeatureDeserializer::NAME,
- FeatureDeserializer::DESCRIPTION,
- FeatureDeserializer::DEPENDENCIES,
- };
- return t;
- }
-
- virtual Optional<std::unique_ptr<FeatureParagraph>> visit_object(Json::Reader& r,
- const Json::Object& obj) override
- {
- std::string name;
- r.required_object_field(
- type_name(), obj, FeatureDeserializer::NAME, name, Json::IdentifierDeserializer::instance);
- auto opt = FeatureDeserializer::instance.visit_object(r, obj);
- if (auto p = opt.get())
- {
- p->get()->name = std::move(name);
- }
- return opt;
- }
-
- static Json::ArrayDeserializer<ArrayFeatureDeserializer> array_instance;
- };
- Json::ArrayDeserializer<ArrayFeatureDeserializer> ArrayFeatureDeserializer::array_instance{
- "an array of feature objects"};
-
- struct FeaturesFieldDeserializer : Json::IDeserializer<std::vector<std::unique_ptr<FeatureParagraph>>>
- {
- virtual StringView type_name() const override { return "a set of features"; }
-
- virtual Span<const StringView> valid_fields() const override { return {}; }
-
- virtual Optional<std::vector<std::unique_ptr<FeatureParagraph>>> visit_array(Json::Reader& r,
- const Json::Array& arr) override
- {
- return ArrayFeatureDeserializer::array_instance.visit_array(r, arr);
- }
-
- virtual Optional<std::vector<std::unique_ptr<FeatureParagraph>>> visit_object(Json::Reader& r,
- const Json::Object& obj) override
- {
- std::vector<std::unique_ptr<FeatureParagraph>> res;
- std::vector<std::string> extra_fields;
-
- for (const auto& pr : obj)
- {
- if (!Json::IdentifierDeserializer::is_ident(pr.first))
- {
- r.add_generic_error(type_name(),
- "unexpected field '",
- pr.first,
- "': must be lowercase alphanumeric+hyphens and not reserved");
- continue;
- }
- std::unique_ptr<FeatureParagraph> v;
- r.visit_in_key(pr.second, pr.first, v, FeatureDeserializer::instance);
- if (v)
- {
- v->name = pr.first.to_string();
- res.push_back(std::move(v));
- }
- }
-
- return std::move(res);
- }
-
- static FeaturesFieldDeserializer instance;
- };
- FeaturesFieldDeserializer FeaturesFieldDeserializer::instance;
-
- static constexpr StringView EXPRESSION_WORDS[] = {
- "WITH",
- "AND",
- "OR",
- };
- static constexpr StringView VALID_LICENSES[] =
-#include "spdx-licenses.inc"
- ;
- static constexpr StringView VALID_EXCEPTIONS[] =
-#include "spdx-licenses.inc"
- ;
-
- // We "parse" this so that we can add actual license parsing at some point in the future
- // without breaking anyone
- struct LicenseExpressionDeserializer : Json::IDeserializer<std::string>
- {
- virtual StringView type_name() const override { return "an SPDX license expression"; }
-
- enum class Mode
- {
- ExpectExpression,
- ExpectContinue,
- ExpectException,
- };
-
- virtual Optional<std::string> visit_string(Json::Reader&, StringView sv) override
- {
- Mode mode = Mode::ExpectExpression;
- size_t open_parens = 0;
- std::string current_word;
-
- const auto check_current_word = [&current_word, &mode] {
- if (current_word.empty())
- {
- return true;
- }
-
- Span<const StringView> valid_ids;
- bool case_sensitive = false;
- switch (mode)
- {
- case Mode::ExpectExpression:
- valid_ids = VALID_LICENSES;
- mode = Mode::ExpectContinue;
- // a single + is allowed on the end of licenses
- if (current_word.back() == '+')
- {
- current_word.pop_back();
- }
- break;
- case Mode::ExpectContinue:
- valid_ids = EXPRESSION_WORDS;
- mode = Mode::ExpectExpression;
- case_sensitive = true;
- break;
- case Mode::ExpectException:
- valid_ids = VALID_EXCEPTIONS;
- mode = Mode::ExpectContinue;
- break;
- }
-
- const auto equal = [&](StringView sv) {
- if (case_sensitive)
- {
- return sv == current_word;
- }
- else
- {
- return Strings::case_insensitive_ascii_equals(sv, current_word);
- }
- };
-
- if (std::find_if(valid_ids.begin(), valid_ids.end(), equal) == valid_ids.end())
- {
- return false;
- }
-
- if (current_word == "WITH")
- {
- mode = Mode::ExpectException;
- }
-
- current_word.clear();
- return true;
- };
-
- for (const auto& ch : sv)
- {
- if (ch == ' ' || ch == '\t')
- {
- if (!check_current_word())
- {
- return nullopt;
- }
- }
- else if (ch == '(')
- {
- if (!check_current_word())
- {
- return nullopt;
- }
- if (mode != Mode::ExpectExpression)
- {
- return nullopt;
- }
- ++open_parens;
- }
- else if (ch == ')')
- {
- if (!check_current_word())
- {
- return nullopt;
- }
- if (mode != Mode::ExpectContinue)
- {
- return nullopt;
- }
- if (open_parens == 0)
- {
- return nullopt;
- }
- --open_parens;
- }
- else
- {
- current_word.push_back(ch);
- }
- }
-
- if (!check_current_word())
- {
- return nullopt;
- }
- else
- {
- return sv.to_string();
- }
- }
-
- static LicenseExpressionDeserializer instance;
- };
- LicenseExpressionDeserializer LicenseExpressionDeserializer::instance;
-
- struct BaselineCommitDeserializer final : Json::IDeserializer<std::string>
- {
- virtual StringView type_name() const override { return "a vcpkg repository commit"; }
-
- virtual Optional<std::string> visit_string(Json::Reader&, StringView s) override
- {
- // We allow non-sha strings here to allow the core vcpkg code to provide better error
- // messages including the current git commit
- return s.to_string();
- }
-
- static BaselineCommitDeserializer instance;
- };
- BaselineCommitDeserializer BaselineCommitDeserializer::instance;
-
- struct ManifestDeserializer : Json::IDeserializer<std::unique_ptr<SourceControlFile>>
- {
- virtual StringView type_name() const override { return "a manifest"; }
-
- constexpr static StringLiteral NAME = "name";
- constexpr static StringLiteral MAINTAINERS = "maintainers";
- constexpr static StringLiteral DESCRIPTION = "description";
- constexpr static StringLiteral HOMEPAGE = "homepage";
- constexpr static StringLiteral DOCUMENTATION = "documentation";
- constexpr static StringLiteral LICENSE = "license";
- constexpr static StringLiteral DEPENDENCIES = "dependencies";
- constexpr static StringLiteral DEV_DEPENDENCIES = "dev-dependencies";
- constexpr static StringLiteral FEATURES = "features";
- constexpr static StringLiteral DEFAULT_FEATURES = "default-features";
- constexpr static StringLiteral SUPPORTS = "supports";
- constexpr static StringLiteral OVERRIDES = "overrides";
- constexpr static StringLiteral BUILTIN_BASELINE = "builtin-baseline";
-
- virtual Span<const StringView> valid_fields() const override
- {
- static const StringView u[] = {
- NAME,
- MAINTAINERS,
- DESCRIPTION,
- HOMEPAGE,
- DOCUMENTATION,
- LICENSE,
- DEPENDENCIES,
- DEV_DEPENDENCIES,
- FEATURES,
- DEFAULT_FEATURES,
- SUPPORTS,
- OVERRIDES,
- BUILTIN_BASELINE,
- };
- static const auto t = Util::Vectors::concat<StringView>(schemed_deserializer_fields(), u);
-
- return t;
- }
-
- virtual Optional<std::unique_ptr<SourceControlFile>> visit_object(Json::Reader& r,
- const Json::Object& obj) override
- {
- auto control_file = std::make_unique<SourceControlFile>();
- control_file->core_paragraph = std::make_unique<SourceParagraph>();
-
- auto& spgh = control_file->core_paragraph;
- spgh->type = Type{Type::PORT};
-
- for (const auto& el : obj)
- {
- if (Strings::starts_with(el.first, "$"))
- {
- spgh->extra_info.insert_or_replace(el.first.to_string(), el.second);
- }
- }
-
- static Json::StringDeserializer url_deserializer{"a url"};
-
- constexpr static StringView inner_type_name = "vcpkg.json";
- DependencyOverrideDeserializer::visit_impl(
- inner_type_name, r, obj, spgh->name, spgh->version, spgh->version_scheme, spgh->port_version);
-
- r.optional_object_field(obj, MAINTAINERS, spgh->maintainers, Json::ParagraphDeserializer::instance);
- r.optional_object_field(obj, DESCRIPTION, spgh->description, Json::ParagraphDeserializer::instance);
- r.optional_object_field(obj, HOMEPAGE, spgh->homepage, url_deserializer);
- r.optional_object_field(obj, DOCUMENTATION, spgh->documentation, url_deserializer);
- r.optional_object_field(obj, LICENSE, spgh->license, LicenseExpressionDeserializer::instance);
- r.optional_object_field(obj, DEPENDENCIES, spgh->dependencies, DependencyArrayDeserializer::instance);
- static Json::ArrayDeserializer<DependencyOverrideDeserializer> overrides_deserializer{
- "an array of overrides"};
- r.optional_object_field(obj, OVERRIDES, spgh->overrides, overrides_deserializer);
-
- if (obj.contains(DEV_DEPENDENCIES))
- {
- r.add_generic_error(type_name(), DEV_DEPENDENCIES, " are not yet supported");
- }
- std::string baseline;
- if (r.optional_object_field(obj, BUILTIN_BASELINE, baseline, BaselineCommitDeserializer::instance))
- {
- spgh->builtin_baseline = std::move(baseline);
- }
-
- r.optional_object_field(obj, SUPPORTS, spgh->supports_expression, PlatformExprDeserializer::instance);
-
- r.optional_object_field(
- obj, DEFAULT_FEATURES, spgh->default_features, Json::IdentifierArrayDeserializer::instance);
-
- r.optional_object_field(
- obj, FEATURES, control_file->feature_paragraphs, FeaturesFieldDeserializer::instance);
-
- if (auto maybe_error = canonicalize(*control_file))
- {
- Checks::exit_with_message(VCPKG_LINE_INFO, maybe_error->error);
- }
- return std::move(control_file);
- }
-
- static ManifestDeserializer instance;
- };
- ManifestDeserializer ManifestDeserializer::instance;
-
- constexpr StringLiteral ManifestDeserializer::NAME;
- constexpr StringLiteral ManifestDeserializer::MAINTAINERS;
- constexpr StringLiteral ManifestDeserializer::DESCRIPTION;
- constexpr StringLiteral ManifestDeserializer::HOMEPAGE;
- constexpr StringLiteral ManifestDeserializer::DOCUMENTATION;
- constexpr StringLiteral ManifestDeserializer::LICENSE;
- constexpr StringLiteral ManifestDeserializer::DEPENDENCIES;
- constexpr StringLiteral ManifestDeserializer::DEV_DEPENDENCIES;
- constexpr StringLiteral ManifestDeserializer::FEATURES;
- constexpr StringLiteral ManifestDeserializer::DEFAULT_FEATURES;
- constexpr StringLiteral ManifestDeserializer::SUPPORTS;
- constexpr StringLiteral ManifestDeserializer::OVERRIDES;
-
- SourceControlFile SourceControlFile::clone() const
- {
- SourceControlFile ret;
- ret.core_paragraph = std::make_unique<SourceParagraph>(*core_paragraph);
- for (const auto& feat_ptr : feature_paragraphs)
- {
- ret.feature_paragraphs.push_back(std::make_unique<FeatureParagraph>(*feat_ptr));
- }
- return ret;
- }
-
- Parse::ParseExpected<SourceControlFile> SourceControlFile::parse_manifest_object(const std::string& origin,
- const Json::Object& manifest)
- {
- Json::Reader reader;
-
- auto res = reader.visit(manifest, ManifestDeserializer::instance);
-
- if (!reader.errors().empty())
- {
- auto err = std::make_unique<ParseControlErrorInfo>();
- err->name = origin;
- err->other_errors = std::move(reader.errors());
- return std::move(err);
- }
- else if (auto p = res.get())
- {
- return std::move(*p);
- }
- else
- {
- Checks::unreachable(VCPKG_LINE_INFO);
- }
- }
-
- Optional<std::string> SourceControlFile::check_against_feature_flags(const fs::path& origin,
- const FeatureFlagSettings& flags) const
- {
- static constexpr StringLiteral s_extended_help = "See `vcpkg help versioning` for more information.";
- if (!flags.versions)
- {
- auto check_deps = [&](View<Dependency> deps) -> Optional<std::string> {
- for (auto&& dep : deps)
- {
- if (dep.constraint.type != Versions::Constraint::Type::None)
- {
- return Strings::concat(
- fs::u8string(origin),
- " was rejected because it uses constraints and the `",
- VcpkgCmdArguments::VERSIONS_FEATURE,
- "` feature flag is disabled.\nThis can be fixed by removing uses of \"version>=\".\n",
- s_extended_help);
- }
- }
- return nullopt;
- };
-
- if (auto r = check_deps(core_paragraph->dependencies)) return r;
-
- for (auto&& fpgh : feature_paragraphs)
- {
- if (auto r = check_deps(fpgh->dependencies)) return r;
- }
-
- if (core_paragraph->overrides.size() != 0)
- {
- return Strings::concat(fs::u8string(origin),
- " was rejected because it uses overrides and the `",
- VcpkgCmdArguments::VERSIONS_FEATURE,
- "` feature flag is disabled.\nThis can be fixed by removing \"overrides\".\n",
- s_extended_help);
- }
-
- if (core_paragraph->builtin_baseline.has_value())
- {
- return Strings::concat(
- fs::u8string(origin),
- " was rejected because it uses builtin-baseline and the `",
- VcpkgCmdArguments::VERSIONS_FEATURE,
- "` feature flag is disabled.\nThis can be fixed by removing \"builtin-baseline\".\n",
- s_extended_help);
- }
- }
- return nullopt;
- }
-
- Parse::ParseExpected<SourceControlFile> SourceControlFile::parse_manifest_file(const fs::path& path_to_manifest,
- const Json::Object& manifest)
- {
- return parse_manifest_object(fs::u8string(path_to_manifest), manifest);
- }
-
- void print_error_message(Span<const std::unique_ptr<Parse::ParseControlErrorInfo>> error_info_list)
- {
- Checks::check_exit(VCPKG_LINE_INFO, error_info_list.size() > 0);
-
- for (auto&& error_info : error_info_list)
- {
- Checks::check_exit(VCPKG_LINE_INFO, error_info != nullptr);
- if (!error_info->error.empty())
- {
- System::print2(
- System::Color::error, "Error: while loading ", error_info->name, ":\n", error_info->error, '\n');
- }
-
- if (!error_info->other_errors.empty())
- {
- System::print2(System::Color::error, "Errors occurred while parsing ", error_info->name, "\n");
- for (auto&& msg : error_info->other_errors)
- System::print2(" ", msg, '\n');
- }
- }
-
- bool have_remaining_fields = false;
- for (auto&& error_info : error_info_list)
- {
- if (!error_info->extra_fields.empty())
- {
- System::print2(System::Color::error,
- "Error: There are invalid fields in the control or manifest file of ",
- error_info->name,
- '\n');
- System::print2("The following fields were not expected:\n");
-
- for (const auto& pr : error_info->extra_fields)
- {
- System::print2(" In ", pr.first, ": ", Strings::join(", ", pr.second), "\n");
- }
- have_remaining_fields = true;
- }
- }
-
- if (have_remaining_fields)
- {
- System::print2("This is the list of valid fields for CONTROL files (case-sensitive): \n\n ",
- Strings::join("\n ", get_list_of_valid_fields()),
- "\n\n");
-#if defined(_WIN32)
- auto bootstrap = ".\\bootstrap-vcpkg.bat";
-#else
- auto bootstrap = "./bootstrap-vcpkg.sh";
-#endif
- System::printf("You may need to update the vcpkg binary; try running %s to update.\n\n", bootstrap);
- }
-
- for (auto&& error_info : error_info_list)
- {
- if (!error_info->missing_fields.empty())
- {
- System::print2(System::Color::error,
- "Error: There are missing fields in the control file of ",
- error_info->name,
- '\n');
- System::print2("The following fields were missing:\n");
- for (const auto& pr : error_info->missing_fields)
- {
- System::print2(" In ", pr.first, ": ", Strings::join(", ", pr.second), "\n");
- }
- }
- }
-
- for (auto&& error_info : error_info_list)
- {
- if (!error_info->expected_types.empty())
- {
- System::print2(System::Color::error,
- "Error: There are invalid field types in the CONTROL or manifest file of ",
- error_info->name,
- '\n');
- System::print2("The following fields had the wrong types:\n\n");
-
- for (const auto& pr : error_info->expected_types)
- {
- System::printf(" %s was expected to be %s\n", pr.first, pr.second);
- }
- System::print2("\n");
- }
- }
- }
-
- Optional<const FeatureParagraph&> SourceControlFile::find_feature(const std::string& featurename) const
- {
- auto it = Util::find_if(feature_paragraphs,
- [&](const std::unique_ptr<FeatureParagraph>& p) { return p->name == featurename; });
- if (it != feature_paragraphs.end())
- return **it;
- else
- return nullopt;
- }
- Optional<const std::vector<Dependency>&> SourceControlFile::find_dependencies_for_feature(
- const std::string& featurename) const
- {
- if (featurename == "core")
- {
- return core_paragraph->dependencies;
- }
- else if (auto p_feature = find_feature(featurename).get())
- return p_feature->dependencies;
- else
- return nullopt;
- }
-
- std::vector<FullPackageSpec> filter_dependencies(const std::vector<vcpkg::Dependency>& deps,
- Triplet t,
- const std::unordered_map<std::string, std::string>& cmake_vars)
- {
- std::vector<FullPackageSpec> ret;
- for (auto&& dep : deps)
- {
- if (dep.platform.evaluate(cmake_vars))
- {
- ret.emplace_back(FullPackageSpec({dep.name, t}, dep.features));
- }
- }
- return ret;
- }
-
- static bool is_dependency_trivial(const Dependency& dep)
- {
- return dep.features.empty() && dep.platform.is_empty() && dep.extra_info.is_empty() &&
- dep.constraint.type == Versions::Constraint::Type::None;
- }
-
- static Json::Object serialize_manifest_impl(const SourceControlFile& scf, bool debug)
- {
- auto serialize_paragraph =
- [&](Json::Object& obj, StringLiteral name, const std::vector<std::string>& pgh, bool always = false) {
- if (!debug)
- {
- if (pgh.empty())
- {
- if (always)
- {
- obj.insert(name, Json::Array());
- }
- return;
- }
- if (pgh.size() == 1)
- {
- obj.insert(name, Json::Value::string(pgh.front()));
- return;
- }
- }
-
- auto& arr = obj.insert(name, Json::Array());
- for (const auto& s : pgh)
- {
- arr.push_back(Json::Value::string(s));
- }
- };
- auto serialize_optional_array =
- [&](Json::Object& obj, StringLiteral name, const std::vector<std::string>& pgh) {
- if (pgh.empty() && !debug) return;
-
- auto& arr = obj.insert(name, Json::Array());
- for (const auto& s : pgh)
- {
- arr.push_back(Json::Value::string(s));
- }
- };
- auto serialize_optional_string = [&](Json::Object& obj, StringLiteral name, const std::string& s) {
- if (!s.empty() || debug)
- {
- obj.insert(name, Json::Value::string(s));
- }
- };
- auto serialize_dependency = [&](Json::Array& arr, const Dependency& dep) {
- if (is_dependency_trivial(dep))
- {
- arr.push_back(Json::Value::string(dep.name));
- }
- else
- {
- auto& dep_obj = arr.push_back(Json::Object());
- for (const auto& el : dep.extra_info)
- {
- dep_obj.insert(el.first.to_string(), el.second);
- }
-
- dep_obj.insert(DependencyDeserializer::NAME, Json::Value::string(dep.name));
-
- auto features_copy = dep.features;
- auto core_it = std::find(features_copy.begin(), features_copy.end(), "core");
- if (core_it != features_copy.end())
- {
- dep_obj.insert(DependencyDeserializer::DEFAULT_FEATURES, Json::Value::boolean(false));
- features_copy.erase(core_it);
- }
-
- serialize_optional_array(dep_obj, DependencyDeserializer::FEATURES, features_copy);
- serialize_optional_string(dep_obj, DependencyDeserializer::PLATFORM, to_string(dep.platform));
- if (dep.constraint.type == Versions::Constraint::Type::Minimum)
- {
- auto s = dep.constraint.value;
- if (dep.constraint.port_version != 0)
- {
- Strings::append(s, '#', dep.constraint.port_version);
- }
- dep_obj.insert(DependencyDeserializer::VERSION_GE, Json::Value::string(std::move(s)));
- }
- }
- };
-
- auto serialize_override = [&](Json::Array& arr, const DependencyOverride& dep) {
- auto& dep_obj = arr.push_back(Json::Object());
- for (const auto& el : dep.extra_info)
- {
- dep_obj.insert(el.first.to_string(), el.second);
- }
-
- dep_obj.insert(DependencyOverrideDeserializer::NAME, Json::Value::string(dep.name));
-
- serialize_schemed_version(dep_obj, dep.version_scheme, dep.version, dep.port_version);
- };
-
- Json::Object obj;
-
- for (const auto& el : scf.core_paragraph->extra_info)
- {
- obj.insert(el.first.to_string(), el.second);
- }
-
- obj.insert(ManifestDeserializer::NAME, Json::Value::string(scf.core_paragraph->name));
-
- serialize_schemed_version(obj,
- scf.core_paragraph->version_scheme,
- scf.core_paragraph->version,
- scf.core_paragraph->port_version,
- debug);
-
- serialize_paragraph(obj, ManifestDeserializer::MAINTAINERS, scf.core_paragraph->maintainers);
- serialize_paragraph(obj, ManifestDeserializer::DESCRIPTION, scf.core_paragraph->description);
-
- serialize_optional_string(obj, ManifestDeserializer::HOMEPAGE, scf.core_paragraph->homepage);
- serialize_optional_string(obj, ManifestDeserializer::DOCUMENTATION, scf.core_paragraph->documentation);
- serialize_optional_string(obj, ManifestDeserializer::LICENSE, scf.core_paragraph->license);
- serialize_optional_string(
- obj, ManifestDeserializer::SUPPORTS, to_string(scf.core_paragraph->supports_expression));
- if (scf.core_paragraph->builtin_baseline.has_value())
- {
- obj.insert(ManifestDeserializer::BUILTIN_BASELINE,
- Json::Value::string(scf.core_paragraph->builtin_baseline.value_or_exit(VCPKG_LINE_INFO)));
- }
-
- if (!scf.core_paragraph->dependencies.empty() || debug)
- {
- auto& deps = obj.insert(ManifestDeserializer::DEPENDENCIES, Json::Array());
-
- for (const auto& dep : scf.core_paragraph->dependencies)
- {
- serialize_dependency(deps, dep);
- }
- }
-
- serialize_optional_array(obj, ManifestDeserializer::DEFAULT_FEATURES, scf.core_paragraph->default_features);
-
- if (!scf.feature_paragraphs.empty() || debug)
- {
- auto& map = obj.insert(ManifestDeserializer::FEATURES, Json::Object());
- for (const auto& feature : scf.feature_paragraphs)
- {
- auto& feature_obj = map.insert(feature->name, Json::Object());
- for (const auto& el : feature->extra_info)
- {
- feature_obj.insert(el.first.to_string(), el.second);
- }
-
- serialize_paragraph(feature_obj, FeatureDeserializer::DESCRIPTION, feature->description, true);
-
- if (!feature->dependencies.empty() || debug)
- {
- auto& deps = feature_obj.insert(FeatureDeserializer::DEPENDENCIES, Json::Array());
- for (const auto& dep : feature->dependencies)
- {
- serialize_dependency(deps, dep);
- }
- }
- }
- }
-
- if (!scf.core_paragraph->overrides.empty() || debug)
- {
- auto& overrides = obj.insert(ManifestDeserializer::OVERRIDES, Json::Array());
-
- for (const auto& over : scf.core_paragraph->overrides)
- {
- serialize_override(overrides, over);
- }
- }
-
- if (debug)
- {
- obj.insert("TYPE", Json::Value::string(Type::to_string(scf.core_paragraph->type)));
- }
-
- return obj;
- }
-
- Json::Object serialize_debug_manifest(const SourceControlFile& scf) { return serialize_manifest_impl(scf, true); }
-
- Json::Object serialize_manifest(const SourceControlFile& scf) { return serialize_manifest_impl(scf, false); }
-}
diff --git a/toolsrc/src/vcpkg/spdx-exceptions.inc b/toolsrc/src/vcpkg/spdx-exceptions.inc
deleted file mode 100644
index c6ef04b70..000000000
--- a/toolsrc/src/vcpkg/spdx-exceptions.inc
+++ /dev/null
@@ -1,45 +0,0 @@
-// Data downloaded from https://raw.githubusercontent.com/spdx/license-list-data/a3cab5c04eaf399ea8ee07ac69c749a9ad6a3f17/json/exceptions.json
-// Generated by scripts/Generate-SpdxLicenseList.ps1
-{
- "GCC-exception-2.0",
- "openvpn-openssl-exception",
- "Nokia-Qt-exception-1.1",
- "GPL-3.0-linking-exception",
- "Fawkes-Runtime-exception",
- "u-boot-exception-2.0",
- "PS-or-PDF-font-exception-20170817",
- "gnu-javamail-exception",
- "LGPL-3.0-linking-exception",
- "DigiRule-FOSS-exception",
- "LLVM-exception",
- "Linux-syscall-note",
- "GPL-3.0-linking-source-exception",
- "Qwt-exception-1.0",
- "389-exception",
- "mif-exception",
- "eCos-exception-2.0",
- "CLISP-exception-2.0",
- "Bison-exception-2.2",
- "Libtool-exception",
- "LZMA-exception",
- "OpenJDK-assembly-exception-1.0",
- "Font-exception-2.0",
- "OCaml-LGPL-linking-exception",
- "GCC-exception-3.1",
- "Bootloader-exception",
- "SHL-2.0",
- "Classpath-exception-2.0",
- "Swift-exception",
- "Autoconf-exception-2.0",
- "FLTK-exception",
- "freertos-exception-2.0",
- "Universal-FOSS-exception-1.0",
- "WxWindows-exception-3.1",
- "OCCT-exception-1.0",
- "Autoconf-exception-3.0",
- "i2p-gpl-java-exception",
- "GPL-CC-1.0",
- "Qt-LGPL-exception-1.1",
- "SHL-2.1",
- "Qt-GPL-exception-1.0",
-}
diff --git a/toolsrc/src/vcpkg/spdx-licenses.inc b/toolsrc/src/vcpkg/spdx-licenses.inc
deleted file mode 100644
index ad3523934..000000000
--- a/toolsrc/src/vcpkg/spdx-licenses.inc
+++ /dev/null
@@ -1,426 +0,0 @@
-// Data downloaded from https://raw.githubusercontent.com/spdx/license-list-data/a3cab5c04eaf399ea8ee07ac69c749a9ad6a3f17/json/licenses.json
-// Generated by scripts/Generate-SpdxLicenseList.ps1
-{
- "0BSD",
- "AAL",
- "ADSL",
- "AFL-1.1",
- "AFL-1.2",
- "AFL-2.0",
- "AFL-2.1",
- "AFL-3.0",
- "AGPL-1.0",
- "AGPL-1.0-only",
- "AGPL-1.0-or-later",
- "AGPL-3.0",
- "AGPL-3.0-only",
- "AGPL-3.0-or-later",
- "AMDPLPA",
- "AML",
- "AMPAS",
- "ANTLR-PD",
- "APAFML",
- "APL-1.0",
- "APSL-1.0",
- "APSL-1.1",
- "APSL-1.2",
- "APSL-2.0",
- "Abstyles",
- "Adobe-2006",
- "Adobe-Glyph",
- "Afmparse",
- "Aladdin",
- "Apache-1.0",
- "Apache-1.1",
- "Apache-2.0",
- "Artistic-1.0",
- "Artistic-1.0-Perl",
- "Artistic-1.0-cl8",
- "Artistic-2.0",
- "BSD-1-Clause",
- "BSD-2-Clause",
- "BSD-2-Clause-FreeBSD",
- "BSD-2-Clause-NetBSD",
- "BSD-2-Clause-Patent",
- "BSD-3-Clause",
- "BSD-3-Clause-Attribution",
- "BSD-3-Clause-Clear",
- "BSD-3-Clause-LBNL",
- "BSD-3-Clause-No-Nuclear-License",
- "BSD-3-Clause-No-Nuclear-License-2014",
- "BSD-3-Clause-No-Nuclear-Warranty",
- "BSD-3-Clause-Open-MPI",
- "BSD-4-Clause",
- "BSD-4-Clause-UC",
- "BSD-Protection",
- "BSD-Source-Code",
- "BSL-1.0",
- "Bahyph",
- "Barr",
- "Beerware",
- "BitTorrent-1.0",
- "BitTorrent-1.1",
- "BlueOak-1.0.0",
- "Borceux",
- "CAL-1.0",
- "CAL-1.0-Combined-Work-Exception",
- "CATOSL-1.1",
- "CC-BY-1.0",
- "CC-BY-2.0",
- "CC-BY-2.5",
- "CC-BY-3.0",
- "CC-BY-4.0",
- "CC-BY-NC-1.0",
- "CC-BY-NC-2.0",
- "CC-BY-NC-2.5",
- "CC-BY-NC-3.0",
- "CC-BY-NC-4.0",
- "CC-BY-NC-ND-1.0",
- "CC-BY-NC-ND-2.0",
- "CC-BY-NC-ND-2.5",
- "CC-BY-NC-ND-3.0",
- "CC-BY-NC-ND-4.0",
- "CC-BY-NC-SA-1.0",
- "CC-BY-NC-SA-2.0",
- "CC-BY-NC-SA-2.5",
- "CC-BY-NC-SA-3.0",
- "CC-BY-NC-SA-4.0",
- "CC-BY-ND-1.0",
- "CC-BY-ND-2.0",
- "CC-BY-ND-2.5",
- "CC-BY-ND-3.0",
- "CC-BY-ND-4.0",
- "CC-BY-SA-1.0",
- "CC-BY-SA-2.0",
- "CC-BY-SA-2.5",
- "CC-BY-SA-3.0",
- "CC-BY-SA-4.0",
- "CC-PDDC",
- "CC0-1.0",
- "CDDL-1.0",
- "CDDL-1.1",
- "CDLA-Permissive-1.0",
- "CDLA-Sharing-1.0",
- "CECILL-1.0",
- "CECILL-1.1",
- "CECILL-2.0",
- "CECILL-2.1",
- "CECILL-B",
- "CECILL-C",
- "CERN-OHL-1.1",
- "CERN-OHL-1.2",
- "CERN-OHL-P-2.0",
- "CERN-OHL-S-2.0",
- "CERN-OHL-W-2.0",
- "CNRI-Jython",
- "CNRI-Python",
- "CNRI-Python-GPL-Compatible",
- "CPAL-1.0",
- "CPL-1.0",
- "CPOL-1.02",
- "CUA-OPL-1.0",
- "Caldera",
- "ClArtistic",
- "Condor-1.1",
- "Crossword",
- "CrystalStacker",
- "Cube",
- "D-FSL-1.0",
- "DOC",
- "DSDP",
- "Dotseqn",
- "ECL-1.0",
- "ECL-2.0",
- "EFL-1.0",
- "EFL-2.0",
- "EPL-1.0",
- "EPL-2.0",
- "EUDatagrid",
- "EUPL-1.0",
- "EUPL-1.1",
- "EUPL-1.2",
- "Entessa",
- "ErlPL-1.1",
- "Eurosym",
- "FSFAP",
- "FSFUL",
- "FSFULLR",
- "FTL",
- "Fair",
- "Frameworx-1.0",
- "FreeImage",
- "GFDL-1.1",
- "GFDL-1.1-only",
- "GFDL-1.1-or-later",
- "GFDL-1.2",
- "GFDL-1.2-only",
- "GFDL-1.2-or-later",
- "GFDL-1.3",
- "GFDL-1.3-only",
- "GFDL-1.3-or-later",
- "GL2PS",
- "GPL-1.0",
- "GPL-1.0+",
- "GPL-1.0-only",
- "GPL-1.0-or-later",
- "GPL-2.0",
- "GPL-2.0+",
- "GPL-2.0-only",
- "GPL-2.0-or-later",
- "GPL-2.0-with-GCC-exception",
- "GPL-2.0-with-autoconf-exception",
- "GPL-2.0-with-bison-exception",
- "GPL-2.0-with-classpath-exception",
- "GPL-2.0-with-font-exception",
- "GPL-3.0",
- "GPL-3.0+",
- "GPL-3.0-only",
- "GPL-3.0-or-later",
- "GPL-3.0-with-GCC-exception",
- "GPL-3.0-with-autoconf-exception",
- "Giftware",
- "Glide",
- "Glulxe",
- "HPND",
- "HPND-sell-variant",
- "HaskellReport",
- "Hippocratic-2.1",
- "IBM-pibs",
- "ICU",
- "IJG",
- "IPA",
- "IPL-1.0",
- "ISC",
- "ImageMagick",
- "Imlib2",
- "Info-ZIP",
- "Intel",
- "Intel-ACPI",
- "Interbase-1.0",
- "JPNIC",
- "JSON",
- "JasPer-2.0",
- "LAL-1.2",
- "LAL-1.3",
- "LGPL-2.0",
- "LGPL-2.0+",
- "LGPL-2.0-only",
- "LGPL-2.0-or-later",
- "LGPL-2.1",
- "LGPL-2.1+",
- "LGPL-2.1-only",
- "LGPL-2.1-or-later",
- "LGPL-3.0",
- "LGPL-3.0+",
- "LGPL-3.0-only",
- "LGPL-3.0-or-later",
- "LGPLLR",
- "LPL-1.0",
- "LPL-1.02",
- "LPPL-1.0",
- "LPPL-1.1",
- "LPPL-1.2",
- "LPPL-1.3a",
- "LPPL-1.3c",
- "Latex2e",
- "Leptonica",
- "LiLiQ-P-1.1",
- "LiLiQ-R-1.1",
- "LiLiQ-Rplus-1.1",
- "Libpng",
- "Linux-OpenIB",
- "MIT",
- "MIT-0",
- "MIT-CMU",
- "MIT-advertising",
- "MIT-enna",
- "MIT-feh",
- "MITNFA",
- "MPL-1.0",
- "MPL-1.1",
- "MPL-2.0",
- "MPL-2.0-no-copyleft-exception",
- "MS-PL",
- "MS-RL",
- "MTLL",
- "MakeIndex",
- "MirOS",
- "Motosoto",
- "MulanPSL-1.0",
- "MulanPSL-2.0",
- "Multics",
- "Mup",
- "NASA-1.3",
- "NBPL-1.0",
- "NCGL-UK-2.0",
- "NCSA",
- "NGPL",
- "NLOD-1.0",
- "NLPL",
- "NOSL",
- "NPL-1.0",
- "NPL-1.1",
- "NPOSL-3.0",
- "NRL",
- "NTP",
- "NTP-0",
- "Naumen",
- "Net-SNMP",
- "NetCDF",
- "Newsletr",
- "Nokia",
- "Noweb",
- "Nunit",
- "O-UDA-1.0",
- "OCCT-PL",
- "OCLC-2.0",
- "ODC-By-1.0",
- "ODbL-1.0",
- "OFL-1.0",
- "OFL-1.0-RFN",
- "OFL-1.0-no-RFN",
- "OFL-1.1",
- "OFL-1.1-RFN",
- "OFL-1.1-no-RFN",
- "OGC-1.0",
- "OGL-Canada-2.0",
- "OGL-UK-1.0",
- "OGL-UK-2.0",
- "OGL-UK-3.0",
- "OGTSL",
- "OLDAP-1.1",
- "OLDAP-1.2",
- "OLDAP-1.3",
- "OLDAP-1.4",
- "OLDAP-2.0",
- "OLDAP-2.0.1",
- "OLDAP-2.1",
- "OLDAP-2.2",
- "OLDAP-2.2.1",
- "OLDAP-2.2.2",
- "OLDAP-2.3",
- "OLDAP-2.4",
- "OLDAP-2.5",
- "OLDAP-2.6",
- "OLDAP-2.7",
- "OLDAP-2.8",
- "OML",
- "OPL-1.0",
- "OSET-PL-2.1",
- "OSL-1.0",
- "OSL-1.1",
- "OSL-2.0",
- "OSL-2.1",
- "OSL-3.0",
- "OpenSSL",
- "PDDL-1.0",
- "PHP-3.0",
- "PHP-3.01",
- "PSF-2.0",
- "Parity-6.0.0",
- "Parity-7.0.0",
- "Plexus",
- "PolyForm-Noncommercial-1.0.0",
- "PolyForm-Small-Business-1.0.0",
- "PostgreSQL",
- "Python-2.0",
- "QPL-1.0",
- "Qhull",
- "RHeCos-1.1",
- "RPL-1.1",
- "RPL-1.5",
- "RPSL-1.0",
- "RSA-MD",
- "RSCPL",
- "Rdisc",
- "Ruby",
- "SAX-PD",
- "SCEA",
- "SGI-B-1.0",
- "SGI-B-1.1",
- "SGI-B-2.0",
- "SHL-0.5",
- "SHL-0.51",
- "SISSL",
- "SISSL-1.2",
- "SMLNJ",
- "SMPPL",
- "SNIA",
- "SPL-1.0",
- "SSH-OpenSSH",
- "SSH-short",
- "SSPL-1.0",
- "SWL",
- "Saxpath",
- "Sendmail",
- "Sendmail-8.23",
- "SimPL-2.0",
- "Sleepycat",
- "Spencer-86",
- "Spencer-94",
- "Spencer-99",
- "StandardML-NJ",
- "SugarCRM-1.1.3",
- "TAPR-OHL-1.0",
- "TCL",
- "TCP-wrappers",
- "TMate",
- "TORQUE-1.1",
- "TOSL",
- "TU-Berlin-1.0",
- "TU-Berlin-2.0",
- "UCL-1.0",
- "UPL-1.0",
- "Unicode-DFS-2015",
- "Unicode-DFS-2016",
- "Unicode-TOU",
- "Unlicense",
- "VOSTROM",
- "VSL-1.0",
- "Vim",
- "W3C",
- "W3C-19980720",
- "W3C-20150513",
- "WTFPL",
- "Watcom-1.0",
- "Wsuipa",
- "X11",
- "XFree86-1.1",
- "XSkat",
- "Xerox",
- "Xnet",
- "YPL-1.0",
- "YPL-1.1",
- "ZPL-1.1",
- "ZPL-2.0",
- "ZPL-2.1",
- "Zed",
- "Zend-2.0",
- "Zimbra-1.3",
- "Zimbra-1.4",
- "Zlib",
- "blessing",
- "bzip2-1.0.5",
- "bzip2-1.0.6",
- "copyleft-next-0.3.0",
- "copyleft-next-0.3.1",
- "curl",
- "diffmark",
- "dvipdfm",
- "eCos-2.0",
- "eGenix",
- "etalab-2.0",
- "gSOAP-1.3b",
- "gnuplot",
- "iMatix",
- "libpng-2.0",
- "libselinux-1.0",
- "libtiff",
- "mpich2",
- "psfrag",
- "psutils",
- "wxWindows",
- "xinetd",
- "xpp",
- "zlib-acknowledgement",
-}
diff --git a/toolsrc/src/vcpkg/statusparagraph.cpp b/toolsrc/src/vcpkg/statusparagraph.cpp
deleted file mode 100644
index ff3700d4b..000000000
--- a/toolsrc/src/vcpkg/statusparagraph.cpp
+++ /dev/null
@@ -1,121 +0,0 @@
-#include <vcpkg/base/util.h>
-
-#include <vcpkg/statusparagraph.h>
-
-using namespace vcpkg::Parse;
-
-namespace vcpkg
-{
- namespace BinaryParagraphRequiredField
- {
- static const std::string STATUS = "Status";
- }
-
- StatusParagraph::StatusParagraph() noexcept : want(Want::ERROR_STATE), state(InstallState::ERROR_STATE) { }
-
- void serialize(const StatusParagraph& pgh, std::string& out_str)
- {
- serialize(pgh.package, out_str);
- out_str.append("Status: ")
- .append(to_string(pgh.want))
- .append(" ok ")
- .append(to_string(pgh.state))
- .push_back('\n');
- }
-
- StatusParagraph::StatusParagraph(Parse::Paragraph&& fields)
- : want(Want::ERROR_STATE), state(InstallState::ERROR_STATE)
- {
- auto status_it = fields.find(BinaryParagraphRequiredField::STATUS);
- Checks::check_maybe_upgrade(
- VCPKG_LINE_INFO, status_it != fields.end(), "Expected 'Status' field in status paragraph");
- std::string status_field = std::move(status_it->second.first);
- fields.erase(status_it);
-
- this->package = BinaryParagraph(std::move(fields));
-
- auto b = status_field.begin();
- const auto mark = b;
- const auto e = status_field.end();
-
- // Todo: improve error handling
- while (b != e && *b != ' ')
- ++b;
-
- want = [](const std::string& text) {
- if (text == "unknown") return Want::UNKNOWN;
- if (text == "install") return Want::INSTALL;
- if (text == "hold") return Want::HOLD;
- if (text == "deinstall") return Want::DEINSTALL;
- if (text == "purge") return Want::PURGE;
- return Want::ERROR_STATE;
- }(std::string(mark, b));
-
- if (std::distance(b, e) < 4) return;
- b += 4;
-
- state = [](const std::string& text) {
- if (text == "not-installed") return InstallState::NOT_INSTALLED;
- if (text == "installed") return InstallState::INSTALLED;
- if (text == "half-installed") return InstallState::HALF_INSTALLED;
- return InstallState::ERROR_STATE;
- }(std::string(b, e));
- }
-
- std::string to_string(InstallState f)
- {
- switch (f)
- {
- case InstallState::HALF_INSTALLED: return "half-installed";
- case InstallState::INSTALLED: return "installed";
- case InstallState::NOT_INSTALLED: return "not-installed";
- default: return "error";
- }
- }
-
- std::string to_string(Want f)
- {
- switch (f)
- {
- case Want::DEINSTALL: return "deinstall";
- case Want::HOLD: return "hold";
- case Want::INSTALL: return "install";
- case Want::PURGE: return "purge";
- case Want::UNKNOWN: return "unknown";
- default: return "error";
- }
- }
-
- std::map<std::string, std::vector<FeatureSpec>> InstalledPackageView::feature_dependencies() const
- {
- auto extract_deps = [&](const std::string& name) { return FeatureSpec{{name, spec().triplet()}, "core"}; };
-
- std::map<std::string, std::vector<FeatureSpec>> deps;
-
- deps.emplace("core", Util::fmap(core->package.dependencies, extract_deps));
-
- for (const StatusParagraph* const& feature : features)
- deps.emplace(feature->package.feature, Util::fmap(feature->package.dependencies, extract_deps));
-
- return deps;
- }
-
- std::vector<PackageSpec> InstalledPackageView::dependencies() const
- {
- // accumulate all features in installed dependencies
- // Todo: make this unneeded by collapsing all package dependencies into the core package
- std::vector<std::string> deps;
- for (auto&& feature : features)
- for (auto&& dep : feature->package.dependencies)
- deps.push_back(dep);
-
- // Add the core paragraph dependencies to the list
- for (auto&& dep : core->package.dependencies)
- deps.push_back(dep);
-
- Util::erase_remove_if(deps, [&](const std::string& pspec) { return pspec == spec().name(); });
- Util::sort_unique_erase(deps);
-
- return PackageSpec::to_package_specs(deps, spec().triplet());
- }
-}
diff --git a/toolsrc/src/vcpkg/statusparagraphs.cpp b/toolsrc/src/vcpkg/statusparagraphs.cpp
deleted file mode 100644
index ba1815224..000000000
--- a/toolsrc/src/vcpkg/statusparagraphs.cpp
+++ /dev/null
@@ -1,186 +0,0 @@
-#include <vcpkg/base/checks.h>
-
-#include <vcpkg/install.h>
-#include <vcpkg/statusparagraphs.h>
-#include <vcpkg/vcpkgpaths.h>
-
-namespace vcpkg
-{
- StatusParagraphs::StatusParagraphs() = default;
-
- StatusParagraphs::StatusParagraphs(std::vector<std::unique_ptr<StatusParagraph>>&& ps) : paragraphs(std::move(ps))
- {
- }
-
- std::vector<std::unique_ptr<StatusParagraph>*> StatusParagraphs::find_all(const std::string& name, Triplet triplet)
- {
- std::vector<std::unique_ptr<StatusParagraph>*> spghs;
- for (auto&& p : *this)
- {
- if (p->package.spec.name() == name && p->package.spec.triplet() == triplet)
- {
- if (p->package.is_feature())
- spghs.emplace_back(&p);
- else
- spghs.emplace(spghs.begin(), &p);
- }
- }
- return spghs;
- }
-
- Optional<InstalledPackageView> StatusParagraphs::get_installed_package_view(const PackageSpec& spec) const
- {
- InstalledPackageView ipv;
- for (auto&& p : *this)
- {
- if (p->package.spec.name() == spec.name() && p->package.spec.triplet() == spec.triplet() &&
- p->is_installed())
- {
- if (p->package.is_feature())
- {
- ipv.features.emplace_back(p.get());
- }
- else
- {
- Checks::check_exit(VCPKG_LINE_INFO, ipv.core == nullptr);
- ipv.core = p.get();
- }
- }
- }
- if (ipv.core != nullptr)
- return ipv;
- else
- return nullopt;
- }
-
- StatusParagraphs::iterator StatusParagraphs::find(const std::string& name,
- Triplet triplet,
- const std::string& feature)
- {
- if (feature == "core")
- {
- // The core feature maps to .feature is empty
- return find(name, triplet, {});
- }
- return std::find_if(begin(), end(), [&](const std::unique_ptr<StatusParagraph>& pgh) {
- const PackageSpec& spec = pgh->package.spec;
- return spec.name() == name && spec.triplet() == triplet && pgh->package.feature == feature;
- });
- }
-
- StatusParagraphs::const_iterator StatusParagraphs::find(const std::string& name,
- Triplet triplet,
- const std::string& feature) const
- {
- if (feature == "core")
- {
- // The core feature maps to .feature == ""
- return find(name, triplet, "");
- }
- return std::find_if(begin(), end(), [&](const std::unique_ptr<StatusParagraph>& pgh) {
- const PackageSpec& spec = pgh->package.spec;
- return spec.name() == name && spec.triplet() == triplet && pgh->package.feature == feature;
- });
- }
-
- StatusParagraphs::const_iterator StatusParagraphs::find_installed(const PackageSpec& spec) const
- {
- auto it = find(spec);
- if (it != end() && (*it)->is_installed())
- {
- return it;
- }
- else
- {
- return end();
- }
- }
-
- StatusParagraphs::const_iterator StatusParagraphs::find_installed(const FeatureSpec& spec) const
- {
- auto it = find(spec);
- if (it != end() && (*it)->is_installed())
- {
- return it;
- }
- else
- {
- return end();
- }
- }
-
- bool vcpkg::StatusParagraphs::is_installed(const PackageSpec& spec) const
- {
- auto it = find(spec);
- return it != end() && (*it)->is_installed();
- }
-
- bool vcpkg::StatusParagraphs::is_installed(const FeatureSpec& spec) const
- {
- auto it = find(spec);
- return it != end() && (*it)->is_installed();
- }
-
- StatusParagraphs::iterator StatusParagraphs::insert(std::unique_ptr<StatusParagraph> pgh)
- {
- Checks::check_exit(VCPKG_LINE_INFO, pgh != nullptr, "Inserted null paragraph");
- const PackageSpec& spec = pgh->package.spec;
- const auto ptr = find(spec.name(), spec.triplet(), pgh->package.feature);
- if (ptr == end())
- {
- paragraphs.push_back(std::move(pgh));
- return paragraphs.rbegin();
- }
-
- // consume data from provided pgh.
- **ptr = std::move(*pgh);
- return ptr;
- }
-
- void serialize(const StatusParagraphs& pghs, std::string& out_str)
- {
- for (auto& pgh : pghs.paragraphs)
- {
- serialize(*pgh, out_str);
- out_str.push_back('\n');
- }
- }
-
- Json::Value serialize_ipv(const InstalledPackageView& ipv, const VcpkgPaths& paths)
- {
- const auto& fs = paths.get_filesystem();
- Json::Object iobj;
- iobj.insert("version-string", Json::Value::string(ipv.core->package.version));
- iobj.insert("port-version", Json::Value::integer(ipv.core->package.port_version));
- iobj.insert("triplet", Json::Value::string(ipv.spec().triplet().to_string()));
- iobj.insert("abi", Json::Value::string(ipv.core->package.abi));
- Json::Array deps;
- for (auto&& dep : ipv.dependencies())
- deps.push_back(Json::Value::string(dep.to_string()));
- if (deps.size() != 0)
- {
- iobj.insert("dependencies", std::move(deps));
- }
- Json::Array features;
- for (auto&& feature : ipv.features)
- {
- features.push_back(Json::Value::string(feature->package.feature));
- }
- if (features.size() != 0)
- {
- iobj.insert("features", std::move(features));
- }
- auto usage = Install::get_cmake_usage(ipv.core->package, paths);
- if (!usage.message.empty())
- {
- iobj.insert("usage", Json::Value::string(std::move(usage.message)));
- }
- auto owns_files = fs.read_lines(paths.listfile_path(ipv.core->package)).value_or_exit(VCPKG_LINE_INFO);
- Json::Array owns;
- for (auto&& owns_file : owns_files)
- owns.push_back(Json::Value::string(std::move(owns_file)));
-
- iobj.insert("owns", std::move(owns));
- return Json::Value::object(std::move(iobj));
- }
-}
diff --git a/toolsrc/src/vcpkg/tools.cpp b/toolsrc/src/vcpkg/tools.cpp
deleted file mode 100644
index eaef5a6b9..000000000
--- a/toolsrc/src/vcpkg/tools.cpp
+++ /dev/null
@@ -1,615 +0,0 @@
-#include <vcpkg/base/checks.h>
-#include <vcpkg/base/downloads.h>
-#include <vcpkg/base/files.h>
-#include <vcpkg/base/optional.h>
-#include <vcpkg/base/strings.h>
-#include <vcpkg/base/stringview.h>
-#include <vcpkg/base/system.print.h>
-#include <vcpkg/base/system.process.h>
-#include <vcpkg/base/util.h>
-
-#include <vcpkg/archives.h>
-#include <vcpkg/tools.h>
-#include <vcpkg/vcpkgpaths.h>
-
-namespace vcpkg
-{
- struct ToolData
- {
- std::array<int, 3> version;
- fs::path exe_path;
- std::string url;
- fs::path download_path;
- bool is_archive;
- fs::path tool_dir_path;
- std::string sha512;
- };
-
- static Optional<std::array<int, 3>> parse_version_string(const std::string& version_as_string)
- {
- static const std::regex RE(R"###((\d+)\.(\d+)\.(\d+))###");
-
- std::match_results<std::string::const_iterator> match;
- const auto found = std::regex_search(version_as_string, match, RE);
- if (!found)
- {
- return {};
- }
-
- const int d1 = atoi(match[1].str().c_str());
- const int d2 = atoi(match[2].str().c_str());
- const int d3 = atoi(match[3].str().c_str());
- const std::array<int, 3> result = {d1, d2, d3};
- return result;
- }
-
- static ExpectedT<ToolData, std::string> parse_tool_data_from_xml(const VcpkgPaths& paths, const std::string& tool)
- {
-#if defined(_WIN32)
- static constexpr StringLiteral OS_STRING = "windows";
-#elif defined(__APPLE__)
- static constexpr StringLiteral OS_STRING = "osx";
-#elif defined(__linux__)
- static constexpr StringLiteral OS_STRING = "linux";
-#elif defined(__FreeBSD__)
- static constexpr StringLiteral OS_STRING = "freebsd";
-#elif defined(__OpenBSD__)
- static constexpr StringLiteral OS_STRING = "openbsd";
-#else
- return std::string("operating system is unknown");
-#endif
-
-#if defined(_WIN32) || defined(__APPLE__) || defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__)
- static const std::string XML_VERSION = "2";
- static const fs::path XML_PATH = paths.scripts / "vcpkgTools.xml";
- static const std::regex XML_VERSION_REGEX{R"###(<tools[\s]+version="([^"]+)">)###"};
- static const std::string XML = paths.get_filesystem().read_contents(XML_PATH).value_or_exit(VCPKG_LINE_INFO);
- std::smatch match_xml_version;
- const bool has_xml_version = std::regex_search(XML.cbegin(), XML.cend(), match_xml_version, XML_VERSION_REGEX);
- Checks::check_exit(VCPKG_LINE_INFO,
- has_xml_version,
- R"(Could not find <tools version="%s"> in %s)",
- XML_VERSION,
- fs::u8string(XML_PATH));
- Checks::check_exit(VCPKG_LINE_INFO,
- XML_VERSION == match_xml_version[1],
- "Expected %s version: [%s], but was [%s]. Please re-run bootstrap-vcpkg.",
- fs::u8string(XML_PATH),
- XML_VERSION,
- match_xml_version[1]);
-
- const std::regex tool_regex{Strings::format(R"###(<tool[\s]+name="%s"[\s]+os="%s">)###", tool, OS_STRING)};
- std::smatch match_tool_entry;
- const bool has_tool_entry = std::regex_search(XML.cbegin(), XML.cend(), match_tool_entry, tool_regex);
- if (!has_tool_entry)
- {
- StringLiteral add_info = "";
- if (tool == "mono")
- {
-#if defined(__APPLE__)
- add_info = " (brew install mono)";
-#else
- add_info = " (e.g. sudo apt install mono-complete). Ubuntu 18.04 users may "
- "need a newer version of mono, available at https://www.mono-project.com/download/stable/";
-#endif
- }
- return Strings::format("Could not automatically acquire %s because there is no entry in %s for os=%s. You "
- "may be able to install %s via your system package manager%s.",
- tool,
- fs::u8string(XML_PATH),
- OS_STRING,
- tool,
- add_info);
- }
-
- const std::string tool_data =
- Strings::find_exactly_one_enclosed(XML, match_tool_entry[0].str(), "</tool>").to_string();
- const std::string version_as_string =
- Strings::find_exactly_one_enclosed(tool_data, "<version>", "</version>").to_string();
- const std::string exe_relative_path =
- Strings::find_exactly_one_enclosed(tool_data, "<exeRelativePath>", "</exeRelativePath>").to_string();
- const std::string url = Strings::find_exactly_one_enclosed(tool_data, "<url>", "</url>").to_string();
- const std::string sha512 = Strings::find_exactly_one_enclosed(tool_data, "<sha512>", "</sha512>").to_string();
- auto archive_name = Strings::find_at_most_one_enclosed(tool_data, "<archiveName>", "</archiveName>");
-
- const Optional<std::array<int, 3>> version = parse_version_string(version_as_string);
- Checks::check_exit(VCPKG_LINE_INFO,
- version.has_value(),
- "Could not parse version for tool %s. Version string was: %s",
- tool,
- version_as_string);
-
- const std::string tool_dir_name = Strings::format("%s-%s-%s", tool, version_as_string, OS_STRING);
- const fs::path tool_dir_path = paths.tools / tool_dir_name;
- const fs::path exe_path = tool_dir_path / exe_relative_path;
- fs::path download_path;
- if (auto a = archive_name.get())
- {
- download_path = paths.downloads / fs::u8path(a->to_string());
- }
- else
- {
- download_path = paths.downloads / fs::u8path(Strings::concat(sha512.substr(0, 8), '-', exe_relative_path));
- }
-
- return ToolData{*version.get(), exe_path, url, download_path, archive_name.has_value(), tool_dir_path, sha512};
-#endif
- }
-
- struct PathAndVersion
- {
- fs::path path;
- std::string version;
- };
-
- struct ToolProvider
- {
- virtual const std::string& tool_data_name() const = 0;
- virtual const std::string& exe_stem() const = 0;
- virtual std::array<int, 3> default_min_version() const = 0;
-
- virtual void add_special_paths(std::vector<fs::path>& out_candidate_paths) const { (void)out_candidate_paths; }
- virtual ExpectedS<std::string> get_version(const VcpkgPaths& paths, const fs::path& path_to_exe) const = 0;
- };
-
- static Optional<PathAndVersion> find_first_with_sufficient_version(const VcpkgPaths& paths,
- const ToolProvider& tool_provider,
- const std::vector<fs::path>& candidates,
- const std::array<int, 3>& expected_version)
- {
- const auto& fs = paths.get_filesystem();
- for (auto&& candidate : candidates)
- {
- if (!fs.exists(candidate)) continue;
- auto maybe_version = tool_provider.get_version(paths, candidate);
- const auto version = maybe_version.get();
- if (!version) continue;
- const auto parsed_version = parse_version_string(*version);
- if (!parsed_version) continue;
- auto& actual_version = *parsed_version.get();
- const auto version_acceptable =
- actual_version[0] > expected_version[0] ||
- (actual_version[0] == expected_version[0] && actual_version[1] > expected_version[1]) ||
- (actual_version[0] == expected_version[0] && actual_version[1] == expected_version[1] &&
- actual_version[2] >= expected_version[2]);
- if (!version_acceptable) continue;
-
- return PathAndVersion{candidate, *version};
- }
-
- return nullopt;
- }
-
- static fs::path fetch_tool(const VcpkgPaths& paths, const std::string& tool_name, const ToolData& tool_data)
- {
- const std::array<int, 3>& version = tool_data.version;
- const std::string version_as_string = Strings::format("%d.%d.%d", version[0], version[1], version[2]);
- Checks::check_maybe_upgrade(VCPKG_LINE_INFO,
- !tool_data.url.empty(),
- "A suitable version of %s was not found (required v%s) and unable to automatically "
- "download a portable one. Please install a newer version of %s.",
- tool_name,
- version_as_string,
- tool_name);
- System::printf("A suitable version of %s was not found (required v%s). Downloading portable %s v%s...\n",
- tool_name,
- version_as_string,
- tool_name,
- version_as_string);
- auto& fs = paths.get_filesystem();
- if (!fs.exists(tool_data.download_path))
- {
- System::print2("Downloading ", tool_name, "...\n");
- System::print2(" ", tool_data.url, " -> ", fs::u8string(tool_data.download_path), "\n");
- Downloads::download_file(fs, tool_data.url, tool_data.download_path, tool_data.sha512);
- }
- else
- {
- Downloads::verify_downloaded_file_hash(fs, tool_data.url, tool_data.download_path, tool_data.sha512);
- }
-
- if (tool_data.is_archive)
- {
- System::print2("Extracting ", tool_name, "...\n");
- Archives::extract_archive(paths, tool_data.download_path, tool_data.tool_dir_path);
- }
- else
- {
- std::error_code ec;
- fs.create_directories(tool_data.exe_path.parent_path(), ec);
- fs.rename(tool_data.download_path, tool_data.exe_path, ec);
- }
-
- Checks::check_exit(VCPKG_LINE_INFO,
- fs.exists(tool_data.exe_path),
- "Expected %s to exist after fetching",
- fs::u8string(tool_data.exe_path));
-
- return tool_data.exe_path;
- }
-
- static PathAndVersion fetch_tool(const VcpkgPaths& paths,
- const ToolProvider& tool_provider,
- const ToolData& tool_data)
- {
- auto downloaded_path = fetch_tool(paths, tool_provider.tool_data_name(), tool_data);
- auto downloaded_version = tool_provider.get_version(paths, downloaded_path).value_or_exit(VCPKG_LINE_INFO);
- return {std::move(downloaded_path), std::move(downloaded_version)};
- }
-
- static PathAndVersion get_path(const VcpkgPaths& paths, const ToolProvider& tool)
- {
- auto& fs = paths.get_filesystem();
-
- std::array<int, 3> min_version = tool.default_min_version();
-
- std::vector<fs::path> candidate_paths;
- auto maybe_tool_data = parse_tool_data_from_xml(paths, tool.tool_data_name());
- if (auto tool_data = maybe_tool_data.get())
- {
- candidate_paths.push_back(tool_data->exe_path);
- min_version = tool_data->version;
- }
-
- auto& exe_stem = tool.exe_stem();
- if (!exe_stem.empty())
- {
- auto paths_from_path = fs.find_from_PATH(exe_stem);
- candidate_paths.insert(candidate_paths.end(), paths_from_path.cbegin(), paths_from_path.cend());
- }
-
- tool.add_special_paths(candidate_paths);
-
- const auto maybe_path = find_first_with_sufficient_version(paths, tool, candidate_paths, min_version);
- if (const auto p = maybe_path.get())
- {
- return *p;
- }
- if (auto tool_data = maybe_tool_data.get())
- {
- return fetch_tool(paths, tool, *tool_data);
- }
-
- Checks::exit_maybe_upgrade(VCPKG_LINE_INFO, maybe_tool_data.error());
- }
-
- struct CMakeProvider : ToolProvider
- {
- std::string m_exe = "cmake";
-
- virtual const std::string& tool_data_name() const override { return m_exe; }
- virtual const std::string& exe_stem() const override { return m_exe; }
- virtual std::array<int, 3> default_min_version() const override { return {3, 17, 1}; }
-
- virtual void add_special_paths(std::vector<fs::path>& out_candidate_paths) const override
- {
-#if defined(_WIN32)
- const auto& program_files = System::get_program_files_platform_bitness();
- if (const auto pf = program_files.get()) out_candidate_paths.push_back(*pf / "CMake" / "bin" / "cmake.exe");
- const auto& program_files_32_bit = System::get_program_files_32_bit();
- if (const auto pf = program_files_32_bit.get())
- out_candidate_paths.push_back(*pf / "CMake" / "bin" / "cmake.exe");
-#else
- // TODO: figure out if this should do anything on non-Windows
- (void)out_candidate_paths;
-#endif
- }
- virtual ExpectedS<std::string> get_version(const VcpkgPaths&, const fs::path& path_to_exe) const override
- {
- auto cmd = System::Command(path_to_exe).string_arg("--version");
- auto rc = System::cmd_execute_and_capture_output(cmd);
- if (rc.exit_code != 0)
- {
- return {Strings::concat(
- std::move(rc.output), "\n\nFailed to get version of ", fs::u8string(path_to_exe), "\n"),
- expected_right_tag};
- }
-
- /* Sample output:
-cmake version 3.10.2
-
-CMake suite maintained and supported by Kitware (kitware.com/cmake).
- */
- return {Strings::find_exactly_one_enclosed(rc.output, "cmake version ", "\n").to_string(),
- expected_left_tag};
- }
- };
-
- struct NinjaProvider : ToolProvider
- {
- std::string m_exe = "ninja";
-
- virtual const std::string& tool_data_name() const override { return m_exe; }
- virtual const std::string& exe_stem() const override { return m_exe; }
- virtual std::array<int, 3> default_min_version() const override { return {3, 5, 1}; }
-
- virtual ExpectedS<std::string> get_version(const VcpkgPaths&, const fs::path& path_to_exe) const override
- {
- auto cmd = System::Command(path_to_exe).string_arg("--version");
- auto rc = System::cmd_execute_and_capture_output(cmd);
- if (rc.exit_code != 0)
- {
- return {Strings::concat(
- std::move(rc.output), "\n\nFailed to get version of ", fs::u8string(path_to_exe), "\n"),
- expected_right_tag};
- }
-
- /* Sample output:
-1.8.2
- */
- return {std::move(rc.output), expected_left_tag};
- }
- };
-
- struct NuGetProvider : ToolProvider
- {
- std::string m_exe = "nuget";
-
- virtual const std::string& tool_data_name() const override { return m_exe; }
- virtual const std::string& exe_stem() const override { return m_exe; }
- virtual std::array<int, 3> default_min_version() const override { return {4, 6, 2}; }
-
- virtual ExpectedS<std::string> get_version(const VcpkgPaths& paths, const fs::path& path_to_exe) const override
- {
- System::Command cmd;
-#ifndef _WIN32
- cmd.path_arg(paths.get_tool_exe(Tools::MONO));
-#else
- (void)paths;
-#endif
- cmd.path_arg(path_to_exe);
- auto rc = System::cmd_execute_and_capture_output(cmd);
- if (rc.exit_code != 0)
- {
-#ifndef _WIN32
- return {Strings::concat(
- std::move(rc.output),
- "\n\nFailed to get version of ",
- fs::u8string(path_to_exe),
- "\nThis may be caused by an incomplete mono installation. Full mono is "
- "available on some systems via `sudo apt install mono-complete`. Ubuntu 18.04 users may "
- "need a newer version of mono, available at https://www.mono-project.com/download/stable/"),
- expected_right_tag};
-#else
- return {Strings::concat(
- std::move(rc.output), "\n\nFailed to get version of ", fs::u8string(path_to_exe), "\n"),
- expected_right_tag};
-#endif
- }
-
- /* Sample output:
-NuGet Version: 4.6.2.5055
-usage: NuGet <command> [args] [options]
-Type 'NuGet help <command>' for help on a specific command.
-
-[[[List of available commands follows]]]
- */
- return {Strings::find_exactly_one_enclosed(rc.output, "NuGet Version: ", "\n").to_string(),
- expected_left_tag};
- }
- };
-
- struct GitProvider : ToolProvider
- {
- std::string m_exe = "git";
-
- virtual const std::string& tool_data_name() const override { return m_exe; }
- virtual const std::string& exe_stem() const override { return m_exe; }
- virtual std::array<int, 3> default_min_version() const override { return {2, 7, 4}; }
-
- virtual void add_special_paths(std::vector<fs::path>& out_candidate_paths) const override
- {
-#if defined(_WIN32)
- const auto& program_files = System::get_program_files_platform_bitness();
- if (const auto pf = program_files.get()) out_candidate_paths.push_back(*pf / "git" / "cmd" / "git.exe");
- const auto& program_files_32_bit = System::get_program_files_32_bit();
- if (const auto pf = program_files_32_bit.get())
- out_candidate_paths.push_back(*pf / "git" / "cmd" / "git.exe");
-#else
- // TODO: figure out if this should do anything on non-windows
- (void)out_candidate_paths;
-#endif
- }
-
- virtual ExpectedS<std::string> get_version(const VcpkgPaths&, const fs::path& path_to_exe) const override
- {
- auto cmd = System::Command(path_to_exe).string_arg("--version");
- auto rc = System::cmd_execute_and_capture_output(cmd);
- if (rc.exit_code != 0)
- {
- return {Strings::concat(
- std::move(rc.output), "\n\nFailed to get version of ", fs::u8string(path_to_exe), "\n"),
- expected_right_tag};
- }
-
- /* Sample output:
-git version 2.17.1.windows.2
- */
- const auto idx = rc.output.find("git version ");
- Checks::check_exit(
- VCPKG_LINE_INFO, idx != std::string::npos, "Unexpected format of git version string: %s", rc.output);
- return {rc.output.substr(idx), expected_left_tag};
- }
- };
-
- struct MonoProvider : ToolProvider
- {
- std::string m_exe = "mono";
-
- virtual const std::string& tool_data_name() const override { return m_exe; }
- virtual const std::string& exe_stem() const override { return m_exe; }
- virtual std::array<int, 3> default_min_version() const override { return {0, 0, 0}; }
-
- virtual ExpectedS<std::string> get_version(const VcpkgPaths&, const fs::path& path_to_exe) const override
- {
- auto rc = System::cmd_execute_and_capture_output(System::Command(path_to_exe).string_arg("--version"));
- if (rc.exit_code != 0)
- {
- return {Strings::concat(
- std::move(rc.output), "\n\nFailed to get version of ", fs::u8string(path_to_exe), "\n"),
- expected_right_tag};
- }
-
- /* Sample output:
-Mono JIT compiler version 6.8.0.105 (Debian 6.8.0.105+dfsg-2 Wed Feb 26 23:23:50 UTC 2020)
- */
- const auto idx = rc.output.find("Mono JIT compiler version ");
- Checks::check_exit(
- VCPKG_LINE_INFO, idx != std::string::npos, "Unexpected format of mono version string: %s", rc.output);
- return {rc.output.substr(idx), expected_left_tag};
- }
- };
-
- struct IfwInstallerBaseProvider : ToolProvider
- {
- std::string m_exe;
- std::string m_toolname = "installerbase";
-
- virtual const std::string& tool_data_name() const override { return m_toolname; }
- virtual const std::string& exe_stem() const override { return m_exe; }
- virtual std::array<int, 3> default_min_version() const override { return {0, 0, 0}; }
-
- virtual void add_special_paths(std::vector<fs::path>& out_candidate_paths) const override
- {
- (void)out_candidate_paths;
- // TODO: Uncomment later
- // const std::vector<fs::path> from_path = Files::find_from_PATH("installerbase");
- // candidate_paths.insert(candidate_paths.end(), from_path.cbegin(), from_path.cend());
- // candidate_paths.push_back(fs::path(System::get_environment_variable("HOMEDRIVE").value_or("C:")) /
- // "Qt" / "Tools" / "QtInstallerFramework" / "3.1" / "bin" / "installerbase.exe");
- // candidate_paths.push_back(fs::path(System::get_environment_variable("HOMEDRIVE").value_or("C:")) /
- // "Qt" / "QtIFW-3.1.0" / "bin" / "installerbase.exe");
- }
-
- virtual ExpectedS<std::string> get_version(const VcpkgPaths&, const fs::path& path_to_exe) const override
- {
- auto cmd = System::Command(path_to_exe).string_arg("--framework-version");
- auto rc = System::cmd_execute_and_capture_output(cmd);
- if (rc.exit_code != 0)
- {
- return {Strings::concat(
- std::move(rc.output), "\n\nFailed to get version of ", fs::u8string(path_to_exe), "\n"),
- expected_right_tag};
- }
-
- /* Sample output:
-3.1.81
- */
- return {std::move(rc.output), expected_left_tag};
- }
- };
-
- struct PowerShellCoreProvider : ToolProvider
- {
- std::string m_exe = "pwsh";
- std::string m_name = "powershell-core";
-
- virtual const std::string& tool_data_name() const override { return m_name; }
- virtual const std::string& exe_stem() const override { return m_exe; }
- virtual std::array<int, 3> default_min_version() const override { return {7, 0, 3}; }
-
- virtual ExpectedS<std::string> get_version(const VcpkgPaths&, const fs::path& path_to_exe) const override
- {
- auto rc = System::cmd_execute_and_capture_output(System::Command(path_to_exe).string_arg("--version"));
- if (rc.exit_code != 0)
- {
- return {Strings::concat(
- std::move(rc.output), "\n\nFailed to get version of ", fs::u8string(path_to_exe), "\n"),
- expected_right_tag};
- }
-
- // Sample output: PowerShell 7.0.3\r\n
- auto output = std::move(rc.output);
- if (!Strings::starts_with(output, "PowerShell "))
- {
- return {Strings::concat("Unexpected format of powershell-core version string: ", output),
- expected_right_tag};
- }
-
- output.erase(0, 11);
- return {Strings::trim(std::move(output)), expected_left_tag};
- }
- };
-
- struct ToolCacheImpl final : ToolCache
- {
- vcpkg::Cache<std::string, fs::path> path_only_cache;
- vcpkg::Cache<std::string, PathAndVersion> path_version_cache;
-
- virtual const fs::path& get_tool_path(const VcpkgPaths& paths, const std::string& tool) const override
- {
- return path_only_cache.get_lazy(tool, [&]() {
- if (tool == Tools::IFW_BINARYCREATOR)
- return get_tool_path(paths, Tools::IFW_INSTALLER_BASE).parent_path() / "binarycreator.exe";
- if (tool == Tools::IFW_REPOGEN)
- return get_tool_path(paths, Tools::IFW_INSTALLER_BASE).parent_path() / "repogen.exe";
-
- return get_tool_pathversion(paths, tool).path;
- });
- }
-
- const PathAndVersion& get_tool_pathversion(const VcpkgPaths& paths, const std::string& tool) const
- {
- return path_version_cache.get_lazy(tool, [&]() -> PathAndVersion {
- // First deal with specially handled tools.
- // For these we may look in locations like Program Files, the PATH etc as well as the auto-downloaded
- // location.
- if (tool == Tools::CMAKE)
- {
- if (System::get_environment_variable("VCPKG_FORCE_SYSTEM_BINARIES").has_value())
- {
- return {"cmake", "0"};
- }
- return get_path(paths, CMakeProvider());
- }
- if (tool == Tools::GIT)
- {
- if (System::get_environment_variable("VCPKG_FORCE_SYSTEM_BINARIES").has_value())
- {
- return {"git", "0"};
- }
- return get_path(paths, GitProvider());
- }
- if (tool == Tools::NINJA)
- {
- if (System::get_environment_variable("VCPKG_FORCE_SYSTEM_BINARIES").has_value())
- {
- return {"ninja", "0"};
- }
- return get_path(paths, NinjaProvider());
- }
- if (tool == Tools::POWERSHELL_CORE)
- {
- if (System::get_environment_variable("VCPKG_FORCE_SYSTEM_BINARIES").has_value())
- {
- return {"pwsh", "0"};
- }
- return get_path(paths, PowerShellCoreProvider());
- }
- if (tool == Tools::NUGET) return get_path(paths, NuGetProvider());
- if (tool == Tools::IFW_INSTALLER_BASE) return get_path(paths, IfwInstallerBaseProvider());
- if (tool == Tools::MONO) return get_path(paths, MonoProvider());
-
- // For other tools, we simply always auto-download them.
- auto maybe_tool_data = parse_tool_data_from_xml(paths, tool);
- if (auto p_tool_data = maybe_tool_data.get())
- {
- if (paths.get_filesystem().exists(p_tool_data->exe_path))
- {
- return {p_tool_data->exe_path, p_tool_data->sha512};
- }
- return {fetch_tool(paths, tool, *p_tool_data), p_tool_data->sha512};
- }
-
- Checks::exit_maybe_upgrade(VCPKG_LINE_INFO, "Unknown or unavailable tool: %s", tool);
- });
- }
-
- virtual const std::string& get_tool_version(const VcpkgPaths& paths, const std::string& tool) const override
- {
- return get_tool_pathversion(paths, tool).version;
- }
- };
-
- std::unique_ptr<ToolCache> get_tool_cache() { return std::make_unique<ToolCacheImpl>(); }
-}
diff --git a/toolsrc/src/vcpkg/triplet.cpp b/toolsrc/src/vcpkg/triplet.cpp
deleted file mode 100644
index 9943ec9a8..000000000
--- a/toolsrc/src/vcpkg/triplet.cpp
+++ /dev/null
@@ -1,110 +0,0 @@
-#include <vcpkg/base/strings.h>
-
-#include <vcpkg/triplet.h>
-#include <vcpkg/vcpkgcmdarguments.h>
-
-namespace vcpkg
-{
- struct TripletInstance
- {
- TripletInstance(std::string&& s) : value(std::move(s)), hash(std::hash<std::string>()(value)) { }
-
- const std::string value;
- const size_t hash = 0;
-
- bool operator==(const TripletInstance& o) const { return o.value == value; }
- };
- const TripletInstance Triplet::DEFAULT_INSTANCE({});
-}
-
-namespace std
-{
- template<>
- struct hash<vcpkg::TripletInstance>
- {
- size_t operator()(const vcpkg::TripletInstance& t) const { return t.hash; }
- };
-}
-
-namespace vcpkg
-{
- Triplet Triplet::from_canonical_name(std::string&& triplet_as_string)
- {
- static std::unordered_set<TripletInstance> g_triplet_instances;
- std::string s(Strings::ascii_to_lowercase(std::move(triplet_as_string)));
- const auto p = g_triplet_instances.emplace(std::move(s));
- return &*p.first;
- }
-
- const std::string& Triplet::canonical_name() const { return this->m_instance->value; }
-
- const std::string& Triplet::to_string() const { return this->canonical_name(); }
- void Triplet::to_string(std::string& out) const { out.append(this->canonical_name()); }
- size_t Triplet::hash_code() const { return m_instance->hash; }
-
- Optional<System::CPUArchitecture> Triplet::guess_architecture() const noexcept
- {
- using System::CPUArchitecture;
- if (Strings::starts_with(this->canonical_name(), "x86-"))
- {
- return CPUArchitecture::X86;
- }
- if (Strings::starts_with(this->canonical_name(), "x64-"))
- {
- return CPUArchitecture::X64;
- }
- if (Strings::starts_with(this->canonical_name(), "arm-"))
- {
- return CPUArchitecture::ARM;
- }
- if (Strings::starts_with(this->canonical_name(), "arm64-"))
- {
- return CPUArchitecture::ARM64;
- }
- if (Strings::starts_with(this->canonical_name(), "s390x-"))
- {
- return CPUArchitecture::S390X;
- }
- if (Strings::starts_with(this->canonical_name(), "ppc64le-"))
- {
- return CPUArchitecture::PPC64LE;
- }
-
- return nullopt;
- }
-
- Triplet default_triplet(const VcpkgCmdArguments& args)
- {
- if (args.triplet != nullptr)
- {
- return Triplet::from_canonical_name(std::string(*args.triplet));
- }
- else
- {
-#if defined(_WIN32)
- return Triplet::from_canonical_name("x86-windows");
-#elif defined(__APPLE__)
- return Triplet::from_canonical_name("x64-osx");
-#elif defined(__FreeBSD__)
- return Triplet::from_canonical_name("x64-freebsd");
-#elif defined(__OpenBSD__)
- return Triplet::from_canonical_name("x64-openbsd");
-#elif defined(__GLIBC__)
-#if defined(__aarch64__)
- return Triplet::from_canonical_name("arm64-linux");
-#elif defined(__arm__)
- return Triplet::from_canonical_name("arm-linux");
-#elif defined(__s390x__)
- return Triplet::from_canonical_name("s390x-linux");
-#elif (defined(__ppc64__) || defined(__PPC64__) || defined(__ppc64le__) || defined(__PPC64LE__)) && \
- defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
- return Triplet::from_canonical_name("ppc64le-linux");
-#else
- return Triplet::from_canonical_name("x64-linux");
-#endif
-#else
- return Triplet::from_canonical_name("x64-linux-musl");
-#endif
- }
- }
-}
diff --git a/toolsrc/src/vcpkg/update.cpp b/toolsrc/src/vcpkg/update.cpp
deleted file mode 100644
index a9ef4a3f7..000000000
--- a/toolsrc/src/vcpkg/update.cpp
+++ /dev/null
@@ -1,103 +0,0 @@
-#include <vcpkg/base/system.print.h>
-
-#include <vcpkg/commands.h>
-#include <vcpkg/help.h>
-#include <vcpkg/paragraphs.h>
-#include <vcpkg/portfileprovider.h>
-#include <vcpkg/update.h>
-#include <vcpkg/vcpkgcmdarguments.h>
-#include <vcpkg/vcpkglib.h>
-
-namespace vcpkg::Update
-{
- bool OutdatedPackage::compare_by_name(const OutdatedPackage& left, const OutdatedPackage& right)
- {
- return left.spec.name() < right.spec.name();
- }
-
- std::vector<OutdatedPackage> find_outdated_packages(const PortFileProvider::PortFileProvider& provider,
- const StatusParagraphs& status_db)
- {
- auto installed_packages = get_installed_ports(status_db);
-
- std::vector<OutdatedPackage> output;
- for (auto&& ipv : installed_packages)
- {
- const auto& pgh = ipv.core;
- auto maybe_scfl = provider.get_control_file(pgh->package.spec.name());
- if (auto p_scfl = maybe_scfl.get())
- {
- const auto& latest_pgh = *p_scfl->source_control_file->core_paragraph;
- auto latest_version = VersionT(latest_pgh.version, latest_pgh.port_version);
- auto installed_version = VersionT(pgh->package.version, pgh->package.port_version);
- if (latest_version != installed_version)
- {
- output.push_back(
- {pgh->package.spec, VersionDiff(std::move(installed_version), std::move(latest_version))});
- }
- }
- else
- {
- // No portfile available
- }
- }
-
- return output;
- }
-
- const CommandStructure COMMAND_STRUCTURE = {
- create_example_string("update"),
- 0,
- 0,
- {},
- nullptr,
- };
-
- void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths)
- {
- (void)args.parse_arguments(COMMAND_STRUCTURE);
- System::print2("Using local portfile versions. To update the local portfiles, use `git pull`.\n");
-
- const StatusParagraphs status_db = database_load_check(paths);
-
- PortFileProvider::PathsPortFileProvider provider(paths, args.overlay_ports);
-
- const auto outdated_packages = SortedVector<OutdatedPackage>(find_outdated_packages(provider, status_db),
- &OutdatedPackage::compare_by_name);
-
- if (outdated_packages.empty())
- {
- System::print2("No packages need updating.\n");
- }
- else
- {
- System::print2("The following packages differ from their port versions:\n");
- for (auto&& package : outdated_packages)
- {
- System::printf(" %-32s %s\n", package.spec, package.version_diff.to_string());
- }
-
-#if defined(_WIN32)
- auto vcpkg_cmd = ".\\vcpkg";
-#else
- auto vcpkg_cmd = "./vcpkg";
-#endif
- System::printf("\n"
- "To update these packages and all dependencies, run\n"
- " %s upgrade\n"
- "\n"
- "To only remove outdated packages, run\n"
- " %s remove --outdated\n"
- "\n",
- vcpkg_cmd,
- vcpkg_cmd);
- }
-
- Checks::exit_success(VCPKG_LINE_INFO);
- }
-
- void UpdateCommand::perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) const
- {
- Update::perform_and_exit(args, paths);
- }
-}
diff --git a/toolsrc/src/vcpkg/userconfig.cpp b/toolsrc/src/vcpkg/userconfig.cpp
deleted file mode 100644
index 5236a3c3b..000000000
--- a/toolsrc/src/vcpkg/userconfig.cpp
+++ /dev/null
@@ -1,77 +0,0 @@
-#include <vcpkg/base/files.h>
-#include <vcpkg/base/lazy.h>
-#include <vcpkg/base/system.h>
-
-#include <vcpkg/paragraphs.h>
-#include <vcpkg/userconfig.h>
-
-namespace vcpkg
-{
- fs::path get_user_dir()
- {
-#if defined(_WIN32)
- return System::get_appdata_local().value_or_exit(VCPKG_LINE_INFO) / "vcpkg";
-#else
- auto maybe_home = System::get_environment_variable("HOME");
- return fs::path(maybe_home.value_or("/var")) / ".vcpkg";
-#endif
- }
-
- static fs::path get_config_path() { return get_user_dir() / "config"; }
-
- UserConfig UserConfig::try_read_data(const Files::Filesystem& fs)
- {
- UserConfig ret;
- try
- {
- auto maybe_pghs = Paragraphs::get_paragraphs(fs, get_config_path());
- if (const auto p_pghs = maybe_pghs.get())
- {
- const auto& pghs = *p_pghs;
-
- Parse::Paragraph keys;
- if (pghs.size() > 0) keys = pghs[0];
-
- for (size_t x = 1; x < pghs.size(); ++x)
- {
- for (auto&& p : pghs[x])
- keys.insert(p);
- }
-
- ret.user_id = keys["User-Id"].first;
- ret.user_time = keys["User-Since"].first;
- ret.user_mac = keys["Mac-Hash"].first;
- ret.last_completed_survey = keys["Survey-Completed"].first;
- }
- }
- catch (...)
- {
- }
-
- return ret;
- }
-
- void UserConfig::try_write_data(Files::Filesystem& fs) const
- {
- try
- {
- auto config_path = get_config_path();
- auto config_dir = config_path.parent_path();
- std::error_code ec;
- fs.create_directory(config_dir, ec);
- fs.write_contents(config_path,
- Strings::format("User-Id: %s\n"
- "User-Since: %s\n"
- "Mac-Hash: %s\n"
- "Survey-Completed: %s\n",
- user_id,
- user_time,
- user_mac,
- last_completed_survey),
- ec);
- }
- catch (...)
- {
- }
- }
-}
diff --git a/toolsrc/src/vcpkg/vcpkgcmdarguments.cpp b/toolsrc/src/vcpkg/vcpkgcmdarguments.cpp
deleted file mode 100644
index 6ac05e538..000000000
--- a/toolsrc/src/vcpkg/vcpkgcmdarguments.cpp
+++ /dev/null
@@ -1,960 +0,0 @@
-#include <vcpkg/base/json.h>
-#include <vcpkg/base/system.debug.h>
-#include <vcpkg/base/system.print.h>
-
-#include <vcpkg/commands.h>
-#include <vcpkg/commands.integrate.h>
-#include <vcpkg/globalstate.h>
-#include <vcpkg/metrics.h>
-#include <vcpkg/vcpkgcmdarguments.h>
-
-namespace vcpkg
-{
- static void set_from_feature_flag(const std::vector<std::string>& flags, StringView flag, Optional<bool>& place)
- {
- if (!place.has_value())
- {
- const auto not_flag = [flag](const std::string& el) {
- return !el.empty() && el[0] == '-' && flag == StringView{el.data() + 1, el.data() + el.size()};
- };
-
- if (std::find(flags.begin(), flags.end(), flag) != flags.end())
- {
- place = true;
- }
- if (std::find_if(flags.begin(), flags.end(), not_flag) != flags.end())
- {
- if (place.has_value())
- {
- System::printf(
- System::Color::error, "Error: both %s and -%s were specified as feature flags\n", flag, flag);
- Metrics::g_metrics.lock()->track_property("error", "error feature flag +-" + flag.to_string());
- Checks::exit_fail(VCPKG_LINE_INFO);
- }
-
- place = false;
- }
- }
- }
-
- static void parse_feature_flags(const std::vector<std::string>& flags, VcpkgCmdArguments& args)
- {
- // NOTE: when these features become default, switch the value_or(false) to value_or(true)
- struct FeatureFlag
- {
- StringView flag_name;
- Optional<bool>& local_option;
- };
-
- const FeatureFlag flag_descriptions[] = {
- {VcpkgCmdArguments::BINARY_CACHING_FEATURE, args.binary_caching},
- {VcpkgCmdArguments::MANIFEST_MODE_FEATURE, args.manifest_mode},
- {VcpkgCmdArguments::COMPILER_TRACKING_FEATURE, args.compiler_tracking},
- {VcpkgCmdArguments::REGISTRIES_FEATURE, args.registries_feature},
- {VcpkgCmdArguments::VERSIONS_FEATURE, args.versions_feature},
- };
-
- for (const auto& desc : flag_descriptions)
- {
- set_from_feature_flag(flags, desc.flag_name, desc.local_option);
- }
- }
-
- static void parse_cojoined_value(StringView new_value,
- StringView option_name,
- std::unique_ptr<std::string>& option_field)
- {
- if (nullptr != option_field)
- {
- System::printf(System::Color::error, "Error: --%s specified multiple times\n", option_name);
- Metrics::g_metrics.lock()->track_property("error", "error option specified multiple times");
- print_usage();
- Checks::exit_fail(VCPKG_LINE_INFO);
- }
-
- option_field = std::make_unique<std::string>(new_value.begin(), new_value.end());
- }
-
- static void parse_switch(bool new_setting, StringView option_name, Optional<bool>& option_field)
- {
- if (option_field && option_field != new_setting)
- {
- System::print2(System::Color::error, "Error: conflicting values specified for --", option_name, '\n');
- Metrics::g_metrics.lock()->track_property("error", "error conflicting switches");
- print_usage();
- Checks::exit_fail(VCPKG_LINE_INFO);
- }
- option_field = new_setting;
- }
-
- static void parse_cojoined_multivalue(StringView new_value,
- StringView option_name,
- std::vector<std::string>& option_field)
- {
- if (new_value.size() == 0)
- {
- System::print2(System::Color::error, "Error: expected value after ", option_name, '\n');
- Metrics::g_metrics.lock()->track_property("error", "error option name");
- print_usage();
- Checks::exit_fail(VCPKG_LINE_INFO);
- }
-
- option_field.emplace_back(new_value.begin(), new_value.end());
- }
-
- static void parse_cojoined_list_multivalue(StringView new_value,
- StringView option_name,
- std::vector<std::string>& option_field)
- {
- if (new_value.size() == 0)
- {
- System::print2(System::Color::error, "Error: expected value after ", option_name, '\n');
- Metrics::g_metrics.lock()->track_property("error", "error option name");
- print_usage();
- Checks::exit_fail(VCPKG_LINE_INFO);
- }
-
- for (const auto& v : Strings::split(new_value, ','))
- {
- option_field.emplace_back(v.begin(), v.end());
- }
- }
-
- VcpkgCmdArguments VcpkgCmdArguments::create_from_command_line(const Files::Filesystem& fs,
- const int argc,
- const CommandLineCharType* const* const argv)
- {
- std::vector<std::string> v;
- for (int i = 1; i < argc; ++i)
- {
- std::string arg;
-#if defined(_WIN32)
- arg = Strings::to_utf8(argv[i]);
-#else
- arg = argv[i];
-#endif
- // Response file?
- if (arg.size() > 0 && arg[0] == '@')
- {
- arg.erase(arg.begin());
- auto lines = fs.read_lines(fs::u8path(arg));
- if (!lines.has_value())
- {
- System::print2(System::Color::error, "Error: Could not open response file ", arg, '\n');
- Checks::exit_fail(VCPKG_LINE_INFO);
- }
- std::copy(lines.get()->begin(), lines.get()->end(), std::back_inserter(v));
- }
- else
- {
- v.emplace_back(std::move(arg));
- }
- }
-
- return VcpkgCmdArguments::create_from_arg_sequence(v.data(), v.data() + v.size());
- }
-
- enum class TryParseArgumentResult
- {
- NotFound,
- Found,
- FoundAndConsumedLookahead
- };
-
- template<class T, class F>
- static TryParseArgumentResult try_parse_argument_as_option(
- StringView arg, Optional<StringView> lookahead, StringView option, T& place, F parser)
- {
- if (Strings::starts_with(arg, "x-") && !Strings::starts_with(option, "x-"))
- {
- arg = arg.substr(2);
- }
-
- if (Strings::starts_with(arg, option))
- {
- if (arg.size() == option.size())
- {
- if (auto next = lookahead.get())
- {
- parser(*next, option, place);
- return TryParseArgumentResult::FoundAndConsumedLookahead;
- }
-
- System::print2(System::Color::error, "Error: expected value after ", option, '\n');
- Metrics::g_metrics.lock()->track_property("error", "error option name");
- print_usage();
- Checks::exit_fail(VCPKG_LINE_INFO);
- }
-
- if (arg.byte_at_index(option.size()) == '=')
- {
- parser(arg.substr(option.size() + 1), option, place);
- return TryParseArgumentResult::Found;
- }
- }
-
- return TryParseArgumentResult::NotFound;
- }
-
- static bool equals_modulo_experimental(StringView arg, StringView option)
- {
- if (Strings::starts_with(arg, "x-") && !Strings::starts_with(option, "x-"))
- {
- return arg.substr(2) == option;
- }
- else
- {
- return arg == option;
- }
- }
-
- // returns true if this does parse this argument as this option
- template<class T>
- static bool try_parse_argument_as_switch(StringView option, StringView arg, T& place)
- {
- if (equals_modulo_experimental(arg, option))
- {
- parse_switch(true, option, place);
- return true;
- }
-
- if (Strings::starts_with(arg, "no-") && equals_modulo_experimental(arg.substr(3), option))
- {
- parse_switch(false, option, place);
- return true;
- }
-
- return false;
- }
-
- VcpkgCmdArguments VcpkgCmdArguments::create_from_arg_sequence(const std::string* arg_first,
- const std::string* arg_last)
- {
- VcpkgCmdArguments args;
- std::vector<std::string> feature_flags;
-
- for (auto it = arg_first; it != arg_last; ++it)
- {
- std::string basic_arg = *it;
-
- if (basic_arg.empty())
- {
- continue;
- }
-
- if (basic_arg.size() >= 2 && basic_arg[0] == '-' && basic_arg[1] != '-')
- {
- Metrics::g_metrics.lock()->track_property("error", "error short options are not supported");
- Checks::exit_with_message(VCPKG_LINE_INFO, "Error: short options are not supported: %s", basic_arg);
- }
-
- if (basic_arg.size() < 2 || basic_arg[0] != '-')
- {
- if (args.command.empty())
- {
- args.command = std::move(basic_arg);
- }
- else
- {
- args.command_arguments.push_back(std::move(basic_arg));
- }
- continue;
- }
-
- // make argument case insensitive before the first =
- auto first_eq = std::find(std::begin(basic_arg), std::end(basic_arg), '=');
- Strings::ascii_to_lowercase(std::begin(basic_arg), first_eq);
- // basic_arg[0] == '-' && basic_arg[1] == '-'
- StringView arg = StringView(basic_arg).substr(2);
- constexpr static std::pair<StringView, std::unique_ptr<std::string> VcpkgCmdArguments::*>
- cojoined_values[] = {
- {VCPKG_ROOT_DIR_ARG, &VcpkgCmdArguments::vcpkg_root_dir},
- {TRIPLET_ARG, &VcpkgCmdArguments::triplet},
- {MANIFEST_ROOT_DIR_ARG, &VcpkgCmdArguments::manifest_root_dir},
- {BUILDTREES_ROOT_DIR_ARG, &VcpkgCmdArguments::buildtrees_root_dir},
- {DOWNLOADS_ROOT_DIR_ARG, &VcpkgCmdArguments::downloads_root_dir},
- {INSTALL_ROOT_DIR_ARG, &VcpkgCmdArguments::install_root_dir},
- {PACKAGES_ROOT_DIR_ARG, &VcpkgCmdArguments::packages_root_dir},
- {SCRIPTS_ROOT_DIR_ARG, &VcpkgCmdArguments::scripts_root_dir},
- {BUILTIN_PORTS_ROOT_DIR_ARG, &VcpkgCmdArguments::builtin_ports_root_dir},
- {BUILTIN_REGISTRY_VERSIONS_DIR_ARG, &VcpkgCmdArguments::builtin_registry_versions_dir},
- };
-
- constexpr static std::pair<StringView, std::vector<std::string> VcpkgCmdArguments::*>
- cojoined_multivalues[] = {
- {OVERLAY_PORTS_ARG, &VcpkgCmdArguments::overlay_ports},
- {OVERLAY_TRIPLETS_ARG, &VcpkgCmdArguments::overlay_triplets},
- {BINARY_SOURCES_ARG, &VcpkgCmdArguments::binary_sources},
- {CMAKE_SCRIPT_ARG, &VcpkgCmdArguments::cmake_args},
- };
-
- constexpr static std::pair<StringView, Optional<bool> VcpkgCmdArguments::*> switches[] = {
- {DEBUG_SWITCH, &VcpkgCmdArguments::debug},
- {DISABLE_METRICS_SWITCH, &VcpkgCmdArguments::disable_metrics},
- {SEND_METRICS_SWITCH, &VcpkgCmdArguments::send_metrics},
- {PRINT_METRICS_SWITCH, &VcpkgCmdArguments::print_metrics},
- {FEATURE_PACKAGES_SWITCH, &VcpkgCmdArguments::feature_packages},
- {BINARY_CACHING_SWITCH, &VcpkgCmdArguments::binary_caching},
- {WAIT_FOR_LOCK_SWITCH, &VcpkgCmdArguments::wait_for_lock},
- {IGNORE_LOCK_FAILURES_SWITCH, &VcpkgCmdArguments::ignore_lock_failures},
- {JSON_SWITCH, &VcpkgCmdArguments::json},
- };
-
- Optional<StringView> lookahead;
- if (it + 1 != arg_last)
- {
- lookahead = it[1];
- }
-
- bool found = false;
- for (const auto& pr : cojoined_values)
- {
- switch (try_parse_argument_as_option(arg, lookahead, pr.first, args.*pr.second, parse_cojoined_value))
- {
- case TryParseArgumentResult::FoundAndConsumedLookahead: ++it; [[fallthrough]];
- case TryParseArgumentResult::Found: found = true; break;
- case TryParseArgumentResult::NotFound: break;
- default: Checks::unreachable(VCPKG_LINE_INFO);
- }
- }
- if (found) continue;
-
- for (const auto& pr : cojoined_multivalues)
- {
- switch (
- try_parse_argument_as_option(arg, lookahead, pr.first, args.*pr.second, parse_cojoined_multivalue))
- {
- case TryParseArgumentResult::FoundAndConsumedLookahead: ++it; [[fallthrough]];
- case TryParseArgumentResult::Found: found = true; break;
- case TryParseArgumentResult::NotFound: break;
- default: Checks::unreachable(VCPKG_LINE_INFO);
- }
- }
- if (found) continue;
-
- switch (try_parse_argument_as_option(
- arg, lookahead, FEATURE_FLAGS_ARG, feature_flags, parse_cojoined_list_multivalue))
- {
- case TryParseArgumentResult::FoundAndConsumedLookahead: ++it; [[fallthrough]];
- case TryParseArgumentResult::Found: found = true; break;
- case TryParseArgumentResult::NotFound: break;
- default: Checks::unreachable(VCPKG_LINE_INFO);
- }
-
- for (const auto& pr : switches)
- {
- if (try_parse_argument_as_switch(pr.first, arg, args.*pr.second))
- {
- found = true;
- break;
- }
- }
- if (found) continue;
-
- const auto eq_pos = std::find(arg.begin(), arg.end(), '=');
- if (eq_pos != arg.end())
- {
- const auto& key = StringView(arg.begin(), eq_pos);
- const auto& value = StringView(eq_pos + 1, arg.end());
-
- args.command_options[key.to_string()].push_back(value.to_string());
- }
- else
- {
- args.command_switches.insert(arg.to_string());
- }
- }
-
- parse_feature_flags(feature_flags, args);
-
- return args;
- }
-
- ParsedArguments VcpkgCmdArguments::parse_arguments(const CommandStructure& command_structure) const
- {
- bool failed = false;
- ParsedArguments output;
-
- const size_t actual_arg_count = command_arguments.size();
-
- if (command_structure.minimum_arity == command_structure.maximum_arity)
- {
- if (actual_arg_count != command_structure.minimum_arity)
- {
- System::printf(System::Color::error,
- "Error: '%s' requires %u arguments, but %u were provided.\n",
- this->command,
- command_structure.minimum_arity,
- actual_arg_count);
- failed = true;
- }
- }
- else
- {
- if (actual_arg_count < command_structure.minimum_arity)
- {
- System::printf(System::Color::error,
- "Error: '%s' requires at least %u arguments, but %u were provided\n",
- this->command,
- command_structure.minimum_arity,
- actual_arg_count);
- failed = true;
- }
- if (actual_arg_count > command_structure.maximum_arity)
- {
- System::printf(System::Color::error,
- "Error: '%s' requires at most %u arguments, but %u were provided\n",
- this->command,
- command_structure.maximum_arity,
- actual_arg_count);
- failed = true;
- }
- }
-
- auto switches_copy = this->command_switches;
- auto options_copy = this->command_options;
-
- const auto find_option = [](const auto& set, StringLiteral name) {
- auto it = set.find(name);
- if (it == set.end() && !Strings::starts_with(name, "x-"))
- {
- it = set.find(Strings::format("x-%s", name));
- }
-
- return it;
- };
-
- for (const auto& switch_ : command_structure.options.switches)
- {
- const auto it = find_option(switches_copy, switch_.name);
- if (it != switches_copy.end())
- {
- output.switches.insert(switch_.name);
- switches_copy.erase(it);
- }
- const auto option_it = find_option(options_copy, switch_.name);
- if (option_it != options_copy.end())
- {
- // This means that the switch was passed like '--a=xyz'
- System::printf(
- System::Color::error, "Error: The option '--%s' does not accept an argument.\n", switch_.name);
- options_copy.erase(option_it);
- failed = true;
- }
- }
-
- for (const auto& option : command_structure.options.settings)
- {
- const auto it = find_option(options_copy, option.name);
- if (it != options_copy.end())
- {
- const auto& value = it->second;
- if (value.empty())
- {
- Checks::unreachable(VCPKG_LINE_INFO);
- }
-
- if (value.size() > 1)
- {
- System::printf(
- System::Color::error, "Error: The option '%s' can only be passed once.\n", option.name);
- failed = true;
- }
- else if (value.front().empty())
- {
- // Fail when not given a value, e.g.: "vcpkg install sqlite3 --additional-ports="
- System::printf(System::Color::error,
- "Error: The option '--%s' must be passed a non-empty argument.\n",
- option.name);
- failed = true;
- }
- else
- {
- output.settings.emplace(option.name, value.front());
- options_copy.erase(it);
- }
- }
- const auto switch_it = find_option(switches_copy, option.name);
- if (switch_it != switches_copy.end())
- {
- // This means that the option was passed like '--a'
- System::printf(
- System::Color::error, "Error: The option '--%s' must be passed an argument.\n", option.name);
- switches_copy.erase(switch_it);
- failed = true;
- }
- }
-
- for (const auto& option : command_structure.options.multisettings)
- {
- const auto it = find_option(options_copy, option.name);
- if (it != options_copy.end())
- {
- const auto& value = it->second;
- for (const auto& v : value)
- {
- if (v.empty())
- {
- System::printf(System::Color::error,
- "Error: The option '--%s' must be passed non-empty arguments.\n",
- option.name);
- failed = true;
- }
- else
- {
- output.multisettings[option.name].push_back(v);
- }
- }
- options_copy.erase(it);
- }
- const auto switch_it = find_option(switches_copy, option.name);
- if (switch_it != switches_copy.end())
- {
- // This means that the option was passed like '--a'
- System::printf(
- System::Color::error, "Error: The option '--%s' must be passed an argument.\n", option.name);
- switches_copy.erase(switch_it);
- failed = true;
- }
- }
-
- if (!switches_copy.empty() || !options_copy.empty())
- {
- System::printf(System::Color::error, "Unknown option(s) for command '%s':\n", this->command);
- for (auto&& switch_ : switches_copy)
- {
- System::print2(" '--", switch_, "'\n");
- }
- for (auto&& option : options_copy)
- {
- System::print2(" '--", option.first, "'\n");
- }
- System::print2("\n");
- failed = true;
- }
-
- if (failed)
- {
- print_usage(command_structure);
- Checks::exit_fail(VCPKG_LINE_INFO);
- }
-
- return output;
- }
-
- void print_usage()
- {
- HelpTableFormatter table;
- table.header("Commands");
- table.format("vcpkg search [pat]", "Search for packages available to be built");
- table.format("vcpkg install <pkg>...", "Install a package");
- table.format("vcpkg remove <pkg>...", "Uninstall a package");
- table.format("vcpkg remove --outdated", "Uninstall all out-of-date packages");
- table.format("vcpkg list", "List installed packages");
- table.format("vcpkg update", "Display list of packages for updating");
- table.format("vcpkg upgrade", "Rebuild all outdated packages");
- table.format("vcpkg x-history <pkg>", "(Experimental) Shows the history of CONTROL versions of a package");
- table.format("vcpkg hash <file> [alg]", "Hash a file by specific algorithm, default SHA512");
- table.format("vcpkg help topics", "Display the list of help topics");
- table.format("vcpkg help <topic>", "Display help for a specific topic");
- table.blank();
- Commands::Integrate::append_helpstring(table);
- table.blank();
- table.format("vcpkg export <pkg>... [opt]...", "Exports a package");
- table.format("vcpkg edit <pkg>",
- "Open up a port for editing (uses " + format_environment_variable("EDITOR") + ", default 'code')");
- table.format("vcpkg create <pkg> <url> [archivename]", "Create a new package");
- table.format("vcpkg owns <pat>", "Search for files in installed packages");
- table.format("vcpkg depend-info <pkg>...", "Display a list of dependencies for packages");
- table.format("vcpkg env", "Creates a clean shell environment for development or compiling");
- table.format("vcpkg version", "Display version information");
- table.format("vcpkg contact", "Display contact information to send feedback");
- table.blank();
- table.header("Options");
- VcpkgCmdArguments::append_common_options(table);
- table.blank();
- table.format("@response_file", "Specify a response file to provide additional parameters");
- table.blank();
- table.example("For more help (including examples) see the accompanying README.md and docs folder.");
- System::print2(table.m_str);
- }
-
- void print_usage(const CommandStructure& command_structure)
- {
- HelpTableFormatter table;
- if (!command_structure.example_text.empty())
- {
- table.example(command_structure.example_text);
- }
-
- table.header("Options");
- for (auto&& option : command_structure.options.switches)
- {
- table.format(Strings::format("--%s", option.name), option.short_help_text);
- }
- for (auto&& option : command_structure.options.settings)
- {
- table.format(Strings::format("--%s=...", option.name), option.short_help_text);
- }
- for (auto&& option : command_structure.options.multisettings)
- {
- table.format(Strings::format("--%s=...", option.name), option.short_help_text);
- }
-
- VcpkgCmdArguments::append_common_options(table);
- System::print2(table.m_str);
- }
-
- void VcpkgCmdArguments::append_common_options(HelpTableFormatter& table)
- {
- static auto opt = [](StringView arg, StringView joiner, StringView value) {
- return Strings::concat("--", arg, joiner, value);
- };
-
- table.format(opt(TRIPLET_ARG, "=", "<t>"), "Specify the target architecture triplet. See 'vcpkg help triplet'");
- table.format("", "(default: " + format_environment_variable("VCPKG_DEFAULT_TRIPLET") + ')');
- table.format(opt(OVERLAY_PORTS_ARG, "=", "<path>"), "Specify directories to be used when searching for ports");
- table.format("", "(also: " + format_environment_variable("VCPKG_OVERLAY_PORTS") + ')');
- table.format(opt(OVERLAY_TRIPLETS_ARG, "=", "<path>"), "Specify directories containing triplets files");
- table.format("", "(also: " + format_environment_variable("VCPKG_OVERLAY_TRIPLETS") + ')');
- table.format(opt(BINARY_SOURCES_ARG, "=", "<path>"),
- "Add sources for binary caching. See 'vcpkg help binarycaching'");
- table.format(opt(DOWNLOADS_ROOT_DIR_ARG, "=", "<path>"), "Specify the downloads root directory");
- table.format("", "(default: " + format_environment_variable("VCPKG_DOWNLOADS") + ')');
- table.format(opt(VCPKG_ROOT_DIR_ARG, "=", "<path>"), "Specify the vcpkg root directory");
- table.format("", "(default: " + format_environment_variable("VCPKG_ROOT") + ')');
- table.format(opt(BUILDTREES_ROOT_DIR_ARG, "=", "<path>"),
- "(Experimental) Specify the buildtrees root directory");
- table.format(opt(INSTALL_ROOT_DIR_ARG, "=", "<path>"), "(Experimental) Specify the install root directory");
- table.format(opt(PACKAGES_ROOT_DIR_ARG, "=", "<path>"), "(Experimental) Specify the packages root directory");
- table.format(opt(SCRIPTS_ROOT_DIR_ARG, "=", "<path>"), "(Experimental) Specify the scripts root directory");
- table.format(opt(BUILTIN_PORTS_ROOT_DIR_ARG, "=", "<path>"),
- "(Experimental) Specify the packages root directory");
- table.format(opt(BUILTIN_REGISTRY_VERSIONS_DIR_ARG, "=", "<path>"),
- "(Experimental) Specify the versions root directory");
- table.format(opt(JSON_SWITCH, "", ""), "(Experimental) Request JSON output");
- }
-
- static void from_env(ZStringView var, std::unique_ptr<std::string>& dst)
- {
- if (dst) return;
-
- auto maybe_val = System::get_environment_variable(var);
- if (auto val = maybe_val.get())
- {
- dst = std::make_unique<std::string>(std::move(*val));
- }
- }
-
- void VcpkgCmdArguments::imbue_from_environment()
- {
- if (!disable_metrics)
- {
- const auto vcpkg_disable_metrics_env = System::get_environment_variable(DISABLE_METRICS_ENV);
- if (vcpkg_disable_metrics_env.has_value())
- {
- disable_metrics = true;
- }
- }
-
- from_env(TRIPLET_ENV, triplet);
- from_env(VCPKG_ROOT_DIR_ENV, vcpkg_root_dir);
- from_env(DOWNLOADS_ROOT_DIR_ENV, downloads_root_dir);
- from_env(DEFAULT_VISUAL_STUDIO_PATH_ENV, default_visual_studio_path);
-
- {
- const auto vcpkg_disable_lock = System::get_environment_variable(IGNORE_LOCK_FAILURES_ENV);
- if (vcpkg_disable_lock.has_value() && !ignore_lock_failures.has_value())
- {
- ignore_lock_failures = true;
- }
- }
-
- {
- const auto vcpkg_overlay_ports_env = System::get_environment_variable(OVERLAY_PORTS_ENV);
- if (const auto unpacked = vcpkg_overlay_ports_env.get())
- {
- auto overlays = Strings::split_paths(*unpacked);
- overlay_ports.insert(std::end(overlay_ports), std::begin(overlays), std::end(overlays));
- }
- }
- {
- const auto vcpkg_overlay_triplets_env = System::get_environment_variable(OVERLAY_TRIPLETS_ENV);
- if (const auto unpacked = vcpkg_overlay_triplets_env.get())
- {
- auto triplets = Strings::split_paths(*unpacked);
- overlay_triplets.insert(std::end(overlay_triplets), std::begin(triplets), std::end(triplets));
- }
- }
- {
- const auto vcpkg_feature_flags_env = System::get_environment_variable(FEATURE_FLAGS_ENV);
- if (const auto v = vcpkg_feature_flags_env.get())
- {
- auto flags = Strings::split(*v, ',');
- parse_feature_flags(flags, *this);
- }
- }
- }
-
- void VcpkgCmdArguments::imbue_or_apply_process_recursion(VcpkgCmdArguments& args)
- {
- static bool s_reentrancy_guard = false;
- Checks::check_exit(
- VCPKG_LINE_INFO,
- !s_reentrancy_guard,
- "VcpkgCmdArguments::imbue_or_apply_process_recursion() modifies global state and thus may only be "
- "called once per process.");
- s_reentrancy_guard = true;
-
- auto maybe_vcpkg_recursive_data = System::get_environment_variable(RECURSIVE_DATA_ENV);
- if (auto vcpkg_recursive_data = maybe_vcpkg_recursive_data.get())
- {
- auto rec_doc = Json::parse(*vcpkg_recursive_data).value_or_exit(VCPKG_LINE_INFO).first;
- const auto& obj = rec_doc.object();
-
- if (auto entry = obj.get(DOWNLOADS_ROOT_DIR_ENV))
- {
- args.downloads_root_dir = std::make_unique<std::string>(entry->string().to_string());
- }
-
- if (obj.get(DISABLE_METRICS_ENV))
- {
- args.disable_metrics = true;
- }
-
- // Setting the recursive data to 'poison' prevents more than one level of recursion because
- // Json::parse() will fail.
- System::set_environment_variable(RECURSIVE_DATA_ENV, "poison");
- }
- else
- {
- Json::Object obj;
- if (args.downloads_root_dir)
- {
- obj.insert(DOWNLOADS_ROOT_DIR_ENV, Json::Value::string(*args.downloads_root_dir.get()));
- }
-
- if (args.disable_metrics)
- {
- obj.insert(DISABLE_METRICS_ENV, Json::Value::boolean(true));
- }
-
- System::set_environment_variable(RECURSIVE_DATA_ENV, Json::stringify(obj, Json::JsonStyle::with_spaces(0)));
- }
- }
-
- void VcpkgCmdArguments::check_feature_flag_consistency() const
- {
- struct
- {
- StringView flag;
- StringView option;
- bool is_inconsistent;
- } possible_inconsistencies[] = {
- {BINARY_CACHING_FEATURE, BINARY_SOURCES_ARG, !binary_sources.empty() && !binary_caching.value_or(true)},
- {MANIFEST_MODE_FEATURE, MANIFEST_ROOT_DIR_ARG, manifest_root_dir && !manifest_mode.value_or(true)},
- };
- for (const auto& el : possible_inconsistencies)
- {
- if (el.is_inconsistent)
- {
- System::printf(System::Color::warning,
- "Warning: %s feature specifically turned off, but --%s was specified.\n",
- el.flag,
- el.option);
- System::printf(System::Color::warning, "Warning: Defaulting to %s being on.\n", el.flag);
- Metrics::g_metrics.lock()->track_property(
- "warning", Strings::format("warning %s alongside %s", el.flag, el.option));
- }
- }
- }
-
- void VcpkgCmdArguments::debug_print_feature_flags() const
- {
- struct
- {
- StringView name;
- Optional<bool> flag;
- } flags[] = {
- {BINARY_CACHING_FEATURE, binary_caching},
- {MANIFEST_MODE_FEATURE, manifest_mode},
- {COMPILER_TRACKING_FEATURE, compiler_tracking},
- {REGISTRIES_FEATURE, registries_feature},
- {VERSIONS_FEATURE, versions_feature},
- };
-
- for (const auto& flag : flags)
- {
- if (auto r = flag.flag.get())
- {
- Debug::print("Feature flag '", flag.name, "' = ", *r ? "on" : "off", "\n");
- }
- else
- {
- Debug::print("Feature flag '", flag.name, "' unset\n");
- }
- }
- }
-
- void VcpkgCmdArguments::track_feature_flag_metrics() const
- {
- struct
- {
- StringView flag;
- bool enabled;
- } flags[] = {
- {BINARY_CACHING_FEATURE, binary_caching_enabled()},
- {COMPILER_TRACKING_FEATURE, compiler_tracking_enabled()},
- {REGISTRIES_FEATURE, registries_enabled()},
- {VERSIONS_FEATURE, versions_enabled()},
- };
-
- for (const auto& flag : flags)
- {
- Metrics::g_metrics.lock()->track_feature(flag.flag.to_string(), flag.enabled);
- }
- }
-
- std::string format_environment_variable(StringLiteral lit)
- {
- std::string result;
-#if defined(_WIN32)
- result.reserve(lit.size() + 2);
- result.push_back('%');
- result.append(lit.data(), lit.size());
- result.push_back('%');
-#else
- result.reserve(lit.size() + 1);
- result.push_back('$');
- result.append(lit.data(), lit.size());
-#endif
- return result;
- }
-
- std::string create_example_string(const std::string& command_and_arguments)
- {
- std::string cs = Strings::format("Example:\n"
- " vcpkg %s\n",
- command_and_arguments);
- return cs;
- }
-
- static void help_table_newline_indent(std::string& target)
- {
- target.push_back('\n');
- target.append(34, ' ');
- }
-
- static constexpr ptrdiff_t S_MAX_LINE_LENGTH = 100;
-
- void HelpTableFormatter::format(StringView col1, StringView col2)
- {
- // 2 space, 31 col1, 1 space, 65 col2 = 99
- m_str.append(2, ' ');
- Strings::append(m_str, col1);
- if (col1.size() > 31)
- {
- help_table_newline_indent(m_str);
- }
- else
- {
- m_str.append(32 - col1.size(), ' ');
- }
- text(col2, 34);
-
- m_str.push_back('\n');
- }
-
- void HelpTableFormatter::header(StringView name)
- {
- m_str.append(name.data(), name.size());
- m_str.push_back(':');
- m_str.push_back('\n');
- }
-
- void HelpTableFormatter::example(StringView example_text)
- {
- m_str.append(example_text.data(), example_text.size());
- m_str.push_back('\n');
- }
-
- void HelpTableFormatter::blank() { m_str.push_back('\n'); }
-
- // Note: this formatting code does not properly handle unicode, however all of our documentation strings are English
- // ASCII.
- void HelpTableFormatter::text(StringView text, int indent)
- {
- const char* line_start = text.begin();
- const char* const e = text.end();
- const char* best_break = std::find_if(line_start, e, [](char ch) { return ch == ' ' || ch == '\n'; });
-
- while (best_break != e)
- {
- const char* next_break = std::find_if(best_break + 1, e, [](char ch) { return ch == ' ' || ch == '\n'; });
- if (*best_break == '\n' || next_break - line_start + indent > S_MAX_LINE_LENGTH)
- {
- m_str.append(line_start, best_break);
- m_str.push_back('\n');
- line_start = best_break + 1;
- best_break = next_break;
- m_str.append(indent, ' ');
- }
- else
- {
- best_break = next_break;
- }
- }
- m_str.append(line_start, best_break);
- }
-
- // out-of-line definitions since C++14 doesn't allow inline constexpr static variables
- constexpr StringLiteral VcpkgCmdArguments::VCPKG_ROOT_DIR_ENV;
- constexpr StringLiteral VcpkgCmdArguments::VCPKG_ROOT_DIR_ARG;
- constexpr StringLiteral VcpkgCmdArguments::MANIFEST_ROOT_DIR_ARG;
-
- constexpr StringLiteral VcpkgCmdArguments::BUILDTREES_ROOT_DIR_ARG;
- constexpr StringLiteral VcpkgCmdArguments::DOWNLOADS_ROOT_DIR_ENV;
- constexpr StringLiteral VcpkgCmdArguments::DOWNLOADS_ROOT_DIR_ARG;
- constexpr StringLiteral VcpkgCmdArguments::INSTALL_ROOT_DIR_ARG;
- constexpr StringLiteral VcpkgCmdArguments::PACKAGES_ROOT_DIR_ARG;
- constexpr StringLiteral VcpkgCmdArguments::SCRIPTS_ROOT_DIR_ARG;
- constexpr StringLiteral VcpkgCmdArguments::BUILTIN_PORTS_ROOT_DIR_ARG;
- constexpr StringLiteral VcpkgCmdArguments::BUILTIN_REGISTRY_VERSIONS_DIR_ARG;
-
- constexpr StringLiteral VcpkgCmdArguments::DEFAULT_VISUAL_STUDIO_PATH_ENV;
-
- constexpr StringLiteral VcpkgCmdArguments::TRIPLET_ENV;
- constexpr StringLiteral VcpkgCmdArguments::TRIPLET_ARG;
- constexpr StringLiteral VcpkgCmdArguments::OVERLAY_PORTS_ENV;
- constexpr StringLiteral VcpkgCmdArguments::OVERLAY_PORTS_ARG;
- constexpr StringLiteral VcpkgCmdArguments::OVERLAY_TRIPLETS_ENV;
- constexpr StringLiteral VcpkgCmdArguments::OVERLAY_TRIPLETS_ARG;
-
- constexpr StringLiteral VcpkgCmdArguments::BINARY_SOURCES_ARG;
-
- constexpr StringLiteral VcpkgCmdArguments::DEBUG_SWITCH;
- constexpr StringLiteral VcpkgCmdArguments::SEND_METRICS_SWITCH;
- constexpr StringLiteral VcpkgCmdArguments::DISABLE_METRICS_ENV;
- constexpr StringLiteral VcpkgCmdArguments::DISABLE_METRICS_SWITCH;
- constexpr StringLiteral VcpkgCmdArguments::PRINT_METRICS_SWITCH;
-
- constexpr StringLiteral VcpkgCmdArguments::WAIT_FOR_LOCK_SWITCH;
- constexpr StringLiteral VcpkgCmdArguments::IGNORE_LOCK_FAILURES_SWITCH;
- constexpr StringLiteral VcpkgCmdArguments::IGNORE_LOCK_FAILURES_ENV;
-
- constexpr StringLiteral VcpkgCmdArguments::JSON_SWITCH;
-
- constexpr StringLiteral VcpkgCmdArguments::FEATURE_FLAGS_ENV;
- constexpr StringLiteral VcpkgCmdArguments::FEATURE_FLAGS_ARG;
-
- constexpr StringLiteral VcpkgCmdArguments::FEATURE_PACKAGES_SWITCH;
- constexpr StringLiteral VcpkgCmdArguments::BINARY_CACHING_FEATURE;
- constexpr StringLiteral VcpkgCmdArguments::BINARY_CACHING_SWITCH;
- constexpr StringLiteral VcpkgCmdArguments::COMPILER_TRACKING_FEATURE;
- constexpr StringLiteral VcpkgCmdArguments::MANIFEST_MODE_FEATURE;
- constexpr StringLiteral VcpkgCmdArguments::REGISTRIES_FEATURE;
- constexpr StringLiteral VcpkgCmdArguments::RECURSIVE_DATA_ENV;
- constexpr StringLiteral VcpkgCmdArguments::VERSIONS_FEATURE;
-
- constexpr StringLiteral VcpkgCmdArguments::CMAKE_SCRIPT_ARG;
-}
diff --git a/toolsrc/src/vcpkg/vcpkglib.cpp b/toolsrc/src/vcpkg/vcpkglib.cpp
deleted file mode 100644
index 5b8e4b439..000000000
--- a/toolsrc/src/vcpkg/vcpkglib.cpp
+++ /dev/null
@@ -1,239 +0,0 @@
-#include <vcpkg/base/files.h>
-#include <vcpkg/base/strings.h>
-#include <vcpkg/base/util.h>
-
-#include <vcpkg/metrics.h>
-#include <vcpkg/paragraphs.h>
-#include <vcpkg/vcpkglib.h>
-#include <vcpkg/vcpkgpaths.h>
-
-namespace vcpkg
-{
- static StatusParagraphs load_current_database(Files::Filesystem& fs,
- const fs::path& vcpkg_dir_status_file,
- const fs::path& vcpkg_dir_status_file_old)
- {
- if (!fs.exists(vcpkg_dir_status_file))
- {
- if (!fs.exists(vcpkg_dir_status_file_old))
- {
- // no status file, use empty db
- return StatusParagraphs();
- }
-
- fs.rename(vcpkg_dir_status_file_old, vcpkg_dir_status_file, VCPKG_LINE_INFO);
- }
-
- auto pghs = Paragraphs::get_paragraphs(fs, vcpkg_dir_status_file).value_or_exit(VCPKG_LINE_INFO);
-
- std::vector<std::unique_ptr<StatusParagraph>> status_pghs;
- for (auto&& p : pghs)
- {
- status_pghs.push_back(std::make_unique<StatusParagraph>(std::move(p)));
- }
-
- return StatusParagraphs(std::move(status_pghs));
- }
-
- StatusParagraphs database_load_check(const VcpkgPaths& paths)
- {
- auto& fs = paths.get_filesystem();
-
- const auto updates_dir = paths.vcpkg_dir_updates;
-
- std::error_code ec;
- fs.create_directory(paths.installed, ec);
- fs.create_directory(paths.vcpkg_dir, ec);
- fs.create_directory(paths.vcpkg_dir_info, ec);
- fs.create_directory(updates_dir, ec);
-
- const fs::path& status_file = paths.vcpkg_dir_status_file;
- const fs::path status_file_old = status_file.parent_path() / "status-old";
- const fs::path status_file_new = status_file.parent_path() / "status-new";
-
- StatusParagraphs current_status_db = load_current_database(fs, status_file, status_file_old);
-
- auto update_files = fs.get_files_non_recursive(updates_dir);
- Util::sort(update_files);
- if (update_files.empty())
- {
- // updates directory is empty, control file is up-to-date.
- return current_status_db;
- }
- for (auto&& file : update_files)
- {
- if (!fs.is_regular_file(file)) continue;
- if (file.filename() == "incomplete") continue;
-
- auto pghs = Paragraphs::get_paragraphs(fs, file).value_or_exit(VCPKG_LINE_INFO);
- for (auto&& p : pghs)
- {
- current_status_db.insert(std::make_unique<StatusParagraph>(std::move(p)));
- }
- }
-
- fs.write_contents(status_file_new, Strings::serialize(current_status_db), VCPKG_LINE_INFO);
-
- fs.rename(status_file_new, status_file, VCPKG_LINE_INFO);
-
- for (auto&& file : update_files)
- {
- if (!fs.is_regular_file(file)) continue;
-
- fs.remove(file, VCPKG_LINE_INFO);
- }
-
- return current_status_db;
- }
-
- void write_update(const VcpkgPaths& paths, const StatusParagraph& p)
- {
- static int update_id = 0;
- auto& fs = paths.get_filesystem();
-
- const auto my_update_id = update_id++;
- const auto tmp_update_filename = paths.vcpkg_dir_updates / "incomplete";
- const auto update_filename = paths.vcpkg_dir_updates / Strings::format("%010d", my_update_id);
-
- fs.write_contents(tmp_update_filename, Strings::serialize(p), VCPKG_LINE_INFO);
- fs.rename(tmp_update_filename, update_filename, VCPKG_LINE_INFO);
- }
-
- static void upgrade_to_slash_terminated_sorted_format(Files::Filesystem& fs,
- std::vector<std::string>* lines,
- const fs::path& listfile_path)
- {
- static bool was_tracked = false;
-
- if (lines->empty())
- {
- return;
- }
-
- if (lines->at(0).back() == '/')
- {
- return; // File already in the new format
- }
-
- if (!was_tracked)
- {
- was_tracked = true;
- Metrics::g_metrics.lock()->track_property("listfile", "update to new format");
- }
-
- // The files are sorted such that directories are placed just before the files they contain
- // (They are not necessarily sorted alphabetically, e.g. libflac)
- // Therefore we can detect the entries that represent directories by comparing every element with the next one
- // and checking if the next has a slash immediately after the current one's length
- for (size_t i = 0; i < lines->size() - 1; i++)
- {
- std::string& current_string = lines->at(i);
- const std::string& next_string = lines->at(i + 1);
-
- const size_t potential_slash_char_index = current_string.length();
- // Make sure the index exists first
- if (next_string.size() > potential_slash_char_index && next_string.at(potential_slash_char_index) == '/')
- {
- current_string += '/'; // Mark as a directory
- }
- }
-
- // After suffixing the directories with a slash, we can now sort.
- // We cannot sort before adding the suffixes because the following (actual example):
- /*
- x86-windows/include/FLAC <<<<<< This would be separated from its group due to sorting
- x86-windows/include/FLAC/all.h
- x86-windows/include/FLAC/assert.h
- x86-windows/include/FLAC/callback.h
- x86-windows/include/FLAC++
- x86-windows/include/FLAC++/all.h
- x86-windows/include/FLAC++/decoder.h
- x86-windows/include/FLAC++/encoder.h
- *
- x86-windows/include/FLAC/ <<<<<< This will now be kept with its group when sorting
- x86-windows/include/FLAC/all.h
- x86-windows/include/FLAC/assert.h
- x86-windows/include/FLAC/callback.h
- x86-windows/include/FLAC++/
- x86-windows/include/FLAC++/all.h
- x86-windows/include/FLAC++/decoder.h
- x86-windows/include/FLAC++/encoder.h
- */
- // Note that after sorting, the FLAC++/ group will be placed before the FLAC/ group
- // The new format is lexicographically sorted
- std::sort(lines->begin(), lines->end());
-
- // Replace the listfile on disk
- const fs::path updated_listfile_path = listfile_path.generic_string() + "_updated";
- fs.write_lines(updated_listfile_path, *lines, VCPKG_LINE_INFO);
- fs.rename(updated_listfile_path, listfile_path, VCPKG_LINE_INFO);
- }
-
- std::vector<InstalledPackageView> get_installed_ports(const StatusParagraphs& status_db)
- {
- std::map<PackageSpec, InstalledPackageView> ipv_map;
-
- for (auto&& pgh : status_db)
- {
- if (!pgh->is_installed()) continue;
- auto& ipv = ipv_map[pgh->package.spec];
- if (!pgh->package.is_feature())
- {
- ipv.core = pgh.get();
- }
- else
- {
- ipv.features.emplace_back(pgh.get());
- }
- }
-
- for (auto&& ipv : ipv_map)
- {
- Checks::check_maybe_upgrade(VCPKG_LINE_INFO,
- ipv.second.core != nullptr,
- "Database is corrupted: package %s has features but no core paragraph.",
- ipv.first);
- }
-
- return Util::fmap(ipv_map, [](auto&& p) -> InstalledPackageView { return std::move(p.second); });
- }
-
- std::vector<StatusParagraphAndAssociatedFiles> get_installed_files(const VcpkgPaths& paths,
- const StatusParagraphs& status_db)
- {
- auto& fs = paths.get_filesystem();
-
- std::vector<StatusParagraphAndAssociatedFiles> installed_files;
-
- for (const std::unique_ptr<StatusParagraph>& pgh : status_db)
- {
- if (!pgh->is_installed() || pgh->package.is_feature())
- {
- continue;
- }
-
- const fs::path listfile_path = paths.listfile_path(pgh->package);
- std::vector<std::string> installed_files_of_current_pgh =
- fs.read_lines(listfile_path).value_or_exit(VCPKG_LINE_INFO);
- Strings::trim_all_and_remove_whitespace_strings(&installed_files_of_current_pgh);
- upgrade_to_slash_terminated_sorted_format(fs, &installed_files_of_current_pgh, listfile_path);
-
- // Remove the directories
- Util::erase_remove_if(installed_files_of_current_pgh,
- [](const std::string& file) { return file.back() == '/'; });
-
- StatusParagraphAndAssociatedFiles pgh_and_files = {
- *pgh, SortedVector<std::string>(std::move(installed_files_of_current_pgh))};
- installed_files.push_back(std::move(pgh_and_files));
- }
-
- return installed_files;
- }
-
- std::string shorten_text(const std::string& desc, const size_t length)
- {
- Checks::check_exit(VCPKG_LINE_INFO, length >= 3);
- auto simple_desc = std::regex_replace(desc, std::regex("\\s+"), " ");
- return simple_desc.size() <= length ? simple_desc : simple_desc.substr(0, length - 3) + "...";
- }
-}
diff --git a/toolsrc/src/vcpkg/vcpkgpaths.cpp b/toolsrc/src/vcpkg/vcpkgpaths.cpp
deleted file mode 100644
index b9f1f3f9c..000000000
--- a/toolsrc/src/vcpkg/vcpkgpaths.cpp
+++ /dev/null
@@ -1,1086 +0,0 @@
-#include <vcpkg/base/expected.h>
-#include <vcpkg/base/files.h>
-#include <vcpkg/base/hash.h>
-#include <vcpkg/base/jsonreader.h>
-#include <vcpkg/base/system.debug.h>
-#include <vcpkg/base/system.process.h>
-#include <vcpkg/base/util.h>
-
-#include <vcpkg/binaryparagraph.h>
-#include <vcpkg/build.h>
-#include <vcpkg/commands.h>
-#include <vcpkg/configuration.h>
-#include <vcpkg/globalstate.h>
-#include <vcpkg/metrics.h>
-#include <vcpkg/packagespec.h>
-#include <vcpkg/registries.h>
-#include <vcpkg/sourceparagraph.h>
-#include <vcpkg/tools.h>
-#include <vcpkg/vcpkgcmdarguments.h>
-#include <vcpkg/vcpkgpaths.h>
-#include <vcpkg/visualstudio.h>
-
-namespace
-{
- using namespace vcpkg;
- fs::path process_input_directory_impl(
- Files::Filesystem& filesystem, const fs::path& root, std::string* option, StringLiteral name, LineInfo li)
- {
- if (option)
- {
- // input directories must exist, so we use canonical
- return filesystem.canonical(li, fs::u8path(*option));
- }
- else
- {
- return root / fs::u8path(name.begin(), name.end());
- }
- }
-
- fs::path process_input_directory(
- Files::Filesystem& filesystem, const fs::path& root, std::string* option, StringLiteral name, LineInfo li)
- {
- auto result = process_input_directory_impl(filesystem, root, option, name, li);
- Debug::print("Using ", name, "-root: ", fs::u8string(result), '\n');
- return result;
- }
-
- fs::path process_output_directory_impl(
- Files::Filesystem& filesystem, const fs::path& root, std::string* option, StringLiteral name, LineInfo li)
- {
- if (option)
- {
- // output directories might not exist, so we use merely absolute
- return filesystem.absolute(li, fs::u8path(*option));
- }
- else
- {
- return root / fs::u8path(name.begin(), name.end());
- }
- }
-
- fs::path process_output_directory(
- Files::Filesystem& filesystem, const fs::path& root, std::string* option, StringLiteral name, LineInfo li)
- {
- auto result = process_output_directory_impl(filesystem, root, option, name, li);
-#if defined(_WIN32)
- result = vcpkg::Files::win32_fix_path_case(result);
-#endif // _WIN32
- Debug::print("Using ", name, "-root: ", fs::u8string(result), '\n');
- return result;
- }
-
- System::Command git_cmd_builder(const VcpkgPaths& paths, const fs::path& dot_git_dir, const fs::path& work_tree)
- {
- return System::Command()
- .path_arg(paths.get_tool_exe(Tools::GIT))
- .string_arg(Strings::concat("--git-dir=", fs::u8string(dot_git_dir)))
- .string_arg(Strings::concat("--work-tree=", fs::u8string(work_tree)));
- }
-} // unnamed namespace
-
-namespace vcpkg
-{
- static Configuration deserialize_configuration(const Json::Object& obj,
- const VcpkgCmdArguments& args,
- const fs::path& filepath)
- {
- Json::Reader reader;
- auto deserializer = make_configuration_deserializer(filepath.parent_path());
-
- auto parsed_config_opt = reader.visit(obj, *deserializer);
- if (!reader.errors().empty())
- {
- System::print2(System::Color::error, "Errors occurred while parsing ", fs::u8string(filepath), "\n");
- for (auto&& msg : reader.errors())
- System::print2(" ", msg, '\n');
-
- System::print2("See https://github.com/Microsoft/vcpkg/tree/master/docs/specifications/registries.md for "
- "more information.\n");
- Checks::exit_fail(VCPKG_LINE_INFO);
- }
-
- parsed_config_opt.get()->validate_feature_flags(args.feature_flag_settings());
-
- return std::move(parsed_config_opt).value_or_exit(VCPKG_LINE_INFO);
- }
-
- struct ManifestAndConfig
- {
- fs::path config_directory;
- Configuration config;
- };
-
- static std::pair<Json::Object, Json::JsonStyle> load_manifest(const Files::Filesystem& fs,
- const fs::path& manifest_dir)
- {
- std::error_code ec;
- auto manifest_path = manifest_dir / fs::u8path("vcpkg.json");
- auto manifest_opt = Json::parse_file(fs, manifest_path, ec);
- if (ec)
- {
- Checks::exit_maybe_upgrade(VCPKG_LINE_INFO,
- "Failed to load manifest from directory %s: %s",
- fs::u8string(manifest_dir),
- ec.message());
- }
-
- if (!manifest_opt.has_value())
- {
- Checks::exit_maybe_upgrade(VCPKG_LINE_INFO,
- "Failed to parse manifest at %s:\n%s",
- fs::u8string(manifest_path),
- manifest_opt.error()->format());
- }
- auto manifest_value = std::move(manifest_opt).value_or_exit(VCPKG_LINE_INFO);
-
- if (!manifest_value.first.is_object())
- {
- System::print2(System::Color::error,
- "Failed to parse manifest at ",
- fs::u8string(manifest_path),
- ": Manifest files must have a top-level object\n");
- Checks::exit_fail(VCPKG_LINE_INFO);
- }
- return {std::move(manifest_value.first.object()), std::move(manifest_value.second)};
- }
-
- struct ConfigAndPath
- {
- fs::path config_directory;
- Configuration config;
- };
-
- // doesn't yet implement searching upwards for configurations, nor inheritance of configurations
- static ConfigAndPath load_configuration(const Files::Filesystem& fs,
- const VcpkgCmdArguments& args,
- const fs::path& vcpkg_root,
- const fs::path& manifest_dir)
- {
- fs::path config_dir;
- if (manifest_dir.empty())
- {
- // classic mode
- config_dir = vcpkg_root;
- }
- else
- {
- // manifest mode
- config_dir = manifest_dir;
- }
-
- auto path_to_config = config_dir / fs::u8path("vcpkg-configuration.json");
- if (!fs.exists(path_to_config))
- {
- return {};
- }
-
- auto parsed_config = Json::parse_file(VCPKG_LINE_INFO, fs, path_to_config);
- if (!parsed_config.first.is_object())
- {
- System::print2(System::Color::error,
- "Failed to parse ",
- fs::u8string(path_to_config),
- ": configuration files must have a top-level object\n");
- Checks::exit_fail(VCPKG_LINE_INFO);
- }
- auto config_obj = std::move(parsed_config.first.object());
-
- return {std::move(config_dir), deserialize_configuration(config_obj, args, path_to_config)};
- }
-
- namespace details
- {
- struct VcpkgPathsImpl
- {
- VcpkgPathsImpl(Files::Filesystem& fs, FeatureFlagSettings ff_settings)
- : fs_ptr(&fs)
- , m_tool_cache(get_tool_cache())
- , m_env_cache(ff_settings.compiler_tracking)
- , m_ff_settings(ff_settings)
- {
- const auto& cache_root =
- System::get_platform_cache_home().value_or_exit(VCPKG_LINE_INFO) / fs::u8path("vcpkg");
- registries_work_tree_dir = cache_root / fs::u8path("registries") / fs::u8path("git");
- registries_dot_git_dir = registries_work_tree_dir / fs::u8path(".git");
- registries_git_trees = cache_root / fs::u8path("registries") / fs::u8path("git-trees");
- }
-
- Lazy<std::vector<VcpkgPaths::TripletFile>> available_triplets;
- Lazy<std::vector<Toolset>> toolsets;
- Lazy<std::map<std::string, std::string>> cmake_script_hashes;
-
- Files::Filesystem* fs_ptr;
-
- fs::path default_vs_path;
- std::vector<fs::path> triplets_dirs;
-
- std::unique_ptr<ToolCache> m_tool_cache;
- Cache<Triplet, fs::path> m_triplets_cache;
- Build::EnvCache m_env_cache;
-
- fs::SystemHandle file_lock_handle;
-
- Optional<std::pair<Json::Object, Json::JsonStyle>> m_manifest_doc;
- fs::path m_manifest_path;
- Configuration m_config;
-
- FeatureFlagSettings m_ff_settings;
-
- fs::path registries_work_tree_dir;
- fs::path registries_dot_git_dir;
- fs::path registries_git_trees;
- };
- }
-
- VcpkgPaths::VcpkgPaths(Files::Filesystem& filesystem, const VcpkgCmdArguments& args)
- : m_pimpl(std::make_unique<details::VcpkgPathsImpl>(filesystem, args.feature_flag_settings()))
- {
- original_cwd = filesystem.current_path(VCPKG_LINE_INFO);
-#if defined(_WIN32)
- original_cwd = vcpkg::Files::win32_fix_path_case(original_cwd);
-#endif // _WIN32
-
- if (args.vcpkg_root_dir)
- {
- root = filesystem.canonical(VCPKG_LINE_INFO, fs::u8path(*args.vcpkg_root_dir));
- }
- else
- {
- root = filesystem.find_file_recursively_up(original_cwd, ".vcpkg-root");
- if (root.empty())
- {
- root = filesystem.find_file_recursively_up(
- filesystem.canonical(VCPKG_LINE_INFO, System::get_exe_path_of_current_process()), ".vcpkg-root");
- }
- }
-
- Checks::check_exit(VCPKG_LINE_INFO, !root.empty(), "Error: Could not detect vcpkg-root.");
- Debug::print("Using vcpkg-root: ", fs::u8string(root), '\n');
-
- std::error_code ec;
- bool manifest_mode_on = args.manifest_mode.value_or(args.manifest_root_dir != nullptr);
- if (args.manifest_root_dir)
- {
- manifest_root_dir = filesystem.canonical(VCPKG_LINE_INFO, fs::u8path(*args.manifest_root_dir));
- }
- else
- {
- manifest_root_dir = filesystem.find_file_recursively_up(original_cwd, fs::u8path("vcpkg.json"));
- }
-
- if (!manifest_root_dir.empty() && manifest_mode_on)
- {
- Debug::print("Using manifest-root: ", fs::u8string(manifest_root_dir), '\n');
-
- installed = process_output_directory(
- filesystem, manifest_root_dir, args.install_root_dir.get(), "vcpkg_installed", VCPKG_LINE_INFO);
-
- const auto vcpkg_lock = root / ".vcpkg-root";
- if (args.wait_for_lock.value_or(false))
- {
- m_pimpl->file_lock_handle = filesystem.take_exclusive_file_lock(vcpkg_lock, ec);
- }
- else
- {
- m_pimpl->file_lock_handle = filesystem.try_take_exclusive_file_lock(vcpkg_lock, ec);
- }
-
- if (ec)
- {
- if (ec == std::errc::device_or_resource_busy || args.ignore_lock_failures.value_or(false))
- {
- System::printf(
- System::Color::error, "Failed to take the filesystem lock on %s:\n", fs::u8string(vcpkg_lock));
- System::printf(System::Color::error, " %s\n", ec.message());
- Checks::exit_fail(VCPKG_LINE_INFO);
- }
- }
-
- m_pimpl->m_manifest_doc = load_manifest(filesystem, manifest_root_dir);
- m_pimpl->m_manifest_path = manifest_root_dir / fs::u8path("vcpkg.json");
- }
- else
- {
- // we ignore the manifest root dir if the user requests -manifest
- if (!manifest_root_dir.empty() && !args.manifest_mode.has_value() && !args.output_json())
- {
- System::print2(System::Color::warning,
- "Warning: manifest-root detected at ",
- fs::generic_u8string(manifest_root_dir),
- ", but manifests are not enabled.\n");
- System::printf(System::Color::warning,
- R"(If you wish to use manifest mode, you may do one of the following:
- * Add the `%s` feature flag to the comma-separated environment
- variable `%s`.
- * Add the `%s` feature flag to the `--%s` option.
- * Pass your manifest directory to the `--%s` option.
-If you wish to silence this error and use classic mode, you can:
- * Add the `-%s` feature flag to `%s`.
- * Add the `-%s` feature flag to `--%s`.
-)",
- VcpkgCmdArguments::MANIFEST_MODE_FEATURE,
- VcpkgCmdArguments::FEATURE_FLAGS_ENV,
- VcpkgCmdArguments::MANIFEST_MODE_FEATURE,
- VcpkgCmdArguments::FEATURE_FLAGS_ARG,
- VcpkgCmdArguments::MANIFEST_ROOT_DIR_ARG,
- VcpkgCmdArguments::MANIFEST_MODE_FEATURE,
- VcpkgCmdArguments::FEATURE_FLAGS_ENV,
- VcpkgCmdArguments::MANIFEST_MODE_FEATURE,
- VcpkgCmdArguments::FEATURE_FLAGS_ARG);
- }
-
- manifest_root_dir.clear();
- installed =
- process_output_directory(filesystem, root, args.install_root_dir.get(), "installed", VCPKG_LINE_INFO);
- }
-
- auto config_file = load_configuration(filesystem, args, root, manifest_root_dir);
-
- config_root_dir = std::move(config_file.config_directory);
- m_pimpl->m_config = std::move(config_file.config);
-
- buildtrees =
- process_output_directory(filesystem, root, args.buildtrees_root_dir.get(), "buildtrees", VCPKG_LINE_INFO);
- downloads =
- process_output_directory(filesystem, root, args.downloads_root_dir.get(), "downloads", VCPKG_LINE_INFO);
- packages =
- process_output_directory(filesystem, root, args.packages_root_dir.get(), "packages", VCPKG_LINE_INFO);
- scripts = process_input_directory(filesystem, root, args.scripts_root_dir.get(), "scripts", VCPKG_LINE_INFO);
- builtin_ports =
- process_output_directory(filesystem, root, args.builtin_ports_root_dir.get(), "ports", VCPKG_LINE_INFO);
- builtin_registry_versions = process_output_directory(
- filesystem, root, args.builtin_registry_versions_dir.get(), "versions", VCPKG_LINE_INFO);
- prefab = root / fs::u8path("prefab");
-
- if (args.default_visual_studio_path)
- {
- m_pimpl->default_vs_path =
- filesystem.canonical(VCPKG_LINE_INFO, fs::u8path(*args.default_visual_studio_path));
- }
-
- triplets = filesystem.canonical(VCPKG_LINE_INFO, root / fs::u8path("triplets"));
- community_triplets = filesystem.canonical(VCPKG_LINE_INFO, triplets / fs::u8path("community"));
-
- tools = downloads / fs::u8path("tools");
- buildsystems = scripts / fs::u8path("buildsystems");
- const auto msbuildDirectory = buildsystems / fs::u8path("msbuild");
- buildsystems_msbuild_targets = msbuildDirectory / fs::u8path("vcpkg.targets");
- buildsystems_msbuild_props = msbuildDirectory / fs::u8path("vcpkg.props");
-
- vcpkg_dir = installed / fs::u8path("vcpkg");
- vcpkg_dir_status_file = vcpkg_dir / fs::u8path("status");
- vcpkg_dir_info = vcpkg_dir / fs::u8path("info");
- vcpkg_dir_updates = vcpkg_dir / fs::u8path("updates");
-
- const auto versioning_tmp = buildtrees / fs::u8path("versioning_tmp");
- const auto versioning_output = buildtrees / fs::u8path("versioning");
-
- baselines_dot_git_dir = versioning_tmp / fs::u8path(".baselines.git");
- baselines_work_tree = versioning_tmp / fs::u8path("baselines-worktree");
- baselines_output = versioning_output / fs::u8path("baselines");
-
- versions_dot_git_dir = versioning_tmp / fs::u8path(".versions.git");
- versions_work_tree = versioning_tmp / fs::u8path("versions-worktree");
- versions_output = versioning_output / fs::u8path("versions");
-
- ports_cmake = filesystem.canonical(VCPKG_LINE_INFO, scripts / fs::u8path("ports.cmake"));
-
- for (auto&& overlay_triplets_dir : args.overlay_triplets)
- {
- m_pimpl->triplets_dirs.emplace_back(
- filesystem.canonical(VCPKG_LINE_INFO, fs::u8path(overlay_triplets_dir)));
- }
- m_pimpl->triplets_dirs.emplace_back(triplets);
- m_pimpl->triplets_dirs.emplace_back(community_triplets);
- }
-
- fs::path VcpkgPaths::package_dir(const PackageSpec& spec) const { return this->packages / fs::u8path(spec.dir()); }
- fs::path VcpkgPaths::build_dir(const PackageSpec& spec) const { return this->buildtrees / fs::u8path(spec.name()); }
- fs::path VcpkgPaths::build_dir(const std::string& package_name) const
- {
- return this->buildtrees / fs::u8path(package_name);
- }
-
- fs::path VcpkgPaths::build_info_file_path(const PackageSpec& spec) const
- {
- return this->package_dir(spec) / "BUILD_INFO";
- }
-
- fs::path VcpkgPaths::listfile_path(const BinaryParagraph& pgh) const
- {
- return this->vcpkg_dir_info / (pgh.fullstem() + ".list");
- }
-
- bool VcpkgPaths::is_valid_triplet(Triplet t) const
- {
- const auto it = Util::find_if(this->get_available_triplets(), [&](auto&& available_triplet) {
- return t.canonical_name() == available_triplet.name;
- });
- return it != this->get_available_triplets().cend();
- }
-
- const std::vector<std::string> VcpkgPaths::get_available_triplets_names() const
- {
- return vcpkg::Util::fmap(this->get_available_triplets(),
- [](auto&& triplet_file) -> std::string { return triplet_file.name; });
- }
-
- const std::vector<VcpkgPaths::TripletFile>& VcpkgPaths::get_available_triplets() const
- {
- return m_pimpl->available_triplets.get_lazy([this]() -> std::vector<TripletFile> {
- std::vector<TripletFile> output;
- Files::Filesystem& fs = this->get_filesystem();
- for (auto&& triplets_dir : m_pimpl->triplets_dirs)
- {
- for (auto&& path : fs.get_files_non_recursive(triplets_dir))
- {
- if (fs::is_regular_file(fs.status(VCPKG_LINE_INFO, path)))
- {
- output.emplace_back(TripletFile(fs::u8string(path.stem().filename()), triplets_dir));
- }
- }
- }
- return output;
- });
- }
-
- const std::map<std::string, std::string>& VcpkgPaths::get_cmake_script_hashes() const
- {
- return m_pimpl->cmake_script_hashes.get_lazy([this]() -> std::map<std::string, std::string> {
- auto& fs = this->get_filesystem();
- std::map<std::string, std::string> helpers;
- auto files = fs.get_files_non_recursive(this->scripts / fs::u8path("cmake"));
- for (auto&& file : files)
- {
- helpers.emplace(fs::u8string(file.stem()),
- Hash::get_file_hash(VCPKG_LINE_INFO, fs, file, Hash::Algorithm::Sha1));
- }
- return helpers;
- });
- }
-
- const fs::path VcpkgPaths::get_triplet_file_path(Triplet triplet) const
- {
- return m_pimpl->m_triplets_cache.get_lazy(
- triplet, [&]() -> auto {
- for (const auto& triplet_dir : m_pimpl->triplets_dirs)
- {
- auto path = triplet_dir / (triplet.canonical_name() + ".cmake");
- if (this->get_filesystem().exists(path))
- {
- return path;
- }
- }
-
- Checks::exit_with_message(
- VCPKG_LINE_INFO, "Error: Triplet file %s.cmake not found", triplet.canonical_name());
- });
- }
-
- const fs::path& VcpkgPaths::get_tool_exe(const std::string& tool) const
- {
- return m_pimpl->m_tool_cache->get_tool_path(*this, tool);
- }
- const std::string& VcpkgPaths::get_tool_version(const std::string& tool) const
- {
- return m_pimpl->m_tool_cache->get_tool_version(*this, tool);
- }
-
- void VcpkgPaths::git_checkout_subpath(const VcpkgPaths& paths,
- StringView commit_sha,
- const fs::path& subpath,
- const fs::path& local_repo,
- const fs::path& destination,
- const fs::path& dot_git_dir,
- const fs::path& work_tree)
- {
- Files::Filesystem& fs = paths.get_filesystem();
- fs.remove_all(work_tree, VCPKG_LINE_INFO);
- fs.remove_all(destination, VCPKG_LINE_INFO);
- fs.remove_all(dot_git_dir, VCPKG_LINE_INFO);
-
- // All git commands are run with: --git-dir={dot_git_dir} --work-tree={work_tree_temp}
- // git clone --no-checkout --local --no-hardlinks {vcpkg_root} {dot_git_dir}
- // note that `--no-hardlinks` is added because otherwise, git fails to clone in some cases
- System::Command clone_cmd_builder = git_cmd_builder(paths, dot_git_dir, work_tree)
- .string_arg("clone")
- .string_arg("--no-checkout")
- .string_arg("--local")
- .string_arg("--no-hardlinks")
- .path_arg(local_repo)
- .path_arg(dot_git_dir);
- const auto clone_output = System::cmd_execute_and_capture_output(clone_cmd_builder);
- Checks::check_exit(VCPKG_LINE_INFO,
- clone_output.exit_code == 0,
- "Failed to clone temporary vcpkg instance.\n%s\n",
- clone_output.output);
-
- // git checkout {commit-sha} -- {subpath}
- System::Command checkout_cmd_builder = git_cmd_builder(paths, dot_git_dir, work_tree)
- .string_arg("checkout")
- .string_arg(commit_sha)
- .string_arg("--")
- .path_arg(subpath);
- const auto checkout_output = System::cmd_execute_and_capture_output(checkout_cmd_builder);
- Checks::check_exit(VCPKG_LINE_INFO,
- checkout_output.exit_code == 0,
- "Error: Failed to checkout %s:%s\n%s\n",
- commit_sha,
- fs::u8string(subpath),
- checkout_output.output);
-
- const fs::path checked_out_path = work_tree / subpath;
- const auto& containing_folder = destination.parent_path();
- if (!fs.exists(containing_folder))
- {
- fs.create_directories(containing_folder, VCPKG_LINE_INFO);
- }
-
- std::error_code ec;
- fs.rename_or_copy(checked_out_path, destination, ".tmp", ec);
- fs.remove_all(work_tree, VCPKG_LINE_INFO);
- fs.remove_all(dot_git_dir, VCPKG_LINE_INFO);
- if (ec)
- {
- System::printf(System::Color::error,
- "Error: Couldn't move checked out files from %s to destination %s",
- fs::u8string(checked_out_path),
- fs::u8string(destination));
- Checks::exit_fail(VCPKG_LINE_INFO);
- }
- }
-
- ExpectedS<std::string> VcpkgPaths::get_current_git_sha() const
- {
- auto cmd = git_cmd_builder(*this, this->root / fs::u8path(".git"), this->root);
- cmd.string_arg("rev-parse").string_arg("HEAD");
- auto output = System::cmd_execute_and_capture_output(cmd);
- if (output.exit_code != 0)
- {
- return {std::move(output.output), expected_right_tag};
- }
- else
- {
- return {Strings::trim(std::move(output.output)), expected_left_tag};
- }
- }
- std::string VcpkgPaths::get_current_git_sha_message() const
- {
- auto maybe_cur_sha = get_current_git_sha();
- if (auto p_sha = maybe_cur_sha.get())
- {
- return Strings::concat("The current commit is \"", *p_sha, '"');
- }
- else
- {
- return Strings::concat("Failed to determine the current commit:\n", maybe_cur_sha.error());
- }
- }
-
- ExpectedS<std::string> VcpkgPaths::git_show(const std::string& treeish, const fs::path& dot_git_dir) const
- {
- // All git commands are run with: --git-dir={dot_git_dir} --work-tree={work_tree_temp}
- // git clone --no-checkout --local {vcpkg_root} {dot_git_dir}
- System::Command showcmd =
- git_cmd_builder(*this, dot_git_dir, dot_git_dir).string_arg("show").string_arg(treeish);
-
- auto output = System::cmd_execute_and_capture_output(showcmd);
- if (output.exit_code == 0)
- {
- return {std::move(output.output), expected_left_tag};
- }
- else
- {
- return {std::move(output.output), expected_right_tag};
- }
- }
-
- ExpectedS<std::map<std::string, std::string, std::less<>>> VcpkgPaths::git_get_local_port_treeish_map() const
- {
- const auto local_repo = this->root / fs::u8path(".git");
- const auto path_with_separator =
- Strings::concat(fs::u8string(this->builtin_ports_directory()), Files::preferred_separator);
- const auto git_cmd = git_cmd_builder(*this, local_repo, this->root)
- .string_arg("ls-tree")
- .string_arg("-d")
- .string_arg("HEAD")
- .string_arg("--")
- .path_arg(path_with_separator);
-
- auto output = System::cmd_execute_and_capture_output(git_cmd);
- if (output.exit_code != 0)
- return Strings::format("Error: Couldn't get local treeish objects for ports.\n%s", output.output);
-
- std::map<std::string, std::string, std::less<>> ret;
- auto lines = Strings::split(output.output, '\n');
- // The first line of the output is always the parent directory itself.
- for (auto line : lines)
- {
- // The default output comes in the format:
- // <mode> SP <type> SP <object> TAB <file>
- auto split_line = Strings::split(line, '\t');
- if (split_line.size() != 2)
- return Strings::format("Error: Unexpected output from command `%s`. Couldn't split by `\\t`.\n%s",
- git_cmd.command_line(),
- line);
-
- auto file_info_section = Strings::split(split_line[0], ' ');
- if (file_info_section.size() != 3)
- return Strings::format("Error: Unexepcted output from command `%s`. Couldn't split by ` `.\n%s",
- git_cmd.command_line(),
- line);
-
- const auto index = split_line[1].find_last_of('/');
- if (index == std::string::npos)
- {
- return Strings::format("Error: Unexpected output from command `%s`. Couldn't split by `/`.\n%s",
- git_cmd.command_line(),
- line);
- }
-
- ret.emplace(split_line[1].substr(index + 1), file_info_section.back());
- }
- return ret;
- }
-
- ExpectedS<fs::path> VcpkgPaths::git_checkout_baseline(StringView commit_sha) const
- {
- Files::Filesystem& fs = get_filesystem();
- const fs::path destination_parent = this->baselines_output / fs::u8path(commit_sha);
- fs::path destination = destination_parent / fs::u8path("baseline.json");
-
- if (!fs.exists(destination))
- {
- const fs::path destination_tmp = destination_parent / fs::u8path("baseline.json.tmp");
- auto treeish = Strings::concat(commit_sha, ":versions/baseline.json");
- auto maybe_contents = git_show(treeish, this->root / fs::u8path(".git"));
- if (auto contents = maybe_contents.get())
- {
- std::error_code ec;
- fs.create_directories(destination_parent, ec);
- if (ec)
- {
- return {Strings::format(
- "Error: while checking out baseline %s\nError: while creating directories %s: %s",
- commit_sha,
- fs::u8string(destination_parent),
- ec.message()),
- expected_right_tag};
- }
- fs.write_contents(destination_tmp, *contents, ec);
- if (ec)
- {
- return {Strings::format("Error: while checking out baseline %s\nError: while writing %s: %s",
- commit_sha,
- fs::u8string(destination_tmp),
- ec.message()),
- expected_right_tag};
- }
- fs.rename(destination_tmp, destination, ec);
- if (ec)
- {
- return {Strings::format("Error: while checking out baseline %s\nError: while renaming %s to %s: %s",
- commit_sha,
- fs::u8string(destination_tmp),
- fs::u8string(destination),
- ec.message()),
- expected_right_tag};
- }
- }
- else
- {
- return {Strings::format("Error: while checking out baseline '%s':\n%s\nThis may be fixed by updating "
- "vcpkg to the latest master via `git pull`.",
- treeish,
- maybe_contents.error()),
- expected_right_tag};
- }
- }
- return destination;
- }
-
- ExpectedS<fs::path> VcpkgPaths::git_checkout_port(StringView port_name,
- StringView git_tree,
- const fs::path& dot_git_dir) const
- {
- /* Check out a git tree into the versioned port recipes folder
- *
- * Since we are checking a git tree object, all files will be checked out to the root of `work-tree`.
- * Because of that, it makes sense to use the git hash as the name for the directory.
- */
- Files::Filesystem& fs = get_filesystem();
- fs::path destination = this->versions_output / fs::u8path(port_name) / fs::u8path(git_tree);
- if (fs.exists(destination))
- {
- return destination;
- }
-
- const fs::path destination_tmp =
- this->versions_output / fs::u8path(port_name) / fs::u8path(Strings::concat(git_tree, ".tmp"));
- const fs::path destination_tar =
- this->versions_output / fs::u8path(port_name) / fs::u8path(Strings::concat(git_tree, ".tar"));
-#define PRELUDE "Error: while checking out port ", port_name, " with git tree ", git_tree, "\n"
- std::error_code ec;
- fs::path failure_point;
- fs.remove_all(destination_tmp, ec, failure_point);
- if (ec)
- {
- return {Strings::concat(PRELUDE, "Error: while removing ", fs::u8string(failure_point), ": ", ec.message()),
- expected_right_tag};
- }
- fs.create_directories(destination_tmp, ec);
- if (ec)
- {
- return {
- Strings::concat(
- PRELUDE, "Error: while creating directories ", fs::u8string(destination_tmp), ": ", ec.message()),
- expected_right_tag};
- }
-
- auto tar_cmd_builder = git_cmd_builder(*this, dot_git_dir, dot_git_dir)
- .string_arg("archive")
- .string_arg(git_tree)
- .string_arg("-o")
- .path_arg(destination_tar);
- const auto tar_output = System::cmd_execute_and_capture_output(tar_cmd_builder);
- if (tar_output.exit_code != 0)
- {
- return {Strings::concat(PRELUDE, "Error: Failed to tar port directory\n", tar_output.output),
- expected_right_tag};
- }
-
- auto extract_cmd_builder = System::Command{this->get_tool_exe(Tools::CMAKE)}
- .string_arg("-E")
- .string_arg("tar")
- .string_arg("xf")
- .path_arg(destination_tar);
-
- const auto extract_output =
- System::cmd_execute_and_capture_output(extract_cmd_builder, System::InWorkingDirectory{destination_tmp});
- if (extract_output.exit_code != 0)
- {
- return {Strings::concat(PRELUDE, "Error: Failed to extract port directory\n", extract_output.output),
- expected_right_tag};
- }
- fs.remove(destination_tar, ec);
- if (ec)
- {
- return {
- Strings::concat(PRELUDE, "Error: while removing ", fs::u8string(destination_tar), ": ", ec.message()),
- expected_right_tag};
- }
- fs.rename(destination_tmp, destination, ec);
- if (ec)
- {
- return {Strings::concat(PRELUDE,
- "Error: while renaming ",
- fs::u8string(destination_tmp),
- " to ",
- fs::u8string(destination),
- ": ",
- ec.message()),
- expected_right_tag};
- }
-
- return destination;
-#undef PRELUDE
- }
-
- ExpectedS<std::string> VcpkgPaths::git_fetch_from_remote_registry(StringView repo, StringView treeish) const
- {
- auto& fs = get_filesystem();
-
- auto work_tree = m_pimpl->registries_work_tree_dir;
- fs.create_directories(work_tree, VCPKG_LINE_INFO);
- auto dot_git_dir = m_pimpl->registries_dot_git_dir;
-
- System::Command init_registries_git_dir = git_cmd_builder(*this, dot_git_dir, work_tree).string_arg("init");
- auto init_output = System::cmd_execute_and_capture_output(init_registries_git_dir);
- if (init_output.exit_code != 0)
- {
- return {Strings::format("Error: Failed to initialize local repository %s.\n%s\n",
- fs::u8string(work_tree),
- init_output.output),
- expected_right_tag};
- }
-
- auto lock_file = work_tree / fs::u8path(".vcpkg-lock");
-
- std::error_code ec;
- Files::ExclusiveFileLock guard(Files::ExclusiveFileLock::Wait::Yes, fs, lock_file, ec);
-
- System::Command fetch_git_ref =
- git_cmd_builder(*this, dot_git_dir, work_tree).string_arg("fetch").string_arg("--").string_arg(repo);
- if (treeish.size() != 0)
- {
- fetch_git_ref.string_arg(treeish);
- }
-
- auto fetch_output = System::cmd_execute_and_capture_output(fetch_git_ref);
- if (fetch_output.exit_code != 0)
- {
- return {Strings::format("Error: Failed to fetch %s%s from repository %s.\n%s\n",
- treeish.size() != 0 ? "ref " : "",
- treeish,
- repo,
- fetch_output.output),
- expected_right_tag};
- }
-
- System::Command get_fetch_head =
- git_cmd_builder(*this, dot_git_dir, work_tree).string_arg("rev-parse").string_arg("FETCH_HEAD");
- auto fetch_head_output = System::cmd_execute_and_capture_output(get_fetch_head);
- if (fetch_head_output.exit_code != 0)
- {
- return {Strings::format("Error: Failed to rev-parse FETCH_HEAD.\n%s\n", fetch_head_output.output),
- expected_right_tag};
- }
- return {Strings::trim(fetch_head_output.output).to_string(), expected_left_tag};
- }
- // returns an error if there was an unexpected error; returns nullopt if the file doesn't exist at the specified
- // hash
- ExpectedS<std::string> VcpkgPaths::git_show_from_remote_registry(StringView hash,
- const fs::path& relative_path) const
- {
- auto revision = Strings::format("%s:%s", hash, fs::generic_u8string(relative_path));
- System::Command git_show =
- git_cmd_builder(*this, m_pimpl->registries_dot_git_dir, m_pimpl->registries_work_tree_dir)
- .string_arg("show")
- .string_arg(revision);
-
- auto git_show_output = System::cmd_execute_and_capture_output(git_show);
- if (git_show_output.exit_code != 0)
- {
- return {git_show_output.output, expected_right_tag};
- }
- return {git_show_output.output, expected_left_tag};
- }
- ExpectedS<std::string> VcpkgPaths::git_find_object_id_for_remote_registry_path(StringView hash,
- const fs::path& relative_path) const
- {
- auto revision = Strings::format("%s:%s", hash, fs::generic_u8string(relative_path));
- System::Command git_rev_parse =
- git_cmd_builder(*this, m_pimpl->registries_dot_git_dir, m_pimpl->registries_work_tree_dir)
- .string_arg("rev-parse")
- .string_arg(revision);
-
- auto git_rev_parse_output = System::cmd_execute_and_capture_output(git_rev_parse);
- if (git_rev_parse_output.exit_code != 0)
- {
- return {git_rev_parse_output.output, expected_right_tag};
- }
- return {Strings::trim(git_rev_parse_output.output).to_string(), expected_left_tag};
- }
- ExpectedS<fs::path> VcpkgPaths::git_checkout_object_from_remote_registry(StringView object) const
- {
- auto& fs = get_filesystem();
- fs.create_directories(m_pimpl->registries_git_trees, VCPKG_LINE_INFO);
-
- auto git_tree_final = m_pimpl->registries_git_trees / fs::u8path(object);
- if (fs.exists(git_tree_final))
- {
- return std::move(git_tree_final);
- }
-
- auto pid = System::get_process_id();
-
- fs::path git_tree_temp = fs::u8path(Strings::format("%s.tmp%ld", fs::u8string(git_tree_final), pid));
- fs::path git_tree_temp_tar = fs::u8path(Strings::format("%s.tmp%ld.tar", fs::u8string(git_tree_final), pid));
- fs.remove_all(git_tree_temp, VCPKG_LINE_INFO);
- fs.create_directory(git_tree_temp, VCPKG_LINE_INFO);
-
- auto dot_git_dir = m_pimpl->registries_dot_git_dir;
- System::Command git_archive = git_cmd_builder(*this, dot_git_dir, m_pimpl->registries_work_tree_dir)
- .string_arg("archive")
- .string_arg("--format")
- .string_arg("tar")
- .string_arg(object)
- .string_arg("--output")
- .path_arg(git_tree_temp_tar);
- auto git_archive_output = System::cmd_execute_and_capture_output(git_archive);
- if (git_archive_output.exit_code != 0)
- {
- return {Strings::format("git archive failed with message:\n%s", git_archive_output.output),
- expected_right_tag};
- }
-
- auto untar =
- System::Command{get_tool_exe(Tools::CMAKE)}.string_arg("-E").string_arg("tar").string_arg("xf").path_arg(
- git_tree_temp_tar);
-
- auto untar_output = System::cmd_execute_and_capture_output(untar, System::InWorkingDirectory{git_tree_temp});
- if (untar_output.exit_code != 0)
- {
- return {Strings::format("cmake's untar failed with message:\n%s", untar_output.output), expected_right_tag};
- }
-
- std::error_code ec;
- fs.rename(git_tree_temp, git_tree_final, ec);
-
- if (fs.exists(git_tree_final))
- {
- return git_tree_final;
- }
- if (ec)
- {
- return {
- Strings::format("rename to %s failed with message:\n%s", fs::u8string(git_tree_final), ec.message()),
- expected_right_tag};
- }
- else
- {
- return {"Unknown error", expected_right_tag};
- }
- }
-
- Optional<const Json::Object&> VcpkgPaths::get_manifest() const
- {
- if (auto p = m_pimpl->m_manifest_doc.get())
- {
- return p->first;
- }
- else
- {
- return nullopt;
- }
- }
- Optional<const fs::path&> VcpkgPaths::get_manifest_path() const
- {
- if (m_pimpl->m_manifest_doc)
- {
- return m_pimpl->m_manifest_path;
- }
- else
- {
- return nullopt;
- }
- }
-
- const Configuration& VcpkgPaths::get_configuration() const { return m_pimpl->m_config; }
-
- const Toolset& VcpkgPaths::get_toolset(const Build::PreBuildInfo& prebuildinfo) const
- {
- if (!prebuildinfo.using_vcvars())
- {
- static Toolset external_toolset = []() -> Toolset {
- Toolset ret;
- ret.dumpbin.clear();
- ret.supported_architectures = {
- ToolsetArchOption{"", System::get_host_processor(), System::get_host_processor()}};
- ret.vcvarsall.clear();
- ret.vcvarsall_options = {};
- ret.version = "external";
- ret.visual_studio_root_path.clear();
- return ret;
- }();
- return external_toolset;
- }
-
-#if !defined(_WIN32)
- Checks::exit_maybe_upgrade(VCPKG_LINE_INFO, "Cannot build windows triplets from non-windows.");
-#else
- View<Toolset> vs_toolsets = get_all_toolsets();
-
- std::vector<const Toolset*> candidates = Util::fmap(vs_toolsets, [](auto&& x) { return &x; });
- const auto tsv = prebuildinfo.platform_toolset.get();
- auto vsp = prebuildinfo.visual_studio_path.get();
- if (!vsp && !m_pimpl->default_vs_path.empty())
- {
- vsp = &m_pimpl->default_vs_path;
- }
-
- if (tsv && vsp)
- {
- Util::erase_remove_if(
- candidates, [&](const Toolset* t) { return *tsv != t->version || *vsp != t->visual_studio_root_path; });
- Checks::check_exit(VCPKG_LINE_INFO,
- !candidates.empty(),
- "Could not find Visual Studio instance at %s with %s toolset.",
- fs::u8string(*vsp),
- *tsv);
-
- Checks::check_exit(VCPKG_LINE_INFO, candidates.size() == 1);
- return *candidates.back();
- }
-
- if (tsv)
- {
- Util::erase_remove_if(candidates, [&](const Toolset* t) { return *tsv != t->version; });
- Checks::check_exit(
- VCPKG_LINE_INFO, !candidates.empty(), "Could not find Visual Studio instance with %s toolset.", *tsv);
- }
-
- if (vsp)
- {
- const fs::path vs_root_path = *vsp;
- Util::erase_remove_if(candidates,
- [&](const Toolset* t) { return vs_root_path != t->visual_studio_root_path; });
- Checks::check_exit(VCPKG_LINE_INFO,
- !candidates.empty(),
- "Could not find Visual Studio instance at %s.",
- vs_root_path.generic_string());
- }
-
- Checks::check_exit(VCPKG_LINE_INFO, !candidates.empty(), "No suitable Visual Studio instances were found");
- return *candidates.front();
-
-#endif
- }
-
- View<Toolset> VcpkgPaths::get_all_toolsets() const
- {
-#if defined(_WIN32)
- return m_pimpl->toolsets.get_lazy(
- [this]() { return VisualStudio::find_toolset_instances_preferred_first(*this); });
-#else
- return {};
-#endif
- }
-
- const System::Environment& VcpkgPaths::get_action_env(const Build::AbiInfo& abi_info) const
- {
- return m_pimpl->m_env_cache.get_action_env(*this, abi_info);
- }
-
- const std::string& VcpkgPaths::get_triplet_info(const Build::AbiInfo& abi_info) const
- {
- return m_pimpl->m_env_cache.get_triplet_info(*this, abi_info);
- }
-
- const Build::CompilerInfo& VcpkgPaths::get_compiler_info(const Build::AbiInfo& abi_info) const
- {
- return m_pimpl->m_env_cache.get_compiler_info(*this, abi_info);
- }
-
- Files::Filesystem& VcpkgPaths::get_filesystem() const { return *m_pimpl->fs_ptr; }
-
- const FeatureFlagSettings& VcpkgPaths::get_feature_flags() const { return m_pimpl->m_ff_settings; }
-
- void VcpkgPaths::track_feature_flag_metrics() const
- {
- struct
- {
- StringView flag;
- bool enabled;
- } flags[] = {{VcpkgCmdArguments::MANIFEST_MODE_FEATURE, manifest_mode_enabled()}};
-
- for (const auto& flag : flags)
- {
- Metrics::g_metrics.lock()->track_feature(flag.flag.to_string(), flag.enabled);
- }
- }
-
- VcpkgPaths::~VcpkgPaths()
- {
- std::error_code ec;
- if (m_pimpl->file_lock_handle.is_valid())
- {
- m_pimpl->fs_ptr->unlock_file_lock(m_pimpl->file_lock_handle, ec);
- if (ec)
- {
- Debug::print("Failed to unlock filesystem lock: ", ec.message(), '\n');
- }
- }
- }
-}
diff --git a/toolsrc/src/vcpkg/versiondeserializers.cpp b/toolsrc/src/vcpkg/versiondeserializers.cpp
deleted file mode 100644
index 2892aa567..000000000
--- a/toolsrc/src/vcpkg/versiondeserializers.cpp
+++ /dev/null
@@ -1,202 +0,0 @@
-#include <vcpkg/base/util.h>
-
-#include <vcpkg/versiondeserializers.h>
-
-using namespace vcpkg;
-using namespace vcpkg::Versions;
-
-namespace
-{
- constexpr StringLiteral BASELINE = "baseline";
- constexpr StringLiteral VERSION_RELAXED = "version";
- constexpr StringLiteral VERSION_SEMVER = "version-semver";
- constexpr StringLiteral VERSION_STRING = "version-string";
- constexpr StringLiteral VERSION_DATE = "version-date";
- constexpr StringLiteral PORT_VERSION = "port-version";
-
- struct VersionDeserializer final : Json::IDeserializer<std::string>
- {
- VersionDeserializer(StringLiteral type) : m_type(type) { }
- StringView type_name() const override { return m_type; }
-
- Optional<std::string> visit_string(Json::Reader& r, StringView sv) override
- {
- StringView pv(std::find(sv.begin(), sv.end(), '#'), sv.end());
- if (pv.size() == 1)
- {
- r.add_generic_error(type_name(), "invalid character '#' in version text");
- }
- else if (pv.size() > 1)
- {
- r.add_generic_error(type_name(),
- "invalid character '#' in version text. Did you mean \"port-version\": ",
- pv.substr(1),
- "?");
- }
- return sv.to_string();
- }
- StringLiteral m_type;
- };
-
- struct GenericVersionTDeserializer : Json::IDeserializer<VersionT>
- {
- GenericVersionTDeserializer(StringLiteral version_field) : m_version_field(version_field) { }
- StringView type_name() const override { return " a version object"; }
-
- Optional<VersionT> visit_object(Json::Reader& r, const Json::Object& obj) override
- {
- std::string version;
- int port_version = 0;
-
- static VersionDeserializer version_deserializer{"version"};
-
- r.required_object_field(type_name(), obj, m_version_field, version, version_deserializer);
- r.optional_object_field(obj, PORT_VERSION, port_version, Json::NaturalNumberDeserializer::instance);
-
- return VersionT{std::move(version), port_version};
- }
- StringLiteral m_version_field;
- };
-}
-
-namespace vcpkg
-{
- std::unique_ptr<Json::IDeserializer<std::string>> make_version_deserializer(StringLiteral type_name)
- {
- return std::make_unique<VersionDeserializer>(type_name);
- }
-
- SchemedVersion visit_required_schemed_deserializer(StringView parent_type, Json::Reader& r, const Json::Object& obj)
- {
- auto maybe_schemed_version = visit_optional_schemed_deserializer(parent_type, r, obj);
- if (auto p = maybe_schemed_version.get())
- {
- return std::move(*p);
- }
- else
- {
- r.add_generic_error(parent_type, "expected a versioning field (example: ", VERSION_STRING, ")");
- return {};
- }
- }
- Optional<SchemedVersion> visit_optional_schemed_deserializer(StringView parent_type,
- Json::Reader& r,
- const Json::Object& obj)
- {
- Versions::Scheme version_scheme = Versions::Scheme::String;
- std::string version;
- int port_version = 0;
-
- static VersionDeserializer version_exact_deserializer{"an exact version string"};
- static VersionDeserializer version_relaxed_deserializer{"a relaxed version string"};
- static VersionDeserializer version_semver_deserializer{"a semantic version string"};
- static VersionDeserializer version_date_deserializer{"a date version string"};
-
- bool has_exact = r.optional_object_field(obj, VERSION_STRING, version, version_exact_deserializer);
- bool has_relax = r.optional_object_field(obj, VERSION_RELAXED, version, version_relaxed_deserializer);
- bool has_semver = r.optional_object_field(obj, VERSION_SEMVER, version, version_semver_deserializer);
- bool has_date = r.optional_object_field(obj, VERSION_DATE, version, version_date_deserializer);
- int num_versions = (int)has_exact + (int)has_relax + (int)has_semver + (int)has_date;
- bool has_port_version =
- r.optional_object_field(obj, PORT_VERSION, port_version, Json::NaturalNumberDeserializer::instance);
-
- if (num_versions == 0)
- {
- if (!has_port_version)
- {
- return nullopt;
- }
- else
- {
- r.add_generic_error(parent_type, "unexpected \"port_version\" without a versioning field");
- }
- }
- else if (num_versions > 1)
- {
- r.add_generic_error(parent_type, "expected only one versioning field");
- }
- else
- {
- if (has_exact)
- {
- version_scheme = Versions::Scheme::String;
- }
- else if (has_relax)
- {
- version_scheme = Versions::Scheme::Relaxed;
- auto v = Versions::RelaxedVersion::from_string(version);
- if (!v.has_value())
- {
- r.add_generic_error(parent_type, "'version' text was not a relaxed version:\n", v.error());
- }
- }
- else if (has_semver)
- {
- version_scheme = Versions::Scheme::Semver;
- auto v = Versions::SemanticVersion::from_string(version);
- if (!v.has_value())
- {
- r.add_generic_error(parent_type, "'version-semver' text was not a semantic version:\n", v.error());
- }
- }
- else if (has_date)
- {
- version_scheme = Versions::Scheme::Date;
- auto v = Versions::DateVersion::from_string(version);
- if (!v.has_value())
- {
- r.add_generic_error(parent_type, "'version-date' text was not a date version:\n", v.error());
- }
- }
- else
- {
- Checks::unreachable(VCPKG_LINE_INFO);
- }
- }
-
- return SchemedVersion(version_scheme, VersionT{version, port_version});
- }
-
- View<StringView> schemed_deserializer_fields()
- {
- static const StringView t[] = {VERSION_RELAXED, VERSION_SEMVER, VERSION_STRING, VERSION_DATE, PORT_VERSION};
- return t;
- }
-
- void serialize_schemed_version(Json::Object& out_obj,
- Versions::Scheme scheme,
- const std::string& version,
- int port_version,
- bool always_emit_port_version)
- {
- auto version_field = [](Versions::Scheme version_scheme) {
- switch (version_scheme)
- {
- case Versions::Scheme::String: return VERSION_STRING;
- case Versions::Scheme::Semver: return VERSION_SEMVER;
- case Versions::Scheme::Relaxed: return VERSION_RELAXED;
- case Versions::Scheme::Date: return VERSION_DATE;
- default: Checks::unreachable(VCPKG_LINE_INFO);
- }
- };
-
- out_obj.insert(version_field(scheme), Json::Value::string(version));
-
- if (port_version != 0 || always_emit_port_version)
- {
- out_obj.insert(PORT_VERSION, Json::Value::integer(port_version));
- }
- }
-
- Json::IDeserializer<VersionT>& get_versiont_deserializer_instance()
- {
- static GenericVersionTDeserializer deserializer(VERSION_STRING);
- return deserializer;
- }
-
- Json::IDeserializer<VersionT>& get_versiontag_deserializer_instance()
- {
- static GenericVersionTDeserializer deserializer(BASELINE);
- return deserializer;
- }
-}
diff --git a/toolsrc/src/vcpkg/versions.cpp b/toolsrc/src/vcpkg/versions.cpp
deleted file mode 100644
index 239c0e728..000000000
--- a/toolsrc/src/vcpkg/versions.cpp
+++ /dev/null
@@ -1,247 +0,0 @@
-#include <vcpkg/base/util.h>
-
-#include <vcpkg/versions.h>
-
-#include <regex>
-
-namespace vcpkg::Versions
-{
- namespace
- {
- Optional<uint64_t> as_numeric(StringView str)
- {
- uint64_t res = 0;
- size_t digits = 0;
- for (auto&& ch : str)
- {
- uint64_t digit_value = static_cast<unsigned char>(ch) - static_cast<unsigned char>('0');
- if (digit_value > 9) return nullopt;
- if (res > std::numeric_limits<uint64_t>::max() / 10 - digit_value) return nullopt;
- ++digits;
- res = res * 10 + digit_value;
- }
- return res;
- }
- }
-
- VersionSpec::VersionSpec(const std::string& port_name, const VersionT& version)
- : port_name(port_name), version(version)
- {
- }
-
- VersionSpec::VersionSpec(const std::string& port_name, const std::string& version_string, int port_version)
- : port_name(port_name), version(version_string, port_version)
- {
- }
-
- bool operator==(const VersionSpec& lhs, const VersionSpec& rhs)
- {
- return std::tie(lhs.port_name, lhs.version) == std::tie(rhs.port_name, rhs.version);
- }
-
- bool operator!=(const VersionSpec& lhs, const VersionSpec& rhs) { return !(lhs == rhs); }
-
- std::size_t VersionSpecHasher::operator()(const VersionSpec& key) const
- {
- using std::hash;
- using std::size_t;
- using std::string;
-
- return hash<string>()(key.port_name) ^ (hash<string>()(key.version.to_string()) >> 1);
- }
-
- ExpectedS<RelaxedVersion> RelaxedVersion::from_string(const std::string& str)
- {
- std::regex relaxed_scheme_match("^(0|[1-9][0-9]*)(\\.(0|[1-9][0-9]*))*");
-
- if (!std::regex_match(str, relaxed_scheme_match))
- {
- return Strings::format(
- "Error: String `%s` must only contain dot-separated numeric values without leading zeroes.", str);
- }
-
- return RelaxedVersion{str, Util::fmap(Strings::split(str, '.'), [](auto&& strval) -> uint64_t {
- return as_numeric(strval).value_or_exit(VCPKG_LINE_INFO);
- })};
- }
-
- ExpectedS<SemanticVersion> SemanticVersion::from_string(const std::string& str)
- {
- // Suggested regex by semver.org
- std::regex semver_scheme_match("^(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)"
- "(?:-((?:0|[1-9][0-9]*|[0-9]*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9][0-9]*|[0-9]"
- "*[a-zA-Z-][0-9a-zA-Z-]*))*))?"
- "(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$");
-
- if (!std::regex_match(str, semver_scheme_match))
- {
- return Strings::format(
- "Error: String `%s` is not a valid Semantic Version string, consult https://semver.org", str);
- }
-
- SemanticVersion ret;
- ret.original_string = str;
- ret.version_string = str;
-
- auto build_found = ret.version_string.find('+');
- if (build_found != std::string::npos)
- {
- ret.version_string.resize(build_found);
- }
-
- auto prerelease_found = ret.version_string.find('-');
- if (prerelease_found != std::string::npos)
- {
- ret.prerelease_string = ret.version_string.substr(prerelease_found + 1);
- ret.identifiers = Strings::split(ret.prerelease_string, '.');
- ret.version_string.resize(prerelease_found);
- }
-
- std::regex version_match("(0|[1-9][0-9]*)(\\.(0|[1-9][0-9]*)){2}");
- if (!std::regex_match(ret.version_string, version_match))
- {
- return Strings::format("Error: String `%s` does not follow the required MAJOR.MINOR.PATCH format.",
- ret.version_string);
- }
-
- auto parts = Strings::split(ret.version_string, '.');
- ret.version = Util::fmap(
- parts, [](auto&& strval) -> uint64_t { return as_numeric(strval).value_or_exit(VCPKG_LINE_INFO); });
-
- return ret;
- }
-
- ExpectedS<DateVersion> DateVersion::from_string(const std::string& str)
- {
- std::regex date_scheme_match("([0-9]{4}-[0-9]{2}-[0-9]{2})(\\.(0|[1-9][0-9]*))*");
- if (!std::regex_match(str, date_scheme_match))
- {
- return Strings::format("Error: String `%s` is not a valid date version."
- "Date section must follow the format YYYY-MM-DD and disambiguators must be "
- "dot-separated positive integer values without leading zeroes.",
- str);
- }
-
- DateVersion ret;
- ret.original_string = str;
- ret.version_string = str;
-
- auto identifiers_found = ret.version_string.find('.');
- if (identifiers_found != std::string::npos)
- {
- ret.identifiers_string = ret.version_string.substr(identifiers_found + 1);
- ret.identifiers = Util::fmap(Strings::split(ret.identifiers_string, '.'), [](auto&& strval) -> uint64_t {
- return as_numeric(strval).value_or_exit(VCPKG_LINE_INFO);
- });
- ret.version_string.resize(identifiers_found);
- }
-
- return ret;
- }
-
- VerComp compare(const std::string& a, const std::string& b, Scheme scheme)
- {
- if (scheme == Scheme::String)
- {
- return (a == b) ? VerComp::eq : VerComp::unk;
- }
- if (scheme == Scheme::Semver)
- {
- return compare(SemanticVersion::from_string(a).value_or_exit(VCPKG_LINE_INFO),
- SemanticVersion::from_string(b).value_or_exit(VCPKG_LINE_INFO));
- }
- if (scheme == Scheme::Relaxed)
- {
- return compare(RelaxedVersion::from_string(a).value_or_exit(VCPKG_LINE_INFO),
- RelaxedVersion::from_string(b).value_or_exit(VCPKG_LINE_INFO));
- }
- if (scheme == Scheme::Date)
- {
- return compare(DateVersion::from_string(a).value_or_exit(VCPKG_LINE_INFO),
- DateVersion::from_string(b).value_or_exit(VCPKG_LINE_INFO));
- }
- Checks::unreachable(VCPKG_LINE_INFO);
- }
-
- VerComp compare(const RelaxedVersion& a, const RelaxedVersion& b)
- {
- if (a.original_string == b.original_string) return VerComp::eq;
-
- if (a.version < b.version) return VerComp::lt;
- if (a.version > b.version) return VerComp::gt;
- Checks::unreachable(VCPKG_LINE_INFO);
- }
-
- VerComp compare(const SemanticVersion& a, const SemanticVersion& b)
- {
- if (a.version_string == b.version_string)
- {
- if (a.prerelease_string == b.prerelease_string) return VerComp::eq;
- if (a.prerelease_string.empty()) return VerComp::gt;
- if (b.prerelease_string.empty()) return VerComp::lt;
- }
-
- // Compare version elements left-to-right.
- if (a.version < b.version) return VerComp::lt;
- if (a.version > b.version) return VerComp::gt;
-
- // Compare identifiers left-to-right.
- auto count = std::min(a.identifiers.size(), b.identifiers.size());
- for (size_t i = 0; i < count; ++i)
- {
- auto&& iden_a = a.identifiers[i];
- auto&& iden_b = b.identifiers[i];
-
- auto a_numeric = as_numeric(iden_a);
- auto b_numeric = as_numeric(iden_b);
-
- // Numeric identifiers always have lower precedence than non-numeric identifiers.
- if (a_numeric.has_value() && !b_numeric.has_value()) return VerComp::lt;
- if (!a_numeric.has_value() && b_numeric.has_value()) return VerComp::gt;
-
- // Identifiers consisting of only digits are compared numerically.
- if (a_numeric.has_value() && b_numeric.has_value())
- {
- auto a_value = a_numeric.value_or_exit(VCPKG_LINE_INFO);
- auto b_value = b_numeric.value_or_exit(VCPKG_LINE_INFO);
-
- if (a_value < b_value) return VerComp::lt;
- if (a_value > b_value) return VerComp::gt;
- continue;
- }
-
- // Identifiers with letters or hyphens are compared lexically in ASCII sort order.
- auto strcmp_result = std::strcmp(iden_a.c_str(), iden_b.c_str());
- if (strcmp_result < 0) return VerComp::lt;
- if (strcmp_result > 0) return VerComp::gt;
- }
-
- // A larger set of pre-release fields has a higher precedence than a smaller set, if all of the preceding
- // identifiers are equal.
- if (a.identifiers.size() < b.identifiers.size()) return VerComp::lt;
- if (a.identifiers.size() > b.identifiers.size()) return VerComp::gt;
-
- // This should be unreachable since direct string comparisons of version_string and prerelease_string should
- // handle this case. If we ever land here, then there's a bug in the the parsing on
- // SemanticVersion::from_string().
- Checks::unreachable(VCPKG_LINE_INFO);
- }
-
- VerComp compare(const Versions::DateVersion& a, const Versions::DateVersion& b)
- {
- if (a.version_string == b.version_string)
- {
- if (a.identifiers_string == b.identifiers_string) return VerComp::eq;
- if (a.identifiers_string.empty() && !b.identifiers_string.empty()) return VerComp::lt;
- if (!a.identifiers_string.empty() && b.identifiers_string.empty()) return VerComp::gt;
- }
-
- // The date parts in our scheme is lexicographically sortable.
- if (a.version_string < b.version_string) return VerComp::lt;
- if (a.version_string > b.version_string) return VerComp::gt;
- if (a.identifiers < b.identifiers) return VerComp::lt;
- if (a.identifiers > b.identifiers) return VerComp::gt;
-
- Checks::unreachable(VCPKG_LINE_INFO);
- }
-}
diff --git a/toolsrc/src/vcpkg/versiont.cpp b/toolsrc/src/vcpkg/versiont.cpp
deleted file mode 100644
index 09dabb450..000000000
--- a/toolsrc/src/vcpkg/versiont.cpp
+++ /dev/null
@@ -1,48 +0,0 @@
-#include <vcpkg/base/strings.h>
-
-#include <vcpkg/versiont.h>
-
-namespace vcpkg
-{
- VersionT::VersionT() noexcept : m_text("0.0.0"), m_port_version(0) { }
- VersionT::VersionT(std::string&& value, int port_version) : m_text(std::move(value)), m_port_version(port_version)
- {
- }
- VersionT::VersionT(const std::string& value, int port_version) : m_text(value), m_port_version(port_version) { }
-
- std::string VersionT::to_string() const { return Strings::concat(*this); }
- void VersionT::to_string(std::string& out) const
- {
- out.append(m_text);
- if (m_port_version) Strings::append(out, '#', m_port_version);
- }
-
- bool operator==(const VersionT& left, const VersionT& right)
- {
- return left.m_port_version == right.m_port_version && left.m_text == right.m_text;
- }
- bool operator!=(const VersionT& left, const VersionT& right) { return !(left == right); }
-
- bool VersionTMapLess::operator()(const VersionT& left, const VersionT& right) const
- {
- auto cmp = left.m_text.compare(right.m_text);
- if (cmp < 0)
- {
- return true;
- }
- else if (cmp > 0)
- {
- return false;
- }
-
- return left.m_port_version < right.m_port_version;
- }
-
- VersionDiff::VersionDiff() noexcept : left(), right() { }
- VersionDiff::VersionDiff(const VersionT& left, const VersionT& right) : left(left), right(right) { }
-
- std::string VersionDiff::to_string() const
- {
- return Strings::format("%s -> %s", left.to_string(), right.to_string());
- }
-}
diff --git a/toolsrc/src/vcpkg/visualstudio.cpp b/toolsrc/src/vcpkg/visualstudio.cpp
deleted file mode 100644
index b1b289191..000000000
--- a/toolsrc/src/vcpkg/visualstudio.cpp
+++ /dev/null
@@ -1,381 +0,0 @@
-#if defined(_WIN32)
-
-#include <vcpkg/base/sortedvector.h>
-#include <vcpkg/base/strings.h>
-#include <vcpkg/base/stringview.h>
-#include <vcpkg/base/system.print.h>
-#include <vcpkg/base/system.process.h>
-#include <vcpkg/base/util.h>
-
-#include <vcpkg/visualstudio.h>
-
-namespace vcpkg::VisualStudio
-{
- static constexpr CStringView V_120 = "v120";
- static constexpr CStringView V_140 = "v140";
- static constexpr CStringView V_141 = "v141";
- static constexpr CStringView V_142 = "v142";
-
- struct VisualStudioInstance
- {
- enum class ReleaseType
- {
- STABLE,
- PRERELEASE,
- LEGACY
- };
-
- static std::string release_type_to_string(const ReleaseType& release_type)
- {
- switch (release_type)
- {
- case ReleaseType::STABLE: return "STABLE";
- case ReleaseType::PRERELEASE: return "PRERELEASE";
- case ReleaseType::LEGACY: return "LEGACY";
- default: Checks::unreachable(VCPKG_LINE_INFO);
- }
- }
-
- static bool preferred_first_comparator(const VisualStudioInstance& left, const VisualStudioInstance& right)
- {
- const auto get_preference_weight = [](const ReleaseType& type) -> int {
- switch (type)
- {
- case ReleaseType::STABLE: return 3;
- case ReleaseType::PRERELEASE: return 2;
- case ReleaseType::LEGACY: return 1;
- default: Checks::unreachable(VCPKG_LINE_INFO);
- }
- };
-
- if (left.release_type != right.release_type)
- {
- return get_preference_weight(left.release_type) > get_preference_weight(right.release_type);
- }
-
- return left.version > right.version;
- }
-
- VisualStudioInstance(fs::path&& root_path, std::string&& version, const ReleaseType& release_type)
- : root_path(std::move(root_path)), version(std::move(version)), release_type(release_type)
- {
- }
-
- fs::path root_path;
- std::string version;
- ReleaseType release_type;
-
- std::string to_string() const
- {
- return Strings::format(
- "%s, %s, %s", fs::u8string(root_path), version, release_type_to_string(release_type));
- }
-
- std::string major_version() const { return version.substr(0, 2); }
- };
-
- static std::vector<VisualStudioInstance> get_visual_studio_instances_internal(const VcpkgPaths& paths)
- {
- const auto& fs = paths.get_filesystem();
- std::vector<VisualStudioInstance> instances;
-
- const auto& program_files_32_bit = System::get_program_files_32_bit().value_or_exit(VCPKG_LINE_INFO);
-
- // Instances from vswhere
- const fs::path vswhere_exe = program_files_32_bit / "Microsoft Visual Studio" / "Installer" / "vswhere.exe";
- if (fs.exists(vswhere_exe))
- {
- const auto code_and_output = System::cmd_execute_and_capture_output(System::Command(vswhere_exe)
- .string_arg("-all")
- .string_arg("-prerelease")
- .string_arg("-legacy")
- .string_arg("-products")
- .string_arg("*")
- .string_arg("-format")
- .string_arg("xml"));
- Checks::check_exit(VCPKG_LINE_INFO,
- code_and_output.exit_code == 0,
- "Running vswhere.exe failed with message:\n%s",
- code_and_output.output);
-
- const auto instance_entries =
- Strings::find_all_enclosed(code_and_output.output, "<instance>", "</instance>");
- for (const StringView& instance : instance_entries)
- {
- auto maybe_is_prerelease =
- Strings::find_at_most_one_enclosed(instance, "<isPrerelease>", "</isPrerelease>");
-
- VisualStudioInstance::ReleaseType release_type = VisualStudioInstance::ReleaseType::LEGACY;
- if (const auto p = maybe_is_prerelease.get())
- {
- const auto s = p->to_string();
- if (s == "0")
- release_type = VisualStudioInstance::ReleaseType::STABLE;
- else if (s == "1")
- release_type = VisualStudioInstance::ReleaseType::PRERELEASE;
- else
- Checks::unreachable(VCPKG_LINE_INFO);
- }
-
- instances.emplace_back(
- Strings::find_exactly_one_enclosed(instance, "<installationPath>", "</installationPath>")
- .to_string(),
- Strings::find_exactly_one_enclosed(instance, "<installationVersion>", "</installationVersion>")
- .to_string(),
- release_type);
- }
- }
-
- // VS2019 instance from environment variable
- auto maybe_vs160_comntools = System::get_environment_variable("vs160comntools");
- if (const auto path_as_string = maybe_vs160_comntools.get())
- {
- // We want lexically_normal(), but it is not available
- // Correct root path might be 2 or 3 levels up, depending on if the path has trailing backslash.
- auto common7_tools = fs::u8path(*path_as_string);
- if (common7_tools.filename().empty())
- instances.emplace_back(common7_tools.parent_path().parent_path().parent_path(),
- "16.0",
- VisualStudioInstance::ReleaseType::LEGACY);
- else
- instances.emplace_back(
- common7_tools.parent_path().parent_path(), "16.0", VisualStudioInstance::ReleaseType::LEGACY);
- }
-
- const auto append_if_has_cl_vs140 = [&](fs::path&& path_root) {
- const auto cl_exe = path_root / "VC" / "bin" / "cl.exe";
- const auto vcvarsall_bat = path_root / "VC" / "vcvarsall.bat";
-
- if (fs.exists(cl_exe) && fs.exists(vcvarsall_bat))
- instances.emplace_back(std::move(path_root), "14.0", VisualStudioInstance::ReleaseType::LEGACY);
- };
-
- // VS2015 instance from environment variable
- auto maybe_vs140_comntools = System::get_environment_variable("vs140comntools");
- if (const auto path_as_string = maybe_vs140_comntools.get())
- {
- // We want lexically_normal(), but it is not available
- // Correct root path might be 2 or 3 levels up, depending on if the path has trailing backslash.
- auto common7_tools = fs::u8path(*path_as_string);
- if (common7_tools.filename().empty())
- append_if_has_cl_vs140(common7_tools.parent_path().parent_path().parent_path());
- else
- append_if_has_cl_vs140(common7_tools.parent_path().parent_path());
- }
-
- // VS2015 instance from Program Files
- append_if_has_cl_vs140(program_files_32_bit / "Microsoft Visual Studio 14.0");
-
- return instances;
- }
-
- std::vector<std::string> get_visual_studio_instances(const VcpkgPaths& paths)
- {
- std::vector<VisualStudioInstance> sorted{get_visual_studio_instances_internal(paths)};
- std::sort(sorted.begin(), sorted.end(), VisualStudioInstance::preferred_first_comparator);
- return Util::fmap(sorted, [](const VisualStudioInstance& instance) { return instance.to_string(); });
- }
-
- std::vector<Toolset> find_toolset_instances_preferred_first(const VcpkgPaths& paths)
- {
- using CPU = System::CPUArchitecture;
-
- const auto& fs = paths.get_filesystem();
-
- // Note: this will contain a mix of vcvarsall.bat locations and dumpbin.exe locations.
- std::vector<fs::path> paths_examined;
-
- std::vector<Toolset> found_toolsets;
- std::vector<Toolset> excluded_toolsets;
-
- const SortedVector<VisualStudioInstance> sorted{get_visual_studio_instances_internal(paths),
- VisualStudioInstance::preferred_first_comparator};
-
- const bool v140_is_available = Util::find_if(sorted, [&](const VisualStudioInstance& vs_instance) {
- return vs_instance.major_version() == "14";
- }) != sorted.end();
-
- for (const VisualStudioInstance& vs_instance : sorted)
- {
- const std::string major_version = vs_instance.major_version();
- if (major_version >= "15")
- {
- const fs::path vc_dir = vs_instance.root_path / "VC";
-
- // Skip any instances that do not have vcvarsall.
- const fs::path vcvarsall_dir = vc_dir / "Auxiliary" / "Build";
- const fs::path vcvarsall_bat = vcvarsall_dir / "vcvarsall.bat";
- paths_examined.push_back(vcvarsall_bat);
- if (!fs.exists(vcvarsall_bat)) continue;
-
- // Get all supported architectures
- std::vector<ToolsetArchOption> supported_architectures;
- if (fs.exists(vcvarsall_dir / "vcvars32.bat"))
- supported_architectures.push_back({"x86", CPU::X86, CPU::X86});
- if (fs.exists(vcvarsall_dir / "vcvars64.bat"))
- supported_architectures.push_back({"amd64", CPU::X64, CPU::X64});
- if (fs.exists(vcvarsall_dir / "vcvarsx86_amd64.bat"))
- supported_architectures.push_back({"x86_amd64", CPU::X86, CPU::X64});
- if (fs.exists(vcvarsall_dir / "vcvarsx86_arm.bat"))
- supported_architectures.push_back({"x86_arm", CPU::X86, CPU::ARM});
- if (fs.exists(vcvarsall_dir / "vcvarsx86_arm64.bat"))
- supported_architectures.push_back({"x86_arm64", CPU::X86, CPU::ARM64});
- if (fs.exists(vcvarsall_dir / "vcvarsamd64_x86.bat"))
- supported_architectures.push_back({"amd64_x86", CPU::X64, CPU::X86});
- if (fs.exists(vcvarsall_dir / "vcvarsamd64_arm.bat"))
- supported_architectures.push_back({"amd64_arm", CPU::X64, CPU::ARM});
- if (fs.exists(vcvarsall_dir / "vcvarsamd64_arm64.bat"))
- supported_architectures.push_back({"amd64_arm64", CPU::X64, CPU::ARM64});
-
- // Locate the "best" MSVC toolchain version
- const fs::path msvc_path = vc_dir / "Tools" / "MSVC";
- std::vector<fs::path> msvc_subdirectories = fs.get_files_non_recursive(msvc_path);
- Util::erase_remove_if(msvc_subdirectories,
- [&fs](const fs::path& path) { return !fs.is_directory(path); });
-
- // Sort them so that latest comes first
- std::sort(
- msvc_subdirectories.begin(),
- msvc_subdirectories.end(),
- [](const fs::path& left, const fs::path& right) { return left.filename() > right.filename(); });
-
- for (const fs::path& subdir : msvc_subdirectories)
- {
- auto toolset_version_full = fs::u8string(subdir.filename());
- auto toolset_version_prefix = toolset_version_full.substr(0, 4);
- CStringView toolset_version;
- std::string vcvars_option;
- if (toolset_version_prefix.size() != 4)
- {
- // unknown toolset
- continue;
- }
- else if (toolset_version_prefix[3] == '1')
- {
- toolset_version = V_141;
- vcvars_option = "-vcvars_ver=14.1";
- }
- else if (toolset_version_prefix[3] == '2')
- {
- toolset_version = V_142;
- vcvars_option = "-vcvars_ver=14.2";
- }
- else
- {
- // unknown toolset minor version
- continue;
- }
- const fs::path dumpbin_path = subdir / "bin" / "HostX86" / "x86" / "dumpbin.exe";
- paths_examined.push_back(dumpbin_path);
- if (fs.exists(dumpbin_path))
- {
- Toolset toolset{vs_instance.root_path,
- dumpbin_path,
- vcvarsall_bat,
- {vcvars_option},
- toolset_version,
- supported_architectures};
-
- const auto english_language_pack = dumpbin_path.parent_path() / "1033";
-
- if (!fs.exists(english_language_pack))
- {
- excluded_toolsets.push_back(std::move(toolset));
- continue;
- }
-
- found_toolsets.push_back(std::move(toolset));
-
- if (v140_is_available)
- {
- found_toolsets.push_back({vs_instance.root_path,
- dumpbin_path,
- vcvarsall_bat,
- {"-vcvars_ver=14.0"},
- V_140,
- supported_architectures});
- }
-
- continue;
- }
- }
-
- continue;
- }
-
- if (major_version == "14" || major_version == "12")
- {
- const fs::path vcvarsall_bat = vs_instance.root_path / "VC" / "vcvarsall.bat";
-
- paths_examined.push_back(vcvarsall_bat);
- if (fs.exists(vcvarsall_bat))
- {
- const fs::path vs_dumpbin_exe = vs_instance.root_path / "VC" / "bin" / "dumpbin.exe";
- paths_examined.push_back(vs_dumpbin_exe);
-
- const fs::path vs_bin_dir = vcvarsall_bat.parent_path() / "bin";
- std::vector<ToolsetArchOption> supported_architectures;
- if (fs.exists(vs_bin_dir / "vcvars32.bat"))
- supported_architectures.push_back({"x86", CPU::X86, CPU::X86});
- if (fs.exists(vs_bin_dir / "amd64\\vcvars64.bat"))
- supported_architectures.push_back({"x64", CPU::X64, CPU::X64});
- if (fs.exists(vs_bin_dir / "x86_amd64\\vcvarsx86_amd64.bat"))
- supported_architectures.push_back({"x86_amd64", CPU::X86, CPU::X64});
- if (fs.exists(vs_bin_dir / "x86_arm\\vcvarsx86_arm.bat"))
- supported_architectures.push_back({"x86_arm", CPU::X86, CPU::ARM});
- if (fs.exists(vs_bin_dir / "amd64_x86\\vcvarsamd64_x86.bat"))
- supported_architectures.push_back({"amd64_x86", CPU::X64, CPU::X86});
- if (fs.exists(vs_bin_dir / "amd64_arm\\vcvarsamd64_arm.bat"))
- supported_architectures.push_back({"amd64_arm", CPU::X64, CPU::ARM});
-
- if (fs.exists(vs_dumpbin_exe))
- {
- const Toolset toolset = {vs_instance.root_path,
- vs_dumpbin_exe,
- vcvarsall_bat,
- {},
- major_version == "14" ? V_140 : V_120,
- supported_architectures};
-
- const auto english_language_pack = vs_dumpbin_exe.parent_path() / "1033";
-
- if (!fs.exists(english_language_pack))
- {
- excluded_toolsets.push_back(toolset);
- break;
- }
-
- found_toolsets.push_back(toolset);
- }
- }
- }
- }
-
- if (!excluded_toolsets.empty())
- {
- System::print2(
- System::Color::warning,
- "Warning: The following VS instances are excluded because the English language pack is unavailable.\n");
- for (const Toolset& toolset : excluded_toolsets)
- {
- System::print2(" ", fs::u8string(toolset.visual_studio_root_path), '\n');
- }
- System::print2(System::Color::warning, "Please install the English language pack.\n");
- }
-
- if (found_toolsets.empty())
- {
- System::print2(System::Color::error, "Could not locate a complete toolset.\n");
- System::print2("The following paths were examined:\n");
- for (const fs::path& path : paths_examined)
- {
- System::print2(" ", fs::u8string(path), '\n');
- }
- Checks::exit_fail(VCPKG_LINE_INFO);
- }
-
- return found_toolsets;
- }
-}
-
-#endif
diff --git a/toolsrc/vcpkg.natvis b/toolsrc/vcpkg.natvis
deleted file mode 100644
index 7f9c7f61e..000000000
--- a/toolsrc/vcpkg.natvis
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
- <Type Name="vcpkg::ErrorHolder&lt;std::error_code&gt;">
- <DisplayString Condition="m_err._Myval!=0">{m_err}</DisplayString>
- <DisplayString Condition="m_err._Myval==0"></DisplayString>
- </Type>
- <Type Name="vcpkg::ErrorHolder&lt;*&gt;">
- <DisplayString Condition="m_is_error==true">{m_err}</DisplayString>
- <DisplayString Condition="m_is_error==false"></DisplayString>
- </Type>
- <Type Name="vcpkg::ExpectedT&lt;*,std::error_code&gt;">
- <DisplayString Condition="m_s.m_err._Myval==0">val: {m_t}</DisplayString>
- <DisplayString Condition="m_s.m_err._Myval!=0">err: {m_s}</DisplayString>
- </Type>
- <Type Name="vcpkg::ExpectedT&lt;*,*&gt;">
- <DisplayString Condition="m_s.m_is_error==false">val: {m_t}</DisplayString>
- <DisplayString Condition="m_s.m_is_error==true">err: {m_s}</DisplayString>
- </Type>
- <Type Name="vcpkg::Optional&lt;*&gt;">
- <DisplayString Condition="m_base.m_is_present==true">{m_base.m_t}</DisplayString>
- <DisplayString Condition="m_base.m_is_present==false">empty</DisplayString>
- </Type>
- <Type Name="vcpkg::TripletInstance">
- <DisplayString>{*(std::string*)this}</DisplayString>
- </Type>
- <Type Name="vcpkg::Triplet">
- <DisplayString>{m_instance}</DisplayString>
- </Type>
- <Type Name="vcpkg::StringLiteral">
- <DisplayString>{m_cstr}</DisplayString>
- </Type>
- <Type Name="std::experimental::filesystem::v1::path">
- <DisplayString>{_Mystr}</DisplayString>
- </Type>
-</AutoVisualizer> \ No newline at end of file
diff --git a/toolsrc/windows-bootstrap/vcpkg.vcxproj b/toolsrc/windows-bootstrap/vcpkg.vcxproj
deleted file mode 100644
index 9cac2ea0d..000000000
--- a/toolsrc/windows-bootstrap/vcpkg.vcxproj
+++ /dev/null
@@ -1,374 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <ItemGroup Label="ProjectConfigurations">
- <ProjectConfiguration Include="Debug|Win32">
- <Configuration>Debug</Configuration>
- <Platform>Win32</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Release|Win32">
- <Configuration>Release</Configuration>
- <Platform>Win32</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Debug|x64">
- <Configuration>Debug</Configuration>
- <Platform>x64</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Release|x64">
- <Configuration>Release</Configuration>
- <Platform>x64</Platform>
- </ProjectConfiguration>
- </ItemGroup>
- <PropertyGroup Label="Globals">
- <ProjectGuid>{34671B80-54F9-46F5-8310-AC429C11D4FB}</ProjectGuid>
- <RootNamespace>vcpkg</RootNamespace>
- </PropertyGroup>
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
- <PropertyGroup>
- <PlatformToolset Condition="'$(PlatformToolset)'==''">$(DefaultPlatformToolset)</PlatformToolset>
- </PropertyGroup>
- <Choose>
- <When Condition="'$(PlatformToolset)' == 'v140'">
- <PropertyGroup>
- <VcpkgUseStdFilesystem>0</VcpkgUseStdFilesystem>
- </PropertyGroup>
- </When>
- <Otherwise>
- <PropertyGroup>
- <VcpkgUseStdFilesystem>1</VcpkgUseStdFilesystem>
- </PropertyGroup>
- </Otherwise>
- </Choose>
- <ItemDefinitionGroup>
- <ClCompile>
- <PreprocessorDefinitions>VCPKG_USE_STD_FILESYSTEM=$(VcpkgUseStdFilesystem);%(PreprocessorDefinitions)</PreprocessorDefinitions>
- </ClCompile>
- </ItemDefinitionGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
- <ConfigurationType>Application</ConfigurationType>
- <UseDebugLibraries>true</UseDebugLibraries>
- <CharacterSet>MultiByte</CharacterSet>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
- <ConfigurationType>Application</ConfigurationType>
- <UseDebugLibraries>false</UseDebugLibraries>
- <WholeProgramOptimization>true</WholeProgramOptimization>
- <CharacterSet>MultiByte</CharacterSet>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
- <ConfigurationType>Application</ConfigurationType>
- <UseDebugLibraries>true</UseDebugLibraries>
- <CharacterSet>MultiByte</CharacterSet>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
- <ConfigurationType>Application</ConfigurationType>
- <UseDebugLibraries>false</UseDebugLibraries>
- <WholeProgramOptimization>true</WholeProgramOptimization>
- <CharacterSet>MultiByte</CharacterSet>
- </PropertyGroup>
- <PropertyGroup>
- <DISABLE_METRICS Condition="'$(DISABLE_METRICS)' == ''">0</DISABLE_METRICS>
- </PropertyGroup>
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
- <ImportGroup Label="ExtensionSettings">
- </ImportGroup>
- <ImportGroup Label="Shared">
- </ImportGroup>
- <PropertyGroup Label="UserMacros" />
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <IntDir>$(SolutionDir)msbuild.x86.debug\$(ProjectName)\</IntDir>
- <OutDir>$(SolutionDir)msbuild.x86.debug\</OutDir>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <OutDir>$(SolutionDir)msbuild.x86.release\</OutDir>
- <IntDir>$(SolutionDir)msbuild.x86.release\$(ProjectName)\</IntDir>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
- <IntDir>$(SolutionDir)msbuild.x64.debug\$(ProjectName)\</IntDir>
- <OutDir>$(SolutionDir)msbuild.x64.debug\</OutDir>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
- <IntDir>$(SolutionDir)msbuild.x64.release\$(ProjectName)\</IntDir>
- <OutDir>$(SolutionDir)msbuild.x64.release\</OutDir>
- </PropertyGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <ClCompile>
- <WarningLevel>Level4</WarningLevel>
- <Optimization>Disabled</Optimization>
- <SDLCheck>true</SDLCheck>
- <AdditionalIncludeDirectories>..\include</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>VCPKG_VERSION=$(VCPKG_VERSION);VCPKG_BASE_VERSION=$(VCPKG_BASE_VERSION);_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <AdditionalOptions>/std:c++latest %(AdditionalOptions)</AdditionalOptions>
- <MultiProcessorCompilation>true</MultiProcessorCompilation>
- <MinimalRebuild>false</MinimalRebuild>
- <PrecompiledHeader>Use</PrecompiledHeader>
- <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
- <ForcedIncludeFiles>pch.h</ForcedIncludeFiles>
- </ClCompile>
- <Link>
- <AdditionalDependencies>winhttp.lib;version.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;Bcrypt.lib;%(AdditionalDependencies)</AdditionalDependencies>
- </Link>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
- <ClCompile>
- <WarningLevel>Level4</WarningLevel>
- <Optimization>Disabled</Optimization>
- <SDLCheck>true</SDLCheck>
- <AdditionalIncludeDirectories>..\include</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>VCPKG_VERSION=$(VCPKG_VERSION);VCPKG_BASE_VERSION=$(VCPKG_BASE_VERSION);_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <AdditionalOptions>/std:c++latest %(AdditionalOptions)</AdditionalOptions>
- <MultiProcessorCompilation>true</MultiProcessorCompilation>
- <MinimalRebuild>false</MinimalRebuild>
- <PrecompiledHeader>Use</PrecompiledHeader>
- <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
- <ForcedIncludeFiles>pch.h</ForcedIncludeFiles>
- </ClCompile>
- <Link>
- <AdditionalDependencies>winhttp.lib;version.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;Bcrypt.lib;%(AdditionalDependencies)</AdditionalDependencies>
- </Link>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <ClCompile>
- <WarningLevel>Level3</WarningLevel>
- <Optimization>MaxSpeed</Optimization>
- <FunctionLevelLinking>true</FunctionLevelLinking>
- <IntrinsicFunctions>true</IntrinsicFunctions>
- <SDLCheck>true</SDLCheck>
- <AdditionalIncludeDirectories>..\include</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>VCPKG_VERSION=$(VCPKG_VERSION);VCPKG_BASE_VERSION=$(VCPKG_BASE_VERSION);_MBCS;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <PreprocessorDefinitions>_MBCS;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <AdditionalOptions>/std:c++latest %(AdditionalOptions)</AdditionalOptions>
- <MultiProcessorCompilation>true</MultiProcessorCompilation>
- <PrecompiledHeader>Use</PrecompiledHeader>
- <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
- <ForcedIncludeFiles>pch.h</ForcedIncludeFiles>
- </ClCompile>
- <Link>
- <EnableCOMDATFolding>true</EnableCOMDATFolding>
- <OptimizeReferences>true</OptimizeReferences>
- <AdditionalDependencies>winhttp.lib;version.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;Bcrypt.lib;%(AdditionalDependencies)</AdditionalDependencies>
- </Link>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
- <ClCompile>
- <WarningLevel>Level3</WarningLevel>
- <Optimization>MaxSpeed</Optimization>
- <FunctionLevelLinking>true</FunctionLevelLinking>
- <IntrinsicFunctions>true</IntrinsicFunctions>
- <SDLCheck>true</SDLCheck>
- <AdditionalIncludeDirectories>..\include</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>VCPKG_VERSION=$(VCPKG_VERSION);VCPKG_BASE_VERSION=$(VCPKG_BASE_VERSION);_MBCS;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <PreprocessorDefinitions>_MBCS;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <AdditionalOptions>/std:c++latest %(AdditionalOptions)</AdditionalOptions>
- <MultiProcessorCompilation>true</MultiProcessorCompilation>
- <PrecompiledHeader>Use</PrecompiledHeader>
- <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
- <ForcedIncludeFiles>pch.h</ForcedIncludeFiles>
- </ClCompile>
- <Link>
- <EnableCOMDATFolding>true</EnableCOMDATFolding>
- <OptimizeReferences>true</OptimizeReferences>
- <AdditionalDependencies>winhttp.lib;version.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;Bcrypt.lib;%(AdditionalDependencies)</AdditionalDependencies>
- </Link>
- </ItemDefinitionGroup>
- <ItemGroup>
- <ClInclude Include="..\include\pch.h" />
- <ClInclude Include="..\include\vcpkg\archives.h" />
- <ClInclude Include="..\include\vcpkg\base\cache.h" />
- <ClInclude Include="..\include\vcpkg\base\checks.h" />
- <ClInclude Include="..\include\vcpkg\base\chrono.h" />
- <ClInclude Include="..\include\vcpkg\base\cofffilereader.h" />
- <ClInclude Include="..\include\vcpkg\base\cstringview.h" />
- <ClInclude Include="..\include\vcpkg\base\downloads.h" />
- <ClInclude Include="..\include\vcpkg\base\enums.h" />
- <ClInclude Include="..\include\vcpkg\base\expected.h" />
- <ClInclude Include="..\include\vcpkg\base\files.h" />
- <ClInclude Include="..\include\vcpkg\base\graphs.h" />
- <ClInclude Include="..\include\vcpkg\base\hash.h" />
- <ClInclude Include="..\include\vcpkg\base\ignore_errors.h" />
- <ClInclude Include="..\include\vcpkg\base\json.h" />
- <ClInclude Include="..\include\vcpkg\base\lazy.h" />
- <ClInclude Include="..\include\vcpkg\base\lineinfo.h" />
- <ClInclude Include="..\include\vcpkg\base\machinetype.h" />
- <ClInclude Include="..\include\vcpkg\base\parse.h" />
- <ClInclude Include="..\include\vcpkg\base\pragmas.h" />
- <ClInclude Include="..\include\vcpkg\base\optional.h" />
- <ClInclude Include="..\include\vcpkg\base\sortedvector.h" />
- <ClInclude Include="..\include\vcpkg\base\span.h" />
- <ClInclude Include="..\include\vcpkg\base\stringliteral.h" />
- <ClInclude Include="..\include\vcpkg\base\stringrange.h" />
- <ClInclude Include="..\include\vcpkg\base\strings.h" />
- <ClInclude Include="..\include\vcpkg\base\stringview.h" />
- <ClInclude Include="..\include\vcpkg\base\system.debug.h" />
- <ClInclude Include="..\include\vcpkg\base\system.h" />
- <ClInclude Include="..\include\vcpkg\base\system.print.h" />
- <ClInclude Include="..\include\vcpkg\base\system.process.h" />
- <ClInclude Include="..\include\vcpkg\base\unicode.h" />
- <ClInclude Include="..\include\vcpkg\base\util.h" />
- <ClInclude Include="..\include\vcpkg\base\view.h" />
- <ClInclude Include="..\include\vcpkg\base\xmlserializer.h" />
- <ClInclude Include="..\include\vcpkg\base\zstringview.h" />
- <ClInclude Include="..\include\vcpkg\binarycaching.h" />
- <ClInclude Include="..\include\vcpkg\binaryparagraph.h" />
- <ClInclude Include="..\include\vcpkg\build.h" />
- <ClInclude Include="..\include\vcpkg\buildenvironment.h" />
- <ClInclude Include="..\include\vcpkg\cmakevars.h" />
- <ClInclude Include="..\include\vcpkg\commands.h" />
- <ClInclude Include="..\include\vcpkg\commands.add-version.h" />
- <ClInclude Include="..\include\vcpkg\commands.autocomplete.h" />
- <ClInclude Include="..\include\vcpkg\commands.buildexternal.h" />
- <ClInclude Include="..\include\vcpkg\commands.cache.h" />
- <ClInclude Include="..\include\vcpkg\commands.ci.h" />
- <ClInclude Include="..\include\vcpkg\commands.ciclean.h" />
- <ClInclude Include="..\include\vcpkg\commands.civerifyversions.h" />
- <ClInclude Include="..\include\vcpkg\commands.contact.h" />
- <ClInclude Include="..\include\vcpkg\commands.create.h" />
- <ClInclude Include="..\include\vcpkg\commands.dependinfo.h" />
- <ClInclude Include="..\include\vcpkg\commands.edit.h" />
- <ClInclude Include="..\include\vcpkg\commands.env.h" />
- <ClInclude Include="..\include\vcpkg\commands.fetch.h" />
- <ClInclude Include="..\include\vcpkg\commands.format-manifest.h" />
- <ClInclude Include="..\include\vcpkg\commands.hash.h" />
- <ClInclude Include="..\include\vcpkg\commands.info.h" />
- <ClInclude Include="..\include\vcpkg\commands.integrate.h" />
- <ClInclude Include="..\include\vcpkg\commands.interface.h" />
- <ClInclude Include="..\include\vcpkg\commands.list.h" />
- <ClInclude Include="..\include\vcpkg\commands.owns.h" />
- <ClInclude Include="..\include\vcpkg\commands.porthistory.h" />
- <ClInclude Include="..\include\vcpkg\commands.portsdiff.h" />
- <ClInclude Include="..\include\vcpkg\commands.search.h" />
- <ClInclude Include="..\include\vcpkg\commands.setinstalled.h" />
- <ClInclude Include="..\include\vcpkg\commands.upgrade.h" />
- <ClInclude Include="..\include\vcpkg\commands.version.h" />
- <ClInclude Include="..\include\vcpkg\commands.xvsinstances.h" />
- <ClInclude Include="..\include\vcpkg\dependencies.h" />
- <ClInclude Include="..\include\vcpkg\export.chocolatey.h" />
- <ClInclude Include="..\include\vcpkg\export.h" />
- <ClInclude Include="..\include\vcpkg\export.ifw.h" />
- <ClInclude Include="..\include\vcpkg\export.prefab.h" />
- <ClInclude Include="..\include\vcpkg\globalstate.h" />
- <ClInclude Include="..\include\vcpkg\help.h" />
- <ClInclude Include="..\include\vcpkg\input.h" />
- <ClInclude Include="..\include\vcpkg\install.h" />
- <ClInclude Include="..\include\vcpkg\platform-expression.h" />
- <ClInclude Include="..\include\vcpkg\metrics.h" />
- <ClInclude Include="..\include\vcpkg\packagespec.h" />
- <ClInclude Include="..\include\vcpkg\paragraphparser.h" />
- <ClInclude Include="..\include\vcpkg\paragraphs.h" />
- <ClInclude Include="..\include\vcpkg\portfileprovider.h" />
- <ClInclude Include="..\include\vcpkg\postbuildlint.h" />
- <ClInclude Include="..\include\vcpkg\postbuildlint.buildtype.h" />
- <ClInclude Include="..\include\vcpkg\registries.h" />
- <ClInclude Include="..\include\vcpkg\remove.h" />
- <ClInclude Include="..\include\vcpkg\sourceparagraph.h" />
- <ClInclude Include="..\include\vcpkg\statusparagraph.h" />
- <ClInclude Include="..\include\vcpkg\statusparagraphs.h" />
- <ClInclude Include="..\include\vcpkg\textrowcol.h" />
- <ClInclude Include="..\include\vcpkg\tools.h" />
- <ClInclude Include="..\include\vcpkg\triplet.h" />
- <ClInclude Include="..\include\vcpkg\update.h" />
- <ClInclude Include="..\include\vcpkg\userconfig.h" />
- <ClInclude Include="..\include\vcpkg\vcpkgcmdarguments.h" />
- <ClInclude Include="..\include\vcpkg\vcpkglib.h" />
- <ClInclude Include="..\include\vcpkg\vcpkgpaths.h" />
- <ClInclude Include="..\include\vcpkg\versiondeserializers.h" />
- <ClInclude Include="..\include\vcpkg\versions.h" />
- <ClInclude Include="..\include\vcpkg\versiont.h" />
- <ClInclude Include="..\include\vcpkg\visualstudio.h" />
- </ItemGroup>
- <ItemGroup>
- <ClCompile Include="..\src\pch.cpp">
- <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
- <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
- <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
- <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="..\src\vcpkg\archives.cpp" />
- <ClCompile Include="..\src\vcpkg\base\checks.cpp" />
- <ClCompile Include="..\src\vcpkg\base\chrono.cpp" />
- <ClCompile Include="..\src\vcpkg\base\cofffilereader.cpp" />
- <ClCompile Include="..\src\vcpkg\base\downloads.cpp" />
- <ClCompile Include="..\src\vcpkg\base\enums.cpp" />
- <ClCompile Include="..\src\vcpkg\base\files.cpp" />
- <ClCompile Include="..\src\vcpkg\base\hash.cpp" />
- <ClCompile Include="..\src\vcpkg\base\json.cpp" />
- <ClCompile Include="..\src\vcpkg\base\machinetype.cpp" />
- <ClCompile Include="..\src\vcpkg\base\parse.cpp" />
- <ClCompile Include="..\src\vcpkg\base\strings.cpp" />
- <ClCompile Include="..\src\vcpkg\base\stringview.cpp" />
- <ClCompile Include="..\src\vcpkg\base\system.cpp" />
- <ClCompile Include="..\src\vcpkg\base\system.print.cpp" />
- <ClCompile Include="..\src\vcpkg\base\system.process.cpp" />
- <ClCompile Include="..\src\vcpkg\base\unicode.cpp" />
- <ClCompile Include="..\src\vcpkg\base\xmlserializer.cpp" />
- <ClCompile Include="..\src\vcpkg\binarycaching.cpp" />
- <ClCompile Include="..\src\vcpkg\binaryparagraph.cpp" />
- <ClCompile Include="..\src\vcpkg\build.cpp" />
- <ClCompile Include="..\src\vcpkg\buildenvironment.cpp" />
- <ClCompile Include="..\src\vcpkg\cmakevars.cpp" />
- <ClCompile Include="..\src\vcpkg\commands.add-version.cpp" />
- <ClCompile Include="..\src\vcpkg\commands.autocomplete.cpp" />
- <ClCompile Include="..\src\vcpkg\commands.buildexternal.cpp" />
- <ClCompile Include="..\src\vcpkg\commands.cache.cpp" />
- <ClCompile Include="..\src\vcpkg\commands.ci.cpp" />
- <ClCompile Include="..\src\vcpkg\commands.ciclean.cpp" />
- <ClCompile Include="..\src\vcpkg\commands.civerifyversions.cpp" />
- <ClCompile Include="..\src\vcpkg\commands.contact.cpp" />
- <ClCompile Include="..\src\vcpkg\commands.cpp" />
- <ClCompile Include="..\src\vcpkg\commands.create.cpp" />
- <ClCompile Include="..\src\vcpkg\commands.dependinfo.cpp" />
- <ClCompile Include="..\src\vcpkg\commands.edit.cpp" />
- <ClCompile Include="..\src\vcpkg\commands.env.cpp" />
- <ClCompile Include="..\src\vcpkg\commands.fetch.cpp" />
- <ClCompile Include="..\src\vcpkg\commands.format-manifest.cpp" />
- <ClCompile Include="..\src\vcpkg\commands.hash.cpp" />
- <ClCompile Include="..\src\vcpkg\commands.info.cpp" />
- <ClCompile Include="..\src\vcpkg\commands.integrate.cpp" />
- <ClCompile Include="..\src\vcpkg\commands.list.cpp" />
- <ClCompile Include="..\src\vcpkg\commands.owns.cpp" />
- <ClCompile Include="..\src\vcpkg\commands.porthistory.cpp" />
- <ClCompile Include="..\src\vcpkg\commands.portsdiff.cpp" />
- <ClCompile Include="..\src\vcpkg\commands.search.cpp" />
- <ClCompile Include="..\src\vcpkg\commands.setinstalled.cpp" />
- <ClCompile Include="..\src\vcpkg\commands.upgrade.cpp" />
- <ClCompile Include="..\src\vcpkg\commands.upload-metrics.cpp" />
- <ClCompile Include="..\src\vcpkg\commands.version.cpp" />
- <ClCompile Include="..\src\vcpkg\commands.xvsinstances.cpp" />
- <ClCompile Include="..\src\vcpkg\configuration.cpp" />
- <ClCompile Include="..\src\vcpkg\dependencies.cpp" />
- <ClCompile Include="..\src\vcpkg\export.cpp" />
- <ClCompile Include="..\src\vcpkg\export.chocolatey.cpp" />
- <ClCompile Include="..\src\vcpkg\export.ifw.cpp" />
- <ClCompile Include="..\src\vcpkg\export.prefab.cpp" />
- <ClCompile Include="..\src\vcpkg\globalstate.cpp" />
- <ClCompile Include="..\src\vcpkg\help.cpp" />
- <ClCompile Include="..\src\vcpkg\input.cpp" />
- <ClCompile Include="..\src\vcpkg\install.cpp" />
- <ClCompile Include="..\src\vcpkg\platform-expression.cpp" />
- <ClCompile Include="..\src\vcpkg\metrics.cpp" />
- <ClCompile Include="..\src\vcpkg\packagespec.cpp" />
- <ClCompile Include="..\src\vcpkg\paragraphs.cpp" />
- <ClCompile Include="..\src\vcpkg\portfileprovider.cpp" />
- <ClCompile Include="..\src\vcpkg\postbuildlint.buildtype.cpp" />
- <ClCompile Include="..\src\vcpkg\postbuildlint.cpp" />
- <ClCompile Include="..\src\vcpkg\registries.cpp" />
- <ClCompile Include="..\src\vcpkg\remove.cpp" />
- <ClCompile Include="..\src\vcpkg\sourceparagraph.cpp" />
- <ClCompile Include="..\src\vcpkg\statusparagraph.cpp" />
- <ClCompile Include="..\src\vcpkg\statusparagraphs.cpp" />
- <ClCompile Include="..\src\vcpkg\tools.cpp" />
- <ClCompile Include="..\src\vcpkg\triplet.cpp" />
- <ClCompile Include="..\src\vcpkg\update.cpp" />
- <ClCompile Include="..\src\vcpkg\userconfig.cpp" />
- <ClCompile Include="..\src\vcpkg\vcpkgcmdarguments.cpp" />
- <ClCompile Include="..\src\vcpkg\vcpkglib.cpp" />
- <ClCompile Include="..\src\vcpkg\vcpkgpaths.cpp" />
- <ClCompile Include="..\src\vcpkg\versiondeserializers.cpp" />
- <ClCompile Include="..\src\vcpkg\versions.cpp" />
- <ClCompile Include="..\src\vcpkg\versiont.cpp" />
- <ClCompile Include="..\src\vcpkg\visualstudio.cpp" />
- <ClCompile Include="..\src\vcpkg.cpp" />
- </ItemGroup>
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
- <ImportGroup Label="ExtensionTargets">
- </ImportGroup>
-</Project>